Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(857)

Side by Side Diff: media/base/android/media_drm_bridge.cc

Issue 1747073003: EME on Android: Improve accuracy of Key System availability. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/android/media_drm_bridge.h" 5 #include "media/base/android/media_drm_bridge.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <algorithm> 8 #include <algorithm>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/android/build_info.h" 11 #include "base/android/build_info.h"
12 #include "base/android/jni_array.h" 12 #include "base/android/jni_array.h"
13 #include "base/android/jni_string.h" 13 #include "base/android/jni_string.h"
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/callback_helpers.h" 15 #include "base/callback_helpers.h"
16 #include "base/containers/hash_tables.h" 16 #include "base/containers/hash_tables.h"
17 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
18 #include "base/location.h" 18 #include "base/location.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/macros.h" 20 #include "base/macros.h"
21 #include "base/single_thread_task_runner.h" 21 #include "base/single_thread_task_runner.h"
22 #include "base/strings/string_number_conversions.h" 22 #include "base/strings/string_number_conversions.h"
23 #include "base/strings/string_util.h" 23 #include "base/strings/string_util.h"
24 #include "base/sys_byteorder.h" 24 #include "base/sys_byteorder.h"
25 #include "base/sys_info.h" 25 #include "base/sys_info.h"
26 #include "base/thread_task_runner_handle.h" 26 #include "base/thread_task_runner_handle.h"
27 #include "jni/MediaDrmBridge_jni.h" 27 #include "jni/MediaDrmBridge_jni.h"
28 #include "media/base/android/media_client_android.h" 28 #include "media/base/android/media_client_android.h"
29 #include "media/base/android/media_codec_util.h"
29 #include "media/base/android/media_drm_bridge_delegate.h" 30 #include "media/base/android/media_drm_bridge_delegate.h"
30 #include "media/base/android/provision_fetcher.h" 31 #include "media/base/android/provision_fetcher.h"
31 #include "media/base/cdm_key_information.h" 32 #include "media/base/cdm_key_information.h"
32 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. 33 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
33 34
34 using base::android::AttachCurrentThread; 35 using base::android::AttachCurrentThread;
35 using base::android::ConvertUTF8ToJavaString; 36 using base::android::ConvertUTF8ToJavaString;
36 using base::android::ConvertJavaStringToUTF8; 37 using base::android::ConvertJavaStringToUTF8;
37 using base::android::JavaByteArrayToByteVector; 38 using base::android::JavaByteArrayToByteVector;
38 using base::android::ScopedJavaGlobalRef; 39 using base::android::ScopedJavaGlobalRef;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 base::LazyInstance<KeySystemManager>::Leaky g_key_system_manager = 168 base::LazyInstance<KeySystemManager>::Leaky g_key_system_manager =
168 LAZY_INSTANCE_INITIALIZER; 169 LAZY_INSTANCE_INITIALIZER;
169 170
170 // Checks whether |key_system| is supported with |container_mime_type|. Only 171 // Checks whether |key_system| is supported with |container_mime_type|. Only
171 // checks |key_system| support if |container_mime_type| is empty. 172 // checks |key_system| support if |container_mime_type| is empty.
172 // TODO(xhwang): The |container_mime_type| is not the same as contentType in 173 // TODO(xhwang): The |container_mime_type| is not the same as contentType in
173 // the EME spec. Revisit this once the spec issue with initData type is 174 // the EME spec. Revisit this once the spec issue with initData type is
174 // resolved. 175 // resolved.
175 bool IsKeySystemSupportedWithTypeImpl(const std::string& key_system, 176 bool IsKeySystemSupportedWithTypeImpl(const std::string& key_system,
176 const std::string& container_mime_type) { 177 const std::string& container_mime_type) {
177 if (!MediaDrmBridge::IsAvailable()) 178 DCHECK(MediaDrmBridge::IsAvailable());
179
180 if (key_system.empty()) {
181 NOTREACHED();
178 return false; 182 return false;
183 }
179 184
180 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); 185 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system);
181 if (scheme_uuid.empty()) 186 if (scheme_uuid.empty())
182 return false; 187 return false;
183 188
184 JNIEnv* env = AttachCurrentThread(); 189 JNIEnv* env = AttachCurrentThread();
185 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid = 190 ScopedJavaLocalRef<jbyteArray> j_scheme_uuid =
186 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size()); 191 base::android::ToJavaByteArray(env, &scheme_uuid[0], scheme_uuid.size());
187 ScopedJavaLocalRef<jstring> j_container_mime_type = 192 ScopedJavaLocalRef<jstring> j_container_mime_type =
188 ConvertUTF8ToJavaString(env, container_mime_type); 193 ConvertUTF8ToJavaString(env, container_mime_type);
(...skipping 19 matching lines...) Expand all
208 case MediaDrmBridge::SECURITY_LEVEL_DEFAULT: 213 case MediaDrmBridge::SECURITY_LEVEL_DEFAULT:
209 return ""; 214 return "";
210 case MediaDrmBridge::SECURITY_LEVEL_1: 215 case MediaDrmBridge::SECURITY_LEVEL_1:
211 return "L1"; 216 return "L1";
212 case MediaDrmBridge::SECURITY_LEVEL_3: 217 case MediaDrmBridge::SECURITY_LEVEL_3:
213 return "L3"; 218 return "L3";
214 } 219 }
215 return ""; 220 return "";
216 } 221 }
217 222
218 } // namespace 223 bool AreMediaDrmApisAvailable() {
219
220 // static
221 bool MediaDrmBridge::IsAvailable() {
222 if (base::android::BuildInfo::GetInstance()->sdk_int() < 19) 224 if (base::android::BuildInfo::GetInstance()->sdk_int() < 19)
223 return false; 225 return false;
224 226
225 int32_t os_major_version = 0; 227 int32_t os_major_version = 0;
226 int32_t os_minor_version = 0; 228 int32_t os_minor_version = 0;
227 int32_t os_bugfix_version = 0; 229 int32_t os_bugfix_version = 0;
228 base::SysInfo::OperatingSystemVersionNumbers( 230 base::SysInfo::OperatingSystemVersionNumbers(
229 &os_major_version, &os_minor_version, &os_bugfix_version); 231 &os_major_version, &os_minor_version, &os_bugfix_version);
230 if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0) 232 if (os_major_version == 4 && os_minor_version == 4 && os_bugfix_version == 0)
231 return false; 233 return false;
232 234
233 return true; 235 return true;
234 } 236 }
235 237
238 } // namespace
239
240 // MediaDrm is not generally usable without MediaCodec. Thus, both the MediaDrm
241 // APIs and MediaCodec APIs must be enabled and not blacklisted.
242 // static
243 bool MediaDrmBridge::IsAvailable() {
244 if (!AreMediaDrmApisAvailable())
245 return false;
246
247 return MediaCodecUtil::IsMediaCodecAvailable();
xhwang 2016/03/02 06:57:08 nit: how about: return AreMediaDrmApisAvailable()
ddorwin 2016/03/02 21:11:53 Done.
248 }
249
236 // static 250 // static
237 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { 251 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) {
238 return RegisterNativesImpl(env); 252 return RegisterNativesImpl(env);
239 } 253 }
240 254
241 // static 255 // static
242 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { 256 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) {
243 DCHECK(!key_system.empty()); 257 if (!MediaDrmBridge::IsAvailable())
258 return false;
259
244 return IsKeySystemSupportedWithTypeImpl(key_system, ""); 260 return IsKeySystemSupportedWithTypeImpl(key_system, "");
245 } 261 }
246 262
247 // static 263 // static
248 bool MediaDrmBridge::IsKeySystemSupportedWithType( 264 bool MediaDrmBridge::IsKeySystemSupportedWithType(
249 const std::string& key_system, 265 const std::string& key_system,
250 const std::string& container_mime_type) { 266 const std::string& container_mime_type) {
251 DCHECK(!key_system.empty() && !container_mime_type.empty()); 267 DCHECK(!container_mime_type.empty()) << "Call IsKeySystemSupported instead";
268
269 if (!MediaDrmBridge::IsAvailable())
270 return false;
271
252 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); 272 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type);
253 } 273 }
254 274
255 // static 275 // static
256 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { 276 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() {
277 if (!MediaDrmBridge::IsAvailable())
278 return std::vector<std::string>();
279
257 return g_key_system_manager.Get().GetPlatformKeySystemNames(); 280 return g_key_system_manager.Get().GetPlatformKeySystemNames();
258 } 281 }
259 282
260 // static 283 // static
261 scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create( 284 scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateInternal(
262 const std::string& key_system, 285 const std::string& key_system,
263 SecurityLevel security_level, 286 SecurityLevel security_level,
264 const CreateFetcherCB& create_fetcher_cb, 287 const CreateFetcherCB& create_fetcher_cb,
265 const SessionMessageCB& session_message_cb, 288 const SessionMessageCB& session_message_cb,
266 const SessionClosedCB& session_closed_cb, 289 const SessionClosedCB& session_closed_cb,
267 const LegacySessionErrorCB& legacy_session_error_cb, 290 const LegacySessionErrorCB& legacy_session_error_cb,
268 const SessionKeysChangeCB& session_keys_change_cb, 291 const SessionKeysChangeCB& session_keys_change_cb,
269 const SessionExpirationUpdateCB& session_expiration_update_cb) { 292 const SessionExpirationUpdateCB& session_expiration_update_cb) {
270 DVLOG(1) << __FUNCTION__; 293 // All paths requires the MediaDrmApis.
271 294 DCHECK(AreMediaDrmApisAvailable());
272 if (!IsAvailable())
273 return nullptr;
274 295
275 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); 296 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system);
276 if (scheme_uuid.empty()) 297 if (scheme_uuid.empty())
277 return nullptr; 298 return nullptr;
278 299
279 scoped_refptr<MediaDrmBridge> media_drm_bridge(new MediaDrmBridge( 300 scoped_refptr<MediaDrmBridge> media_drm_bridge(new MediaDrmBridge(
280 scheme_uuid, security_level, create_fetcher_cb, session_message_cb, 301 scheme_uuid, security_level, create_fetcher_cb, session_message_cb,
281 session_closed_cb, legacy_session_error_cb, session_keys_change_cb, 302 session_closed_cb, legacy_session_error_cb, session_keys_change_cb,
282 session_expiration_update_cb)); 303 session_expiration_update_cb));
283 304
284 if (media_drm_bridge->j_media_drm_.is_null()) 305 if (media_drm_bridge->j_media_drm_.is_null())
285 media_drm_bridge = nullptr; 306 media_drm_bridge = nullptr;
286 307
287 return media_drm_bridge; 308 return media_drm_bridge;
288 } 309 }
289 310
290 // static 311 // static
312 scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create(
313 const std::string& key_system,
314 SecurityLevel security_level,
315 const CreateFetcherCB& create_fetcher_cb,
316 const SessionMessageCB& session_message_cb,
317 const SessionClosedCB& session_closed_cb,
318 const LegacySessionErrorCB& legacy_session_error_cb,
319 const SessionKeysChangeCB& session_keys_change_cb,
320 const SessionExpirationUpdateCB& session_expiration_update_cb) {
321 DVLOG(1) << __FUNCTION__;
322
323 if (!IsAvailable())
324 return nullptr;
325
326 return CreateInternal(key_system, security_level, create_fetcher_cb,
327 session_message_cb, session_closed_cb,
328 legacy_session_error_cb, session_keys_change_cb,
329 session_expiration_update_cb);
330 }
331
332 // static
291 scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport( 333 scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport(
292 const std::string& key_system, 334 const std::string& key_system,
293 SecurityLevel security_level, 335 SecurityLevel security_level,
294 const CreateFetcherCB& create_fetcher_cb) { 336 const CreateFetcherCB& create_fetcher_cb) {
295 DVLOG(1) << __FUNCTION__; 337 DVLOG(1) << __FUNCTION__;
296 338
339 // Sessions won't be used so decoding capability is not required.
340 if (!AreMediaDrmApisAvailable())
341 return nullptr;
342
297 return MediaDrmBridge::Create(key_system, security_level, create_fetcher_cb, 343 return MediaDrmBridge::Create(key_system, security_level, create_fetcher_cb,
298 SessionMessageCB(), SessionClosedCB(), 344 SessionMessageCB(), SessionClosedCB(),
299 LegacySessionErrorCB(), SessionKeysChangeCB(), 345 LegacySessionErrorCB(), SessionKeysChangeCB(),
300 SessionExpirationUpdateCB()); 346 SessionExpirationUpdateCB());
301 } 347 }
302 348
303 void MediaDrmBridge::SetServerCertificate( 349 void MediaDrmBridge::SetServerCertificate(
304 const std::vector<uint8_t>& certificate, 350 const std::vector<uint8_t>& certificate,
305 scoped_ptr<media::SimpleCdmPromise> promise) { 351 scoped_ptr<media::SimpleCdmPromise> promise) {
306 DVLOG(2) << __FUNCTION__ << "(" << certificate.size() << " bytes)"; 352 DVLOG(2) << __FUNCTION__ << "(" << certificate.size() << " bytes)";
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 JNIEnv* env = AttachCurrentThread(); 876 JNIEnv* env = AttachCurrentThread();
831 877
832 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray( 878 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray(
833 env, reinterpret_cast<const uint8_t*>(response.data()), response.size()); 879 env, reinterpret_cast<const uint8_t*>(response.data()), response.size());
834 880
835 Java_MediaDrmBridge_processProvisionResponse(env, j_media_drm_.obj(), success, 881 Java_MediaDrmBridge_processProvisionResponse(env, j_media_drm_.obj(), success,
836 j_response.obj()); 882 j_response.obj());
837 } 883 }
838 884
839 } // namespace media 885 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698