/** * Try to open a session, do provisioning if necessary. * @param allowProvisioning if provisioning is allowed, set this to false when calling from * processing provision response. * @return true on success, false otherwise. */ private boolean openInternal(boolean allowProvisioning) { if (isOpen()) { // Already opened return true; } try { sessionId = mediaDrm.openSession(); eventDispatcher.dispatch(DefaultDrmSessionEventListener::onDrmSessionAcquired); mediaCrypto = mediaDrm.createMediaCrypto(sessionId); state = STATE_OPENED; return true; } catch (NotProvisionedException e) { if (allowProvisioning) { provisioningManager.provisionRequired(this); } else { onError(e); } } catch (Exception e) { onError(e); } return false; }
private boolean restoreKeys() { try { mediaDrm.restoreKeys(sessionId, offlineLicenseKeySetId); return true; } catch (Exception e) { Log.e(TAG, "Error trying to restore Widevine keys.", e); onError(e); } return false; }
private void setStubKeySetId(byte[] keySetId) throws android.media.NotProvisionedException, android.media.DeniedByServerException { when(mediaDrm.provideKeyResponse(any(byte[].class), any(byte[].class))).thenReturn(keySetId); }
@SuppressWarnings("PMD.AvoidCatchingGenericException") // We are forced to catch Exception as ResourceBusyException is minSdk 19 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) @Override public DrmSession<FrameworkMediaCrypto> acquireSession(Looper playbackLooper, DrmInitData drmInitData) { DrmSession<FrameworkMediaCrypto> drmSession; try { SessionId sessionId = SessionId.of(mediaDrm.openSession()); FrameworkMediaCrypto mediaCrypto = mediaDrm.createMediaCrypto(sessionId.asBytes()); mediaDrm.restoreKeys(sessionId.asBytes(), keySetIdToRestore.asBytes()); drmSession = new LocalDrmSession(mediaCrypto, keySetIdToRestore, sessionId); } catch (Exception exception) { drmSession = new InvalidDrmSession(new DrmSession.DrmSessionException(exception)); notifyErrorListener(drmSession); } return drmSession; }
@Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(mediaDrm.openSession()).thenReturn(new byte[] {1, 2, 3}); offlineLicenseHelper = new OfflineLicenseHelper<>(C.WIDEVINE_UUID, mediaDrm, mediaDrmCallback, null); }
@Test public void givenValidMediaDrm_whenAcquiringSession_thenRestoresKeys() throws MediaCryptoException { given(mediaDrm.createMediaCrypto(SESSION_ID.asBytes())).willReturn(frameworkMediaCrypto); localDrmSessionManager.acquireSession(IGNORED_LOOPER, IGNORED_DRM_DATA); verify(mediaDrm).restoreKeys(SESSION_ID.asBytes(), KEY_SET_ID_TO_RESTORE.asBytes()); }
/** * @return True if the session is closed and cleaned up, false otherwise. */ public boolean release() { if (--openCount == 0) { state = STATE_RELEASED; postResponseHandler.removeCallbacksAndMessages(null); postRequestHandler.removeCallbacksAndMessages(null); postRequestHandler = null; requestHandlerThread.quit(); requestHandlerThread = null; mediaCrypto = null; lastException = null; currentKeyRequest = null; currentProvisionRequest = null; if (sessionId != null) { mediaDrm.closeSession(sessionId); sessionId = null; eventDispatcher.dispatch(DefaultDrmSessionEventListener::onDrmSessionReleased); } return true; } return false; }
@Test public void givenValidMediaDrm_whenAcquiringSession_thenReturnsLocalDrmSession() throws MediaCryptoException { given(mediaDrm.createMediaCrypto(SESSION_ID.asBytes())).willReturn(frameworkMediaCrypto); DrmSession<FrameworkMediaCrypto> drmSession = localDrmSessionManager.acquireSession(IGNORED_LOOPER, IGNORED_DRM_DATA); LocalDrmSession localDrmSession = new LocalDrmSession(frameworkMediaCrypto, KEY_SET_ID_TO_RESTORE, SESSION_ID); assertThat(drmSession).isEqualTo(localDrmSession); }
@Override public Map<String, String> queryKeyStatus() { return sessionId == null ? null : mediaDrm.queryKeyStatus(sessionId); }
private void postKeyRequest(int type, boolean allowRetry) { byte[] scope = type == ExoMediaDrm.KEY_TYPE_RELEASE ? offlineLicenseKeySetId : sessionId; try { currentKeyRequest = mediaDrm.getKeyRequest(scope, schemeDatas, type, optionalKeyRequestParameters); postRequestHandler.post(MSG_KEYS, currentKeyRequest, allowRetry); } catch (Exception e) { onKeysError(e); } }
@RequiresApi(api = Build.VERSION_CODES.KITKAT) @Test public void givenOpeningSessionError_whenAcquiringSession_thenNotifiesErrorEventListenerOnHandler() throws MediaDrmException { given(mediaDrm.openSession()).willThrow(new ResourceBusyException("resource is busy")); localDrmSessionManager.acquireSession(IGNORED_LOOPER, IGNORED_DRM_DATA); ArgumentCaptor<Runnable> argumentCaptor = ArgumentCaptor.forClass(Runnable.class); verify(handler).post(argumentCaptor.capture()); argumentCaptor.getValue().run(); verify(eventListener).onDrmSessionManagerError(any(DrmSession.DrmSessionException.class)); }
@Override public void releaseSession(DrmSession<FrameworkMediaCrypto> drmSession) { FrameworkDrmSession frameworkDrmSession = (FrameworkDrmSession) drmSession; SessionId sessionId = frameworkDrmSession.getSessionId(); mediaDrm.closeSession(sessionId.asBytes()); } }
private void setStubLicenseAndPlaybackDurationValues( long licenseDuration, long playbackDuration) { HashMap<String, String> keyStatus = new HashMap<>(); keyStatus.put( WidevineUtil.PROPERTY_LICENSE_DURATION_REMAINING, String.valueOf(licenseDuration)); keyStatus.put( WidevineUtil.PROPERTY_PLAYBACK_DURATION_REMAINING, String.valueOf(playbackDuration)); when(mediaDrm.queryKeyStatus(any(byte[].class))).thenReturn(keyStatus); }
@Before public void setUp() throws MediaDrmException, MediaCryptoException { frameworkMediaCrypto = FrameworkMediaCryptoFixture.aFrameworkMediaCrypto().build(); given(mediaDrm.openSession()).willReturn(SESSION_ID.asBytes()); localDrmSessionManager = new LocalDrmSessionManager( KEY_SET_ID_TO_RESTORE, mediaDrm, DRM_SCHEME, handler, eventListener ); }
@Test public void givenAcquiredSession_whenReleasingSession_thenClosesCurrentSession() { DrmSession<FrameworkMediaCrypto> drmSession = new LocalDrmSession(frameworkMediaCrypto, KEY_SET_ID_TO_RESTORE, SESSION_ID); localDrmSessionManager.releaseSession(drmSession); verify(mediaDrm).closeSession(SESSION_ID.asBytes()); } }
private void onKeyResponse(Object request, Object response) { if (request != currentKeyRequest || !isOpen()) { // This event is stale. return; } currentKeyRequest = null; if (response instanceof Exception) { onKeysError((Exception) response); return; } try { byte[] responseData = (byte[]) response; if (mode == DefaultDrmSessionManager.MODE_RELEASE) { mediaDrm.provideKeyResponse(offlineLicenseKeySetId, responseData); eventDispatcher.dispatch(DefaultDrmSessionEventListener::onDrmKeysRestored); } else { byte[] keySetId = mediaDrm.provideKeyResponse(sessionId, responseData); if ((mode == DefaultDrmSessionManager.MODE_DOWNLOAD || (mode == DefaultDrmSessionManager.MODE_PLAYBACK && offlineLicenseKeySetId != null)) && keySetId != null && keySetId.length != 0) { offlineLicenseKeySetId = keySetId; } state = STATE_OPENED_WITH_KEYS; eventDispatcher.dispatch(DefaultDrmSessionEventListener::onDrmKeysLoaded); } } catch (Exception e) { onKeysError(e); } }
@RequiresApi(api = Build.VERSION_CODES.KITKAT) @Test public void givenOpeningSessionError_whenAcquiringSession_thenReturnsInvalidDrmSession() throws MediaDrmException { ResourceBusyException resourceBusyException = new ResourceBusyException("resource is busy"); given(mediaDrm.openSession()).willThrow(resourceBusyException); DrmSession<FrameworkMediaCrypto> drmSession = localDrmSessionManager.acquireSession(IGNORED_LOOPER, IGNORED_DRM_DATA); assertThat(drmSession).isInstanceOf(InvalidDrmSession.class); assertThat(drmSession.getError().getCause()).isEqualTo(resourceBusyException); }