Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / renderer / media / chrome_key_systems.cc
blob71937fd87c2f95bbd5622b15a47e60dcc7b3d57b
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 "content/public/renderer/render_thread.h"
17 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
19 // The following must be after widevine_cdm_version.h.
21 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
22 #include <gnu/libc-version.h>
23 #include "base/version.h"
24 #endif
26 #if defined(OS_ANDROID)
27 #include "chrome/common/encrypted_media_messages_android.h"
28 #endif
30 using content::KeySystemInfo;
31 using content::SupportedCodecs;
33 #if defined(ENABLE_PEPPER_CDMS)
34 static bool IsPepperCdmRegistered(
35 const std::string& pepper_type,
36 std::vector<base::string16>* additional_param_names,
37 std::vector<base::string16>* additional_param_values) {
38 bool is_registered = false;
39 content::RenderThread::Get()->Send(
40 new ChromeViewHostMsg_IsInternalPluginRegisteredForMimeType(
41 pepper_type,
42 &is_registered,
43 additional_param_names,
44 additional_param_values));
46 return is_registered;
49 // External Clear Key (used for testing).
50 static void AddExternalClearKey(
51 std::vector<KeySystemInfo>* concrete_key_systems) {
52 static const char kExternalClearKeyKeySystem[] =
53 "org.chromium.externalclearkey";
54 static const char kExternalClearKeyDecryptOnlyKeySystem[] =
55 "org.chromium.externalclearkey.decryptonly";
56 static const char kExternalClearKeyFileIOTestKeySystem[] =
57 "org.chromium.externalclearkey.fileiotest";
58 static const char kExternalClearKeyInitializeFailKeySystem[] =
59 "org.chromium.externalclearkey.initializefail";
60 static const char kExternalClearKeyCrashKeySystem[] =
61 "org.chromium.externalclearkey.crash";
62 static const char kExternalClearKeyPepperType[] =
63 "application/x-ppapi-clearkey-cdm";
65 std::vector<base::string16> additional_param_names;
66 std::vector<base::string16> additional_param_values;
67 if (!IsPepperCdmRegistered(kExternalClearKeyPepperType,
68 &additional_param_names,
69 &additional_param_values)) {
70 return;
73 KeySystemInfo info(kExternalClearKeyKeySystem);
75 info.supported_codecs = content::EME_CODEC_WEBM_ALL;
76 #if defined(USE_PROPRIETARY_CODECS)
77 info.supported_codecs |= content::EME_CODEC_MP4_ALL;
78 #endif // defined(USE_PROPRIETARY_CODECS)
80 info.pepper_type = kExternalClearKeyPepperType;
82 concrete_key_systems->push_back(info);
84 // Add support of decrypt-only mode in ClearKeyCdm.
85 info.key_system = kExternalClearKeyDecryptOnlyKeySystem;
86 concrete_key_systems->push_back(info);
88 // A key system that triggers FileIO test in ClearKeyCdm.
89 info.key_system = kExternalClearKeyFileIOTestKeySystem;
90 concrete_key_systems->push_back(info);
92 // A key system that Chrome thinks is supported by ClearKeyCdm, but actually
93 // will be refused by ClearKeyCdm. This is to test the CDM initialization
94 // failure case.
95 info.key_system = kExternalClearKeyInitializeFailKeySystem;
96 concrete_key_systems->push_back(info);
98 // A key system that triggers a crash in ClearKeyCdm.
99 info.key_system = kExternalClearKeyCrashKeySystem;
100 concrete_key_systems->push_back(info);
102 #endif // defined(ENABLE_PEPPER_CDMS)
105 #if defined(WIDEVINE_CDM_AVAILABLE)
106 enum WidevineCdmType {
107 WIDEVINE,
108 WIDEVINE_HR,
109 #if defined(OS_ANDROID)
110 WIDEVINE_HR_NON_COMPOSITING,
111 #endif
114 #if !defined(OS_ANDROID)
115 static bool IsWidevineHrSupported() {
116 // TODO(jrummell): Need to call CheckPlatformState() but it is
117 // asynchronous, and needs to be done in the browser.
118 return false;
120 #endif
122 // Return |name|'s parent key system.
123 static std::string GetDirectParentName(std::string name) {
124 int last_period = name.find_last_of('.');
125 DCHECK_GT(last_period, 0);
126 return name.substr(0, last_period);
129 static void AddWidevineWithCodecs(
130 WidevineCdmType widevine_cdm_type,
131 SupportedCodecs supported_codecs,
132 std::vector<KeySystemInfo>* concrete_key_systems) {
133 KeySystemInfo info(kWidevineKeySystem);
135 switch (widevine_cdm_type) {
136 case WIDEVINE:
137 // For standard Widevine, add parent name.
138 info.parent_key_system = GetDirectParentName(kWidevineKeySystem);
139 break;
140 case WIDEVINE_HR:
141 info.key_system.append(".hr");
142 break;
143 #if defined(OS_ANDROID)
144 case WIDEVINE_HR_NON_COMPOSITING:
145 info.key_system.append(".hrnoncompositing");
146 break;
147 #endif
148 default:
149 NOTREACHED();
152 // TODO(xhwang): A container or an initDataType may be supported even though
153 // there are no codecs supported in that container. Fix this when we support
154 // initDataType.
155 info.supported_codecs = supported_codecs;
157 #if defined(ENABLE_PEPPER_CDMS)
158 info.pepper_type = kWidevineCdmPluginMimeType;
159 #endif // defined(ENABLE_PEPPER_CDMS)
161 concrete_key_systems->push_back(info);
164 #if defined(ENABLE_PEPPER_CDMS)
165 // When the adapter is registered, a name-value pair is inserted in
166 // additional_param_* that lists the supported codecs. The name is "codecs" and
167 // the value is a comma-delimited list of codecs.
168 // This function finds "codecs" and parses the value into the vector |codecs|.
169 // Converts the codec strings to UTF-8 since we only expect ASCII strings and
170 // this simplifies the rest of the code in this file.
171 void GetSupportedCodecs(
172 const std::vector<base::string16>& additional_param_names,
173 const std::vector<base::string16>& additional_param_values,
174 std::vector<std::string>* codecs) {
175 DCHECK(codecs->empty());
176 DCHECK_EQ(additional_param_names.size(), additional_param_values.size());
177 for (size_t i = 0; i < additional_param_names.size(); ++i) {
178 if (additional_param_names[i] ==
179 base::ASCIIToUTF16(kCdmSupportedCodecsParamName)) {
180 const base::string16& codecs_string16 = additional_param_values[i];
181 std::string codecs_string;
182 if (!base::UTF16ToUTF8(codecs_string16.c_str(),
183 codecs_string16.length(),
184 &codecs_string)) {
185 DLOG(WARNING) << "Non-UTF-8 codecs string.";
186 // Continue using the best effort conversion.
188 base::SplitString(codecs_string,
189 kCdmSupportedCodecsValueDelimiter,
190 codecs);
191 break;
196 static void AddPepperBasedWidevine(
197 std::vector<KeySystemInfo>* concrete_key_systems) {
198 #if defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
199 Version glibc_version(gnu_get_libc_version());
200 DCHECK(glibc_version.IsValid());
201 if (glibc_version.IsOlderThan(WIDEVINE_CDM_MIN_GLIBC_VERSION))
202 return;
203 #endif // defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
205 std::vector<base::string16> additional_param_names;
206 std::vector<base::string16> additional_param_values;
207 if (!IsPepperCdmRegistered(kWidevineCdmPluginMimeType,
208 &additional_param_names,
209 &additional_param_values)) {
210 DVLOG(1) << "Widevine CDM is not currently available.";
211 return;
214 std::vector<std::string> codecs;
215 GetSupportedCodecs(additional_param_names, additional_param_values, &codecs);
217 SupportedCodecs supported_codecs = content::EME_CODEC_NONE;
218 for (size_t i = 0; i < codecs.size(); ++i) {
219 if (codecs[i] == kCdmSupportedCodecVorbis)
220 supported_codecs |= content::EME_CODEC_WEBM_VORBIS;
221 if (codecs[i] == kCdmSupportedCodecVp8)
222 supported_codecs |= content::EME_CODEC_WEBM_VP8;
223 if (codecs[i] == kCdmSupportedCodecVp9)
224 supported_codecs |= content::EME_CODEC_WEBM_VP9;
225 #if defined(USE_PROPRIETARY_CODECS)
226 if (codecs[i] == kCdmSupportedCodecAac)
227 supported_codecs |= content::EME_CODEC_MP4_AAC;
228 if (codecs[i] == kCdmSupportedCodecAvc1)
229 supported_codecs |= content::EME_CODEC_MP4_AVC1;
230 #endif // defined(USE_PROPRIETARY_CODECS)
233 AddWidevineWithCodecs(WIDEVINE, supported_codecs, concrete_key_systems);
235 if (IsWidevineHrSupported())
236 AddWidevineWithCodecs(WIDEVINE_HR, supported_codecs, concrete_key_systems);
238 #elif defined(OS_ANDROID)
239 static void AddAndroidWidevine(
240 std::vector<KeySystemInfo>* concrete_key_systems) {
241 SupportedKeySystemRequest request;
242 SupportedKeySystemResponse response;
244 request.key_system = kWidevineKeySystem;
245 request.codecs = content::EME_CODEC_WEBM_ALL | content::EME_CODEC_MP4_ALL;
246 content::RenderThread::Get()->Send(
247 new ChromeViewHostMsg_GetSupportedKeySystems(request, &response));
248 DCHECK(response.compositing_codecs & content::EME_CODEC_ALL)
249 << "unrecognized codec";
250 DCHECK(response.non_compositing_codecs & content::EME_CODEC_ALL)
251 << "unrecognized codec";
252 if (response.compositing_codecs != content::EME_CODEC_NONE) {
253 AddWidevineWithCodecs(
254 WIDEVINE,
255 static_cast<SupportedCodecs>(response.compositing_codecs),
256 concrete_key_systems);
259 if (response.non_compositing_codecs != content::EME_CODEC_NONE) {
260 AddWidevineWithCodecs(
261 WIDEVINE_HR_NON_COMPOSITING,
262 static_cast<SupportedCodecs>(response.non_compositing_codecs),
263 concrete_key_systems);
266 #endif // defined(ENABLE_PEPPER_CDMS)
267 #endif // defined(WIDEVINE_CDM_AVAILABLE)
269 void AddChromeKeySystems(std::vector<KeySystemInfo>* key_systems_info) {
270 #if defined(ENABLE_PEPPER_CDMS)
271 AddExternalClearKey(key_systems_info);
272 #endif
274 #if defined(WIDEVINE_CDM_AVAILABLE)
275 #if defined(ENABLE_PEPPER_CDMS)
276 AddPepperBasedWidevine(key_systems_info);
277 #elif defined(OS_ANDROID)
278 AddAndroidWidevine(key_systems_info);
279 #endif
280 #endif