/** * Instantiates a new instance which uses Widevine CDM. Call {@link #release()} when the instance * is no longer required. * * @param defaultLicenseUrl The default license URL. Used for key requests that do not specify * their own license URL. * @param forceDefaultLicenseUrl Whether to use {@code defaultLicenseUrl} for key requests that * include their own license URL. * @param httpDataSourceFactory A factory from which to obtain {@link HttpDataSource} instances. * @return A new instance which uses Widevine CDM. * @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be * instantiated. */ public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance( String defaultLicenseUrl, boolean forceDefaultLicenseUrl, Factory httpDataSourceFactory) throws UnsupportedDrmException { return newWidevineInstance(defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory, null); }
private void releaseLicense() throws DrmSessionException { offlineLicenseHelper.releaseLicense(offlineLicenseKeySetId); offlineLicenseKeySetId = null; }
/** * Releases an offline license. * * @param offlineLicenseKeySetId The key set id of the license to be released. * @throws DrmSessionException Thrown when a DRM session error occurs. */ public synchronized void releaseLicense(byte[] offlineLicenseKeySetId) throws DrmSessionException { Assertions.checkNotNull(offlineLicenseKeySetId); blockingKeyRequest(DefaultDrmSessionManager.MODE_RELEASE, offlineLicenseKeySetId, null); }
@Test public void testDownloadRenewReleaseKey() throws Exception { setStubLicenseAndPlaybackDurationValues(1000, 200); byte[] keySetId = {2, 5, 8}; setStubKeySetId(keySetId); byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData()); assertOfflineLicenseKeySetIdEqual(keySetId, offlineLicenseKeySetId); byte[] keySetId2 = {6, 7, 0, 1, 4}; setStubKeySetId(keySetId2); byte[] offlineLicenseKeySetId2 = offlineLicenseHelper.renewLicense(offlineLicenseKeySetId); assertOfflineLicenseKeySetIdEqual(keySetId2, offlineLicenseKeySetId2); offlineLicenseHelper.releaseLicense(offlineLicenseKeySetId2); }
@Test public void testGetLicenseDurationRemainingSec() throws Exception { long licenseDuration = 1000; int playbackDuration = 200; setStubLicenseAndPlaybackDurationValues(licenseDuration, playbackDuration); setDefaultStubKeySetId(); byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData()); Pair<Long, Long> licenseDurationRemainingSec = offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId); assertThat(licenseDurationRemainingSec.first).isEqualTo(licenseDuration); assertThat(licenseDurationRemainingSec.second).isEqualTo(playbackDuration); }
@Test public void testDownloadLicenseFailsIfNullInitData() throws Exception { try { offlineLicenseHelper.downloadLicense(null); fail(); } catch (IllegalArgumentException e) { // Expected. } }
@After public void tearDown() throws Exception { offlineLicenseHelper.release(); offlineLicenseHelper = null; }
@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 testWidevineOfflineExpiredLicenseV22() throws Exception { if (Util.SDK_INT < 22) { return; // Pass. } downloadLicense(); // Wait until the license expires long licenseDuration = offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId).first; assertWithMessage( "License duration should be less than 30 sec. " + "Server settings might have changed.") .that(licenseDuration < 30) .isTrue(); while (licenseDuration > 0) { synchronized (this) { wait(licenseDuration * 1000 + 2000); } long previousDuration = licenseDuration; licenseDuration = offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId).first; assertWithMessage("License duration should be decreasing.") .that(previousDuration > licenseDuration) .isTrue(); } // DefaultDrmSessionManager should renew the license and stream play fine testRunner.run(); }
@Test public void testWidevineOfflineLicenseV22() throws Exception { if (Util.SDK_INT < 22) { return; // Pass. } downloadLicense(); testRunner.run(); // Renew license after playback should still work offlineLicenseKeySetId = offlineLicenseHelper.renewLicense(offlineLicenseKeySetId); assertThat(offlineLicenseKeySetId).isNotNull(); }
private byte[] blockingKeyRequest(@Mode int licenseMode, byte[] offlineLicenseKeySetId, DrmInitData drmInitData) throws DrmSessionException { DrmSession<T> drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId, drmInitData); DrmSessionException error = drmSession.getError(); byte[] keySetId = drmSession.getOfflineLicenseKeySetId(); drmSessionManager.releaseSession(drmSession); if (error != null) { throw error; } return keySetId; }
@Test public void testGetLicenseDurationRemainingSecExpiredLicense() throws Exception { long licenseDuration = 0; int playbackDuration = 0; setStubLicenseAndPlaybackDurationValues(licenseDuration, playbackDuration); setDefaultStubKeySetId(); byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData()); Pair<Long, Long> licenseDurationRemainingSec = offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId); assertThat(licenseDurationRemainingSec.first).isEqualTo(licenseDuration); assertThat(licenseDurationRemainingSec.second).isEqualTo(playbackDuration); }
@Test public void testDownloadLicenseFailsIfNoKeySetIdIsReturned() throws Exception { setStubLicenseAndPlaybackDurationValues(1000, 200); byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData()); assertThat(offlineLicenseKeySetId).isNull(); }
@After public void tearDown() throws Exception { testRunner = null; if (offlineLicenseKeySetId != null) { releaseLicense(); } if (offlineLicenseHelper != null) { offlineLicenseHelper.release(); } offlineLicenseHelper = null; httpDataSourceFactory = null; }
/** * Instantiates a new instance which uses Widevine CDM. Call {@link #release()} when the instance * is no longer required. * * @param defaultLicenseUrl The default license URL. Used for key requests that do not specify * their own license URL. * @param forceDefaultLicenseUrl Whether to use {@code defaultLicenseUrl} for key requests that * include their own license URL. * @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument * to {@link MediaDrm#getKeyRequest(byte[], byte[], String, int, HashMap)}. May be null. * @return A new instance which uses Widevine CDM. * @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be * instantiated. * @see DefaultDrmSessionManager#DefaultDrmSessionManager(java.util.UUID, ExoMediaDrm, * MediaDrmCallback, HashMap, Handler, DefaultDrmSessionEventListener) */ public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance( String defaultLicenseUrl, boolean forceDefaultLicenseUrl, Factory httpDataSourceFactory, HashMap<String, String> optionalKeyRequestParameters) throws UnsupportedDrmException { return new OfflineLicenseHelper<>(C.WIDEVINE_UUID, FrameworkMediaDrm.newInstance(C.WIDEVINE_UUID), new HttpMediaDrmCallback(defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory), optionalKeyRequestParameters); }
@Test public void testWidevineOfflineLicenseExpiresOnPauseV22() throws Exception { if (Util.SDK_INT < 22) { return; // Pass. } downloadLicense(); // During playback pause until the license expires then continue playback Pair<Long, Long> licenseDurationRemainingSec = offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId); long licenseDuration = licenseDurationRemainingSec.first; assertWithMessage( "License duration should be less than 30 sec. " + "Server settings might have changed.") .that(licenseDuration < 30) .isTrue(); ActionSchedule schedule = new ActionSchedule.Builder(TAG) .waitForPlaybackState(Player.STATE_READY) .delay(3000).pause().delay(licenseDuration * 1000 + 2000).play().build(); // DefaultDrmSessionManager should renew the license and stream play fine testRunner.setActionSchedule(schedule).run(); }
/** * Returns the remaining license and playback durations in seconds, for an offline license. * * @param offlineLicenseKeySetId The key set id of the license. * @return The remaining license and playback durations, in seconds. * @throws DrmSessionException Thrown when a DRM session error occurs. */ public synchronized Pair<Long, Long> getLicenseDurationRemainingSec(byte[] offlineLicenseKeySetId) throws DrmSessionException { Assertions.checkNotNull(offlineLicenseKeySetId); DrmSession<T> drmSession = openBlockingKeyRequest(DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, null); DrmSessionException error = drmSession.getError(); Pair<Long, Long> licenseDurationRemainingSec = WidevineUtil.getLicenseDurationRemainingSec(drmSession); drmSessionManager.releaseSession(drmSession); if (error != null) { if (error.getCause() instanceof KeysExpiredException) { return Pair.create(0L, 0L); } throw error; } return licenseDurationRemainingSec; }
@Test public void testDownloadLicenseDoesNotFailIfDurationNotAvailable() throws Exception { setDefaultStubKeySetId(); byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData()); assertThat(offlineLicenseKeySetId).isNotNull(); }
/** * Instantiates a new instance which uses Widevine CDM. Call {@link #release()} when the instance * is no longer required. * * @param defaultLicenseUrl The default license URL. Used for key requests that do not specify * their own license URL. * @param httpDataSourceFactory A factory from which to obtain {@link HttpDataSource} instances. * @return A new instance which uses Widevine CDM. * @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be * instantiated. */ public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance( String defaultLicenseUrl, Factory httpDataSourceFactory) throws UnsupportedDrmException { return newWidevineInstance(defaultLicenseUrl, false, httpDataSourceFactory, null); }
/** * Renews an offline license. * * @param offlineLicenseKeySetId The key set id of the license to be renewed. * @return The renewed offline license key set id. * @throws DrmSessionException Thrown when a DRM session error occurs. */ public synchronized byte[] renewLicense(byte[] offlineLicenseKeySetId) throws DrmSessionException { Assertions.checkNotNull(offlineLicenseKeySetId); return blockingKeyRequest(DefaultDrmSessionManager.MODE_DOWNLOAD, offlineLicenseKeySetId, null); }