Switch DRM and download components from HttpDataSource to DataSource

All the (Http)DataSource interactions can be done with the DataSource
interface and don't need HttpDataSource.

PiperOrigin-RevId: 436520898
This commit is contained in:
ibaker 2022-03-22 18:11:31 +00:00 committed by Ian Baker
parent d57958e86d
commit 54d3e45473
4 changed files with 43 additions and 45 deletions

View File

@ -34,7 +34,7 @@ import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.TracksInfo; import androidx.media3.common.TracksInfo;
import androidx.media3.common.util.Log; import androidx.media3.common.util.Log;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.datasource.HttpDataSource; import androidx.media3.datasource.DataSource;
import androidx.media3.exoplayer.RenderersFactory; import androidx.media3.exoplayer.RenderersFactory;
import androidx.media3.exoplayer.drm.DrmSession; import androidx.media3.exoplayer.drm.DrmSession;
import androidx.media3.exoplayer.drm.DrmSessionEventListener; import androidx.media3.exoplayer.drm.DrmSessionEventListener;
@ -66,7 +66,7 @@ public class DownloadTracker {
private static final String TAG = "DownloadTracker"; private static final String TAG = "DownloadTracker";
private final Context context; private final Context context;
private final HttpDataSource.Factory httpDataSourceFactory; private final DataSource.Factory dataSourceFactory;
private final CopyOnWriteArraySet<Listener> listeners; private final CopyOnWriteArraySet<Listener> listeners;
private final HashMap<Uri, Download> downloads; private final HashMap<Uri, Download> downloads;
private final DownloadIndex downloadIndex; private final DownloadIndex downloadIndex;
@ -74,11 +74,9 @@ public class DownloadTracker {
@Nullable private StartDownloadDialogHelper startDownloadDialogHelper; @Nullable private StartDownloadDialogHelper startDownloadDialogHelper;
public DownloadTracker( public DownloadTracker(
Context context, Context context, DataSource.Factory dataSourceFactory, DownloadManager downloadManager) {
HttpDataSource.Factory httpDataSourceFactory,
DownloadManager downloadManager) {
this.context = context.getApplicationContext(); this.context = context.getApplicationContext();
this.httpDataSourceFactory = httpDataSourceFactory; this.dataSourceFactory = dataSourceFactory;
listeners = new CopyOnWriteArraySet<>(); listeners = new CopyOnWriteArraySet<>();
downloads = new HashMap<>(); downloads = new HashMap<>();
downloadIndex = downloadManager.getDownloadIndex(); downloadIndex = downloadManager.getDownloadIndex();
@ -119,8 +117,7 @@ public class DownloadTracker {
startDownloadDialogHelper = startDownloadDialogHelper =
new StartDownloadDialogHelper( new StartDownloadDialogHelper(
fragmentManager, fragmentManager,
DownloadHelper.forMediaItem( DownloadHelper.forMediaItem(context, mediaItem, renderersFactory, dataSourceFactory),
context, mediaItem, renderersFactory, httpDataSourceFactory),
mediaItem); mediaItem);
} }
} }
@ -218,7 +215,7 @@ public class DownloadTracker {
new WidevineOfflineLicenseFetchTask( new WidevineOfflineLicenseFetchTask(
format, format,
mediaItem.localConfiguration.drmConfiguration, mediaItem.localConfiguration.drmConfiguration,
httpDataSourceFactory, dataSourceFactory,
/* dialogHelper= */ this, /* dialogHelper= */ this,
helper); helper);
widevineOfflineLicenseFetchTask.execute(); widevineOfflineLicenseFetchTask.execute();
@ -361,7 +358,7 @@ public class DownloadTracker {
private final Format format; private final Format format;
private final MediaItem.DrmConfiguration drmConfiguration; private final MediaItem.DrmConfiguration drmConfiguration;
private final HttpDataSource.Factory httpDataSourceFactory; private final DataSource.Factory dataSourceFactory;
private final StartDownloadDialogHelper dialogHelper; private final StartDownloadDialogHelper dialogHelper;
private final DownloadHelper downloadHelper; private final DownloadHelper downloadHelper;
@ -371,12 +368,12 @@ public class DownloadTracker {
public WidevineOfflineLicenseFetchTask( public WidevineOfflineLicenseFetchTask(
Format format, Format format,
MediaItem.DrmConfiguration drmConfiguration, MediaItem.DrmConfiguration drmConfiguration,
HttpDataSource.Factory httpDataSourceFactory, DataSource.Factory dataSourceFactory,
StartDownloadDialogHelper dialogHelper, StartDownloadDialogHelper dialogHelper,
DownloadHelper downloadHelper) { DownloadHelper downloadHelper) {
this.format = format; this.format = format;
this.drmConfiguration = drmConfiguration; this.drmConfiguration = drmConfiguration;
this.httpDataSourceFactory = httpDataSourceFactory; this.dataSourceFactory = dataSourceFactory;
this.dialogHelper = dialogHelper; this.dialogHelper = dialogHelper;
this.downloadHelper = downloadHelper; this.downloadHelper = downloadHelper;
} }
@ -387,7 +384,7 @@ public class DownloadTracker {
OfflineLicenseHelper.newWidevineInstance( OfflineLicenseHelper.newWidevineInstance(
drmConfiguration.licenseUri.toString(), drmConfiguration.licenseUri.toString(),
drmConfiguration.forceDefaultLicenseUri, drmConfiguration.forceDefaultLicenseUri,
httpDataSourceFactory, dataSourceFactory,
drmConfiguration.licenseRequestHeaders, drmConfiguration.licenseRequestHeaders,
new DrmSessionEventListener.EventDispatcher()); new DrmSessionEventListener.EventDispatcher());
try { try {

View File

@ -24,8 +24,8 @@ import androidx.annotation.RequiresApi;
import androidx.media3.common.MediaItem; import androidx.media3.common.MediaItem;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DefaultHttpDataSource; import androidx.media3.datasource.DefaultHttpDataSource;
import androidx.media3.datasource.HttpDataSource;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import java.util.Map; import java.util.Map;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -42,7 +42,7 @@ public final class DefaultDrmSessionManagerProvider implements DrmSessionManager
@GuardedBy("lock") @GuardedBy("lock")
private @MonotonicNonNull DrmSessionManager manager; private @MonotonicNonNull DrmSessionManager manager;
@Nullable private HttpDataSource.Factory drmHttpDataSourceFactory; @Nullable private DataSource.Factory drmHttpDataSourceFactory;
@Nullable private String userAgent; @Nullable private String userAgent;
public DefaultDrmSessionManagerProvider() { public DefaultDrmSessionManagerProvider() {
@ -50,23 +50,21 @@ public final class DefaultDrmSessionManagerProvider implements DrmSessionManager
} }
/** /**
* Sets the {@link HttpDataSource.Factory} to be used for creating {@link HttpMediaDrmCallback * Sets the {@link DataSource.Factory} which is used to create {@link HttpMediaDrmCallback}
* HttpMediaDrmCallbacks} which executes key and provisioning requests over HTTP. If {@code null} * instances. If {@code null} is passed a {@link DefaultHttpDataSource.Factory} is used.
* is passed the {@link DefaultHttpDataSource.Factory} is used.
* *
* @param drmHttpDataSourceFactory The HTTP data source factory or {@code null} to use {@link * @param drmDataSourceFactory The data source factory or {@code null} to use {@link
* DefaultHttpDataSource.Factory}. * DefaultHttpDataSource.Factory}.
*/ */
public void setDrmHttpDataSourceFactory( public void setDrmHttpDataSourceFactory(@Nullable DataSource.Factory drmDataSourceFactory) {
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) { this.drmHttpDataSourceFactory = drmDataSourceFactory;
this.drmHttpDataSourceFactory = drmHttpDataSourceFactory;
} }
/** /**
* Sets the optional user agent to be used for DRM requests. * Sets the optional user agent to be used for DRM requests.
* *
* <p>In case a factory has been set by {@link * <p>In case a factory has been set by {@link #setDrmHttpDataSourceFactory(DataSource.Factory)},
* #setDrmHttpDataSourceFactory(HttpDataSource.Factory)}, this user agent is ignored. * this user agent is ignored.
* *
* @param userAgent The user agent to be used for DRM requests. * @param userAgent The user agent to be used for DRM requests.
*/ */
@ -94,7 +92,7 @@ public final class DefaultDrmSessionManagerProvider implements DrmSessionManager
@RequiresApi(18) @RequiresApi(18)
private DrmSessionManager createManager(MediaItem.DrmConfiguration drmConfiguration) { private DrmSessionManager createManager(MediaItem.DrmConfiguration drmConfiguration) {
HttpDataSource.Factory dataSourceFactory = DataSource.Factory dataSourceFactory =
drmHttpDataSourceFactory != null drmHttpDataSourceFactory != null
? drmHttpDataSourceFactory ? drmHttpDataSourceFactory
: new DefaultHttpDataSource.Factory().setUserAgent(userAgent); : new DefaultHttpDataSource.Factory().setUserAgent(userAgent);

View File

@ -22,9 +22,9 @@ import androidx.media3.common.C;
import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DataSourceInputStream; import androidx.media3.datasource.DataSourceInputStream;
import androidx.media3.datasource.DataSpec; import androidx.media3.datasource.DataSpec;
import androidx.media3.datasource.HttpDataSource;
import androidx.media3.datasource.HttpDataSource.InvalidResponseCodeException; import androidx.media3.datasource.HttpDataSource.InvalidResponseCodeException;
import androidx.media3.datasource.StatsDataSource; import androidx.media3.datasource.StatsDataSource;
import androidx.media3.exoplayer.drm.ExoMediaDrm.KeyRequest; import androidx.media3.exoplayer.drm.ExoMediaDrm.KeyRequest;
@ -36,41 +36,47 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
/** A {@link MediaDrmCallback} that makes requests using {@link HttpDataSource} instances. */ /** A {@link MediaDrmCallback} that makes requests using {@link DataSource} instances. */
@UnstableApi @UnstableApi
public final class HttpMediaDrmCallback implements MediaDrmCallback { public final class HttpMediaDrmCallback implements MediaDrmCallback {
private static final int MAX_MANUAL_REDIRECTS = 5; private static final int MAX_MANUAL_REDIRECTS = 5;
private final HttpDataSource.Factory dataSourceFactory; private final DataSource.Factory dataSourceFactory;
@Nullable private final String defaultLicenseUrl; @Nullable private final String defaultLicenseUrl;
private final boolean forceDefaultLicenseUrl; private final boolean forceDefaultLicenseUrl;
private final Map<String, String> keyRequestProperties; private final Map<String, String> keyRequestProperties;
/** /**
* Constructs an instance.
*
* @param defaultLicenseUrl The default license URL. Used for key requests that do not specify * @param defaultLicenseUrl The default license URL. Used for key requests that do not specify
* their own license URL. May be {@code null} if it's known that all key requests will specify * their own license URL. May be {@code null} if it's known that all key requests will specify
* their own URLs. * their own URLs.
* @param dataSourceFactory A factory from which to obtain {@link HttpDataSource} instances. * @param dataSourceFactory A factory from which to obtain {@link DataSource} instances. This will
* usually be an HTTP-based {@link DataSource}.
*/ */
public HttpMediaDrmCallback( public HttpMediaDrmCallback(
@Nullable String defaultLicenseUrl, HttpDataSource.Factory dataSourceFactory) { @Nullable String defaultLicenseUrl, DataSource.Factory dataSourceFactory) {
this(defaultLicenseUrl, /* forceDefaultLicenseUrl= */ false, dataSourceFactory); this(defaultLicenseUrl, /* forceDefaultLicenseUrl= */ false, dataSourceFactory);
} }
/** /**
* Constructs an instance.
*
* @param defaultLicenseUrl The default license URL. Used for key requests that do not specify * @param defaultLicenseUrl The default license URL. Used for key requests that do not specify
* their own license URL, or for all key requests if {@code forceDefaultLicenseUrl} is set to * their own license URL, or for all key requests if {@code forceDefaultLicenseUrl} is set to
* true. May be {@code null} if {@code forceDefaultLicenseUrl} is {@code false} and if it's * true. May be {@code null} if {@code forceDefaultLicenseUrl} is {@code false} and if it's
* known that all key requests will specify their own URLs. * known that all key requests will specify their own URLs.
* @param forceDefaultLicenseUrl Whether to force use of {@code defaultLicenseUrl} for key * @param forceDefaultLicenseUrl Whether to force use of {@code defaultLicenseUrl} for key
* requests that include their own license URL. * requests that include their own license URL.
* @param dataSourceFactory A factory from which to obtain {@link HttpDataSource} instances. * @param dataSourceFactory A factory from which to obtain {@link DataSource} instances. This will
* * usually be an HTTP-based {@link DataSource}.
*/ */
public HttpMediaDrmCallback( public HttpMediaDrmCallback(
@Nullable String defaultLicenseUrl, @Nullable String defaultLicenseUrl,
boolean forceDefaultLicenseUrl, boolean forceDefaultLicenseUrl,
HttpDataSource.Factory dataSourceFactory) { DataSource.Factory dataSourceFactory) {
Assertions.checkArgument(!(forceDefaultLicenseUrl && TextUtils.isEmpty(defaultLicenseUrl))); Assertions.checkArgument(!(forceDefaultLicenseUrl && TextUtils.isEmpty(defaultLicenseUrl)));
this.dataSourceFactory = dataSourceFactory; this.dataSourceFactory = dataSourceFactory;
this.defaultLicenseUrl = defaultLicenseUrl; this.defaultLicenseUrl = defaultLicenseUrl;
@ -156,7 +162,7 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
} }
private static byte[] executePost( private static byte[] executePost(
HttpDataSource.Factory dataSourceFactory, DataSource.Factory dataSourceFactory,
String url, String url,
@Nullable byte[] httpBody, @Nullable byte[] httpBody,
Map<String, String> requestProperties) Map<String, String> requestProperties)

View File

@ -26,7 +26,7 @@ import androidx.media3.common.DrmInitData;
import androidx.media3.common.Format; import androidx.media3.common.Format;
import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.HttpDataSource; import androidx.media3.datasource.DataSource;
import androidx.media3.exoplayer.analytics.PlayerId; import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.drm.DefaultDrmSessionManager.Mode; import androidx.media3.exoplayer.drm.DefaultDrmSessionManager.Mode;
import androidx.media3.exoplayer.drm.DrmSession.DrmSessionException; import androidx.media3.exoplayer.drm.DrmSession.DrmSessionException;
@ -53,20 +53,17 @@ public final class OfflineLicenseHelper {
* *
* @param defaultLicenseUrl The default license URL. Used for key requests that do not specify * @param defaultLicenseUrl The default license URL. Used for key requests that do not specify
* their own license URL. * their own license URL.
* @param httpDataSourceFactory A factory from which to obtain {@link HttpDataSource} instances. * @param dataSourceFactory A factory from which to obtain {@link DataSource} instances.
* @param eventDispatcher A {@link DrmSessionEventListener.EventDispatcher} used to distribute * @param eventDispatcher A {@link DrmSessionEventListener.EventDispatcher} used to distribute
* DRM-related events. * DRM-related events.
* @return A new instance which uses Widevine CDM. * @return A new instance which uses Widevine CDM.
*/ */
public static OfflineLicenseHelper newWidevineInstance( public static OfflineLicenseHelper newWidevineInstance(
String defaultLicenseUrl, String defaultLicenseUrl,
HttpDataSource.Factory httpDataSourceFactory, DataSource.Factory dataSourceFactory,
DrmSessionEventListener.EventDispatcher eventDispatcher) { DrmSessionEventListener.EventDispatcher eventDispatcher) {
return newWidevineInstance( return newWidevineInstance(
defaultLicenseUrl, defaultLicenseUrl, /* forceDefaultLicenseUrl= */ false, dataSourceFactory, eventDispatcher);
/* forceDefaultLicenseUrl= */ false,
httpDataSourceFactory,
eventDispatcher);
} }
/** /**
@ -77,7 +74,7 @@ public final class OfflineLicenseHelper {
* their own license URL. * their own license URL.
* @param forceDefaultLicenseUrl Whether to use {@code defaultLicenseUrl} for key requests that * @param forceDefaultLicenseUrl Whether to use {@code defaultLicenseUrl} for key requests that
* include their own license URL. * include their own license URL.
* @param httpDataSourceFactory A factory from which to obtain {@link HttpDataSource} instances. * @param dataSourceFactory A factory from which to obtain {@link DataSource} instances.
* @param eventDispatcher A {@link DrmSessionEventListener.EventDispatcher} used to distribute * @param eventDispatcher A {@link DrmSessionEventListener.EventDispatcher} used to distribute
* DRM-related events. * DRM-related events.
* @return A new instance which uses Widevine CDM. * @return A new instance which uses Widevine CDM.
@ -85,12 +82,12 @@ public final class OfflineLicenseHelper {
public static OfflineLicenseHelper newWidevineInstance( public static OfflineLicenseHelper newWidevineInstance(
String defaultLicenseUrl, String defaultLicenseUrl,
boolean forceDefaultLicenseUrl, boolean forceDefaultLicenseUrl,
HttpDataSource.Factory httpDataSourceFactory, DataSource.Factory dataSourceFactory,
DrmSessionEventListener.EventDispatcher eventDispatcher) { DrmSessionEventListener.EventDispatcher eventDispatcher) {
return newWidevineInstance( return newWidevineInstance(
defaultLicenseUrl, defaultLicenseUrl,
forceDefaultLicenseUrl, forceDefaultLicenseUrl,
httpDataSourceFactory, dataSourceFactory,
/* optionalKeyRequestParameters= */ null, /* optionalKeyRequestParameters= */ null,
eventDispatcher); eventDispatcher);
} }
@ -113,7 +110,7 @@ public final class OfflineLicenseHelper {
public static OfflineLicenseHelper newWidevineInstance( public static OfflineLicenseHelper newWidevineInstance(
String defaultLicenseUrl, String defaultLicenseUrl,
boolean forceDefaultLicenseUrl, boolean forceDefaultLicenseUrl,
HttpDataSource.Factory httpDataSourceFactory, DataSource.Factory dataSourceFactory,
@Nullable Map<String, String> optionalKeyRequestParameters, @Nullable Map<String, String> optionalKeyRequestParameters,
DrmSessionEventListener.EventDispatcher eventDispatcher) { DrmSessionEventListener.EventDispatcher eventDispatcher) {
return new OfflineLicenseHelper( return new OfflineLicenseHelper(
@ -121,7 +118,7 @@ public final class OfflineLicenseHelper {
.setKeyRequestParameters(optionalKeyRequestParameters) .setKeyRequestParameters(optionalKeyRequestParameters)
.build( .build(
new HttpMediaDrmCallback( new HttpMediaDrmCallback(
defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory)), defaultLicenseUrl, forceDefaultLicenseUrl, dataSourceFactory)),
eventDispatcher); eventDispatcher);
} }