Automated g4 rollback of changelist 217189082.

*** Reason for rollback ***

Broke photos (b/117818304)

*** Original change description ***

Add ExoPlayer.setForegroundMode

Issue: #2826

***

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=217356705
This commit is contained in:
falhassen 2018-10-16 11:44:56 -07:00 committed by Oliver Woodman
parent cc914494d7
commit 423a954e1b
6 changed files with 18 additions and 165 deletions

View File

@ -2,8 +2,6 @@
### dev-v2 (not yet released) ### ### dev-v2 (not yet released) ###
* Improve decoder re-use between playbacks. TODO: Write and link a blog post
here ([#2826](https://github.com/google/ExoPlayer/issues/2826)).
* Improve initial bandwidth meter estimates using the current country and * Improve initial bandwidth meter estimates using the current country and
network type. network type.
* Do not retry failed loads whose error is `FileNotFoundException`. * Do not retry failed loads whose error is `FileNotFoundException`.

View File

@ -209,34 +209,4 @@ public interface ExoPlayer extends Player {
/** Returns the currently active {@link SeekParameters} of the player. */ /** Returns the currently active {@link SeekParameters} of the player. */
SeekParameters getSeekParameters(); SeekParameters getSeekParameters();
/**
* Sets whether the player is allowed to keep holding limited resources such as video decoders,
* even when in the idle state. By doing so, the player may be able to reduce latency when
* starting to play another piece of content for which the same resources are required.
*
* <p>This mode should be used with caution, since holding limited resources may prevent other
* players of media components from acquiring them. It should only be enabled when <em>both</em>
* of the following conditions are true:
*
* <ul>
* <li>The application that owns the player is in the foreground.
* <li>The player is used in a way that may benefit from foreground mode. For this to be true,
* the same player instance must be used to play multiple pieces of content, and there must
* be gaps between the playbacks (i.e. {@link #stop} is called to halt one playback, and
* {@link #prepare} is called some time later to start a new one).
* </ul>
*
* <p>Note that foreground mode is <em>not</em> useful for switching between content without gaps
* between the playbacks. For this use case {@link #stop} does not need to be called, and simply
* calling {@link #prepare} for the new media will cause limited resources to be retained even if
* foreground mode is not enabled.
*
* <p>If foreground mode is enabled, it's the application's responsibility to disable it when the
* conditions described above no longer hold.
*
* @param foregroundMode Whether the player is allowed to keep limited resources even when in the
* idle state.
*/
void setForegroundMode(boolean foregroundMode);
} }

View File

@ -71,7 +71,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
private int pendingOperationAcks; private int pendingOperationAcks;
private boolean hasPendingPrepare; private boolean hasPendingPrepare;
private boolean hasPendingSeek; private boolean hasPendingSeek;
private boolean foregroundMode;
private PlaybackParameters playbackParameters; private PlaybackParameters playbackParameters;
private SeekParameters seekParameters; private SeekParameters seekParameters;
private @Nullable ExoPlaybackException playbackError; private @Nullable ExoPlaybackException playbackError;
@ -360,14 +359,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
return seekParameters; return seekParameters;
} }
@Override
public void setForegroundMode(boolean foregroundMode) {
if (this.foregroundMode != foregroundMode) {
this.foregroundMode = foregroundMode;
internalPlayer.setForegroundMode(foregroundMode);
}
}
@Override @Override
public void stop(boolean reset) { public void stop(boolean reset) {
if (reset) { if (reset) {

View File

@ -44,7 +44,6 @@ import com.google.android.exoplayer2.util.Util;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
/** Implements the internal behavior of {@link ExoPlayerImpl}. */ /** Implements the internal behavior of {@link ExoPlayerImpl}. */
/* package */ final class ExoPlayerImplInternal /* package */ final class ExoPlayerImplInternal
@ -77,10 +76,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
private static final int MSG_TRACK_SELECTION_INVALIDATED = 11; private static final int MSG_TRACK_SELECTION_INVALIDATED = 11;
private static final int MSG_SET_REPEAT_MODE = 12; private static final int MSG_SET_REPEAT_MODE = 12;
private static final int MSG_SET_SHUFFLE_ENABLED = 13; private static final int MSG_SET_SHUFFLE_ENABLED = 13;
private static final int MSG_SET_FOREGROUND_MODE = 14; private static final int MSG_SEND_MESSAGE = 14;
private static final int MSG_SEND_MESSAGE = 15; private static final int MSG_SEND_MESSAGE_TO_TARGET_THREAD = 15;
private static final int MSG_SEND_MESSAGE_TO_TARGET_THREAD = 16; private static final int MSG_PLAYBACK_PARAMETERS_CHANGED_INTERNAL = 16;
private static final int MSG_PLAYBACK_PARAMETERS_CHANGED_INTERNAL = 17;
private static final int PREPARING_SOURCE_INTERVAL_MS = 10; private static final int PREPARING_SOURCE_INTERVAL_MS = 10;
private static final int RENDERING_INTERVAL_MS = 10; private static final int RENDERING_INTERVAL_MS = 10;
@ -117,7 +115,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
private boolean rebuffering; private boolean rebuffering;
@Player.RepeatMode private int repeatMode; @Player.RepeatMode private int repeatMode;
private boolean shuffleModeEnabled; private boolean shuffleModeEnabled;
private boolean foregroundMode;
private int pendingPrepareCount; private int pendingPrepareCount;
private SeekPosition pendingInitialSeekPosition; private SeekPosition pendingInitialSeekPosition;
@ -221,29 +218,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
handler.obtainMessage(MSG_SEND_MESSAGE, message).sendToTarget(); handler.obtainMessage(MSG_SEND_MESSAGE, message).sendToTarget();
} }
public synchronized void setForegroundMode(boolean foregroundMode) {
if (foregroundMode) {
handler.obtainMessage(MSG_SET_FOREGROUND_MODE, /* foregroundMode */ 1, 0).sendToTarget();
} else {
AtomicBoolean processedFlag = new AtomicBoolean();
handler
.obtainMessage(MSG_SET_FOREGROUND_MODE, /* foregroundMode */ 0, 0, processedFlag)
.sendToTarget();
boolean wasInterrupted = false;
while (!processedFlag.get() && !released) {
try {
wait();
} catch (InterruptedException e) {
wasInterrupted = true;
}
}
if (wasInterrupted) {
// Restore the interrupted status.
Thread.currentThread().interrupt();
}
}
}
public synchronized void release() { public synchronized void release() {
if (released) { if (released) {
return; return;
@ -337,15 +311,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
case MSG_SET_SEEK_PARAMETERS: case MSG_SET_SEEK_PARAMETERS:
setSeekParametersInternal((SeekParameters) msg.obj); setSeekParametersInternal((SeekParameters) msg.obj);
break; break;
case MSG_SET_FOREGROUND_MODE:
setForegroundModeInternal(
/* foregroundMode= */ msg.arg1 != 0, /* processedFlag= */ (AtomicBoolean) msg.obj);
break;
case MSG_STOP: case MSG_STOP:
stopInternal( stopInternal(/* reset= */ msg.arg1 != 0, /* acknowledgeStop= */ true);
/* forceResetRenderers= */ false,
/* resetPositionAndState= */ msg.arg1 != 0,
/* acknowledgeStop= */ true);
break; break;
case MSG_PERIOD_PREPARED: case MSG_PERIOD_PREPARED:
handlePeriodPrepared((MediaPeriod) msg.obj); handlePeriodPrepared((MediaPeriod) msg.obj);
@ -378,26 +345,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
maybeNotifyPlaybackInfoChanged(); maybeNotifyPlaybackInfoChanged();
} catch (ExoPlaybackException e) { } catch (ExoPlaybackException e) {
Log.e(TAG, "Playback error.", e); Log.e(TAG, "Playback error.", e);
stopInternal( stopInternal(/* reset= */ false, /* acknowledgeStop= */ false);
/* forceResetRenderers= */ true,
/* resetPositionAndState= */ false,
/* acknowledgeStop= */ false);
eventHandler.obtainMessage(MSG_ERROR, e).sendToTarget(); eventHandler.obtainMessage(MSG_ERROR, e).sendToTarget();
maybeNotifyPlaybackInfoChanged(); maybeNotifyPlaybackInfoChanged();
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "Source error.", e); Log.e(TAG, "Source error.", e);
stopInternal( stopInternal(/* reset= */ false, /* acknowledgeStop= */ false);
/* forceResetRenderers= */ false,
/* resetPositionAndState= */ false,
/* acknowledgeStop= */ false);
eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForSource(e)).sendToTarget(); eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForSource(e)).sendToTarget();
maybeNotifyPlaybackInfoChanged(); maybeNotifyPlaybackInfoChanged();
} catch (RuntimeException e) { } catch (RuntimeException e) {
Log.e(TAG, "Internal runtime error.", e); Log.e(TAG, "Internal runtime error.", e);
stopInternal( stopInternal(/* reset= */ false, /* acknowledgeStop= */ false);
/* forceResetRenderers= */ true,
/* resetPositionAndState= */ false,
/* acknowledgeStop= */ false);
eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForUnexpected(e)) eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForUnexpected(e))
.sendToTarget(); .sendToTarget();
maybeNotifyPlaybackInfoChanged(); maybeNotifyPlaybackInfoChanged();
@ -436,8 +394,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void prepareInternal(MediaSource mediaSource, boolean resetPosition, boolean resetState) { private void prepareInternal(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
pendingPrepareCount++; pendingPrepareCount++;
resetInternal( resetInternal(/* releaseMediaSource= */ true, resetPosition, resetState);
/* resetRenderers= */ false, /* releaseMediaSource= */ true, resetPosition, resetState);
loadControl.onPrepared(); loadControl.onPrepared();
this.mediaSource = mediaSource; this.mediaSource = mediaSource;
setState(Player.STATE_BUFFERING); setState(Player.STATE_BUFFERING);
@ -674,10 +631,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
// End playback, as we didn't manage to find a valid seek position. // End playback, as we didn't manage to find a valid seek position.
setState(Player.STATE_ENDED); setState(Player.STATE_ENDED);
resetInternal( resetInternal(
/* resetRenderers= */ false, /* releaseMediaSource= */ false, /* resetPosition= */ true, /* resetState= */ false);
/* releaseMediaSource= */ false,
/* resetPosition= */ true,
/* resetState= */ false);
} else { } else {
// Execute the seek in the current media periods. // Execute the seek in the current media periods.
long newPeriodPositionUs = periodPositionUs; long newPeriodPositionUs = periodPositionUs;
@ -784,33 +738,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
this.seekParameters = seekParameters; this.seekParameters = seekParameters;
} }
private void setForegroundModeInternal( private void stopInternal(boolean reset, boolean acknowledgeStop) {
boolean foregroundMode, @Nullable AtomicBoolean processedFlag) {
if (this.foregroundMode != foregroundMode) {
this.foregroundMode = foregroundMode;
if (!foregroundMode) {
for (Renderer renderer : renderers) {
if (renderer.getState() == Renderer.STATE_DISABLED) {
renderer.reset();
}
}
}
}
if (processedFlag != null) {
synchronized (this) {
processedFlag.set(true);
notifyAll();
}
}
}
private void stopInternal(
boolean forceResetRenderers, boolean resetPositionAndState, boolean acknowledgeStop) {
resetInternal( resetInternal(
/* resetRenderers= */ forceResetRenderers || !foregroundMode, /* releaseMediaSource= */ true, /* resetPosition= */ reset, /* resetState= */ reset);
/* releaseMediaSource= */ true,
/* resetPosition= */ resetPositionAndState,
/* resetState= */ resetPositionAndState);
playbackInfoUpdate.incrementPendingOperationAcks( playbackInfoUpdate.incrementPendingOperationAcks(
pendingPrepareCount + (acknowledgeStop ? 1 : 0)); pendingPrepareCount + (acknowledgeStop ? 1 : 0));
pendingPrepareCount = 0; pendingPrepareCount = 0;
@ -820,10 +750,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void releaseInternal() { private void releaseInternal() {
resetInternal( resetInternal(
/* resetRenderers= */ true, /* releaseMediaSource= */ true, /* resetPosition= */ true, /* resetState= */ true);
/* releaseMediaSource= */ true,
/* resetPosition= */ true,
/* resetState= */ true);
loadControl.onReleased(); loadControl.onReleased();
setState(Player.STATE_IDLE); setState(Player.STATE_IDLE);
internalPlaybackThread.quit(); internalPlaybackThread.quit();
@ -845,10 +772,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
private void resetInternal( private void resetInternal(
boolean resetRenderers, boolean releaseMediaSource, boolean resetPosition, boolean resetState) {
boolean releaseMediaSource,
boolean resetPosition,
boolean resetState) {
handler.removeMessages(MSG_DO_SOME_WORK); handler.removeMessages(MSG_DO_SOME_WORK);
rebuffering = false; rebuffering = false;
mediaClock.stop(); mediaClock.stop();
@ -858,17 +782,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
disableRenderer(renderer); disableRenderer(renderer);
} catch (ExoPlaybackException | RuntimeException e) { } catch (ExoPlaybackException | RuntimeException e) {
// There's nothing we can do. // There's nothing we can do.
Log.e(TAG, "Disable failed.", e); Log.e(TAG, "Stop failed.", e);
}
}
if (resetRenderers) {
for (Renderer renderer : renderers) {
try {
renderer.reset();
} catch (RuntimeException e) {
// There's nothing we can do.
Log.e(TAG, "Reset failed.", e);
}
} }
} }
enabledRenderers = new Renderer[0]; enabledRenderers = new Renderer[0];
@ -1075,6 +989,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
mediaClock.onRendererDisabled(renderer); mediaClock.onRendererDisabled(renderer);
ensureStopped(renderer); ensureStopped(renderer);
renderer.disable(); renderer.disable();
renderer.reset();
} }
private void reselectTracksInternal() throws ExoPlaybackException { private void reselectTracksInternal() throws ExoPlaybackException {
@ -1379,10 +1294,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
setState(Player.STATE_ENDED); setState(Player.STATE_ENDED);
// Reset, but retain the source so that it can still be used should a seek occur. // Reset, but retain the source so that it can still be used should a seek occur.
resetInternal( resetInternal(
/* resetRenderers= */ false, /* releaseMediaSource= */ false, /* resetPosition= */ true, /* resetState= */ false);
/* releaseMediaSource= */ false,
/* resetPosition= */ true,
/* resetState= */ false);
} }
/** /**
@ -1727,17 +1639,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
throws ExoPlaybackException { throws ExoPlaybackException {
enabledRenderers = new Renderer[totalEnabledRendererCount]; enabledRenderers = new Renderer[totalEnabledRendererCount];
int enabledRendererCount = 0; int enabledRendererCount = 0;
TrackSelectorResult trackSelectorResult = queue.getPlayingPeriod().getTrackSelectorResult(); MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
// Reset all disabled renderers before enabling any new ones. This makes sure resources released
// by the disabled renderers will be available to renderers that are being enabled.
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
if (!trackSelectorResult.isRendererEnabled(i)) { if (playingPeriodHolder.getTrackSelectorResult().isRendererEnabled(i)) {
renderers[i].reset();
}
}
// Enable the renderers.
for (int i = 0; i < renderers.length; i++) {
if (trackSelectorResult.isRendererEnabled(i)) {
enableRenderer(i, rendererWasEnabledFlags[i], enabledRendererCount++); enableRenderer(i, rendererWasEnabledFlags[i], enabledRendererCount++);
} }
} }

View File

@ -958,11 +958,6 @@ public class SimpleExoPlayer extends BasePlayer
return player.getSeekParameters(); return player.getSeekParameters();
} }
@Override
public void setForegroundMode(boolean foregroundMode) {
player.setForegroundMode(foregroundMode);
}
@Override @Override
public void stop(boolean reset) { public void stop(boolean reset) {
verifyApplicationThread(); verifyApplicationThread();

View File

@ -267,9 +267,4 @@ public abstract class StubExoPlayer extends BasePlayer implements ExoPlayer {
public long getContentBufferedPosition() { public long getContentBufferedPosition() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public void setForegroundMode(boolean foregroundMode) {
throw new UnsupportedOperationException();
}
} }