diff --git a/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java index bbfadf34af9..6c7b72522ab 100644 --- a/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java @@ -70,8 +70,6 @@ import java.net.CookieHandler; import java.net.CookieManager; import java.net.CookiePolicy; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; /** @@ -239,19 +237,9 @@ private void initializePlayer() { if (drmSchemeUuid != null) { String drmLicenseUrl = intent.getStringExtra(DRM_LICENSE_URL); String[] keyRequestPropertiesArray = intent.getStringArrayExtra(DRM_KEY_REQUEST_PROPERTIES); - Map keyRequestProperties; - if (keyRequestPropertiesArray == null || keyRequestPropertiesArray.length < 2) { - keyRequestProperties = null; - } else { - keyRequestProperties = new HashMap<>(); - for (int i = 0; i < keyRequestPropertiesArray.length - 1; i += 2) { - keyRequestProperties.put(keyRequestPropertiesArray[i], - keyRequestPropertiesArray[i + 1]); - } - } try { drmSessionManager = buildDrmSessionManager(drmSchemeUuid, drmLicenseUrl, - keyRequestProperties); + keyRequestPropertiesArray); } catch (UnsupportedDrmException e) { int errorStringId = Util.SDK_INT < 18 ? R.string.error_drm_not_supported : (e.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME @@ -349,12 +337,18 @@ private MediaSource buildMediaSource(Uri uri, String overrideExtension) { } private DrmSessionManager buildDrmSessionManager(UUID uuid, - String licenseUrl, Map keyRequestProperties) throws UnsupportedDrmException { + String licenseUrl, String[] keyRequestPropertiesArray) throws UnsupportedDrmException { if (Util.SDK_INT < 18) { return null; } HttpMediaDrmCallback drmCallback = new HttpMediaDrmCallback(licenseUrl, - buildHttpDataSourceFactory(false), keyRequestProperties); + buildHttpDataSourceFactory(false)); + if (keyRequestPropertiesArray != null) { + for (int i = 0; i < keyRequestPropertiesArray.length - 1; i += 2) { + drmCallback.setKeyRequestProperty(keyRequestPropertiesArray[i], + keyRequestPropertiesArray[i + 1]); + } + } return new DefaultDrmSessionManager<>(uuid, FrameworkMediaDrm.newInstance(uuid), drmCallback, null, mainHandler, eventLogger); } diff --git a/library/src/main/java/com/google/android/exoplayer2/drm/HttpMediaDrmCallback.java b/library/src/main/java/com/google/android/exoplayer2/drm/HttpMediaDrmCallback.java index e0c9ca52968..f9d5efffb15 100644 --- a/library/src/main/java/com/google/android/exoplayer2/drm/HttpMediaDrmCallback.java +++ b/library/src/main/java/com/google/android/exoplayer2/drm/HttpMediaDrmCallback.java @@ -24,6 +24,8 @@ import com.google.android.exoplayer2.upstream.DataSourceInputStream; import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.HttpDataSource; +import com.google.android.exoplayer2.upstream.HttpDataSource.Factory; +import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Util; import java.io.IOException; import java.util.HashMap; @@ -57,21 +59,62 @@ public HttpMediaDrmCallback(String defaultUrl, HttpDataSource.Factory dataSource } /** + * @deprecated Use {@link HttpMediaDrmCallback#HttpMediaDrmCallback(String, Factory)}. Request + * properties can be set by calling {@link #setKeyRequestProperty(String, String)}. * @param defaultUrl The default license URL. * @param dataSourceFactory A factory from which to obtain {@link HttpDataSource} instances. * @param keyRequestProperties Request properties to set when making key requests, or null. */ + @Deprecated public HttpMediaDrmCallback(String defaultUrl, HttpDataSource.Factory dataSourceFactory, Map keyRequestProperties) { this.dataSourceFactory = dataSourceFactory; this.defaultUrl = defaultUrl; - this.keyRequestProperties = keyRequestProperties; + this.keyRequestProperties = new HashMap<>(); + if (keyRequestProperties != null) { + this.keyRequestProperties.putAll(keyRequestProperties); + } + } + + /** + * Sets a header for key requests made by the callback. + * + * @param name The name of the header field. + * @param value The value of the field. + */ + public void setKeyRequestProperty(String name, String value) { + Assertions.checkNotNull(name); + Assertions.checkNotNull(value); + synchronized (keyRequestProperties) { + keyRequestProperties.put(name, value); + } + } + + /** + * Clears a header for key requests made by the callback. + * + * @param name The name of the header field. + */ + public void clearKeyRequestProperty(String name) { + Assertions.checkNotNull(name); + synchronized (keyRequestProperties) { + keyRequestProperties.remove(name); + } + } + + /** + * Clears all headers for key requests made by the callback. + */ + public void clearAllKeyRequestProperties() { + synchronized (keyRequestProperties) { + keyRequestProperties.clear(); + } } @Override public byte[] executeProvisionRequest(UUID uuid, ProvisionRequest request) throws IOException { String url = request.getDefaultUrl() + "&signedRequest=" + new String(request.getData()); - return executePost(url, new byte[0], null); + return executePost(dataSourceFactory, url, new byte[0], null); } @Override @@ -85,14 +128,14 @@ public byte[] executeKeyRequest(UUID uuid, KeyRequest request) throws Exception if (C.PLAYREADY_UUID.equals(uuid)) { requestProperties.putAll(PLAYREADY_KEY_REQUEST_PROPERTIES); } - if (keyRequestProperties != null) { + synchronized (keyRequestProperties) { requestProperties.putAll(keyRequestProperties); } - return executePost(url, request.getData(), requestProperties); + return executePost(dataSourceFactory, url, request.getData(), requestProperties); } - private byte[] executePost(String url, byte[] data, Map requestProperties) - throws IOException { + private static byte[] executePost(HttpDataSource.Factory dataSourceFactory, String url, + byte[] data, Map requestProperties) throws IOException { HttpDataSource dataSource = dataSourceFactory.createDataSource(); if (requestProperties != null) { for (Map.Entry requestProperty : requestProperties.entrySet()) { diff --git a/library/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java b/library/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java index a11d65d4d33..f4a65931b67 100644 --- a/library/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java +++ b/library/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java @@ -93,7 +93,7 @@ public static DashManifest downloadManifest(HttpDataSource dataSource, String ma public static OfflineLicenseHelper newWidevineInstance( String licenseUrl, Factory httpDataSourceFactory) throws UnsupportedDrmException { return newWidevineInstance( - new HttpMediaDrmCallback(licenseUrl, httpDataSourceFactory, null), null); + new HttpMediaDrmCallback(licenseUrl, httpDataSourceFactory), null); } /** diff --git a/library/src/main/java/com/google/android/exoplayer2/upstream/HttpDataSource.java b/library/src/main/java/com/google/android/exoplayer2/upstream/HttpDataSource.java index 8df8624102c..a988cf1a335 100644 --- a/library/src/main/java/com/google/android/exoplayer2/upstream/HttpDataSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/upstream/HttpDataSource.java @@ -41,8 +41,8 @@ interface Factory extends DataSource.Factory { HttpDataSource createDataSource(); /** - * Sets a default request header field for {@link HttpDataSource} instances subsequently - * created by the factory. Previously created instances are not affected. + * Sets a default request header for {@link HttpDataSource} instances subsequently created by + * the factory. Previously created instances are not affected. * * @param name The name of the header field. * @param value The value of the field. @@ -50,16 +50,16 @@ interface Factory extends DataSource.Factory { void setDefaultRequestProperty(String name, String value); /** - * Clears a default request header field for {@link HttpDataSource} instances subsequently - * created by the factory. Previously created instances are not affected. + * Clears a default request header for {@link HttpDataSource} instances subsequently created by + * the factory. Previously created instances are not affected. * * @param name The name of the header field. */ void clearDefaultRequestProperty(String name); /** - * Clears all default request header fields for all {@link HttpDataSource} instances - * subsequently created by the factory. Previously created instances are not affected. + * Clears all default request header for all {@link HttpDataSource} instances subsequently + * created by the factory. Previously created instances are not affected. */ void clearAllDefaultRequestProperties(); @@ -232,7 +232,7 @@ public InvalidResponseCodeException(int responseCode, Map> int read(byte[] buffer, int offset, int readLength) throws HttpDataSourceException; /** - * Sets the value of a request header field. The value will be used for subsequent connections + * Sets the value of a request header. The value will be used for subsequent connections * established by the source. * * @param name The name of the header field. @@ -241,7 +241,7 @@ public InvalidResponseCodeException(int responseCode, Map> void setRequestProperty(String name, String value); /** - * Clears the value of a request header field. The change will apply to subsequent connections + * Clears the value of a request header. The change will apply to subsequent connections * established by the source. * * @param name The name of the header field. @@ -249,7 +249,7 @@ public InvalidResponseCodeException(int responseCode, Map> void clearRequestProperty(String name); /** - * Clears all request header fields that were set by {@link #setRequestProperty(String, String)}. + * Clears all request headers that were set by {@link #setRequestProperty(String, String)}. */ void clearAllRequestProperties();