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

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: feedback 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 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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698