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

Side by Side Diff: media/base/android/java/src/org/chromium/media/MediaDrmBridge.java

Issue 2790783002: [Clank] Add JNI interface for media persistent license storage (Closed)
Patch Set: Rename init Created 3 years, 8 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 2013 The Chromium Authors. All rights reserved. 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 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 package org.chromium.media; 5 package org.chromium.media;
6 6
7 import android.annotation.SuppressLint; 7 import android.annotation.SuppressLint;
8 import android.annotation.TargetApi; 8 import android.annotation.TargetApi;
9 import android.media.MediaCrypto; 9 import android.media.MediaCrypto;
10 import android.media.MediaDrm; 10 import android.media.MediaDrm;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 76
77 // A session only for the purpose of creating a MediaCrypto object. Created 77 // A session only for the purpose of creating a MediaCrypto object. Created
78 // after construction, or after the provisioning process is successfully 78 // after construction, or after the provisioning process is successfully
79 // completed. No getKeyRequest() should be called on |mMediaCryptoSession|. 79 // completed. No getKeyRequest() should be called on |mMediaCryptoSession|.
80 private SessionId mMediaCryptoSession; 80 private SessionId mMediaCryptoSession;
81 81
82 // The map of all opened sessions (excluding mMediaCryptoSession) to their 82 // The map of all opened sessions (excluding mMediaCryptoSession) to their
83 // associated meta data, e.g. mime types, key types. 83 // associated meta data, e.g. mime types, key types.
84 private MediaDrmSessionManager mSessionManager; 84 private MediaDrmSessionManager mSessionManager;
85 85
86 // The persistent storage to record origin provisioning informations.
87 private MediaDrmStorageBridge mStorage;
88
86 // The queue of all pending createSession() data. 89 // The queue of all pending createSession() data.
87 private ArrayDeque<PendingCreateSessionData> mPendingCreateSessionDataQueue; 90 private ArrayDeque<PendingCreateSessionData> mPendingCreateSessionDataQueue;
88 91
89 private boolean mResetDeviceCredentialsPending; 92 private boolean mResetDeviceCredentialsPending;
90 93
91 // MediaDrmBridge is waiting for provisioning response from the server. 94 // MediaDrmBridge is waiting for provisioning response from the server.
92 private boolean mProvisioningPending; 95 private boolean mProvisioningPending;
93 96
94 /** 97 /**
95 * An equivalent of MediaDrm.KeyStatus, which is only available on M+. 98 * An equivalent of MediaDrm.KeyStatus, which is only available on M+.
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 192
190 private boolean isNativeMediaDrmBridgeValid() { 193 private boolean isNativeMediaDrmBridgeValid() {
191 return mNativeMediaDrmBridge != INVALID_NATIVE_MEDIA_DRM_BRIDGE; 194 return mNativeMediaDrmBridge != INVALID_NATIVE_MEDIA_DRM_BRIDGE;
192 } 195 }
193 196
194 private boolean isWidevine() { 197 private boolean isWidevine() {
195 return mSchemeUUID.equals(WIDEVINE_UUID); 198 return mSchemeUUID.equals(WIDEVINE_UUID);
196 } 199 }
197 200
198 @TargetApi(Build.VERSION_CODES.M) 201 @TargetApi(Build.VERSION_CODES.M)
199 private MediaDrmBridge(UUID schemeUUID, long nativeMediaDrmBridge) 202 private MediaDrmBridge(UUID schemeUUID, long nativeMediaDrmBridge,
200 throws android.media.UnsupportedSchemeException { 203 long nativeMediaDrmStorageBridge) throws android.media.UnsupportedSc hemeException {
201 mSchemeUUID = schemeUUID; 204 mSchemeUUID = schemeUUID;
202 mMediaDrm = new MediaDrm(schemeUUID); 205 mMediaDrm = new MediaDrm(schemeUUID);
203 206
204 mNativeMediaDrmBridge = nativeMediaDrmBridge; 207 mNativeMediaDrmBridge = nativeMediaDrmBridge;
205 assert isNativeMediaDrmBridgeValid(); 208 assert isNativeMediaDrmBridgeValid();
206 209
207 mSessionManager = new MediaDrmSessionManager(); 210 mStorage = new MediaDrmStorageBridge(nativeMediaDrmStorageBridge);
211 mSessionManager = new MediaDrmSessionManager(mStorage);
212
208 mPendingCreateSessionDataQueue = new ArrayDeque<PendingCreateSessionData >(); 213 mPendingCreateSessionDataQueue = new ArrayDeque<PendingCreateSessionData >();
209 mResetDeviceCredentialsPending = false; 214 mResetDeviceCredentialsPending = false;
210 mProvisioningPending = false; 215 mProvisioningPending = false;
211 216
212 mMediaDrm.setOnEventListener(new EventListener()); 217 mMediaDrm.setOnEventListener(new EventListener());
213 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 218 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
214 mMediaDrm.setOnExpirationUpdateListener(new ExpirationUpdateListener (), null); 219 mMediaDrm.setOnExpirationUpdateListener(new ExpirationUpdateListener (), null);
215 mMediaDrm.setOnKeyStatusChangeListener(new KeyStatusChangeListener() , null); 220 mMediaDrm.setOnKeyStatusChangeListener(new KeyStatusChangeListener() , null);
216 } 221 }
217 222
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 return MediaDrm.isCryptoSchemeSupported(cryptoScheme, containerMimeType) ; 328 return MediaDrm.isCryptoSchemeSupported(cryptoScheme, containerMimeType) ;
324 } 329 }
325 330
326 /** 331 /**
327 * Create a new MediaDrmBridge from the crypto scheme UUID. 332 * Create a new MediaDrmBridge from the crypto scheme UUID.
328 * 333 *
329 * @param schemeUUID Crypto scheme UUID. 334 * @param schemeUUID Crypto scheme UUID.
330 * @param securityOrigin Security origin. Empty value means no need for orig in isolated storage. 335 * @param securityOrigin Security origin. Empty value means no need for orig in isolated storage.
331 * @param securityLevel Security level. If empty, the default one should be used. 336 * @param securityLevel Security level. If empty, the default one should be used.
332 * @param nativeMediaDrmBridge Native object of this class. 337 * @param nativeMediaDrmBridge Native object of this class.
338 * @param nativeMediaDrmStorageBridge Native object of persistent storage.
333 */ 339 */
334 @CalledByNative 340 @CalledByNative
335 private static MediaDrmBridge create(byte[] schemeUUID, String securityOrigi n, 341 private static MediaDrmBridge create(byte[] schemeUUID, String securityOrigi n,
336 String securityLevel, long nativeMediaDrmBridge) { 342 String securityLevel, long nativeMediaDrmBridge, long nativeMediaDrm StorageBridge) {
337 UUID cryptoScheme = getUUIDFromBytes(schemeUUID); 343 UUID cryptoScheme = getUUIDFromBytes(schemeUUID);
338 if (cryptoScheme == null || !MediaDrm.isCryptoSchemeSupported(cryptoSche me)) { 344 if (cryptoScheme == null || !MediaDrm.isCryptoSchemeSupported(cryptoSche me)) {
339 return null; 345 return null;
340 } 346 }
341 347
342 MediaDrmBridge mediaDrmBridge = null; 348 MediaDrmBridge mediaDrmBridge = null;
343 try { 349 try {
344 mediaDrmBridge = new MediaDrmBridge(cryptoScheme, nativeMediaDrmBrid ge); 350 mediaDrmBridge = new MediaDrmBridge(
351 cryptoScheme, nativeMediaDrmBridge, nativeMediaDrmStorageBri dge);
345 Log.d(TAG, "MediaDrmBridge successfully created."); 352 Log.d(TAG, "MediaDrmBridge successfully created.");
346 } catch (android.media.UnsupportedSchemeException e) { 353 } catch (android.media.UnsupportedSchemeException e) {
347 Log.e(TAG, "Unsupported DRM scheme", e); 354 Log.e(TAG, "Unsupported DRM scheme", e);
348 return null; 355 return null;
349 } catch (java.lang.IllegalArgumentException e) { 356 } catch (java.lang.IllegalArgumentException e) {
350 Log.e(TAG, "Failed to create MediaDrmBridge", e); 357 Log.e(TAG, "Failed to create MediaDrmBridge", e);
351 return null; 358 return null;
352 } catch (java.lang.IllegalStateException e) { 359 } catch (java.lang.IllegalStateException e) {
353 Log.e(TAG, "Failed to create MediaDrmBridge", e); 360 Log.e(TAG, "Failed to create MediaDrmBridge", e);
354 return null; 361 return null;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 try { 513 try {
507 // Some implementations don't have removeKeys, crbug/475632 514 // Some implementations don't have removeKeys, crbug/475632
508 mMediaDrm.removeKeys(sessionId.drmId()); 515 mMediaDrm.removeKeys(sessionId.drmId());
509 } catch (Exception e) { 516 } catch (Exception e) {
510 Log.e(TAG, "removeKeys failed: ", e); 517 Log.e(TAG, "removeKeys failed: ", e);
511 } 518 }
512 519
513 closeSessionNoException(sessionId); 520 closeSessionNoException(sessionId);
514 onSessionClosed(sessionId); 521 onSessionClosed(sessionId);
515 } 522 }
516 mSessionManager = new MediaDrmSessionManager(); 523 mSessionManager = new MediaDrmSessionManager(mStorage);
517 524
518 // Close mMediaCryptoSession if it's open or notify MediaCrypto 525 // Close mMediaCryptoSession if it's open or notify MediaCrypto
519 // creation failure if it's never successfully opened. 526 // creation failure if it's never successfully opened.
520 if (mMediaCryptoSession == null) { 527 if (mMediaCryptoSession == null) {
521 // MediaCrypto never notified. Notify a null one now. 528 // MediaCrypto never notified. Notify a null one now.
522 onMediaCryptoReady(null); 529 onMediaCryptoReady(null);
523 } else { 530 } else {
524 closeSessionNoException(mMediaCryptoSession); 531 closeSessionNoException(mMediaCryptoSession);
525 mMediaCryptoSession = null; 532 mMediaCryptoSession = null;
526 } 533 }
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 if (mResetDeviceCredentialsPending) { 917 if (mResetDeviceCredentialsPending) {
911 onResetDeviceCredentialsCompleted(success); 918 onResetDeviceCredentialsCompleted(success);
912 mResetDeviceCredentialsPending = false; 919 mResetDeviceCredentialsPending = false;
913 } 920 }
914 921
915 if (!success || (mMediaCryptoSession == null && !createMediaCrypto())) { 922 if (!success || (mMediaCryptoSession == null && !createMediaCrypto())) {
916 release(); 923 release();
917 return; 924 return;
918 } 925 }
919 926
920 processPendingCreateSessionData(); 927 if (!useOriginIsolatedStorage()) {
928 processPendingCreateSessionData();
929 return;
930 }
931
932 mStorage.onProvisioned(new Callback<Boolean>() {
933 @Override
934 public void onResult(Boolean initSuccess) {
935 if (!initSuccess) {
936 Log.e(TAG, "Failed to initialize storage for origin");
937 release();
938 return;
939 }
940
941 processPendingCreateSessionData();
942 }
943 });
944 }
945
946 private boolean useOriginIsolatedStorage() {
947 assert mMediaDrm != null;
948
949 boolean isMOrHigher = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
950 boolean isOriginSet = !isWidevine() || !mMediaDrm.getPropertyString(ORIG IN).isEmpty();
xhwang 2017/03/31 03:47:57 Is it ever possible that getPropertyString(ORIGIN)
yucliu1 2017/03/31 05:38:17 We should check origin only for M or higher device
xhwang 2017/03/31 06:25:50 At least for now, per-origin provisioning is a req
yucliu1 2017/03/31 18:42:30 Good point! And I think we want to disable the fea
951
952 return isMOrHigher && isOriginSet;
921 } 953 }
922 954
923 /** 955 /**
924 * Provides the provision response to MediaDrm. 956 * Provides the provision response to MediaDrm.
925 * 957 *
926 * @returns false if the response is invalid or on error, true otherwise. 958 * @returns false if the response is invalid or on error, true otherwise.
927 */ 959 */
928 boolean provideProvisionResponse(byte[] response) { 960 boolean provideProvisionResponse(byte[] response) {
929 if (response == null || response.length == 0) { 961 if (response == null || response.length == 0) {
930 Log.e(TAG, "Invalid provision response."); 962 Log.e(TAG, "Invalid provision response.");
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 long nativeMediaDrmBridge, byte[] emeSessionId, int requestType, byt e[] message); 1168 long nativeMediaDrmBridge, byte[] emeSessionId, int requestType, byt e[] message);
1137 private native void nativeOnSessionClosed(long nativeMediaDrmBridge, byte[] emeSessionId); 1169 private native void nativeOnSessionClosed(long nativeMediaDrmBridge, byte[] emeSessionId);
1138 private native void nativeOnSessionKeysChange(long nativeMediaDrmBridge, byt e[] emeSessionId, 1170 private native void nativeOnSessionKeysChange(long nativeMediaDrmBridge, byt e[] emeSessionId,
1139 Object[] keysInfo, boolean hasAdditionalUsableKey); 1171 Object[] keysInfo, boolean hasAdditionalUsableKey);
1140 private native void nativeOnSessionExpirationUpdate( 1172 private native void nativeOnSessionExpirationUpdate(
1141 long nativeMediaDrmBridge, byte[] emeSessionId, long expirationTime) ; 1173 long nativeMediaDrmBridge, byte[] emeSessionId, long expirationTime) ;
1142 1174
1143 private native void nativeOnResetDeviceCredentialsCompleted( 1175 private native void nativeOnResetDeviceCredentialsCompleted(
1144 long nativeMediaDrmBridge, boolean success); 1176 long nativeMediaDrmBridge, boolean success);
1145 } 1177 }
OLDNEW
« no previous file with comments | « media/base/android/android_util.cc ('k') | media/base/android/java/src/org/chromium/media/MediaDrmSessionManager.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698