1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165

media / cdm / supported_cdm_versions.h [blame]

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_CDM_SUPPORTED_CDM_VERSIONS_H_
#define MEDIA_CDM_SUPPORTED_CDM_VERSIONS_H_

#include <stddef.h>

#include <array>

#include "media/base/media_export.h"
#include "media/cdm/api/content_decryption_module.h"

// A library CDM interface is "supported" if it's implemented by CdmAdapter and
// CdmWrapper. Typically multiple CDM interfaces are supported:
// - The latest stable CDM interface.
// - Previous stable CDM interface(s), for supporting older CDMs.
// - Experimental CDM interface(s), for development.
//
// A library CDM interface is "enabled" if it's enabled at runtime, e.g. being
// able to be registered and creating CDM instances. Experimental CDM interfaces
// must not be enabled by default.
//
// Whether a CDM interface is enabled can also be overridden by using command
// line switch switches::kOverrideEnabledCdmInterfaceVersion for finer control
// in a test environment or for local debugging, including enabling experimental
// CDM interfaces.

namespace media {

struct SupportedVersion {
  int version;
  bool enabled;
};

constexpr std::array<SupportedVersion, 3> kSupportedCdmInterfaceVersions = {{
    {10, true},
    {11, false},
    {12, false},
}};

// In most cases CdmInterface::kVersion == CdmInterface::Host::kVersion. However
// this is not guaranteed. For example, a newer CDM interface may use an
// existing CDM host. So we keep CDM host support separate from CDM interface
// support. In CdmInterfaceTraits we also static assert that for supported CDM
// interface, CdmInterface::Host::kVersion must also be supported.
constexpr int kMinSupportedCdmHostVersion = 10;
constexpr int kMaxSupportedCdmHostVersion = 12;

constexpr bool IsSupportedCdmModuleVersion(int version) {
  return version == CDM_MODULE_VERSION;
}

// Returns whether the CDM interface of |version| is supported in the
// implementation.
constexpr bool IsSupportedCdmInterfaceVersion(int version) {
  for (size_t i = 0; i < kSupportedCdmInterfaceVersions.size(); ++i) {
    if (kSupportedCdmInterfaceVersions[i].version == version)
      return true;
  }

  return false;
}

// Returns whether the CDM host interface of |version| is supported in the
// implementation. Currently there's no way to disable a supported CDM host
// interface at run time.
constexpr bool IsSupportedCdmHostVersion(int version) {
  return kMinSupportedCdmHostVersion <= version &&
         version <= kMaxSupportedCdmHostVersion;
}

// Returns whether the CDM interface of |version| is enabled by default.
constexpr bool IsCdmInterfaceVersionEnabledByDefault(int version) {
  for (size_t i = 0; i < kSupportedCdmInterfaceVersions.size(); ++i) {
    if (kSupportedCdmInterfaceVersions[i].version == version)
      return kSupportedCdmInterfaceVersions[i].enabled;
  }

  return false;
}

// Returns whether the CDM interface of |version| is supported in the
// implementation and enabled at runtime.
MEDIA_EXPORT bool IsSupportedAndEnabledCdmInterfaceVersion(int version);

typedef bool (*VersionCheckFunc)(int version);

// Returns true if all versions in the range [min_version, max_version] and no
// versions outside the range are supported, and false otherwise.
constexpr bool CheckVersions(VersionCheckFunc check_func,
                             int min_version,
                             int max_version) {
  // For simplicity, only check one version out of the range boundary.
  if (check_func(min_version - 1) || check_func(max_version + 1))
    return false;

  for (int version = min_version; version <= max_version; ++version) {
    if (!check_func(version))
      return false;
  }

  return true;
}

// Ensures CDM interface versions in and only in the range [min_version,
// max_version] are supported in the implementation.
constexpr bool CheckSupportedCdmInterfaceVersions(int min_version,
                                                  int max_version) {
  return CheckVersions(IsSupportedCdmInterfaceVersion, min_version,
                       max_version);
}

// Ensures CDM host interface versions in and only in the range [min_version,
// max_version] are supported in the implementation.
constexpr bool CheckSupportedCdmHostVersions(int min_version, int max_version) {
  return CheckVersions(IsSupportedCdmHostVersion, min_version, max_version);
}

// Traits for CDM Interfaces
template <int CdmInterfaceVersion>
struct CdmInterfaceTraits {};

// TODO(xhwang): CDM_9 support has been removed; consider to use a macro to
// help define CdmInterfaceTraits specializations.
template <>
struct CdmInterfaceTraits<10> {
  using CdmInterface = cdm::ContentDecryptionModule_10;
  static_assert(CdmInterface::kVersion == 10, "CDM interface version mismatch");
  static_assert(IsSupportedCdmHostVersion(CdmInterface::Host::kVersion),
                "Host not supported");
  static_assert(
      CdmInterface::kIsStable ||
          !IsCdmInterfaceVersionEnabledByDefault(CdmInterface::kVersion),
      "Experimental CDM interface should not be enabled by default");
};

template <>
struct CdmInterfaceTraits<11> {
  using CdmInterface = cdm::ContentDecryptionModule_11;
  static_assert(CdmInterface::kVersion == 11, "CDM interface version mismatch");
  static_assert(IsSupportedCdmHostVersion(CdmInterface::Host::kVersion),
                "Host not supported");
  static_assert(
      CdmInterface::kIsStable ||
          !IsCdmInterfaceVersionEnabledByDefault(CdmInterface::kVersion),
      "Experimental CDM interface should not be enabled by default");
};

template <>
struct CdmInterfaceTraits<12> {
  using CdmInterface = cdm::ContentDecryptionModule_12;
  static_assert(CdmInterface::kVersion == 12, "CDM interface version mismatch");
  static_assert(IsSupportedCdmHostVersion(CdmInterface::Host::kVersion),
                "Host not supported");
  static_assert(
      CdmInterface::kIsStable ||
          !IsCdmInterfaceVersionEnabledByDefault(CdmInterface::kVersion),
      "Experimental CDM interface should not be enabled by default");
};

}  // namespace media

#endif  // MEDIA_CDM_SUPPORTED_CDM_VERSIONS_H_