mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Compare commits
No commits in common. "1ea69ca7bea83a561b56a6d6f07d1c08b19f32c8" and "f261fe187a350ca0ff3d080f61fa9766a0aef653" have entirely different histories.
1ea69ca7be
...
f261fe187a
@ -23,9 +23,6 @@
|
||||
* DataSource:
|
||||
* Audio:
|
||||
* Allow constant power upmixing/downmixing in DefaultAudioMixer.
|
||||
* Make `ChannelMappingAudioProcessor`, `TrimmingAudioProcessor` and
|
||||
`ToFloatPcmAudioProcessor` public
|
||||
([#2339](https://github.com/androidx/media/issues/2339)).
|
||||
* Video:
|
||||
* Add experimental `ExoPlayer` API to include the
|
||||
`MediaCodec.BUFFER_FLAG_DECODE_ONLY` flag when queuing decode-only input
|
||||
@ -71,9 +68,6 @@
|
||||
* MIDI extension:
|
||||
* Leanback extension:
|
||||
* Cast extension:
|
||||
* Add support for `getDeviceVolume()`, `setDeviceVolume()`,
|
||||
`getDeviceMuted()`, and `setDeviceMuted()`
|
||||
([#2089](https://github.com/androidx/media/issues/2089)).
|
||||
* Test Utilities:
|
||||
* Removed `transformer.TestUtil.addAudioDecoders(String...)`,
|
||||
`transformer.TestUtil.addAudioEncoders(String...)`, and
|
||||
|
@ -27,7 +27,6 @@ dependencies {
|
||||
api 'com.google.android.gms:play-services-cast-framework:21.5.0'
|
||||
implementation 'androidx.annotation:annotation:' + androidxAnnotationVersion
|
||||
api project(modulePrefix + 'lib-common')
|
||||
compileOnly 'com.google.errorprone:error_prone_annotations:' + errorProneVersion
|
||||
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
|
||||
compileOnly 'org.jetbrains.kotlin:kotlin-annotations-jvm:' + kotlinAnnotationsVersion
|
||||
testImplementation project(modulePrefix + 'test-utils')
|
||||
|
@ -29,7 +29,6 @@ import android.media.MediaRouter2.TransferCallback;
|
||||
import android.media.RouteDiscoveryPreference;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Range;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
@ -60,7 +59,6 @@ import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.Size;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
import com.google.android.gms.cast.Cast;
|
||||
import com.google.android.gms.cast.CastStatusCodes;
|
||||
import com.google.android.gms.cast.MediaInfo;
|
||||
import com.google.android.gms.cast.MediaQueueItem;
|
||||
@ -75,8 +73,6 @@ import com.google.android.gms.cast.framework.media.RemoteMediaClient.MediaChanne
|
||||
import com.google.android.gms.common.api.PendingResult;
|
||||
import com.google.android.gms.common.api.ResultCallback;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.annotations.InlineMe;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
@ -97,23 +93,12 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
@UnstableApi
|
||||
public final class CastPlayer extends BasePlayer {
|
||||
|
||||
/**
|
||||
* Maximum volume to use for {@link #getDeviceVolume()} and {@link #setDeviceVolume}.
|
||||
*
|
||||
* <p>These methods are implemented around {@link CastSession#setVolume} and {@link
|
||||
* CastSession#getVolume} which operate on a {@code [0, 1]} range. So this value allows us to
|
||||
* convert to and from the int-based volume scale that {@link #getDeviceVolume()} uses.
|
||||
*/
|
||||
private static final int MAX_VOLUME = 20;
|
||||
|
||||
/**
|
||||
* A {@link DeviceInfo#PLAYBACK_TYPE_REMOTE remote} {@link DeviceInfo} with a null {@link
|
||||
* DeviceInfo#routingControllerId}.
|
||||
*/
|
||||
public static final DeviceInfo DEVICE_INFO_REMOTE_EMPTY =
|
||||
new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_REMOTE).setMaxVolume(MAX_VOLUME).build();
|
||||
|
||||
private static final Range<Integer> VOLUME_RANGE = new Range<>(0, MAX_VOLUME);
|
||||
new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_REMOTE).build();
|
||||
|
||||
static {
|
||||
MediaLibraryInfo.registerModule("media3.cast");
|
||||
@ -128,11 +113,6 @@ public final class CastPlayer extends BasePlayer {
|
||||
COMMAND_STOP,
|
||||
COMMAND_SEEK_TO_DEFAULT_POSITION,
|
||||
COMMAND_SEEK_TO_MEDIA_ITEM,
|
||||
COMMAND_GET_DEVICE_VOLUME,
|
||||
COMMAND_ADJUST_DEVICE_VOLUME,
|
||||
COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS,
|
||||
COMMAND_SET_DEVICE_VOLUME,
|
||||
COMMAND_SET_DEVICE_VOLUME_WITH_FLAGS,
|
||||
COMMAND_SET_REPEAT_MODE,
|
||||
COMMAND_SET_SPEED_AND_PITCH,
|
||||
COMMAND_GET_CURRENT_MEDIA_ITEM,
|
||||
@ -164,8 +144,6 @@ public final class CastPlayer extends BasePlayer {
|
||||
@Nullable private final Api30Impl api30Impl;
|
||||
|
||||
// Result callbacks.
|
||||
private final Cast.Listener castListener;
|
||||
|
||||
private final StatusListener statusListener;
|
||||
private final SeekResultCallback seekResultCallback;
|
||||
|
||||
@ -176,10 +154,7 @@ public final class CastPlayer extends BasePlayer {
|
||||
// Internal state.
|
||||
private final StateHolder<Boolean> playWhenReady;
|
||||
private final StateHolder<Integer> repeatMode;
|
||||
private boolean isMuted;
|
||||
private int deviceVolume;
|
||||
private final StateHolder<PlaybackParameters> playbackParameters;
|
||||
@Nullable private CastSession castSession;
|
||||
@Nullable private RemoteMediaClient remoteMediaClient;
|
||||
private CastTimeline currentTimeline;
|
||||
private Tracks currentTracks;
|
||||
@ -282,7 +257,6 @@ public final class CastPlayer extends BasePlayer {
|
||||
this.maxSeekToPreviousPositionMs = maxSeekToPreviousPositionMs;
|
||||
timelineTracker = new CastTimelineTracker(mediaItemConverter);
|
||||
period = new Timeline.Period();
|
||||
castListener = new CastListener();
|
||||
statusListener = new StatusListener();
|
||||
seekResultCallback = new SeekResultCallback();
|
||||
listeners =
|
||||
@ -292,7 +266,6 @@ public final class CastPlayer extends BasePlayer {
|
||||
(listener, flags) -> listener.onEvents(/* player= */ this, new Events(flags)));
|
||||
playWhenReady = new StateHolder<>(false);
|
||||
repeatMode = new StateHolder<>(REPEAT_MODE_OFF);
|
||||
deviceVolume = MAX_VOLUME;
|
||||
playbackParameters = new StateHolder<>(PlaybackParameters.DEFAULT);
|
||||
playbackState = STATE_IDLE;
|
||||
currentTimeline = CastTimeline.EMPTY_CAST_TIMELINE;
|
||||
@ -305,7 +278,8 @@ public final class CastPlayer extends BasePlayer {
|
||||
|
||||
SessionManager sessionManager = castContext.getSessionManager();
|
||||
sessionManager.addSessionManagerListener(statusListener, CastSession.class);
|
||||
setCastSession(sessionManager.getCurrentCastSession());
|
||||
CastSession session = sessionManager.getCurrentCastSession();
|
||||
setRemoteMediaClient(session != null ? session.getRemoteMediaClient() : null);
|
||||
updateInternalStateAndNotifyIfChanged();
|
||||
if (SDK_INT >= 30 && context != null) {
|
||||
api30Impl = new Api30Impl(context);
|
||||
@ -855,98 +829,61 @@ public final class CastPlayer extends BasePlayer {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
/** This method is not supported and always returns {@code 0}. */
|
||||
@Override
|
||||
public int getDeviceVolume() {
|
||||
return deviceVolume;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** This method is not supported and always returns {@code false}. */
|
||||
@Override
|
||||
public boolean isDeviceMuted() {
|
||||
return isMuted;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setDeviceVolume(int, int)} instead.
|
||||
*/
|
||||
@InlineMe(replacement = "this.setDeviceVolume(volume, 0)")
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setDeviceVolume(@IntRange(from = 0) int volume) {
|
||||
setDeviceVolume(volume, /* flags= */ 0);
|
||||
}
|
||||
public void setDeviceVolume(int volume) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void setDeviceVolume(@IntRange(from = 0) int volume, @C.VolumeFlags int flags) {
|
||||
if (castSession == null) {
|
||||
return;
|
||||
}
|
||||
volume = VOLUME_RANGE.clamp(volume);
|
||||
try {
|
||||
// See [Internal ref: b/399691860] for context on why we don't use
|
||||
// RemoteMediaClient.setStreamVolume.
|
||||
castSession.setVolume((float) volume / MAX_VOLUME);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Ignoring setDeviceVolume due to exception", e);
|
||||
return;
|
||||
}
|
||||
setDeviceVolumeAndNotifyIfChanged(volume, isMuted);
|
||||
listeners.flushEvents();
|
||||
}
|
||||
public void setDeviceVolume(int volume, @C.VolumeFlags int flags) {}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #increaseDeviceVolume(int)} instead.
|
||||
*/
|
||||
@InlineMe(replacement = "this.increaseDeviceVolume(0)")
|
||||
@Deprecated
|
||||
@Override
|
||||
public void increaseDeviceVolume() {
|
||||
increaseDeviceVolume(/* flags= */ 0);
|
||||
}
|
||||
public void increaseDeviceVolume() {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void increaseDeviceVolume(@C.VolumeFlags int flags) {
|
||||
setDeviceVolume(getDeviceVolume() + 1, flags);
|
||||
}
|
||||
public void increaseDeviceVolume(@C.VolumeFlags int flags) {}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #decreaseDeviceVolume(int)} (int)} instead.
|
||||
* @deprecated Use {@link #decreaseDeviceVolume(int)} instead.
|
||||
*/
|
||||
@InlineMe(replacement = "this.decreaseDeviceVolume(0)")
|
||||
@Deprecated
|
||||
@Override
|
||||
public void decreaseDeviceVolume() {
|
||||
decreaseDeviceVolume(/* flags= */ 0);
|
||||
}
|
||||
public void decreaseDeviceVolume() {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void decreaseDeviceVolume(@C.VolumeFlags int flags) {
|
||||
setDeviceVolume(getDeviceVolume() - 1, flags);
|
||||
}
|
||||
public void decreaseDeviceVolume(@C.VolumeFlags int flags) {}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setDeviceMuted(boolean, int)} instead.
|
||||
*/
|
||||
@InlineMe(replacement = "this.setDeviceMuted(muted, 0)")
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setDeviceMuted(boolean muted) {
|
||||
setDeviceMuted(muted, /* flags= */ 0);
|
||||
}
|
||||
public void setDeviceMuted(boolean muted) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void setDeviceMuted(boolean muted, @C.VolumeFlags int flags) {
|
||||
if (castSession == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
castSession.setMute(muted);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Ignoring setDeviceMuted due to exception", e);
|
||||
return;
|
||||
}
|
||||
setDeviceVolumeAndNotifyIfChanged(deviceVolume, muted);
|
||||
listeners.flushEvents();
|
||||
}
|
||||
public void setDeviceMuted(boolean muted, @C.VolumeFlags int flags) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
@ -969,7 +906,6 @@ public final class CastPlayer extends BasePlayer {
|
||||
? getCurrentTimeline().getPeriod(oldWindowIndex, period, /* setIds= */ true).uid
|
||||
: null;
|
||||
updatePlayerStateAndNotifyIfChanged(/* resultCallback= */ null);
|
||||
updateVolumeAndNotifyIfChanged();
|
||||
updateRepeatModeAndNotifyIfChanged(/* resultCallback= */ null);
|
||||
updatePlaybackRateAndNotifyIfChanged(/* resultCallback= */ null);
|
||||
boolean playingPeriodChangedByTimelineChange = updateTimelineAndNotifyIfChanged();
|
||||
@ -1078,14 +1014,6 @@ public final class CastPlayer extends BasePlayer {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresNonNull("castSession")
|
||||
private void updateVolumeAndNotifyIfChanged() {
|
||||
if (castSession != null) {
|
||||
int deviceVolume = VOLUME_RANGE.clamp((int) Math.round(castSession.getVolume() * MAX_VOLUME));
|
||||
setDeviceVolumeAndNotifyIfChanged(deviceVolume, castSession.isMute());
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresNonNull("remoteMediaClient")
|
||||
private void updateRepeatModeAndNotifyIfChanged(@Nullable ResultCallback<?> resultCallback) {
|
||||
if (repeatMode.acceptsUpdate(resultCallback)) {
|
||||
@ -1327,17 +1255,6 @@ public final class CastPlayer extends BasePlayer {
|
||||
/* adIndexInAdGroup= */ C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
private void setDeviceVolumeAndNotifyIfChanged(
|
||||
@IntRange(from = 0) int deviceVolume, boolean isMuted) {
|
||||
if (this.deviceVolume != deviceVolume || this.isMuted != isMuted) {
|
||||
this.deviceVolume = deviceVolume;
|
||||
this.isMuted = isMuted;
|
||||
listeners.queueEvent(
|
||||
Player.EVENT_DEVICE_VOLUME_CHANGED,
|
||||
listener -> listener.onDeviceVolumeChanged(deviceVolume, isMuted));
|
||||
}
|
||||
}
|
||||
|
||||
private void setRepeatModeAndNotifyIfChanged(@Player.RepeatMode int repeatMode) {
|
||||
if (this.repeatMode.value != repeatMode) {
|
||||
this.repeatMode.value = repeatMode;
|
||||
@ -1390,16 +1307,7 @@ public final class CastPlayer extends BasePlayer {
|
||||
}
|
||||
}
|
||||
|
||||
private void setCastSession(@Nullable CastSession castSession) {
|
||||
if (this.castSession != null) {
|
||||
this.castSession.removeCastListener(castListener);
|
||||
}
|
||||
if (castSession != null) {
|
||||
castSession.addCastListener(castListener);
|
||||
}
|
||||
this.castSession = castSession;
|
||||
RemoteMediaClient remoteMediaClient =
|
||||
castSession != null ? castSession.getRemoteMediaClient() : null;
|
||||
private void setRemoteMediaClient(@Nullable RemoteMediaClient remoteMediaClient) {
|
||||
if (this.remoteMediaClient == remoteMediaClient) {
|
||||
// Do nothing.
|
||||
return;
|
||||
@ -1560,22 +1468,22 @@ public final class CastPlayer extends BasePlayer {
|
||||
|
||||
@Override
|
||||
public void onSessionStarted(CastSession castSession, String s) {
|
||||
setCastSession(castSession);
|
||||
setRemoteMediaClient(castSession.getRemoteMediaClient());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionResumed(CastSession castSession, boolean b) {
|
||||
setCastSession(castSession);
|
||||
setRemoteMediaClient(castSession.getRemoteMediaClient());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionEnded(CastSession castSession, int i) {
|
||||
setCastSession(null);
|
||||
setRemoteMediaClient(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionSuspended(CastSession castSession, int i) {
|
||||
setCastSession(null);
|
||||
setRemoteMediaClient(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1737,7 +1645,6 @@ public final class CastPlayer extends BasePlayer {
|
||||
// TODO b/364580007 - Populate volume information, and implement Player volume-related
|
||||
// methods.
|
||||
return new DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_REMOTE)
|
||||
.setMaxVolume(MAX_VOLUME)
|
||||
.setRoutingControllerId(remoteController.getId())
|
||||
.build();
|
||||
}
|
||||
@ -1769,13 +1676,4 @@ public final class CastPlayer extends BasePlayer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class CastListener extends Cast.Listener {
|
||||
|
||||
@Override
|
||||
public void onVolumeChanged() {
|
||||
updateVolumeAndNotifyIfChanged();
|
||||
listeners.flushEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,6 @@ import androidx.media3.common.Player.Listener;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.util.Assertions;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.gms.cast.Cast;
|
||||
import com.google.android.gms.cast.MediaInfo;
|
||||
import com.google.android.gms.cast.MediaQueueItem;
|
||||
import com.google.android.gms.cast.MediaStatus;
|
||||
@ -84,7 +83,6 @@ import com.google.android.gms.cast.framework.media.RemoteMediaClient;
|
||||
import com.google.android.gms.common.api.PendingResult;
|
||||
import com.google.android.gms.common.api.ResultCallback;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@ -104,7 +102,6 @@ public class CastPlayerTest {
|
||||
|
||||
private CastPlayer castPlayer;
|
||||
private DefaultMediaItemConverter mediaItemConverter;
|
||||
private Cast.Listener castListener;
|
||||
private RemoteMediaClient.Callback remoteMediaClientCallback;
|
||||
|
||||
@Mock private RemoteMediaClient mockRemoteMediaClient;
|
||||
@ -120,7 +117,6 @@ public class CastPlayerTest {
|
||||
private ArgumentCaptor<ResultCallback<RemoteMediaClient.MediaChannelResult>>
|
||||
setResultCallbackArgumentCaptor;
|
||||
|
||||
@Captor private ArgumentCaptor<Cast.Listener> castListenerArgumentCaptor;
|
||||
@Captor private ArgumentCaptor<RemoteMediaClient.Callback> callbackArgumentCaptor;
|
||||
@Captor private ArgumentCaptor<MediaQueueItem[]> queueItemsArgumentCaptor;
|
||||
@Captor private ArgumentCaptor<MediaItem> mediaItemCaptor;
|
||||
@ -143,8 +139,6 @@ public class CastPlayerTest {
|
||||
mediaItemConverter = new DefaultMediaItemConverter();
|
||||
castPlayer = new CastPlayer(mockCastContext, mediaItemConverter);
|
||||
castPlayer.addListener(mockListener);
|
||||
verify(mockCastSession).addCastListener(castListenerArgumentCaptor.capture());
|
||||
castListener = castListenerArgumentCaptor.getValue();
|
||||
verify(mockRemoteMediaClient).registerCallback(callbackArgumentCaptor.capture());
|
||||
remoteMediaClientCallback = callbackArgumentCaptor.getValue();
|
||||
}
|
||||
@ -1404,10 +1398,10 @@ public class CastPlayerTest {
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_SET_MEDIA_ITEM)).isTrue();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_GET_AUDIO_ATTRIBUTES)).isFalse();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_GET_VOLUME)).isFalse();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_GET_DEVICE_VOLUME)).isTrue();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_GET_DEVICE_VOLUME)).isFalse();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_SET_VOLUME)).isFalse();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_SET_DEVICE_VOLUME)).isTrue();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_ADJUST_DEVICE_VOLUME)).isTrue();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_SET_DEVICE_VOLUME)).isFalse();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_ADJUST_DEVICE_VOLUME)).isFalse();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)).isFalse();
|
||||
assertThat(castPlayer.isCommandAvailable(COMMAND_GET_TEXT)).isFalse();
|
||||
assertThat(castPlayer.isCommandAvailable(Player.COMMAND_RELEASE)).isTrue();
|
||||
@ -1941,40 +1935,6 @@ public class CastPlayerTest {
|
||||
assertThat(deviceInfo.playbackType).isEqualTo(DeviceInfo.PLAYBACK_TYPE_REMOTE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDeviceVolume_updatesCastSessionVolume() throws IOException {
|
||||
int maxVolume = castPlayer.getDeviceInfo().maxVolume;
|
||||
int volumeToSet = 10;
|
||||
castPlayer.addListener(mockListener);
|
||||
castPlayer.setDeviceVolume(volumeToSet, /* flags= */ 0);
|
||||
|
||||
verify(mockListener, times(1)).onDeviceVolumeChanged(volumeToSet, /* muted= */ false);
|
||||
verify(mockCastSession).setVolume((double) volumeToSet / maxVolume);
|
||||
assertThat(castPlayer.getDeviceVolume()).isEqualTo(volumeToSet);
|
||||
|
||||
double newCastSessionVolume = .25;
|
||||
int expectedDeviceVolume = (int) (newCastSessionVolume * maxVolume);
|
||||
when(mockCastSession.getVolume()).thenReturn(newCastSessionVolume);
|
||||
castListener.onVolumeChanged();
|
||||
assertThat(castPlayer.getDeviceVolume()).isEqualTo(expectedDeviceVolume);
|
||||
verify(mockListener, times(1)).onDeviceVolumeChanged(volumeToSet, /* muted= */ false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDeviceMuted_mutesCastSession() throws IOException {
|
||||
castPlayer.addListener(mockListener);
|
||||
castPlayer.setDeviceMuted(true, /* flags= */ 0);
|
||||
|
||||
verify(mockListener, times(1)).onDeviceVolumeChanged(0, /* muted= */ true);
|
||||
verify(mockCastSession).setMute(true);
|
||||
assertThat(castPlayer.isDeviceMuted()).isEqualTo(true);
|
||||
|
||||
when(mockCastSession.isMute()).thenReturn(false);
|
||||
castListener.onVolumeChanged();
|
||||
assertThat(castPlayer.isDeviceMuted()).isEqualTo(false);
|
||||
verify(mockListener, times(1)).onDeviceVolumeChanged(0, /* muted= */ false);
|
||||
}
|
||||
|
||||
private int[] createMediaQueueItemIds(int numberOfIds) {
|
||||
int[] mediaQueueItemIds = new int[numberOfIds];
|
||||
for (int i = 0; i < numberOfIds; i++) {
|
||||
|
@ -1057,13 +1057,12 @@ public interface ExoPlayer extends Player {
|
||||
*
|
||||
* @param playbackLooper A {@link Looper}.
|
||||
* @return This builder.
|
||||
* @throws IllegalStateException If {@link #build()} has already been called, or when the
|
||||
* {@linkplain Looper#getMainLooper() main looper} is passed in.
|
||||
* @throws IllegalStateException If {@link #build()} has already been called.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
@UnstableApi
|
||||
public Builder setPlaybackLooper(Looper playbackLooper) {
|
||||
checkState(!buildCalled && playbackLooper != Looper.getMainLooper());
|
||||
checkState(!buildCalled);
|
||||
this.playbackLooperProvider = new PlaybackLooperProvider(playbackLooper);
|
||||
return this;
|
||||
}
|
||||
|
@ -2651,8 +2651,7 @@ import java.util.Objects;
|
||||
hasSecondaryRenderers && !isPrewarmingDisabledUntilNextTransition;
|
||||
if (arePrewarmingRenderersHandlingDiscontinuity) {
|
||||
for (int i = 0; i < renderers.length; i++) {
|
||||
if (!newTrackSelectorResult.isRendererEnabled(i)
|
||||
|| renderers[i].getTrackType() == C.TRACK_TYPE_NONE) {
|
||||
if (!newTrackSelectorResult.isRendererEnabled(i)) {
|
||||
continue;
|
||||
}
|
||||
// TODO: This check should ideally be replaced by a per-stream discontinuity check
|
||||
|
@ -23,7 +23,6 @@ import androidx.media3.common.Format;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
import androidx.media3.common.audio.BaseAudioProcessor;
|
||||
import androidx.media3.common.util.Assertions;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
@ -31,8 +30,7 @@ import java.util.Arrays;
|
||||
* An {@link AudioProcessor} that applies a mapping from input channels onto specified output
|
||||
* channels. This can be used to reorder, duplicate or discard channels.
|
||||
*/
|
||||
@UnstableApi
|
||||
public final class ChannelMappingAudioProcessor extends BaseAudioProcessor {
|
||||
/* package */ final class ChannelMappingAudioProcessor extends BaseAudioProcessor {
|
||||
|
||||
@Nullable private int[] pendingOutputChannels;
|
||||
@Nullable private int[] outputChannels;
|
||||
|
@ -62,7 +62,7 @@ public final class DefaultAudioOffloadSupportProvider
|
||||
* offload variable rate support.
|
||||
*/
|
||||
public DefaultAudioOffloadSupportProvider(@Nullable Context context) {
|
||||
this.context = context == null ? null : context.getApplicationContext();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -592,7 +592,7 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
|
||||
@RequiresNonNull("#1.audioProcessorChain")
|
||||
private DefaultAudioSink(Builder builder) {
|
||||
context = builder.context == null ? null : builder.context.getApplicationContext();
|
||||
context = builder.context;
|
||||
audioAttributes = AudioAttributes.DEFAULT;
|
||||
audioCapabilities = context != null ? null : builder.audioCapabilities;
|
||||
audioProcessorChain = builder.audioProcessorChain;
|
||||
|
@ -19,7 +19,6 @@ import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
import androidx.media3.common.audio.BaseAudioProcessor;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@ -35,8 +34,7 @@ import java.nio.ByteBuffer;
|
||||
* <li>{@link C#ENCODING_PCM_FLOAT} ({@link #isActive()} will return {@code false})
|
||||
* </ul>
|
||||
*/
|
||||
@UnstableApi
|
||||
public final class ToFloatPcmAudioProcessor extends BaseAudioProcessor {
|
||||
/* package */ final class ToFloatPcmAudioProcessor extends BaseAudioProcessor {
|
||||
|
||||
private static final int FLOAT_NAN_AS_INT = Float.floatToIntBits(Float.NaN);
|
||||
private static final double PCM_32_BIT_INT_TO_PCM_32_BIT_FLOAT_FACTOR = 1.0 / 0x7FFFFFFF;
|
||||
|
@ -20,13 +20,11 @@ import static java.lang.Math.min;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.audio.BaseAudioProcessor;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/** Audio processor for trimming samples from the start/end of data. */
|
||||
@UnstableApi
|
||||
public final class TrimmingAudioProcessor extends BaseAudioProcessor {
|
||||
/* package */ final class TrimmingAudioProcessor extends BaseAudioProcessor {
|
||||
|
||||
private int trimStartFrames;
|
||||
private int trimEndFrames;
|
||||
|
@ -197,12 +197,11 @@ public final class DefaultPreloadManager extends BasePreloadManager<Integer> {
|
||||
* @param preloadLooper A {@link Looper}.
|
||||
* @return This builder.
|
||||
* @throws IllegalStateException If {@link #build()}, {@link #buildExoPlayer()} or {@link
|
||||
* #buildExoPlayer(ExoPlayer.Builder)} has already been called, or when the {@linkplain
|
||||
* Looper#getMainLooper() main looper} is passed in.
|
||||
* #buildExoPlayer(ExoPlayer.Builder)} has already been called.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Builder setPreloadLooper(Looper preloadLooper) {
|
||||
checkState(!buildCalled && !buildExoPlayerCalled && preloadLooper != Looper.getMainLooper());
|
||||
checkState(!buildCalled && !buildExoPlayerCalled);
|
||||
this.preloadLooperProvider = new PlaybackLooperProvider(preloadLooper);
|
||||
return this;
|
||||
}
|
||||
|
@ -679,9 +679,9 @@ public final class ExoPlayerTest {
|
||||
@Test
|
||||
public void renderersLifecycle_onlyRenderersThatAreEnabled_areSetToFinal() throws Exception {
|
||||
AtomicInteger videoStreamSetToFinalCount = new AtomicInteger();
|
||||
FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO);
|
||||
FakeRenderer audioRenderer = new FakeRenderer(C.TRACK_TYPE_AUDIO);
|
||||
ForwardingRenderer forwardingVideoRenderer =
|
||||
final FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO);
|
||||
final FakeRenderer audioRenderer = new FakeRenderer(C.TRACK_TYPE_AUDIO);
|
||||
final ForwardingRenderer forwardingVideoRenderer =
|
||||
new ForwardingRenderer(videoRenderer) {
|
||||
@Override
|
||||
public void setCurrentStreamFinal() {
|
||||
@ -694,18 +694,18 @@ public final class ExoPlayerTest {
|
||||
new TestExoPlayerBuilder(context)
|
||||
.setRenderers(forwardingVideoRenderer, audioRenderer))
|
||||
.build();
|
||||
// Use media sources with discontinuities so that enabled streams are set to final. Also ensure
|
||||
// to use Formats that are not guaranteed to be only sync samples, so ClippingMediaSource
|
||||
// maintains the initial discontinuity.
|
||||
Format videoFormat = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_AV1).build();
|
||||
Format audioFormat = new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_DTS).build();
|
||||
// Use media sources with discontinuities so that enabled streams are set to final.
|
||||
ClippingMediaSource clippedFakeAudioSource =
|
||||
new ClippingMediaSource.Builder(new FakeMediaSource(new FakeTimeline(), audioFormat))
|
||||
new ClippingMediaSource.Builder(
|
||||
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.AUDIO_FORMAT))
|
||||
.setEndPositionMs(300)
|
||||
.build();
|
||||
ClippingMediaSource clippedFakeAudioVideoSource =
|
||||
new ClippingMediaSource.Builder(
|
||||
new FakeMediaSource(new FakeTimeline(), videoFormat, audioFormat))
|
||||
new FakeMediaSource(
|
||||
new FakeTimeline(),
|
||||
ExoPlayerTestRunner.VIDEO_FORMAT,
|
||||
ExoPlayerTestRunner.AUDIO_FORMAT))
|
||||
.setEndPositionMs(300)
|
||||
.build();
|
||||
player.setMediaSources(
|
||||
|
@ -67,7 +67,6 @@ import androidx.media3.test.utils.robolectric.ShadowMediaCodecConfig;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@ -1610,56 +1609,6 @@ public class ExoPlayerWithPrewarmingRenderersTest {
|
||||
assertThat(secondaryVideoState3).isEqualTo(Renderer.STATE_STARTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void
|
||||
play_withNoSampleRendererAndInitialDiscontinuity_usesPrewarmingAndTransitionsWithoutError()
|
||||
throws Exception {
|
||||
Clock fakeClock = new FakeClock(/* isAutoAdvancing= */ true);
|
||||
RenderersFactory renderersFactoryWithNoSampleRenderer =
|
||||
new FakeRenderersFactorySupportingSecondaryVideoRenderer(
|
||||
fakeClock, /* includeNoSampleRenderer= */ true);
|
||||
ExoPlayer player =
|
||||
new TestExoPlayerBuilder(context)
|
||||
.setClock(fakeClock)
|
||||
.setRenderersFactory(renderersFactoryWithNoSampleRenderer)
|
||||
.build();
|
||||
Renderer secondaryVideoRenderer = player.getSecondaryRenderer(/* index= */ 0);
|
||||
Renderer noSampleRenderer = player.getRenderer(/* index= */ 2);
|
||||
assertThat(secondaryVideoRenderer.getTrackType()).isEqualTo(C.TRACK_TYPE_VIDEO);
|
||||
assertThat(noSampleRenderer.getTrackType()).isEqualTo(C.TRACK_TYPE_NONE);
|
||||
// Set a playlist that allows a new renderer to be enabled early and uses an initial
|
||||
// discontinuity.
|
||||
player.setMediaSources(
|
||||
ImmutableList.of(
|
||||
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT),
|
||||
new FakeMediaSource(
|
||||
new FakeTimeline(),
|
||||
ExoPlayerTestRunner.VIDEO_FORMAT,
|
||||
ExoPlayerTestRunner.AUDIO_FORMAT) {
|
||||
@Override
|
||||
public MediaPeriod createPeriod(
|
||||
MediaPeriodId id, Allocator allocator, long startPositionUs) {
|
||||
FakeMediaPeriod fakeMediaPeriod =
|
||||
(FakeMediaPeriod) super.createPeriod(id, allocator, startPositionUs);
|
||||
fakeMediaPeriod.setDiscontinuityPositionUs(100);
|
||||
return fakeMediaPeriod;
|
||||
}
|
||||
}));
|
||||
player.prepare();
|
||||
|
||||
// Play until secondary video renderer item is started, verifying its being used for prewarming.
|
||||
// This step should not have any influence on the NoSampleRenderer and it should not throw.
|
||||
player.play();
|
||||
advance(player)
|
||||
.untilBackgroundThreadCondition(
|
||||
() -> secondaryVideoRenderer.getState() == Renderer.STATE_STARTED);
|
||||
@Renderer.State int noSampleRendererState = noSampleRenderer.getState();
|
||||
advance(player).untilState(Player.STATE_ENDED);
|
||||
player.release();
|
||||
|
||||
assertThat(noSampleRendererState).isEqualTo(Renderer.STATE_STARTED);
|
||||
}
|
||||
|
||||
/** {@link FakeMediaSource} that prevents any reading of samples off the sample queue. */
|
||||
private static final class FakeBlockingMediaSource extends FakeMediaSource {
|
||||
|
||||
@ -1721,16 +1670,9 @@ public class ExoPlayerWithPrewarmingRenderersTest {
|
||||
private static class FakeRenderersFactorySupportingSecondaryVideoRenderer
|
||||
implements RenderersFactory {
|
||||
protected final Clock clock;
|
||||
private final boolean includeNoSampleRenderer;
|
||||
|
||||
public FakeRenderersFactorySupportingSecondaryVideoRenderer(Clock clock) {
|
||||
this(clock, /* includeNoSampleRenderer= */ false);
|
||||
}
|
||||
|
||||
public FakeRenderersFactorySupportingSecondaryVideoRenderer(
|
||||
Clock clock, boolean includeNoSampleRenderer) {
|
||||
this.clock = clock;
|
||||
this.includeNoSampleRenderer = includeNoSampleRenderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1742,25 +1684,10 @@ public class ExoPlayerWithPrewarmingRenderersTest {
|
||||
MetadataOutput metadataRendererOutput) {
|
||||
HandlerWrapper clockAwareHandler =
|
||||
clock.createHandler(eventHandler.getLooper(), /* callback= */ null);
|
||||
Renderer[] renderers =
|
||||
new Renderer[] {
|
||||
new FakeVideoRenderer(clockAwareHandler, videoRendererEventListener),
|
||||
new FakeAudioRenderer(clockAwareHandler, audioRendererEventListener)
|
||||
};
|
||||
if (includeNoSampleRenderer) {
|
||||
renderers = Arrays.copyOf(renderers, renderers.length + 1);
|
||||
renderers[renderers.length - 1] =
|
||||
new NoSampleRenderer() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "NoSampleRenderer";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(long positionUs, long elapsedRealtimeUs) {}
|
||||
};
|
||||
}
|
||||
return renderers;
|
||||
return new Renderer[] {
|
||||
new FakeVideoRenderer(clockAwareHandler, videoRendererEventListener),
|
||||
new FakeAudioRenderer(clockAwareHandler, audioRendererEventListener)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,6 +30,7 @@ import static org.robolectric.Shadows.shadowOf;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.AdPlaybackState;
|
||||
import androidx.media3.common.C;
|
||||
@ -67,9 +68,7 @@ import com.google.common.collect.Iterables;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -82,7 +81,6 @@ public class DefaultPreloadManagerTest {
|
||||
private Context context;
|
||||
@Mock private TargetPreloadStatusControl<Integer> mockTargetPreloadStatusControl;
|
||||
private RenderersFactory renderersFactory;
|
||||
private HandlerThread preloadThread;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@ -97,13 +95,6 @@ public class DefaultPreloadManagerTest {
|
||||
SystemClock.DEFAULT.createHandler(handler.getLooper(), /* callback= */ null),
|
||||
audioListener)
|
||||
};
|
||||
preloadThread = new HandlerThread("DefaultPreloadManagerTest");
|
||||
preloadThread.start();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
preloadThread.quit();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -111,7 +102,7 @@ public class DefaultPreloadManagerTest {
|
||||
DefaultPreloadManager preloadManager =
|
||||
new DefaultPreloadManager.Builder(context, mockTargetPreloadStatusControl)
|
||||
.setRenderersFactory(renderersFactory)
|
||||
.setPreloadLooper(preloadThread.getLooper())
|
||||
.setPreloadLooper(Util.getCurrentOrMainLooper())
|
||||
.build();
|
||||
MediaItem.Builder mediaItemBuilder = new MediaItem.Builder();
|
||||
MediaItem mediaItem1 =
|
||||
@ -132,7 +123,7 @@ public class DefaultPreloadManagerTest {
|
||||
DefaultPreloadManager preloadManager =
|
||||
new DefaultPreloadManager.Builder(context, mockTargetPreloadStatusControl)
|
||||
.setRenderersFactory(renderersFactory)
|
||||
.setPreloadLooper(preloadThread.getLooper())
|
||||
.setPreloadLooper(Util.getCurrentOrMainLooper())
|
||||
.build();
|
||||
MediaItem.Builder mediaItemBuilder = new MediaItem.Builder();
|
||||
MediaItem mediaItem1 =
|
||||
@ -157,7 +148,7 @@ public class DefaultPreloadManagerTest {
|
||||
DefaultPreloadManager preloadManager =
|
||||
new DefaultPreloadManager.Builder(context, mockTargetPreloadStatusControl)
|
||||
.setRenderersFactory(renderersFactory)
|
||||
.setPreloadLooper(preloadThread.getLooper())
|
||||
.setPreloadLooper(Util.getCurrentOrMainLooper())
|
||||
.build();
|
||||
MediaItem mediaItem =
|
||||
new MediaItem.Builder()
|
||||
@ -187,6 +178,8 @@ public class DefaultPreloadManagerTest {
|
||||
ProgressiveMediaSource.Factory mediaSourceFactory =
|
||||
new ProgressiveMediaSource.Factory(
|
||||
new DefaultDataSource.Factory(ApplicationProvider.getApplicationContext()));
|
||||
HandlerThread preloadThread = new HandlerThread("preload");
|
||||
preloadThread.start();
|
||||
DefaultPreloadManager preloadManager =
|
||||
new DefaultPreloadManager.Builder(context, targetPreloadStatusControl)
|
||||
.setMediaSourceFactory(mediaSourceFactory)
|
||||
@ -223,6 +216,8 @@ public class DefaultPreloadManagerTest {
|
||||
assertThat(preloadManagerListener.onCompletedMediaItemRecords)
|
||||
.containsExactly(mediaItem0, mediaItem1, mediaItem2)
|
||||
.inOrder();
|
||||
|
||||
preloadThread.quit();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -600,7 +595,7 @@ public class DefaultPreloadManagerTest {
|
||||
new DefaultPreloadManager.Builder(context, targetPreloadStatusControl)
|
||||
.setMediaSourceFactory(mockMediaSourceFactory)
|
||||
.setRenderersFactory(renderersFactory)
|
||||
.setPreloadLooper(preloadThread.getLooper())
|
||||
.setPreloadLooper(Util.getCurrentOrMainLooper())
|
||||
.build();
|
||||
MediaItem.Builder mediaItemBuilder = new MediaItem.Builder();
|
||||
MediaItem mediaItem0 =
|
||||
@ -672,7 +667,7 @@ public class DefaultPreloadManagerTest {
|
||||
new DefaultPreloadManager.Builder(context, targetPreloadStatusControl)
|
||||
.setMediaSourceFactory(mockMediaSourceFactory)
|
||||
.setRenderersFactory(renderersFactory)
|
||||
.setPreloadLooper(preloadThread.getLooper())
|
||||
.setPreloadLooper(Util.getCurrentOrMainLooper())
|
||||
.build();
|
||||
MediaItem.Builder mediaItemBuilder = new MediaItem.Builder();
|
||||
MediaItem mediaItem1 =
|
||||
@ -699,11 +694,11 @@ public class DefaultPreloadManagerTest {
|
||||
});
|
||||
preloadManager.add(mediaItem1, /* rankingData= */ 1);
|
||||
preloadManager.invalidate();
|
||||
shadowOf(preloadThread.getLooper()).idle();
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
boolean mediaItem1Removed = preloadManager.remove(mediaItem1);
|
||||
boolean mediaItem2Removed = preloadManager.remove(mediaItem2);
|
||||
shadowOf(preloadThread.getLooper()).idle();
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
assertThat(mediaItem1Removed).isTrue();
|
||||
assertThat(mediaItem2Removed).isFalse();
|
||||
@ -720,7 +715,7 @@ public class DefaultPreloadManagerTest {
|
||||
new DefaultPreloadManager.Builder(context, targetPreloadStatusControl)
|
||||
.setMediaSourceFactory(mockMediaSourceFactory)
|
||||
.setRenderersFactory(renderersFactory)
|
||||
.setPreloadLooper(preloadThread.getLooper())
|
||||
.setPreloadLooper(Util.getCurrentOrMainLooper())
|
||||
.build();
|
||||
MediaItem.Builder mediaItemBuilder = new MediaItem.Builder();
|
||||
MediaItem mediaItem1 =
|
||||
@ -747,7 +742,7 @@ public class DefaultPreloadManagerTest {
|
||||
});
|
||||
preloadManager.add(mediaItem1, /* rankingData= */ 1);
|
||||
preloadManager.invalidate();
|
||||
shadowOf(preloadThread.getLooper()).idle();
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
MediaSource mediaSource1 = preloadManager.getMediaSource(mediaItem1);
|
||||
DefaultMediaSourceFactory defaultMediaSourceFactory =
|
||||
new DefaultMediaSourceFactory((Context) ApplicationProvider.getApplicationContext());
|
||||
@ -757,7 +752,7 @@ public class DefaultPreloadManagerTest {
|
||||
boolean mediaSource1Removed = preloadManager.remove(mediaSource1);
|
||||
boolean mediaSource2Removed = preloadManager.remove(mediaSource2);
|
||||
boolean mediaSource3Removed = preloadManager.remove(mediaSource3);
|
||||
shadowOf(preloadThread.getLooper()).idle();
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
assertThat(mediaSource1Removed).isTrue();
|
||||
assertThat(mediaSource2Removed).isFalse();
|
||||
@ -767,8 +762,7 @@ public class DefaultPreloadManagerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reset_returnZeroCount_sourcesButNotRendererCapabilitiesListReleased()
|
||||
throws TimeoutException {
|
||||
public void reset_returnZeroCount_sourcesButNotRendererCapabilitiesListReleased() {
|
||||
TargetPreloadStatusControl<Integer> targetPreloadStatusControl =
|
||||
rankingData -> new DefaultPreloadManager.Status(STAGE_SOURCE_PREPARED);
|
||||
MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class);
|
||||
@ -795,7 +789,7 @@ public class DefaultPreloadManagerTest {
|
||||
new DefaultPreloadManager.Builder(context, targetPreloadStatusControl)
|
||||
.setMediaSourceFactory(mockMediaSourceFactory)
|
||||
.setRenderersFactory(renderersFactory)
|
||||
.setPreloadLooper(preloadThread.getLooper())
|
||||
.setPreloadLooper(Util.getCurrentOrMainLooper())
|
||||
.build();
|
||||
MediaItem.Builder mediaItemBuilder = new MediaItem.Builder();
|
||||
MediaItem mediaItem1 =
|
||||
@ -823,11 +817,10 @@ public class DefaultPreloadManagerTest {
|
||||
preloadManager.add(mediaItem1, /* rankingData= */ 1);
|
||||
preloadManager.add(mediaItem2, /* rankingData= */ 2);
|
||||
preloadManager.invalidate();
|
||||
shadowOf(preloadThread.getLooper()).idle();
|
||||
shadowOf(Util.getCurrentOrMainLooper()).idle();
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
preloadManager.reset();
|
||||
shadowOf(preloadThread.getLooper()).idle();
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
assertThat(preloadManager.getSourceCount()).isEqualTo(0);
|
||||
assertThat(internalSourceToReleaseReferenceByMediaId).containsExactly("mediaId1", "mediaId2");
|
||||
@ -895,7 +888,7 @@ public class DefaultPreloadManagerTest {
|
||||
preloadManager.add(mediaItem2, /* rankingData= */ 2);
|
||||
preloadManager.invalidate();
|
||||
shadowOf(preloadThread.getLooper()).idle();
|
||||
shadowOf(Util.getCurrentOrMainLooper()).idle();
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
preloadManager.release();
|
||||
shadowOf(preloadThread.getLooper()).idle();
|
||||
|
@ -70,7 +70,6 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
|
||||
public static final Format AUDIO_FORMAT =
|
||||
new Format.Builder()
|
||||
.setSampleMimeType(MimeTypes.AUDIO_AAC)
|
||||
.setCodecs("mp4a.40.2")
|
||||
.setAverageBitrate(100_000)
|
||||
.setChannelCount(2)
|
||||
.setSampleRate(44100)
|
||||
|
@ -62,7 +62,6 @@ import java.util.List;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -111,7 +110,6 @@ public class ReplayCacheTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("TODO: b/391109644 - Fix this test and re-enable it")
|
||||
public void replayOnEveryFrame_withExoPlayer_succeeds()
|
||||
throws PlaybackException, TimeoutException {
|
||||
assumeTrue(
|
||||
|
Loading…
x
Reference in New Issue
Block a user