Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |