From fefb2a03c2f62e809cf63eedf4d6a9d718aaa467 Mon Sep 17 00:00:00 2001 From: bachinger Date: Wed, 13 May 2020 10:21:46 +0100 Subject: [PATCH] Provide a constructor that does not require a context The only reason to require a context for creating an instance of DefaultMediaSourceFactory is creating a user agent. DownloadHelper has a bunch of static methods that need to instantiate a DefaultMediaSourceFactory without a Context. By adding a setter for the user agent we can remove that restriction and use a default user agent. PiperOrigin-RevId: 311291603 --- .../exoplayer2/demo/PlayerActivity.java | 2 +- .../source/DefaultMediaSourceFactory.java | 84 +++++++++++++------ .../source/DefaultMediaSourceFactoryTest.java | 8 +- 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java b/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java index 47d7966b18..884b811664 100644 --- a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java +++ b/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java @@ -325,7 +325,7 @@ public class PlayerActivity extends AppCompatActivity player = new SimpleExoPlayer.Builder(/* context= */ this, renderersFactory) .setMediaSourceFactory( - new DefaultMediaSourceFactory( + DefaultMediaSourceFactory.newInstance( /* context= */ this, dataSourceFactory, new AdSupportProvider())) .setTrackSelector(trackSelector) .build(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java index 0ec2d278be..28ef30fa60 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source; import android.content.Context; import android.net.Uri; +import android.os.Build; import android.util.SparseArray; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; @@ -94,8 +95,8 @@ import java.util.Map; * *

Ad support for media items with ad tag uri

* - *

For a media item with an ad tag uri an {@link AdSupportProvider} needs to be passed to the - * constructor {@link #DefaultMediaSourceFactory(Context, DataSource.Factory, AdSupportProvider)}. + *

For a media item with an ad tag uri, an {@link AdSupportProvider} needs to be passed to {@link + * #newInstance(Context, DataSource.Factory, AdSupportProvider)}. */ public final class DefaultMediaSourceFactory implements MediaSourceFactory { @@ -128,6 +129,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { * DefaultDataSourceFactory)}. * * @param context The {@link Context}. + * @return A new instance of {@link DefaultMediaSourceFactory}. */ public static DefaultMediaSourceFactory newInstance(Context context) { return newInstance( @@ -141,41 +143,60 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { * * @param context The {@link Context}. * @param dataSourceFactory A {@link DataSource.Factory} to be used to create media sources. + * @return A new instance of {@link DefaultMediaSourceFactory}. */ public static DefaultMediaSourceFactory newInstance( Context context, DataSource.Factory dataSourceFactory) { - return new DefaultMediaSourceFactory(context, dataSourceFactory, /* adSupportProvider= */ null); + return new DefaultMediaSourceFactory(dataSourceFactory, /* adSupportProvider= */ null) + .setDrmUserAgent(Util.getUserAgent(context, ExoPlayerLibraryInfo.VERSION_SLASHY)); } - private static final String TAG = "DefaultMediaSourceFactory"; - - private final DataSource.Factory dataSourceFactory; - @Nullable private final AdSupportProvider adSupportProvider; - private final SparseArray mediaSourceFactories; - @C.ContentType private final int[] supportedTypes; - private final String userAgent; - - private DrmSessionManager drmSessionManager; - private HttpDataSource.Factory drmHttpDataSourceFactory; - @Nullable private List streamKeys; - /** * Creates a new instance with the given {@link Context} and {@link DataSource.Factory}. * * @param context The {@link Context}. * @param dataSourceFactory A {@link DataSource.Factory} to be used to create media sources. + * @param adSupportProvider A {@link AdSupportProvider} to be used to create ad media sources. + * @return A new instance of {@link DefaultMediaSourceFactory}. + */ + public static DefaultMediaSourceFactory newInstance( + Context context, DataSource.Factory dataSourceFactory, AdSupportProvider adSupportProvider) { + return new DefaultMediaSourceFactory(dataSourceFactory, adSupportProvider) + .setDrmUserAgent(Util.getUserAgent(context, ExoPlayerLibraryInfo.VERSION_SLASHY)); + } + + private static final String TAG = "DefaultMediaSourceFactory"; + private static final String DEFAULT_USER_AGENT = + ExoPlayerLibraryInfo.VERSION_SLASHY + + " (Linux;Android " + + Build.VERSION.RELEASE + + ") " + + ExoPlayerLibraryInfo.VERSION_SLASHY; + + private final DataSource.Factory dataSourceFactory; + @Nullable private final AdSupportProvider adSupportProvider; + private final SparseArray mediaSourceFactories; + @C.ContentType private final int[] supportedTypes; + + private DrmSessionManager drmSessionManager; + @Nullable private HttpDataSource.Factory drmHttpDataSourceFactory; + private String userAgent; + @Nullable private List streamKeys; + + /** + * Creates a new instance with the {@link DataSource.Factory} for downloading media and an {@link + * AdSupportProvider} to create {@link AdsMediaSource AdsMediaSources}. + * + * @param dataSourceFactory A {@link DataSource.Factory} to be used to create media sources. * @param adSupportProvider An {@link AdSupportProvider} to get ads loaders and ad view providers * to be used to create {@link AdsMediaSource AdsMediaSources}. */ public DefaultMediaSourceFactory( - Context context, - DataSource.Factory dataSourceFactory, - @Nullable AdSupportProvider adSupportProvider) { + DataSource.Factory dataSourceFactory, @Nullable AdSupportProvider adSupportProvider) { this.dataSourceFactory = dataSourceFactory; this.adSupportProvider = adSupportProvider; drmSessionManager = DrmSessionManager.getDummyDrmSessionManager(); - userAgent = Util.getUserAgent(context, ExoPlayerLibraryInfo.VERSION_SLASHY); - drmHttpDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent); + userAgent = DEFAULT_USER_AGENT; mediaSourceFactories = loadDelegates(dataSourceFactory); supportedTypes = new int[mediaSourceFactories.size()]; for (int i = 0; i < mediaSourceFactories.size(); i++) { @@ -194,10 +215,21 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { */ public DefaultMediaSourceFactory setDrmHttpDataSourceFactory( @Nullable HttpDataSource.Factory drmHttpDataSourceFactory) { - this.drmHttpDataSourceFactory = - drmHttpDataSourceFactory != null - ? drmHttpDataSourceFactory - : new DefaultHttpDataSourceFactory(userAgent); + this.drmHttpDataSourceFactory = drmHttpDataSourceFactory; + return this; + } + + /** + * Sets the optional user agent to be used for DRM requests. + * + *

In case a factory has been set by {@link + * #setDrmHttpDataSourceFactory(HttpDataSource.Factory)}, this user agent is ignored. + * + * @param userAgent The user agent to be used for DRM requests. + * @return This factory, for convenience. + */ + public DefaultMediaSourceFactory setDrmUserAgent(@Nullable String userAgent) { + this.userAgent = userAgent != null ? userAgent : DEFAULT_USER_AGENT; return this; } @@ -309,7 +341,9 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { new HttpMediaDrmCallback( drmConfiguration.licenseUri.toString(), drmConfiguration.forceDefaultLicenseUri, - drmHttpDataSourceFactory); + drmHttpDataSourceFactory != null + ? drmHttpDataSourceFactory + : new DefaultHttpDataSourceFactory(userAgent)); for (Map.Entry entry : drmConfiguration.requestHeaders.entrySet()) { drmCallback.setKeyRequestProperty(entry.getKey(), entry.getValue()); } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactoryTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactoryTest.java index 0e723a0263..3b4b38c3af 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactoryTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactoryTest.java @@ -193,9 +193,9 @@ public final class DefaultMediaSourceFactoryTest { Uri adTagUri = Uri.parse(URI_MEDIA); MediaItem mediaItem = new MediaItem.Builder().setUri(URI_MEDIA).setAdTagUri(adTagUri).build(); DefaultMediaSourceFactory defaultMediaSourceFactory = - new DefaultMediaSourceFactory( + DefaultMediaSourceFactory.newInstance( applicationContext, - new DefaultDataSourceFactory(applicationContext, "userAgent"), + new DefaultDataSourceFactory(applicationContext, /* userAgent= */ "ua"), createAdSupportProvider(mock(AdsLoader.class), mock(AdsLoader.AdViewProvider.class))); MediaSource mediaSource = defaultMediaSourceFactory.createMediaSource(mediaItem); @@ -209,9 +209,9 @@ public final class DefaultMediaSourceFactoryTest { MediaItem mediaItem = new MediaItem.Builder().setUri(URI_MEDIA).setAdTagUri(Uri.parse(URI_MEDIA)).build(); DefaultMediaSourceFactory defaultMediaSourceFactory = - new DefaultMediaSourceFactory( + DefaultMediaSourceFactory.newInstance( applicationContext, - new DefaultDataSourceFactory(applicationContext, "userAgent"), + new DefaultDataSourceFactory(applicationContext, /* userAgent= */ "ua"), createAdSupportProvider(/* adsLoader= */ null, mock(AdsLoader.AdViewProvider.class))); MediaSource mediaSource = defaultMediaSourceFactory.createMediaSource(mediaItem);