Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / renderer / media / chrome_key_systems.cc
blob80112758b1d362405b3dda636aea98f5405371ed
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/renderer/media/chrome_key_systems.h"
7 #include <string>
8 #include <vector>
10 #include "base/logging.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/common/render_messages.h"
15 #include "components/cdm/renderer/widevine_key_systems.h"
16 #include "content/public/renderer/render_thread.h"
17 #include "media/base/eme_constants.h"
19 #if defined(OS_ANDROID)
20 #include "components/cdm/renderer/android_key_systems.h"
21 #endif
23 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
25 // The following must be after widevine_cdm_version.h.
27 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
28 #include <gnu/libc-version.h>
29 #include "base/version.h"
30 #endif
32 using media::KeySystemInfo;
33 using media::SupportedCodecs;
35 #if defined(ENABLE_PEPPER_CDMS)
36 static bool IsPepperCdmAvailable(
37 const std::string& pepper_type,
38 std::vector<base::string16>* additional_param_names,
39 std::vector<base::string16>* additional_param_values) {
40 bool is_available = false;
41 content::RenderThread::Get()->Send(
42 new ChromeViewHostMsg_IsInternalPluginAvailableForMimeType(
43 pepper_type,
44 &is_available,
45 additional_param_names,
46 additional_param_values));
48 return is_available;
51 // External Clear Key (used for testing).
52 static void AddExternalClearKey(
53 std::vector<KeySystemInfo>* concrete_key_systems) {
54 static const char kExternalClearKeyKeySystem[] =
55 "org.chromium.externalclearkey";
56 static const char kExternalClearKeyDecryptOnlyKeySystem[] =
57 "org.chromium.externalclearkey.decryptonly";
58 static const char kExternalClearKeyFileIOTestKeySystem[] =
59 "org.chromium.externalclearkey.fileiotest";
60 static const char kExternalClearKeyInitializeFailKeySystem[] =
61 "org.chromium.externalclearkey.initializefail";
62 static const char kExternalClearKeyCrashKeySystem[] =
63 "org.chromium.externalclearkey.crash";
64 static const char kExternalClearKeyPepperType[] =
65 "application/x-ppapi-clearkey-cdm";
67 std::vector<base::string16> additional_param_names;
68 std::vector<base::string16> additional_param_values;
69 if (!IsPepperCdmAvailable(kExternalClearKeyPepperType,
70 &additional_param_names,
71 &additional_param_values)) {
72 return;
75 KeySystemInfo info;
76 info.key_system = kExternalClearKeyKeySystem;
78 info.supported_init_data_types =
79 media::kInitDataTypeMaskWebM | media::kInitDataTypeMaskKeyIds;
80 info.supported_codecs = media::EME_CODEC_WEBM_ALL;
81 #if defined(USE_PROPRIETARY_CODECS)
82 info.supported_init_data_types |= media::kInitDataTypeMaskCenc;
83 info.supported_codecs |= media::EME_CODEC_MP4_ALL;
84 #endif // defined(USE_PROPRIETARY_CODECS)
86 info.max_audio_robustness = media::EmeRobustness::EMPTY;
87 info.max_video_robustness = media::EmeRobustness::EMPTY;
89 // Persistent sessions are faked.
90 info.persistent_license_support = media::EmeSessionTypeSupport::SUPPORTED;
91 info.persistent_release_message_support =
92 media::EmeSessionTypeSupport::NOT_SUPPORTED;
93 info.persistent_state_support = media::EmeFeatureSupport::REQUESTABLE;
94 info.distinctive_identifier_support = media::EmeFeatureSupport::NOT_SUPPORTED;
96 info.pepper_type = kExternalClearKeyPepperType;
98 concrete_key_systems->push_back(info);
100 // Add support of decrypt-only mode in ClearKeyCdm.
101 info.key_system = kExternalClearKeyDecryptOnlyKeySystem;
102 concrete_key_systems->push_back(info);
104 // A key system that triggers FileIO test in ClearKeyCdm.
105 info.key_system = kExternalClearKeyFileIOTestKeySystem;
106 concrete_key_systems->push_back(info);
108 // A key system that Chrome thinks is supported by ClearKeyCdm, but actually
109 // will be refused by ClearKeyCdm. This is to test the CDM initialization
110 // failure case.
111 info.key_system = kExternalClearKeyInitializeFailKeySystem;
112 concrete_key_systems->push_back(info);
114 // A key system that triggers a crash in ClearKeyCdm.
115 info.key_system = kExternalClearKeyCrashKeySystem;
116 concrete_key_systems->push_back(info);
119 #if defined(WIDEVINE_CDM_AVAILABLE)
120 // This function finds "codecs" and parses the value into the vector |codecs|.
121 // Converts the codec strings to UTF-8 since we only expect ASCII strings and
122 // this simplifies the rest of the code in this file.
123 void GetSupportedCodecsForPepperCdm(
124 const std::vector<base::string16>& additional_param_names,
125 const std::vector<base::string16>& additional_param_values,
126 std::vector<std::string>* codecs) {
127 DCHECK(codecs->empty());
128 DCHECK_EQ(additional_param_names.size(), additional_param_values.size());
129 for (size_t i = 0; i < additional_param_names.size(); ++i) {
130 if (additional_param_names[i] ==
131 base::ASCIIToUTF16(kCdmSupportedCodecsParamName)) {
132 const base::string16& codecs_string16 = additional_param_values[i];
133 std::string codecs_string;
134 if (!base::UTF16ToUTF8(codecs_string16.c_str(),
135 codecs_string16.length(),
136 &codecs_string)) {
137 DLOG(WARNING) << "Non-UTF-8 codecs string.";
138 // Continue using the best effort conversion.
140 *codecs = base::SplitString(
141 codecs_string, std::string(1, kCdmSupportedCodecsValueDelimiter),
142 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
143 break;
148 static void AddPepperBasedWidevine(
149 std::vector<KeySystemInfo>* concrete_key_systems) {
150 #if defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
151 Version glibc_version(gnu_get_libc_version());
152 DCHECK(glibc_version.IsValid());
153 if (glibc_version.IsOlderThan(WIDEVINE_CDM_MIN_GLIBC_VERSION))
154 return;
155 #endif // defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
157 std::vector<base::string16> additional_param_names;
158 std::vector<base::string16> additional_param_values;
159 if (!IsPepperCdmAvailable(kWidevineCdmPluginMimeType,
160 &additional_param_names,
161 &additional_param_values)) {
162 DVLOG(1) << "Widevine CDM is not currently available.";
163 return;
166 std::vector<std::string> codecs;
167 GetSupportedCodecsForPepperCdm(additional_param_names,
168 additional_param_values,
169 &codecs);
171 SupportedCodecs supported_codecs = media::EME_CODEC_NONE;
173 // Audio codecs are always supported.
174 // TODO(sandersd): Distinguish these from those that are directly supported,
175 // as those may offer a higher level of protection.
176 supported_codecs |= media::EME_CODEC_WEBM_OPUS;
177 supported_codecs |= media::EME_CODEC_WEBM_VORBIS;
178 #if defined(USE_PROPRIETARY_CODECS)
179 supported_codecs |= media::EME_CODEC_MP4_AAC;
180 #endif // defined(USE_PROPRIETARY_CODECS)
182 for (size_t i = 0; i < codecs.size(); ++i) {
183 if (codecs[i] == kCdmSupportedCodecVp8)
184 supported_codecs |= media::EME_CODEC_WEBM_VP8;
185 if (codecs[i] == kCdmSupportedCodecVp9)
186 supported_codecs |= media::EME_CODEC_WEBM_VP9;
187 #if defined(USE_PROPRIETARY_CODECS)
188 if (codecs[i] == kCdmSupportedCodecAvc1)
189 supported_codecs |= media::EME_CODEC_MP4_AVC1;
190 #endif // defined(USE_PROPRIETARY_CODECS)
193 cdm::AddWidevineWithCodecs(
194 cdm::WIDEVINE, supported_codecs,
195 #if defined(OS_CHROMEOS)
196 media::EmeRobustness::HW_SECURE_ALL, // Maximum audio robustness.
197 media::EmeRobustness::HW_SECURE_ALL, // Maximim video robustness.
198 media::EmeSessionTypeSupport::
199 SUPPORTED_WITH_IDENTIFIER, // Persistent-license.
200 media::EmeSessionTypeSupport::
201 NOT_SUPPORTED, // Persistent-release-message.
202 media::EmeFeatureSupport::REQUESTABLE, // Persistent state.
203 media::EmeFeatureSupport::REQUESTABLE, // Distinctive identifier.
204 #else // (Desktop)
205 media::EmeRobustness::SW_SECURE_CRYPTO, // Maximum audio robustness.
206 media::EmeRobustness::SW_SECURE_DECODE, // Maximum video robustness.
207 media::EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-license.
208 media::EmeSessionTypeSupport::
209 NOT_SUPPORTED, // persistent-release-message.
210 media::EmeFeatureSupport::REQUESTABLE, // Persistent state.
211 media::EmeFeatureSupport::NOT_SUPPORTED, // Distinctive identifier.
212 #endif // defined(OS_CHROMEOS)
213 concrete_key_systems);
215 #endif // defined(WIDEVINE_CDM_AVAILABLE)
216 #endif // defined(ENABLE_PEPPER_CDMS)
218 void AddChromeKeySystems(std::vector<KeySystemInfo>* key_systems_info) {
219 #if defined(ENABLE_PEPPER_CDMS)
220 AddExternalClearKey(key_systems_info);
222 #if defined(WIDEVINE_CDM_AVAILABLE)
223 AddPepperBasedWidevine(key_systems_info);
224 #endif // defined(WIDEVINE_CDM_AVAILABLE)
225 #endif // defined(ENABLE_PEPPER_CDMS)
227 #if defined(OS_ANDROID)
228 cdm::AddAndroidWidevine(key_systems_info);
229 #endif // defined(OS_ANDROID)