Commit a2a44cdc by tonihei Committed by Rohit Singh

Add missing command checks to MediaSessionLegacyStub and PlayerWrapper

This player didn't fully check all player commands before calling the
respective methods.

PiperOrigin-RevId: 502353704
parent 664ab72d
...@@ -1290,7 +1290,7 @@ import org.checkerframework.checker.initialization.qual.Initialized; ...@@ -1290,7 +1290,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
if (msg.what == MSG_PLAYER_INFO_CHANGED) { if (msg.what == MSG_PLAYER_INFO_CHANGED) {
playerInfo = playerInfo =
playerInfo.copyWithTimelineAndSessionPositionInfo( playerInfo.copyWithTimelineAndSessionPositionInfo(
getPlayerWrapper().getCurrentTimeline(), getPlayerWrapper().getCurrentTimelineWithCommandCheck(),
getPlayerWrapper().createSessionPositionInfoForBundling()); getPlayerWrapper().createSessionPositionInfoForBundling());
dispatchOnPlayerInfoChanged(playerInfo, excludeTimeline, excludeTracks); dispatchOnPlayerInfoChanged(playerInfo, excludeTimeline, excludeTracks);
excludeTimeline = true; excludeTimeline = true;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package androidx.media3.session; package androidx.media3.session;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.os.Looper; import android.os.Looper;
...@@ -42,6 +43,7 @@ public class PlayerWrapperTest { ...@@ -42,6 +43,7 @@ public class PlayerWrapperTest {
@Before @Before
public void setUp() { public void setUp() {
playerWrapper = new PlayerWrapper(player); playerWrapper = new PlayerWrapper(player);
when(player.isCommandAvailable(anyInt())).thenReturn(true);
when(player.getApplicationLooper()).thenReturn(Looper.myLooper()); when(player.getApplicationLooper()).thenReturn(Looper.myLooper());
} }
......
...@@ -220,7 +220,7 @@ public class MediaSessionKeyEventTest { ...@@ -220,7 +220,7 @@ public class MediaSessionKeyEventTest {
dispatchMediaKeyEvent(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, false); dispatchMediaKeyEvent(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, false);
player.awaitMethodCalled(MockPlayer.METHOD_SEEK_TO_WITH_MEDIA_ITEM_INDEX, TIMEOUT_MS); player.awaitMethodCalled(MockPlayer.METHOD_SEEK_TO_DEFAULT_POSITION, TIMEOUT_MS);
player.awaitMethodCalled(MockPlayer.METHOD_PLAY, TIMEOUT_MS); player.awaitMethodCalled(MockPlayer.METHOD_PLAY, TIMEOUT_MS);
} }
......
...@@ -38,12 +38,19 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; ...@@ -38,12 +38,19 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.media3.common.AudioAttributes;
import androidx.media3.common.DeviceInfo;
import androidx.media3.common.ForwardingPlayer;
import androidx.media3.common.MediaItem; import androidx.media3.common.MediaItem;
import androidx.media3.common.MediaMetadata; import androidx.media3.common.MediaMetadata;
import androidx.media3.common.Player; import androidx.media3.common.Player;
import androidx.media3.common.Rating; import androidx.media3.common.Rating;
import androidx.media3.common.StarRating; import androidx.media3.common.StarRating;
import androidx.media3.common.Timeline;
import androidx.media3.common.TrackSelectionParameters; import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.Tracks;
import androidx.media3.common.text.CueGroup;
import androidx.media3.session.MediaSession.ControllerInfo; import androidx.media3.session.MediaSession.ControllerInfo;
import androidx.media3.test.session.common.HandlerThreadTestRule; import androidx.media3.test.session.common.HandlerThreadTestRule;
import androidx.media3.test.session.common.MainLooperTestRule; import androidx.media3.test.session.common.MainLooperTestRule;
...@@ -262,6 +269,168 @@ public class MediaSessionPermissionTest { ...@@ -262,6 +269,168 @@ public class MediaSessionPermissionTest {
TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT)); TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT));
} }
@Test
public void setPlayer_withoutAvailableCommands_doesNotCallProtectedPlayerGetters()
throws Exception {
MockPlayer mockPlayer =
new MockPlayer.Builder()
.setApplicationLooper(threadTestRule.getHandler().getLooper())
.build();
// Set remote device info to ensure we also cover the volume provider compat setup.
mockPlayer.deviceInfo =
new DeviceInfo(DeviceInfo.PLAYBACK_TYPE_REMOTE, /* minVolume= */ 0, /* maxVolume= */ 100);
Player player =
new ForwardingPlayer(mockPlayer) {
@Override
public boolean isCommandAvailable(int command) {
return false;
}
@Override
public Tracks getCurrentTracks() {
throw new UnsupportedOperationException();
}
@Override
public MediaMetadata getMediaMetadata() {
throw new UnsupportedOperationException();
}
@Override
public MediaMetadata getPlaylistMetadata() {
throw new UnsupportedOperationException();
}
@Override
public Timeline getCurrentTimeline() {
throw new UnsupportedOperationException();
}
@Override
public int getCurrentPeriodIndex() {
throw new UnsupportedOperationException();
}
@Override
public int getCurrentMediaItemIndex() {
throw new UnsupportedOperationException();
}
@Override
public int getNextMediaItemIndex() {
throw new UnsupportedOperationException();
}
@Override
public int getPreviousMediaItemIndex() {
throw new UnsupportedOperationException();
}
@Nullable
@Override
public MediaItem getCurrentMediaItem() {
throw new UnsupportedOperationException();
}
@Override
public long getDuration() {
throw new UnsupportedOperationException();
}
@Override
public long getCurrentPosition() {
throw new UnsupportedOperationException();
}
@Override
public long getBufferedPosition() {
throw new UnsupportedOperationException();
}
@Override
public long getTotalBufferedDuration() {
throw new UnsupportedOperationException();
}
@Override
public boolean isCurrentMediaItemDynamic() {
throw new UnsupportedOperationException();
}
@Override
public boolean isCurrentMediaItemLive() {
throw new UnsupportedOperationException();
}
@Override
public boolean isPlayingAd() {
throw new UnsupportedOperationException();
}
@Override
public int getCurrentAdGroupIndex() {
throw new UnsupportedOperationException();
}
@Override
public int getCurrentAdIndexInAdGroup() {
throw new UnsupportedOperationException();
}
@Override
public long getContentDuration() {
throw new UnsupportedOperationException();
}
@Override
public long getContentPosition() {
throw new UnsupportedOperationException();
}
@Override
public long getContentBufferedPosition() {
throw new UnsupportedOperationException();
}
@Override
public AudioAttributes getAudioAttributes() {
throw new UnsupportedOperationException();
}
@Override
public CueGroup getCurrentCues() {
throw new UnsupportedOperationException();
}
@Override
public int getDeviceVolume() {
throw new UnsupportedOperationException();
}
@Override
public boolean isDeviceMuted() {
throw new UnsupportedOperationException();
}
};
MediaSession session = new MediaSession.Builder(context, player).setId(SESSION_ID).build();
MediaController controller =
new MediaController.Builder(context, session.getToken())
.setApplicationLooper(threadTestRule.getHandler().getLooper())
.buildAsync()
.get();
// Test passes if none of the protected player getters have been called.
threadTestRule
.getHandler()
.postAndSync(
() -> {
controller.release();
session.release();
player.release();
});
}
private ControllerInfo getTestControllerInfo() { private ControllerInfo getTestControllerInfo() {
List<ControllerInfo> controllers = session.getConnectedControllers(); List<ControllerInfo> controllers = session.getConnectedControllers();
assertThat(controllers).isNotNull(); assertThat(controllers).isNotNull();
......
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