| 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 return AreMediaDrmApisAvailable() && MediaCodecUtil::IsMediaCodecAvailable(); |
| 245 } |
| 246 |
| 236 // static | 247 // static |
| 237 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { | 248 bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { |
| 238 return RegisterNativesImpl(env); | 249 return RegisterNativesImpl(env); |
| 239 } | 250 } |
| 240 | 251 |
| 241 // static | 252 // static |
| 242 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { | 253 bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { |
| 243 DCHECK(!key_system.empty()); | 254 if (!MediaDrmBridge::IsAvailable()) |
| 255 return false; |
| 256 |
| 244 return IsKeySystemSupportedWithTypeImpl(key_system, ""); | 257 return IsKeySystemSupportedWithTypeImpl(key_system, ""); |
| 245 } | 258 } |
| 246 | 259 |
| 247 // static | 260 // static |
| 248 bool MediaDrmBridge::IsKeySystemSupportedWithType( | 261 bool MediaDrmBridge::IsKeySystemSupportedWithType( |
| 249 const std::string& key_system, | 262 const std::string& key_system, |
| 250 const std::string& container_mime_type) { | 263 const std::string& container_mime_type) { |
| 251 DCHECK(!key_system.empty() && !container_mime_type.empty()); | 264 DCHECK(!container_mime_type.empty()) << "Call IsKeySystemSupported instead"; |
| 265 |
| 266 if (!MediaDrmBridge::IsAvailable()) |
| 267 return false; |
| 268 |
| 252 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); | 269 return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); |
| 253 } | 270 } |
| 254 | 271 |
| 255 // static | 272 // static |
| 256 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { | 273 std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() { |
| 274 if (!MediaDrmBridge::IsAvailable()) |
| 275 return std::vector<std::string>(); |
| 276 |
| 257 return g_key_system_manager.Get().GetPlatformKeySystemNames(); | 277 return g_key_system_manager.Get().GetPlatformKeySystemNames(); |
| 258 } | 278 } |
| 259 | 279 |
| 260 // static | 280 // static |
| 261 scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create( | 281 scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateInternal( |
| 262 const std::string& key_system, | 282 const std::string& key_system, |
| 263 SecurityLevel security_level, | 283 SecurityLevel security_level, |
| 264 const CreateFetcherCB& create_fetcher_cb, | 284 const CreateFetcherCB& create_fetcher_cb, |
| 265 const SessionMessageCB& session_message_cb, | 285 const SessionMessageCB& session_message_cb, |
| 266 const SessionClosedCB& session_closed_cb, | 286 const SessionClosedCB& session_closed_cb, |
| 267 const LegacySessionErrorCB& legacy_session_error_cb, | 287 const LegacySessionErrorCB& legacy_session_error_cb, |
| 268 const SessionKeysChangeCB& session_keys_change_cb, | 288 const SessionKeysChangeCB& session_keys_change_cb, |
| 269 const SessionExpirationUpdateCB& session_expiration_update_cb) { | 289 const SessionExpirationUpdateCB& session_expiration_update_cb) { |
| 270 DVLOG(1) << __FUNCTION__; | 290 // All paths requires the MediaDrmApis. |
| 271 | 291 DCHECK(AreMediaDrmApisAvailable()); |
| 272 if (!IsAvailable()) | |
| 273 return nullptr; | |
| 274 | 292 |
| 275 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); | 293 UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system); |
| 276 if (scheme_uuid.empty()) | 294 if (scheme_uuid.empty()) |
| 277 return nullptr; | 295 return nullptr; |
| 278 | 296 |
| 279 scoped_refptr<MediaDrmBridge> media_drm_bridge(new MediaDrmBridge( | 297 scoped_refptr<MediaDrmBridge> media_drm_bridge(new MediaDrmBridge( |
| 280 scheme_uuid, security_level, create_fetcher_cb, session_message_cb, | 298 scheme_uuid, security_level, create_fetcher_cb, session_message_cb, |
| 281 session_closed_cb, legacy_session_error_cb, session_keys_change_cb, | 299 session_closed_cb, legacy_session_error_cb, session_keys_change_cb, |
| 282 session_expiration_update_cb)); | 300 session_expiration_update_cb)); |
| 283 | 301 |
| 284 if (media_drm_bridge->j_media_drm_.is_null()) | 302 if (media_drm_bridge->j_media_drm_.is_null()) |
| 285 media_drm_bridge = nullptr; | 303 media_drm_bridge = nullptr; |
| 286 | 304 |
| 287 return media_drm_bridge; | 305 return media_drm_bridge; |
| 288 } | 306 } |
| 289 | 307 |
| 290 // static | 308 // static |
| 309 scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create( |
| 310 const std::string& key_system, |
| 311 SecurityLevel security_level, |
| 312 const CreateFetcherCB& create_fetcher_cb, |
| 313 const SessionMessageCB& session_message_cb, |
| 314 const SessionClosedCB& session_closed_cb, |
| 315 const LegacySessionErrorCB& legacy_session_error_cb, |
| 316 const SessionKeysChangeCB& session_keys_change_cb, |
| 317 const SessionExpirationUpdateCB& session_expiration_update_cb) { |
| 318 DVLOG(1) << __FUNCTION__; |
| 319 |
| 320 if (!IsAvailable()) |
| 321 return nullptr; |
| 322 |
| 323 return CreateInternal(key_system, security_level, create_fetcher_cb, |
| 324 session_message_cb, session_closed_cb, |
| 325 legacy_session_error_cb, session_keys_change_cb, |
| 326 session_expiration_update_cb); |
| 327 } |
| 328 |
| 329 // static |
| 291 scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport( | 330 scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport( |
| 292 const std::string& key_system, | 331 const std::string& key_system, |
| 293 SecurityLevel security_level, | 332 SecurityLevel security_level, |
| 294 const CreateFetcherCB& create_fetcher_cb) { | 333 const CreateFetcherCB& create_fetcher_cb) { |
| 295 DVLOG(1) << __FUNCTION__; | 334 DVLOG(1) << __FUNCTION__; |
| 296 | 335 |
| 336 // Sessions won't be used so decoding capability is not required. |
| 337 if (!AreMediaDrmApisAvailable()) |
| 338 return nullptr; |
| 339 |
| 297 return MediaDrmBridge::Create(key_system, security_level, create_fetcher_cb, | 340 return MediaDrmBridge::Create(key_system, security_level, create_fetcher_cb, |
| 298 SessionMessageCB(), SessionClosedCB(), | 341 SessionMessageCB(), SessionClosedCB(), |
| 299 LegacySessionErrorCB(), SessionKeysChangeCB(), | 342 LegacySessionErrorCB(), SessionKeysChangeCB(), |
| 300 SessionExpirationUpdateCB()); | 343 SessionExpirationUpdateCB()); |
| 301 } | 344 } |
| 302 | 345 |
| 303 void MediaDrmBridge::SetServerCertificate( | 346 void MediaDrmBridge::SetServerCertificate( |
| 304 const std::vector<uint8_t>& certificate, | 347 const std::vector<uint8_t>& certificate, |
| 305 scoped_ptr<media::SimpleCdmPromise> promise) { | 348 scoped_ptr<media::SimpleCdmPromise> promise) { |
| 306 DVLOG(2) << __FUNCTION__ << "(" << certificate.size() << " bytes)"; | 349 DVLOG(2) << __FUNCTION__ << "(" << certificate.size() << " bytes)"; |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 JNIEnv* env = AttachCurrentThread(); | 873 JNIEnv* env = AttachCurrentThread(); |
| 831 | 874 |
| 832 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray( | 875 ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray( |
| 833 env, reinterpret_cast<const uint8_t*>(response.data()), response.size()); | 876 env, reinterpret_cast<const uint8_t*>(response.data()), response.size()); |
| 834 | 877 |
| 835 Java_MediaDrmBridge_processProvisionResponse(env, j_media_drm_.obj(), success, | 878 Java_MediaDrmBridge_processProvisionResponse(env, j_media_drm_.obj(), success, |
| 836 j_response.obj()); | 879 j_response.obj()); |
| 837 } | 880 } |
| 838 | 881 |
| 839 } // namespace media | 882 } // namespace media |
| OLD | NEW |