Commit ca4b5d0a by olly Committed by Oliver Woodman

Make context non-optional for DefaultBandwidthMeter

- Added ability to override the DefaultBandwidthMeter network type.
- These methods currently only work properly if called before the
  meter is used, but the plan is for them to be handled in the same
  way as internally detected network changes.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=217887019
parent 4c6507e7
......@@ -18,6 +18,8 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.google.android.exoplayer2.ext.flac.test">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application android:debuggable="true"
android:allowBackup="false"
tools:ignore="MissingApplicationIcon,HardcodedDebugMode">
......
......@@ -83,7 +83,7 @@ public class FlacPlaybackTest {
Looper.prepare();
LibflacAudioRenderer audioRenderer = new LibflacAudioRenderer();
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
player = ExoPlayerFactory.newInstance(new Renderer[] {audioRenderer}, trackSelector);
player = ExoPlayerFactory.newInstance(context, new Renderer[] {audioRenderer}, trackSelector);
player.addListener(this);
MediaSource mediaSource =
new ExtractorMediaSource.Factory(
......
......@@ -18,6 +18,8 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.google.android.exoplayer2.ext.opus.test">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application android:debuggable="true"
android:allowBackup="false"
tools:ignore="MissingApplicationIcon,HardcodedDebugMode">
......
......@@ -83,7 +83,7 @@ public class OpusPlaybackTest {
Looper.prepare();
LibopusAudioRenderer audioRenderer = new LibopusAudioRenderer();
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
player = ExoPlayerFactory.newInstance(new Renderer[] {audioRenderer}, trackSelector);
player = ExoPlayerFactory.newInstance(context, new Renderer[] {audioRenderer}, trackSelector);
player.addListener(this);
MediaSource mediaSource =
new ExtractorMediaSource.Factory(
......
......@@ -18,6 +18,8 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.google.android.exoplayer2.ext.vp9.test">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application android:debuggable="true"
android:allowBackup="false"
tools:ignore="MissingApplicationIcon,HardcodedDebugMode">
......
......@@ -116,7 +116,7 @@ public class VpxPlaybackTest {
Looper.prepare();
LibvpxVideoRenderer videoRenderer = new LibvpxVideoRenderer(true, 0);
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
player = ExoPlayerFactory.newInstance(new Renderer[] {videoRenderer}, trackSelector);
player = ExoPlayerFactory.newInstance(context, new Renderer[] {videoRenderer}, trackSelector);
player.addListener(this);
MediaSource mediaSource =
new ExtractorMediaSource.Factory(
......
......@@ -19,7 +19,6 @@ import android.content.Context;
import android.os.Looper;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
......@@ -44,51 +43,13 @@ public final class ExoPlayerFactory {
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance.
* @deprecated Use {@link #newSimpleInstance(Context, RenderersFactory, TrackSelector,
* LoadControl)}.
*/
@Deprecated
public static SimpleExoPlayer newSimpleInstance(
Context context, TrackSelector trackSelector, LoadControl loadControl) {
RenderersFactory renderersFactory = new DefaultRenderersFactory(context);
return newSimpleInstance(context, renderersFactory, trackSelector, loadControl);
}
/**
* Creates a {@link SimpleExoPlayer} instance. Available extension renderers are not used.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks.
* @deprecated Use {@link #newSimpleInstance(Context, RenderersFactory, TrackSelector,
* LoadControl)}.
*/
@Deprecated
public static SimpleExoPlayer newSimpleInstance(
Context context,
TrackSelector trackSelector,
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
RenderersFactory renderersFactory = new DefaultRenderersFactory(context);
return newSimpleInstance(
context, renderersFactory, trackSelector, loadControl, drmSessionManager);
}
/**
* Creates a {@link SimpleExoPlayer} instance.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks.
* @param extensionRendererMode The extension renderer mode, which determines if and how available
* extension renderers are used. Note that extensions must be included in the application
* build for them to be considered available.
* @deprecated Use {@link #newSimpleInstance(Context, RenderersFactory, TrackSelector,
* LoadControl)}.
* LoadControl, DrmSessionManager)}.
*/
@Deprecated
public static SimpleExoPlayer newSimpleInstance(
......@@ -116,7 +77,7 @@ public final class ExoPlayerFactory {
* @param allowedVideoJoiningTimeMs The maximum duration for which a video renderer can attempt to
* seamlessly join an ongoing playback.
* @deprecated Use {@link #newSimpleInstance(Context, RenderersFactory, TrackSelector,
* LoadControl)}.
* LoadControl, DrmSessionManager)}.
*/
@Deprecated
public static SimpleExoPlayer newSimpleInstance(
......@@ -154,30 +115,45 @@ public final class ExoPlayerFactory {
/**
* Creates a {@link SimpleExoPlayer} instance.
*
* @param context A {@link Context}.
* @param renderersFactory A factory for creating {@link Renderer}s to be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @deprecated Use {@link #newSimpleInstance(Context, RenderersFactory, TrackSelector)}. The use
* of {@link SimpleExoPlayer#setAudioAttributes(AudioAttributes, boolean)} to manage audio
* focus will be unavailable for the {@link SimpleExoPlayer} returned by this method.
*/
@Deprecated
@SuppressWarnings("nullness:argument.type.incompatible")
public static SimpleExoPlayer newSimpleInstance(
RenderersFactory renderersFactory, TrackSelector trackSelector) {
return newSimpleInstance(
/* context= */ null, renderersFactory, trackSelector, new DefaultLoadControl());
Context context, RenderersFactory renderersFactory, TrackSelector trackSelector) {
return newSimpleInstance(context, renderersFactory, trackSelector, new DefaultLoadControl());
}
/**
* Creates a {@link SimpleExoPlayer} instance.
*
* @param context A {@link Context}.
* @param renderersFactory A factory for creating {@link Renderer}s to be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance.
*/
public static SimpleExoPlayer newSimpleInstance(
Context context, RenderersFactory renderersFactory, TrackSelector trackSelector) {
return newSimpleInstance(context, renderersFactory, trackSelector, new DefaultLoadControl());
Context context, TrackSelector trackSelector, LoadControl loadControl) {
RenderersFactory renderersFactory = new DefaultRenderersFactory(context);
return newSimpleInstance(context, renderersFactory, trackSelector, loadControl);
}
/**
* Creates a {@link SimpleExoPlayer} instance. Available extension renderers are not used.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks.
*/
public static SimpleExoPlayer newSimpleInstance(
Context context,
TrackSelector trackSelector,
LoadControl loadControl,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
RenderersFactory renderersFactory = new DefaultRenderersFactory(context);
return newSimpleInstance(
context, renderersFactory, trackSelector, loadControl, drmSessionManager);
}
/**
......@@ -355,7 +331,7 @@ public final class ExoPlayerFactory {
trackSelector,
loadControl,
drmSessionManager,
getDefaultBandwidthMeter(),
getDefaultBandwidthMeter(context),
analyticsCollectorFactory,
looper);
}
......@@ -397,28 +373,32 @@ public final class ExoPlayerFactory {
/**
* Creates an {@link ExoPlayer} instance.
*
* @param context A {@link Context}.
* @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
*/
public static ExoPlayer newInstance(Renderer[] renderers, TrackSelector trackSelector) {
return newInstance(renderers, trackSelector, new DefaultLoadControl());
public static ExoPlayer newInstance(
Context context, Renderer[] renderers, TrackSelector trackSelector) {
return newInstance(context, renderers, trackSelector, new DefaultLoadControl());
}
/**
* Creates an {@link ExoPlayer} instance.
*
* @param context A {@link Context}.
* @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance.
*/
public static ExoPlayer newInstance(Renderer[] renderers, TrackSelector trackSelector,
LoadControl loadControl) {
return newInstance(renderers, trackSelector, loadControl, Util.getLooper());
public static ExoPlayer newInstance(
Context context, Renderer[] renderers, TrackSelector trackSelector, LoadControl loadControl) {
return newInstance(context, renderers, trackSelector, loadControl, Util.getLooper());
}
/**
* Creates an {@link ExoPlayer} instance.
*
* @param context A {@link Context}.
* @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance.
......@@ -426,13 +406,19 @@ public final class ExoPlayerFactory {
* used to call listeners on.
*/
public static ExoPlayer newInstance(
Renderer[] renderers, TrackSelector trackSelector, LoadControl loadControl, Looper looper) {
return newInstance(renderers, trackSelector, loadControl, getDefaultBandwidthMeter(), looper);
Context context,
Renderer[] renderers,
TrackSelector trackSelector,
LoadControl loadControl,
Looper looper) {
return newInstance(
context, renderers, trackSelector, loadControl, getDefaultBandwidthMeter(context), looper);
}
/**
* Creates an {@link ExoPlayer} instance.
*
* @param context A {@link Context}.
* @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance.
......@@ -440,7 +426,9 @@ public final class ExoPlayerFactory {
* @param looper The {@link Looper} which must be used for all calls to the player and which is
* used to call listeners on.
*/
@SuppressWarnings("unused")
public static ExoPlayer newInstance(
Context context,
Renderer[] renderers,
TrackSelector trackSelector,
LoadControl loadControl,
......@@ -450,9 +438,9 @@ public final class ExoPlayerFactory {
renderers, trackSelector, loadControl, bandwidthMeter, Clock.DEFAULT, looper);
}
private static synchronized BandwidthMeter getDefaultBandwidthMeter() {
private static synchronized BandwidthMeter getDefaultBandwidthMeter(Context context) {
if (singletonBandwidthMeter == null) {
singletonBandwidthMeter = new DefaultBandwidthMeter.Builder().build();
singletonBandwidthMeter = new DefaultBandwidthMeter.Builder(context).build();
}
return singletonBandwidthMeter;
}
......
......@@ -82,18 +82,13 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
private int slidingWindowMaxWeight;
private Clock clock;
/** @deprecated Use {@link #Builder(Context)} instead. */
@Deprecated
public Builder() {
this(/* context= */ null);
}
/**
* Creates a builder with default parameters and without listener.
*
* @param context A context.
*/
public Builder(@Nullable Context context) {
public Builder(Context context) {
// Handling of null is for backward compatibility only.
this.context = context == null ? null : context.getApplicationContext();
initialBitrateEstimates = getInitialBitrateEstimatesForCountry(Util.getCountryCode(context));
slidingWindowMaxWeight = DEFAULT_SLIDING_WINDOW_MAX_WEIGHT;
......@@ -187,14 +182,9 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
* @return A bandwidth meter with the configured properties.
*/
public DefaultBandwidthMeter build() {
Long initialBitrateEstimate =
initialBitrateEstimates.get(
context == null ? C.NETWORK_TYPE_UNKNOWN : Util.getNetworkType(context));
if (initialBitrateEstimate == null) {
initialBitrateEstimate = initialBitrateEstimates.get(C.NETWORK_TYPE_UNKNOWN);
}
DefaultBandwidthMeter bandwidthMeter =
new DefaultBandwidthMeter(initialBitrateEstimate, slidingWindowMaxWeight, clock);
new DefaultBandwidthMeter(
context, initialBitrateEstimates, slidingWindowMaxWeight, clock);
if (eventHandler != null && eventListener != null) {
bandwidthMeter.addEventListener(eventHandler, eventListener);
}
......@@ -225,6 +215,7 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
private static final int ELAPSED_MILLIS_FOR_ESTIMATE = 2000;
private static final int BYTES_TRANSFERRED_FOR_ESTIMATE = 512 * 1024;
private final SparseArray<Long> initialBitrateEstimates;
private final EventDispatcher<EventListener> eventDispatcher;
private final SlidingPercentile slidingPercentile;
private final Clock clock;
......@@ -237,34 +228,54 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
private long totalBytesTransferred;
private long bitrateEstimate;
/** Creates a bandwidth meter with default parameters. */
public DefaultBandwidthMeter() {
this(DEFAULT_INITIAL_BITRATE_ESTIMATE, DEFAULT_SLIDING_WINDOW_MAX_WEIGHT, Clock.DEFAULT);
}
/** @deprecated Use {@link Builder} instead. */
@Deprecated
public DefaultBandwidthMeter(Handler eventHandler, EventListener eventListener) {
this(DEFAULT_INITIAL_BITRATE_ESTIMATE, DEFAULT_SLIDING_WINDOW_MAX_WEIGHT, Clock.DEFAULT);
if (eventHandler != null && eventListener != null) {
addEventListener(eventHandler, eventListener);
}
public DefaultBandwidthMeter() {
this(
/* context= */ null,
/* initialBitrateEstimates= */ new SparseArray<>(),
DEFAULT_SLIDING_WINDOW_MAX_WEIGHT,
Clock.DEFAULT);
}
/** @deprecated Use {@link Builder} instead. */
@Deprecated
public DefaultBandwidthMeter(Handler eventHandler, EventListener eventListener, int maxWeight) {
this(DEFAULT_INITIAL_BITRATE_ESTIMATE, maxWeight, Clock.DEFAULT);
public DefaultBandwidthMeter(Handler eventHandler, EventListener eventListener) {
this(
/* context= */ null,
/* initialBitrateEstimates= */ new SparseArray<>(),
DEFAULT_SLIDING_WINDOW_MAX_WEIGHT,
Clock.DEFAULT);
if (eventHandler != null && eventListener != null) {
addEventListener(eventHandler, eventListener);
}
}
private DefaultBandwidthMeter(long initialBitrateEstimate, int maxWeight, Clock clock) {
private DefaultBandwidthMeter(
@Nullable Context context,
SparseArray<Long> initialBitrateEstimates,
int maxWeight,
Clock clock) {
this.initialBitrateEstimates = initialBitrateEstimates;
this.eventDispatcher = new EventDispatcher<>();
this.slidingPercentile = new SlidingPercentile(maxWeight);
this.clock = clock;
bitrateEstimate = initialBitrateEstimate;
bitrateEstimate =
getInitialBitrateEstimateForNetworkType(
context == null ? C.NETWORK_TYPE_UNKNOWN : Util.getNetworkType(context));
}
/**
* Overrides the network type. Handled in the same way as if the meter had detected a change from
* the current network type to the specified network type.
*
* <p>Applications should not normally call this method. It is intended for testing purposes.
*
* @param networkType The overriding network type.
*/
public synchronized void setNetworkTypeOverride(@C.NetworkType int networkType) {
// TODO: Handle properly as a network change (in same way as non-external network changes).
bitrateEstimate = getInitialBitrateEstimateForNetworkType(networkType);
}
@Override
......@@ -343,6 +354,17 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
eventDispatcher.dispatch(listener -> listener.onBandwidthSample(elapsedMs, bytes, bitrate));
}
private long getInitialBitrateEstimateForNetworkType(@C.NetworkType int networkType) {
Long initialBitrateEstimate = initialBitrateEstimates.get(networkType);
if (initialBitrateEstimate == null) {
initialBitrateEstimate = initialBitrateEstimates.get(C.NETWORK_TYPE_UNKNOWN);
}
if (initialBitrateEstimate == null) {
initialBitrateEstimate = DEFAULT_INITIAL_BITRATE_ESTIMATE;
}
return initialBitrateEstimate;
}
private static Map<String, int[]> createInitialBitrateCountryGroupAssignment() {
HashMap<String, int[]> countryGroupAssignment = new HashMap<>();
countryGroupAssignment.put("AD", new int[] {1, 0, 0, 0});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment