Add MediaItem.DrmConfiguration.Builder and use it in MediaItem.Builder

PiperOrigin-RevId: 395896034
This commit is contained in:
ibaker 2021-09-10 12:00:12 +01:00 committed by Oliver Woodman
parent 7dff223d80
commit 9f3c2fb5e1
2 changed files with 327 additions and 143 deletions

View File

@ -26,13 +26,14 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -71,14 +72,9 @@ public final class MediaItem implements Bundleable {
private boolean clipRelativeToLiveWindow; private boolean clipRelativeToLiveWindow;
private boolean clipRelativeToDefaultPosition; private boolean clipRelativeToDefaultPosition;
private boolean clipStartsAtKeyFrame; private boolean clipStartsAtKeyFrame;
@Nullable private Uri drmLicenseUri; // TODO: Change this to @Nullable DrmConfiguration once all the deprecated individual setters
private Map<String, String> drmLicenseRequestHeaders; // are removed.
@Nullable private UUID drmUuid; private DrmConfiguration.Builder drmConfiguration;
private boolean drmMultiSession;
private boolean drmPlayClearContentWithoutKey;
private boolean drmForceDefaultLicenseUri;
private List<Integer> drmSessionForClearTypes;
@Nullable private byte[] drmKeySetId;
private List<StreamKey> streamKeys; private List<StreamKey> streamKeys;
@Nullable private String customCacheKey; @Nullable private String customCacheKey;
private List<Subtitle> subtitles; private List<Subtitle> subtitles;
@ -93,10 +89,10 @@ public final class MediaItem implements Bundleable {
private float liveMaxPlaybackSpeed; private float liveMaxPlaybackSpeed;
/** Creates a builder. */ /** Creates a builder. */
@SuppressWarnings("deprecation") // Temporarily uses DrmConfiguration.Builder() constructor.
public Builder() { public Builder() {
clipEndPositionMs = C.TIME_END_OF_SOURCE; clipEndPositionMs = C.TIME_END_OF_SOURCE;
drmSessionForClearTypes = Collections.emptyList(); drmConfiguration = new DrmConfiguration.Builder();
drmLicenseRequestHeaders = Collections.emptyMap();
streamKeys = Collections.emptyList(); streamKeys = Collections.emptyList();
subtitles = Collections.emptyList(); subtitles = Collections.emptyList();
liveTargetOffsetMs = C.TIME_UNSET; liveTargetOffsetMs = C.TIME_UNSET;
@ -128,17 +124,10 @@ public final class MediaItem implements Bundleable {
streamKeys = playbackProperties.streamKeys; streamKeys = playbackProperties.streamKeys;
subtitles = playbackProperties.subtitles; subtitles = playbackProperties.subtitles;
tag = playbackProperties.tag; tag = playbackProperties.tag;
@Nullable DrmConfiguration drmConfiguration = playbackProperties.drmConfiguration; drmConfiguration =
if (drmConfiguration != null) { playbackProperties.drmConfiguration != null
drmLicenseUri = drmConfiguration.licenseUri; ? playbackProperties.drmConfiguration.buildUpon()
drmLicenseRequestHeaders = drmConfiguration.requestHeaders; : new DrmConfiguration.Builder();
drmMultiSession = drmConfiguration.multiSession;
drmForceDefaultLicenseUri = drmConfiguration.forceDefaultLicenseUri;
drmPlayClearContentWithoutKey = drmConfiguration.playClearContentWithoutKey;
drmSessionForClearTypes = drmConfiguration.sessionForClearTypes;
drmUuid = drmConfiguration.uuid;
drmKeySetId = drmConfiguration.getKeySetId();
}
@Nullable AdsConfiguration adsConfiguration = playbackProperties.adsConfiguration; @Nullable AdsConfiguration adsConfiguration = playbackProperties.adsConfiguration;
if (adsConfiguration != null) { if (adsConfiguration != null) {
adTagUri = adsConfiguration.adTagUri; adTagUri = adsConfiguration.adTagUri;
@ -243,149 +232,111 @@ public final class MediaItem implements Bundleable {
return this; return this;
} }
/** Sets the optional DRM configuration. */
public Builder setDrmConfiguration(@Nullable DrmConfiguration drmConfiguration) {
this.drmConfiguration =
drmConfiguration != null ? drmConfiguration.buildUpon() : new DrmConfiguration.Builder();
return this;
}
/** /**
* Sets the optional default DRM license server URI. If this URI is set, the {@link * @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
* DrmConfiguration#uuid} needs to be specified as well. * DrmConfiguration.Builder#setLicenseUri(Uri)} instead.
*
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
* are passed non-null values.
*/ */
@Deprecated
public Builder setDrmLicenseUri(@Nullable Uri licenseUri) { public Builder setDrmLicenseUri(@Nullable Uri licenseUri) {
drmLicenseUri = licenseUri; drmConfiguration.setLicenseUri(licenseUri);
return this; return this;
} }
/** /**
* Sets the optional default DRM license server URI. If this URI is set, the {@link * @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
* DrmConfiguration#uuid} needs to be specified as well. * DrmConfiguration.Builder#setLicenseUri(String)} instead.
*
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
* are passed non-null values.
*/ */
@Deprecated
public Builder setDrmLicenseUri(@Nullable String licenseUri) { public Builder setDrmLicenseUri(@Nullable String licenseUri) {
drmLicenseUri = licenseUri == null ? null : Uri.parse(licenseUri); drmConfiguration.setLicenseUri(licenseUri);
return this; return this;
} }
/** /**
* Sets the optional request headers attached to the DRM license request. * @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
* * DrmConfiguration.Builder#setLicenseRequestHeaders(Map)} instead.
* <p>{@code null} or an empty {@link Map} can be used for a reset.
*
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
* are passed non-null values.
*/ */
@Deprecated
public Builder setDrmLicenseRequestHeaders( public Builder setDrmLicenseRequestHeaders(
@Nullable Map<String, String> licenseRequestHeaders) { @Nullable Map<String, String> licenseRequestHeaders) {
this.drmLicenseRequestHeaders = drmConfiguration.setLicenseRequestHeaders(licenseRequestHeaders);
licenseRequestHeaders != null && !licenseRequestHeaders.isEmpty()
? Collections.unmodifiableMap(new HashMap<>(licenseRequestHeaders))
: Collections.emptyMap();
return this; return this;
} }
/** /**
* Sets the {@link UUID} of the protection scheme. * @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and pass the {@code uuid} to
* * {@link DrmConfiguration.Builder#Builder(UUID)} instead.
* <p>If {@code uuid} is null or unset then no {@link DrmConfiguration} object is created during
* {@link #build()} and no other {@code Builder} methods that would populate {@link
* MediaItem.PlaybackProperties#drmConfiguration} should be called.
*
* <p>This method should only be called if {@link #setUri} is passed a non-null value.
*/ */
@Deprecated
public Builder setDrmUuid(@Nullable UUID uuid) { public Builder setDrmUuid(@Nullable UUID uuid) {
drmUuid = uuid; drmConfiguration.setNullableUuid(uuid);
return this; return this;
} }
/** /**
* Sets whether the DRM configuration is multi session enabled. * @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
* * DrmConfiguration.Builder#setMultiSession(boolean)} instead.
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
* are passed non-null values.
*/ */
@Deprecated
public Builder setDrmMultiSession(boolean multiSession) { public Builder setDrmMultiSession(boolean multiSession) {
drmMultiSession = multiSession; drmConfiguration.setMultiSession(multiSession);
return this; return this;
} }
/** /**
* Sets whether to force use the default DRM license server URI even if the media specifies its * @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
* own DRM license server URI. * DrmConfiguration.Builder#setForceDefaultLicenseUri(boolean)} instead.
*
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
* are passed non-null values.
*/ */
@Deprecated
public Builder setDrmForceDefaultLicenseUri(boolean forceDefaultLicenseUri) { public Builder setDrmForceDefaultLicenseUri(boolean forceDefaultLicenseUri) {
this.drmForceDefaultLicenseUri = forceDefaultLicenseUri; drmConfiguration.setForceDefaultLicenseUri(forceDefaultLicenseUri);
return this; return this;
} }
/** /**
* Sets whether clear samples within protected content should be played when keys for the * @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
* encrypted part of the content have yet to be loaded. * DrmConfiguration.Builder#setPlayClearContentWithoutKey(boolean)} instead.
*
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
* are passed non-null values.
*/ */
@Deprecated
public Builder setDrmPlayClearContentWithoutKey(boolean playClearContentWithoutKey) { public Builder setDrmPlayClearContentWithoutKey(boolean playClearContentWithoutKey) {
this.drmPlayClearContentWithoutKey = playClearContentWithoutKey; drmConfiguration.setPlayClearContentWithoutKey(playClearContentWithoutKey);
return this; return this;
} }
/** /**
* Sets whether a DRM session should be used for clear tracks of type {@link C#TRACK_TYPE_VIDEO} * @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
* and {@link C#TRACK_TYPE_AUDIO}. * DrmConfiguration.Builder#setSessionForClearPeriods(boolean)} instead.
*
* <p>This method overrides what has been set by previously calling {@link
* #setDrmSessionForClearTypes(List)}.
*
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
* are passed non-null values.
*/ */
@Deprecated
public Builder setDrmSessionForClearPeriods(boolean sessionForClearPeriods) { public Builder setDrmSessionForClearPeriods(boolean sessionForClearPeriods) {
this.setDrmSessionForClearTypes( drmConfiguration.setSessionForClearPeriods(sessionForClearPeriods);
sessionForClearPeriods
? Arrays.asList(C.TRACK_TYPE_VIDEO, C.TRACK_TYPE_AUDIO)
: Collections.emptyList());
return this; return this;
} }
/** /**
* Sets a list of {@link C.TrackType track types} for which to use a DRM session even when the * @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
* tracks are in the clear. * DrmConfiguration.Builder#setSessionForClearTypes(List)} instead.
*
* <p>For the common case of using a DRM session for {@link C#TRACK_TYPE_VIDEO} and {@link
* C#TRACK_TYPE_AUDIO} the {@link #setDrmSessionForClearPeriods(boolean)} can be used.
*
* <p>This method overrides what has been set by previously calling {@link
* #setDrmSessionForClearPeriods(boolean)}.
*
* <p>{@code null} or an empty {@link List} can be used for a reset.
*
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
* are passed non-null values.
*/ */
@Deprecated
public Builder setDrmSessionForClearTypes(@Nullable List<Integer> sessionForClearTypes) { public Builder setDrmSessionForClearTypes(@Nullable List<Integer> sessionForClearTypes) {
this.drmSessionForClearTypes = drmConfiguration.setSessionForClearTypes(sessionForClearTypes);
sessionForClearTypes != null && !sessionForClearTypes.isEmpty()
? Collections.unmodifiableList(new ArrayList<>(sessionForClearTypes))
: Collections.emptyList();
return this; return this;
} }
/** /**
* Sets the key set ID of the offline license. * @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
* * DrmConfiguration.Builder#setKeySetId(byte[])} instead.
* <p>The key set ID identifies an offline license. The ID is required to query, renew or
* release an existing offline license (see {@code DefaultDrmSessionManager#setMode(int
* mode,byte[] offlineLicenseKeySetId)}).
*
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
* are passed non-null values.
*/ */
@Deprecated
public Builder setDrmKeySetId(@Nullable byte[] keySetId) { public Builder setDrmKeySetId(@Nullable byte[] keySetId) {
this.drmKeySetId = keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null; drmConfiguration.setKeySetId(keySetId);
return this; return this;
} }
@ -568,7 +519,8 @@ public final class MediaItem implements Bundleable {
/** Returns a new {@link MediaItem} instance with the current builder values. */ /** Returns a new {@link MediaItem} instance with the current builder values. */
public MediaItem build() { public MediaItem build() {
checkState(drmLicenseUri == null || drmUuid != null); // TODO: remove this check once all the deprecated individual DRM setters are removed.
checkState(drmConfiguration.licenseUri == null || drmConfiguration.uuid != null);
@Nullable PlaybackProperties playbackProperties = null; @Nullable PlaybackProperties playbackProperties = null;
@Nullable Uri uri = this.uri; @Nullable Uri uri = this.uri;
if (uri != null) { if (uri != null) {
@ -576,17 +528,7 @@ public final class MediaItem implements Bundleable {
new PlaybackProperties( new PlaybackProperties(
uri, uri,
mimeType, mimeType,
drmUuid != null drmConfiguration.uuid != null ? drmConfiguration.build() : null,
? new DrmConfiguration(
drmUuid,
drmLicenseUri,
drmLicenseRequestHeaders,
drmMultiSession,
drmForceDefaultLicenseUri,
drmPlayClearContentWithoutKey,
drmSessionForClearTypes,
drmKeySetId)
: null,
adTagUri != null ? new AdsConfiguration(adTagUri, adsId) : null, adTagUri != null ? new AdsConfiguration(adTagUri, adsId) : null,
streamKeys, streamKeys,
customCacheKey, customCacheKey,
@ -615,6 +557,165 @@ public final class MediaItem implements Bundleable {
/** DRM configuration for a media item. */ /** DRM configuration for a media item. */
public static final class DrmConfiguration { public static final class DrmConfiguration {
/** Builder for {@link DrmConfiguration}. */
public static final class Builder {
// TODO remove @Nullable annotation when the deprecated zero-arg constructor is removed.
@Nullable private UUID uuid;
@Nullable private Uri licenseUri;
private ImmutableMap<String, String> licenseRequestHeaders;
private boolean multiSession;
private boolean playClearContentWithoutKey;
private boolean forceDefaultLicenseUri;
private ImmutableList<Integer> sessionForClearTypes;
@Nullable private byte[] keySetId;
/**
* Constructs an instance.
*
* @param uuid The {@link UUID} of the protection scheme.
*/
public Builder(UUID uuid) {
this.uuid = uuid;
this.licenseRequestHeaders = ImmutableMap.of();
this.sessionForClearTypes = ImmutableList.of();
}
/**
* @deprecated This only exists to support the deprecated setters for individual DRM
* properties on {@link MediaItem.Builder}.
*/
@Deprecated
private Builder() {
this.licenseRequestHeaders = ImmutableMap.of();
this.sessionForClearTypes = ImmutableList.of();
}
private Builder(DrmConfiguration drmConfiguration) {
this.uuid = drmConfiguration.uuid;
this.licenseUri = drmConfiguration.licenseUri;
this.licenseRequestHeaders = drmConfiguration.requestHeaders;
this.multiSession = drmConfiguration.multiSession;
this.playClearContentWithoutKey = drmConfiguration.playClearContentWithoutKey;
this.forceDefaultLicenseUri = drmConfiguration.forceDefaultLicenseUri;
this.sessionForClearTypes = drmConfiguration.sessionForClearTypes;
this.keySetId = drmConfiguration.keySetId;
}
/** Sets the {@link UUID} of the protection scheme. */
public Builder setUuid(UUID uuid) {
this.uuid = uuid;
return this;
}
/**
* @deprecated This only exists to support the deprecated {@link
* MediaItem.Builder#setDrmUuid(UUID)}.
*/
@Deprecated
private Builder setNullableUuid(@Nullable UUID uuid) {
this.uuid = uuid;
return this;
}
/** Sets the optional default DRM license server URI. */
public Builder setLicenseUri(@Nullable Uri licenseUri) {
this.licenseUri = licenseUri;
return this;
}
/** Sets the optional default DRM license server URI. */
public Builder setLicenseUri(@Nullable String licenseUri) {
this.licenseUri = licenseUri == null ? null : Uri.parse(licenseUri);
return this;
}
/** Sets the optional request headers attached to DRM license requests. */
public Builder setLicenseRequestHeaders(@Nullable Map<String, String> licenseRequestHeaders) {
this.licenseRequestHeaders =
licenseRequestHeaders != null
? ImmutableMap.copyOf(licenseRequestHeaders)
: ImmutableMap.of();
return this;
}
/** Sets whether multi session is enabled. */
public Builder setMultiSession(boolean multiSession) {
this.multiSession = multiSession;
return this;
}
/**
* Sets whether to always use the default DRM license server URI even if the media specifies
* its own DRM license server URI.
*/
public Builder setForceDefaultLicenseUri(boolean forceDefaultLicenseUri) {
this.forceDefaultLicenseUri = forceDefaultLicenseUri;
return this;
}
/**
* Sets whether clear samples within protected content should be played when keys for the
* encrypted part of the content have yet to be loaded.
*/
public Builder setPlayClearContentWithoutKey(boolean playClearContentWithoutKey) {
this.playClearContentWithoutKey = playClearContentWithoutKey;
return this;
}
/**
* Sets whether a DRM session should be used for clear tracks of type {@link
* C#TRACK_TYPE_VIDEO} and {@link C#TRACK_TYPE_AUDIO}.
*
* <p>This method overrides what has been set by previously calling {@link
* #setSessionForClearTypes(List)}.
*/
public Builder setSessionForClearPeriods(boolean sessionForClearPeriods) {
this.setSessionForClearTypes(
sessionForClearPeriods
? ImmutableList.of(C.TRACK_TYPE_VIDEO, C.TRACK_TYPE_AUDIO)
: ImmutableList.of());
return this;
}
/**
* Sets a list of {@link C}{@code .TRACK_TYPE_*} constants for which to use a DRM session even
* when the tracks are in the clear.
*
* <p>For the common case of using a DRM session for {@link C#TRACK_TYPE_VIDEO} and {@link
* C#TRACK_TYPE_AUDIO} the {@link #setSessionForClearPeriods(boolean)} can be used.
*
* <p>This method overrides what has been set by previously calling {@link
* #setSessionForClearPeriods(boolean)}.
*
* <p>{@code null} or an empty {@link List} can be used for a reset.
*/
public Builder setSessionForClearTypes(@Nullable List<Integer> sessionForClearTypes) {
this.sessionForClearTypes =
sessionForClearTypes != null
? ImmutableList.copyOf(sessionForClearTypes)
: ImmutableList.of();
return this;
}
/**
* Sets the key set ID of the offline license.
*
* <p>The key set ID identifies an offline license. The ID is required to query, renew or
* release an existing offline license (see {@code DefaultDrmSessionManager#setMode(int
* mode,byte[] offlineLicenseKeySetId)}).
*/
public Builder setKeySetId(@Nullable byte[] keySetId) {
this.keySetId = keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null;
return this;
}
public DrmConfiguration build() {
return new DrmConfiguration(this);
}
}
/** The UUID of the protection scheme. */ /** The UUID of the protection scheme. */
public final UUID uuid; public final UUID uuid;
@ -625,7 +726,7 @@ public final class MediaItem implements Bundleable {
@Nullable public final Uri licenseUri; @Nullable public final Uri licenseUri;
/** The headers to attach to the request to the DRM license server. */ /** The headers to attach to the request to the DRM license server. */
public final Map<String, String> requestHeaders; public final ImmutableMap<String, String> requestHeaders;
/** Whether the DRM configuration is multi session enabled. */ /** Whether the DRM configuration is multi session enabled. */
public final boolean multiSession; public final boolean multiSession;
@ -643,28 +744,23 @@ public final class MediaItem implements Bundleable {
public final boolean forceDefaultLicenseUri; public final boolean forceDefaultLicenseUri;
/** The types of clear tracks for which to use a DRM session. */ /** The types of clear tracks for which to use a DRM session. */
public final List<Integer> sessionForClearTypes; public final ImmutableList<Integer> sessionForClearTypes;
@Nullable private final byte[] keySetId; @Nullable private final byte[] keySetId;
private DrmConfiguration( private DrmConfiguration(Builder builder) {
UUID uuid, checkState(!(builder.forceDefaultLicenseUri && builder.licenseUri == null));
@Nullable Uri licenseUri, this.uuid = checkNotNull(builder.uuid);
Map<String, String> requestHeaders, this.licenseUri = builder.licenseUri;
boolean multiSession, this.requestHeaders = builder.licenseRequestHeaders;
boolean forceDefaultLicenseUri, this.multiSession = builder.multiSession;
boolean playClearContentWithoutKey, this.forceDefaultLicenseUri = builder.forceDefaultLicenseUri;
List<Integer> drmSessionForClearTypes, this.playClearContentWithoutKey = builder.playClearContentWithoutKey;
@Nullable byte[] keySetId) { this.sessionForClearTypes = builder.sessionForClearTypes;
Assertions.checkArgument(!(forceDefaultLicenseUri && licenseUri == null)); this.keySetId =
this.uuid = uuid; builder.keySetId != null
this.licenseUri = licenseUri; ? Arrays.copyOf(builder.keySetId, builder.keySetId.length)
this.requestHeaders = requestHeaders; : null;
this.multiSession = multiSession;
this.forceDefaultLicenseUri = forceDefaultLicenseUri;
this.playClearContentWithoutKey = playClearContentWithoutKey;
this.sessionForClearTypes = drmSessionForClearTypes;
this.keySetId = keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null;
} }
/** Returns the key set ID of the offline license. */ /** Returns the key set ID of the offline license. */
@ -673,6 +769,10 @@ public final class MediaItem implements Bundleable {
return keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null; return keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null;
} }
public Builder buildUpon() {
return new Builder(this);
}
@Override @Override
public boolean equals(@Nullable Object obj) { public boolean equals(@Nullable Object obj) {
if (this == obj) { if (this == obj) {

View File

@ -22,6 +22,7 @@ import android.net.Uri;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -77,14 +78,15 @@ public class MediaItemTest {
} }
@Test @Test
public void builderSetDrmConfig_isNullByDefault() { public void builder_drmConfigIsNullByDefault() {
// Null value by default. // Null value by default.
MediaItem mediaItem = new MediaItem.Builder().setUri(URI_STRING).build(); MediaItem mediaItem = new MediaItem.Builder().setUri(URI_STRING).build();
assertThat(mediaItem.playbackProperties.drmConfiguration).isNull(); assertThat(mediaItem.playbackProperties.drmConfiguration).isNull();
} }
@Test @Test
public void builderSetDrmConfig_setsAllProperties() { @SuppressWarnings("deprecation") // Testing deprecated methods
public void builderSetDrmPropertiesIndividually() {
Uri licenseUri = Uri.parse(URI_STRING); Uri licenseUri = Uri.parse(URI_STRING);
Map<String, String> requestHeaders = new HashMap<>(); Map<String, String> requestHeaders = new HashMap<>();
requestHeaders.put("Referer", "http://www.google.com"); requestHeaders.put("Referer", "http://www.google.com");
@ -92,14 +94,14 @@ public class MediaItemTest {
MediaItem mediaItem = MediaItem mediaItem =
new MediaItem.Builder() new MediaItem.Builder()
.setUri(URI_STRING) .setUri(URI_STRING)
.setDrmUuid(C.WIDEVINE_UUID)
.setDrmLicenseUri(licenseUri) .setDrmLicenseUri(licenseUri)
.setDrmLicenseRequestHeaders(requestHeaders) .setDrmLicenseRequestHeaders(requestHeaders)
.setDrmMultiSession(true) .setDrmMultiSession(true)
.setDrmForceDefaultLicenseUri(true) .setDrmForceDefaultLicenseUri(true)
.setDrmPlayClearContentWithoutKey(true) .setDrmPlayClearContentWithoutKey(true)
.setDrmSessionForClearTypes(Collections.singletonList(C.TRACK_TYPE_AUDIO)) .setDrmSessionForClearTypes(ImmutableList.of(C.TRACK_TYPE_AUDIO))
.setDrmKeySetId(keySetId) .setDrmKeySetId(keySetId)
.setDrmUuid(C.WIDEVINE_UUID)
.build(); .build();
assertThat(mediaItem.playbackProperties.drmConfiguration).isNotNull(); assertThat(mediaItem.playbackProperties.drmConfiguration).isNotNull();
@ -116,6 +118,73 @@ public class MediaItemTest {
} }
@Test @Test
@SuppressWarnings("deprecation") // Testing deprecated methods
public void builderSetDrmConfigurationOverwritesIndividualProperties() {
Uri licenseUri = Uri.parse(URI_STRING);
Map<String, String> requestHeaders = new HashMap<>();
requestHeaders.put("Referer", "http://www.google.com");
byte[] keySetId = new byte[] {1, 2, 3};
MediaItem mediaItem =
new MediaItem.Builder()
.setUri(URI_STRING)
.setDrmLicenseUri(licenseUri)
.setDrmLicenseRequestHeaders(requestHeaders)
.setDrmMultiSession(true)
.setDrmForceDefaultLicenseUri(true)
.setDrmPlayClearContentWithoutKey(true)
.setDrmSessionForClearTypes(Collections.singletonList(C.TRACK_TYPE_AUDIO))
.setDrmKeySetId(keySetId)
.setDrmUuid(C.WIDEVINE_UUID)
.setDrmConfiguration(new MediaItem.DrmConfiguration.Builder(C.CLEARKEY_UUID).build())
.build();
assertThat(mediaItem.playbackProperties.drmConfiguration).isNotNull();
assertThat(mediaItem.playbackProperties.drmConfiguration.uuid).isEqualTo(C.CLEARKEY_UUID);
assertThat(mediaItem.playbackProperties.drmConfiguration.licenseUri).isNull();
assertThat(mediaItem.playbackProperties.drmConfiguration.requestHeaders).isEmpty();
assertThat(mediaItem.playbackProperties.drmConfiguration.multiSession).isFalse();
assertThat(mediaItem.playbackProperties.drmConfiguration.forceDefaultLicenseUri).isFalse();
assertThat(mediaItem.playbackProperties.drmConfiguration.playClearContentWithoutKey).isFalse();
assertThat(mediaItem.playbackProperties.drmConfiguration.sessionForClearTypes).isEmpty();
assertThat(mediaItem.playbackProperties.drmConfiguration.getKeySetId()).isNull();
}
@Test
public void builderSetDrmConfiguration() {
Uri licenseUri = Uri.parse(URI_STRING);
Map<String, String> requestHeaders = new HashMap<>();
requestHeaders.put("Referer", "http://www.google.com");
byte[] keySetId = new byte[] {1, 2, 3};
MediaItem mediaItem =
new MediaItem.Builder()
.setUri(URI_STRING)
.setDrmConfiguration(
new MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
.setLicenseUri(licenseUri)
.setLicenseRequestHeaders(requestHeaders)
.setMultiSession(true)
.setForceDefaultLicenseUri(true)
.setPlayClearContentWithoutKey(true)
.setSessionForClearTypes(ImmutableList.of(C.TRACK_TYPE_AUDIO))
.setKeySetId(keySetId)
.build())
.build();
assertThat(mediaItem.playbackProperties.drmConfiguration).isNotNull();
assertThat(mediaItem.playbackProperties.drmConfiguration.uuid).isEqualTo(C.WIDEVINE_UUID);
assertThat(mediaItem.playbackProperties.drmConfiguration.licenseUri).isEqualTo(licenseUri);
assertThat(mediaItem.playbackProperties.drmConfiguration.requestHeaders)
.isEqualTo(requestHeaders);
assertThat(mediaItem.playbackProperties.drmConfiguration.multiSession).isTrue();
assertThat(mediaItem.playbackProperties.drmConfiguration.forceDefaultLicenseUri).isTrue();
assertThat(mediaItem.playbackProperties.drmConfiguration.playClearContentWithoutKey).isTrue();
assertThat(mediaItem.playbackProperties.drmConfiguration.sessionForClearTypes)
.containsExactly(C.TRACK_TYPE_AUDIO);
assertThat(mediaItem.playbackProperties.drmConfiguration.getKeySetId()).isEqualTo(keySetId);
}
@Test
@SuppressWarnings("deprecation") // Testing deprecated methods
public void builderSetDrmSessionForClearPeriods_setsAudioAndVideoTracks() { public void builderSetDrmSessionForClearPeriods_setsAudioAndVideoTracks() {
Uri licenseUri = Uri.parse(URI_STRING); Uri licenseUri = Uri.parse(URI_STRING);
MediaItem mediaItem = MediaItem mediaItem =
@ -132,6 +201,21 @@ public class MediaItemTest {
} }
@Test @Test
public void drmConfigurationBuilderSetSessionForClearPeriods_overridesSetSessionForClearTypes() {
Uri licenseUri = Uri.parse(URI_STRING);
MediaItem.DrmConfiguration drmConfiguration =
new MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
.setLicenseUri(licenseUri)
.setSessionForClearTypes(ImmutableList.of(C.TRACK_TYPE_AUDIO))
.setSessionForClearPeriods(true)
.build();
assertThat(drmConfiguration.sessionForClearTypes)
.containsExactly(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO);
}
@Test
@SuppressWarnings("deprecation") // Testing deprecated methods
public void builderSetDrmUuid_notCalled_throwsIllegalStateException() { public void builderSetDrmUuid_notCalled_throwsIllegalStateException() {
assertThrows( assertThrows(
IllegalStateException.class, IllegalStateException.class,