| /* |
| * Copyright 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package androidx.media2.test.client.tests; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| |
| import android.media.AudioManager; |
| import android.os.Build; |
| import android.os.Bundle; |
| import android.os.ParcelFileDescriptor; |
| import android.support.v4.media.MediaMetadataCompat; |
| import android.support.v4.media.session.MediaControllerCompat; |
| import android.support.v4.media.session.MediaSessionCompat.QueueItem; |
| import android.support.v4.media.session.PlaybackStateCompat; |
| |
| import androidx.media.AudioAttributesCompat; |
| import androidx.media.VolumeProviderCompat; |
| import androidx.media2.common.FileMediaItem; |
| import androidx.media2.common.MediaItem; |
| import androidx.media2.common.MediaMetadata; |
| import androidx.media2.common.SessionPlayer; |
| import androidx.media2.session.MediaSession; |
| import androidx.media2.session.MediaUtils; |
| import androidx.media2.session.RemoteSessionPlayer; |
| import androidx.media2.test.client.MediaTestUtils; |
| import androidx.media2.test.client.RemoteMediaSession; |
| import androidx.media2.test.common.PollingCheck; |
| import androidx.media2.test.common.TestUtils; |
| import androidx.test.ext.junit.runners.AndroidJUnit4; |
| import androidx.test.filters.LargeTest; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| import java.util.List; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| import java.util.concurrent.atomic.AtomicInteger; |
| import java.util.concurrent.atomic.AtomicReference; |
| |
| /** |
| * Tests for {@link MediaControllerCompat.Callback} with {@link MediaSession}. |
| */ |
| @RunWith(AndroidJUnit4.class) |
| @LargeTest |
| public class MediaControllerCompatCallbackWithMediaSessionTest extends MediaSessionTestBase { |
| private static final String TAG = "MCCCallbackTestWithMS2"; |
| |
| private static final long TIMEOUT_MS = 1000L; |
| private static final float EPSILON = 1e-6f; |
| |
| private RemoteMediaSession mSession; |
| private MediaControllerCompat mControllerCompat; |
| |
| @Before |
| @Override |
| public void setUp() throws Exception { |
| super.setUp(); |
| mSession = new RemoteMediaSession(TAG, mContext, null); |
| mControllerCompat = new MediaControllerCompat(mContext, mSession.getCompatToken()); |
| } |
| |
| @After |
| @Override |
| public void cleanUp() throws Exception { |
| super.cleanUp(); |
| mSession.close(); |
| } |
| |
| @Test |
| public void repeatModeChange() throws Exception { |
| int testRepeatMode = SessionPlayer.REPEAT_MODE_GROUP; |
| |
| CountDownLatch latch = new CountDownLatch(1); |
| AtomicInteger repeatModeRef = new AtomicInteger(); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onRepeatModeChanged(int repeatMode) { |
| repeatModeRef.set(repeatMode); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| mSession.getMockPlayer().setRepeatMode(testRepeatMode); |
| mSession.getMockPlayer().notifyRepeatModeChanged(); |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(testRepeatMode, repeatModeRef.get()); |
| assertEquals(testRepeatMode, mControllerCompat.getRepeatMode()); |
| } |
| |
| @Test |
| public void shuffleModeChange() throws Exception { |
| int testShuffleMode = SessionPlayer.SHUFFLE_MODE_GROUP; |
| |
| CountDownLatch latch = new CountDownLatch(1); |
| AtomicInteger shuffleModeRef = new AtomicInteger(); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onShuffleModeChanged(int shuffleMode) { |
| shuffleModeRef.set(shuffleMode); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| mSession.getMockPlayer().setShuffleMode(testShuffleMode); |
| mSession.getMockPlayer().notifyShuffleModeChanged(); |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(testShuffleMode, shuffleModeRef.get()); |
| assertEquals(testShuffleMode, mControllerCompat.getShuffleMode()); |
| } |
| |
| @Test |
| public void close() throws Exception { |
| CountDownLatch latch = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onSessionDestroyed() { |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| mSession.close(); |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| } |
| |
| @Test |
| public void updatePlayer() throws Exception { |
| int testState = SessionPlayer.PLAYER_STATE_PLAYING; |
| int testBufferingPosition = 1500; |
| float testSpeed = 1.5f; |
| List<MediaItem> testPlaylist = MediaTestUtils.createFileMediaItems(3); |
| int testItemIndex = 0; |
| String testPlaylistTitle = "testPlaylistTitle"; |
| MediaMetadata testPlaylistMetadata = new MediaMetadata.Builder() |
| .putText(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, testPlaylistTitle).build(); |
| |
| AtomicReference<PlaybackStateCompat> playbackStateRef = new AtomicReference<>(); |
| AtomicReference<MediaMetadataCompat> metadataRef = new AtomicReference<>(); |
| AtomicReference<CharSequence> queueTitleRef = new AtomicReference<>(); |
| CountDownLatch latchForPlaybackState = new CountDownLatch(1); |
| CountDownLatch latchForMetadata = new CountDownLatch(1); |
| CountDownLatch latchForQueue = new CountDownLatch(2); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onPlaybackStateChanged(PlaybackStateCompat state) { |
| playbackStateRef.set(state); |
| latchForPlaybackState.countDown(); |
| } |
| |
| @Override |
| public void onMetadataChanged(MediaMetadataCompat metadata) { |
| metadataRef.set(metadata); |
| latchForMetadata.countDown(); |
| } |
| |
| @Override |
| public void onQueueChanged(List<QueueItem> queue) { |
| latchForQueue.countDown(); |
| } |
| |
| @Override |
| public void onQueueTitleChanged(CharSequence title) { |
| queueTitleRef.set(title); |
| latchForQueue.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| Bundle playerConfig = new RemoteMediaSession.MockPlayerConfigBuilder() |
| .setPlayerState(testState) |
| .setBufferedPosition(testBufferingPosition) |
| .setPlaybackSpeed(testSpeed) |
| .setPlaylist(testPlaylist) |
| .setPlaylistMetadata(testPlaylistMetadata) |
| .setCurrentMediaItem(testPlaylist.get(testItemIndex)) |
| .build(); |
| mSession.updatePlayer(playerConfig); |
| |
| assertTrue(latchForPlaybackState.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(testState, MediaUtils.convertToPlayerState(playbackStateRef.get())); |
| assertEquals(testBufferingPosition, playbackStateRef.get().getBufferedPosition()); |
| assertEquals(testSpeed, playbackStateRef.get().getPlaybackSpeed(), EPSILON); |
| |
| assertTrue(latchForMetadata.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(testPlaylist.get(testItemIndex).getMediaId(), |
| metadataRef.get().getString(MediaMetadata.METADATA_KEY_MEDIA_ID)); |
| |
| assertTrue(latchForQueue.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| List<QueueItem> queue = mControllerCompat.getQueue(); |
| assertNotNull(queue); |
| assertEquals(testPlaylist.size(), queue.size()); |
| for (int i = 0; i < testPlaylist.size(); i++) { |
| assertEquals(testPlaylist.get(i).getMediaId(), |
| queue.get(i).getDescription().getMediaId()); |
| } |
| assertEquals(testPlaylistTitle, queueTitleRef.get().toString()); |
| } |
| |
| @Test |
| public void updatePlayer_playbackTypeChangedToRemote() throws Exception { |
| int controlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE; |
| int maxVolume = 25; |
| int currentVolume = 10; |
| |
| AtomicReference<MediaControllerCompat.PlaybackInfo> infoRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onAudioInfoChanged(MediaControllerCompat.PlaybackInfo info) { |
| infoRef.set(info); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| Bundle playerConfig = new RemoteMediaSession.MockPlayerConfigBuilder() |
| .setVolumeControlType(controlType) |
| .setMaxVolume(maxVolume) |
| .setCurrentVolume(currentVolume) |
| .build(); |
| mSession.updatePlayer(playerConfig); |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE, |
| infoRef.get().getPlaybackType()); |
| assertEquals(controlType, infoRef.get().getVolumeControl()); |
| assertEquals(maxVolume, infoRef.get().getMaxVolume()); |
| |
| MediaControllerCompat.PlaybackInfo info = mControllerCompat.getPlaybackInfo(); |
| assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE, |
| info.getPlaybackType()); |
| assertEquals(controlType, info.getVolumeControl()); |
| assertEquals(maxVolume, info.getMaxVolume()); |
| assertEquals(currentVolume, info.getCurrentVolume()); |
| } |
| |
| @Test |
| public void updatePlayer_playbackTypeChangedToLocal() throws Exception { |
| Bundle playerConfig = new RemoteMediaSession.MockPlayerConfigBuilder() |
| .setVolumeControlType(VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE) |
| .setMaxVolume(10) |
| .setCurrentVolume(1) |
| .build(); |
| mSession.updatePlayer(playerConfig); |
| |
| int legacyStream = AudioManager.STREAM_RING; |
| AudioAttributesCompat attrs = new AudioAttributesCompat.Builder() |
| .setLegacyStreamType(legacyStream).build(); |
| |
| AtomicReference<MediaControllerCompat.PlaybackInfo> infoRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onAudioInfoChanged(MediaControllerCompat.PlaybackInfo info) { |
| infoRef.set(info); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| Bundle playerConfigToUpdate = new RemoteMediaSession.MockPlayerConfigBuilder() |
| .setPlaybackSpeed(1) |
| .setAudioAttributes(attrs) |
| .build(); |
| mSession.updatePlayer(playerConfigToUpdate); |
| |
| // In API 21 and 22, onAudioInfoChanged is not called when playback is changed to local. |
| if (Build.VERSION.SDK_INT == 21 || Build.VERSION.SDK_INT == 22) { |
| PollingCheck.waitFor(TIMEOUT_MS, |
| () -> mControllerCompat.getPlaybackInfo().getPlaybackType() |
| == MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_LOCAL); |
| } else { |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_LOCAL, |
| infoRef.get().getPlaybackType()); |
| assertEquals(legacyStream, infoRef.get().getAudioAttributes().getLegacyStreamType()); |
| } |
| |
| MediaControllerCompat.PlaybackInfo info = mControllerCompat.getPlaybackInfo(); |
| assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_LOCAL, |
| info.getPlaybackType()); |
| assertEquals(legacyStream, info.getAudioAttributes().getLegacyStreamType()); |
| } |
| |
| @Test |
| public void updatePlayer_playbackTypeNotChanged_local() throws Exception { |
| int legacyStream = AudioManager.STREAM_RING; |
| AudioAttributesCompat attrs = new AudioAttributesCompat.Builder() |
| .setLegacyStreamType(legacyStream).build(); |
| |
| AtomicReference<MediaControllerCompat.PlaybackInfo> infoRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onAudioInfoChanged(MediaControllerCompat.PlaybackInfo info) { |
| infoRef.set(info); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| Bundle playerConfig = new RemoteMediaSession.MockPlayerConfigBuilder() |
| .setPlaybackSpeed(1) |
| .setAudioAttributes(attrs) |
| .build(); |
| mSession.updatePlayer(playerConfig); |
| |
| // In API 21+, onAudioInfoChanged() is not called when playbackType is not changed. |
| if (Build.VERSION.SDK_INT >= 21) { |
| PollingCheck.waitFor(TIMEOUT_MS, |
| () -> mControllerCompat.getPlaybackInfo().getPlaybackType() |
| == MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_LOCAL); |
| } else { |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_LOCAL, |
| infoRef.get().getPlaybackType()); |
| assertEquals(legacyStream, infoRef.get().getAudioAttributes().getLegacyStreamType()); |
| } |
| |
| MediaControllerCompat.PlaybackInfo info = mControllerCompat.getPlaybackInfo(); |
| assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_LOCAL, |
| info.getPlaybackType()); |
| assertEquals(legacyStream, info.getAudioAttributes().getLegacyStreamType()); |
| } |
| |
| @Test |
| public void updatePlayer_playbackTypeNotChanged_remote() throws Exception { |
| Bundle playerConfig = new RemoteMediaSession.MockPlayerConfigBuilder() |
| .setVolumeControlType(VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE) |
| .setMaxVolume(10) |
| .setCurrentVolume(1) |
| .build(); |
| mSession.updatePlayer(playerConfig); |
| |
| int controlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE; |
| int maxVolume = 25; |
| int currentVolume = 10; |
| |
| AtomicReference<MediaControllerCompat.PlaybackInfo> infoRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onAudioInfoChanged(MediaControllerCompat.PlaybackInfo info) { |
| infoRef.set(info); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| Bundle playerConfigToUpdate = new RemoteMediaSession.MockPlayerConfigBuilder() |
| .setVolumeControlType(controlType) |
| .setMaxVolume(maxVolume) |
| .setCurrentVolume(currentVolume) |
| .build(); |
| mSession.updatePlayer(playerConfigToUpdate); |
| |
| // In API 21+, onAudioInfoChanged() is not called when playbackType is not changed. |
| if (Build.VERSION.SDK_INT >= 21) { |
| PollingCheck.waitFor(TIMEOUT_MS, |
| () -> mControllerCompat.getPlaybackInfo().getPlaybackType() |
| == MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE); |
| } else { |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE, |
| infoRef.get().getPlaybackType()); |
| assertEquals(controlType, infoRef.get().getVolumeControl()); |
| assertEquals(maxVolume, infoRef.get().getMaxVolume()); |
| assertEquals(currentVolume, infoRef.get().getCurrentVolume()); |
| } |
| |
| MediaControllerCompat.PlaybackInfo info = mControllerCompat.getPlaybackInfo(); |
| assertEquals(MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE, |
| info.getPlaybackType()); |
| assertEquals(controlType, info.getVolumeControl()); |
| assertEquals(maxVolume, info.getMaxVolume()); |
| assertEquals(currentVolume, info.getCurrentVolume()); |
| } |
| |
| @Test |
| public void playerStateChange() throws Exception { |
| int targetState = SessionPlayer.PLAYER_STATE_PLAYING; |
| |
| AtomicReference<PlaybackStateCompat> playbackStateRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(2); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onSessionReady() { |
| latch.countDown(); |
| } |
| |
| @Override |
| public void onPlaybackStateChanged(PlaybackStateCompat state) { |
| playbackStateRef.set(state); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| mSession.getMockPlayer().notifyPlayerStateChanged(targetState); |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(targetState, MediaUtils.convertToPlayerState(playbackStateRef.get())); |
| assertEquals(targetState, |
| MediaUtils.convertToPlayerState(mControllerCompat.getPlaybackState())); |
| } |
| |
| @Test |
| public void playbackSpeedChange() throws Exception { |
| float speed = 1.5f; |
| |
| AtomicReference<PlaybackStateCompat> playbackStateRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onPlaybackStateChanged(PlaybackStateCompat state) { |
| playbackStateRef.set(state); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| mSession.getMockPlayer().setPlaybackSpeed(speed); |
| mSession.getMockPlayer().notifyPlaybackSpeedChanged(speed); |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(speed, playbackStateRef.get().getPlaybackSpeed(), EPSILON); |
| assertEquals(speed, mControllerCompat.getPlaybackState().getPlaybackSpeed(), EPSILON); |
| } |
| |
| @Test |
| public void bufferingStateChange() throws Exception { |
| List<MediaItem> testPlaylist = MediaTestUtils.createFileMediaItems(3); |
| int testItemIndex = 0; |
| int testBufferingState = SessionPlayer.BUFFERING_STATE_BUFFERING_AND_PLAYABLE; |
| long testBufferingPosition = 500; |
| mSession.getMockPlayer().setPlaylistWithDummyItem(testPlaylist); |
| |
| AtomicReference<PlaybackStateCompat> playbackStateRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onPlaybackStateChanged(PlaybackStateCompat state) { |
| playbackStateRef.set(state); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| mSession.getMockPlayer().setBufferedPosition(testBufferingPosition); |
| mSession.getMockPlayer().notifyBufferingStateChanged(testItemIndex, testBufferingState); |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(testBufferingPosition, playbackStateRef.get().getBufferedPosition()); |
| assertEquals(testBufferingPosition, |
| mControllerCompat.getPlaybackState().getBufferedPosition()); |
| } |
| |
| @Test |
| public void seekComplete() throws Exception { |
| long testSeekPosition = 1300; |
| |
| AtomicReference<PlaybackStateCompat> playbackStateRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onPlaybackStateChanged(PlaybackStateCompat state) { |
| playbackStateRef.set(state); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| mSession.getMockPlayer().setCurrentPosition(testSeekPosition); |
| mSession.getMockPlayer().setPlayerState(SessionPlayer.PLAYER_STATE_PAUSED); |
| mSession.getMockPlayer().notifySeekCompleted(testSeekPosition); |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(testSeekPosition, playbackStateRef.get().getPosition()); |
| assertEquals(testSeekPosition, mControllerCompat.getPlaybackState().getPosition()); |
| } |
| |
| @Test |
| public void currentMediaItemChange() throws Exception { |
| int testItemIndex = 3; |
| long testPosition = 1234; |
| String displayTitle = "displayTitle"; |
| MediaMetadata metadata = new MediaMetadata.Builder() |
| .putText(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, displayTitle).build(); |
| MediaItem currentMediaItem = new FileMediaItem.Builder(ParcelFileDescriptor.adoptFd(-1)) |
| .setMetadata(metadata) |
| .build(); |
| |
| List<MediaItem> playlist = MediaTestUtils.createFileMediaItems(5); |
| playlist.set(testItemIndex, currentMediaItem); |
| mSession.getMockPlayer().setPlaylistWithDummyItem(playlist); |
| |
| AtomicReference<MediaMetadataCompat> metadataRef = new AtomicReference<>(); |
| AtomicReference<PlaybackStateCompat> playbackStateRef = new AtomicReference<>(); |
| CountDownLatch latchForMetadata = new CountDownLatch(1); |
| CountDownLatch latchForPlaybackState = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onMetadataChanged(MediaMetadataCompat metadata) { |
| metadataRef.set(metadata); |
| latchForMetadata.countDown(); |
| } |
| |
| @Override |
| public void onPlaybackStateChanged(PlaybackStateCompat state) { |
| playbackStateRef.set(state); |
| latchForPlaybackState.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| mSession.getMockPlayer().setCurrentMediaItem(testItemIndex); |
| mSession.getMockPlayer().setCurrentPosition(testPosition); |
| mSession.getMockPlayer().notifyCurrentMediaItemChanged(testItemIndex); |
| |
| assertTrue(latchForMetadata.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(displayTitle, |
| metadataRef.get().getString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)); |
| assertEquals(displayTitle, |
| mControllerCompat.getMetadata().getString( |
| MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE)); |
| if (MediaTestUtils.isServiceToT()) { |
| // TODO(b/156594425): Move these assertions out of this condition once the |
| // previous session is updated to have the fix of b/159147455. |
| assertTrue(latchForPlaybackState.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(testPosition, playbackStateRef.get().getPosition()); |
| assertEquals(testPosition, mControllerCompat.getPlaybackState().getPosition()); |
| } |
| } |
| |
| @Test |
| public void playlistAndPlaylistMetadataChange() throws Exception { |
| List<MediaItem> playlist = MediaTestUtils.createFileMediaItems(5); |
| String playlistTitle = "playlistTitle"; |
| MediaMetadata playlistMetadata = new MediaMetadata.Builder() |
| .putText(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, playlistTitle).build(); |
| |
| AtomicReference<CharSequence> queueTitleRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(2); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onQueueChanged(List<QueueItem> queue) { |
| latch.countDown(); |
| } |
| |
| @Override |
| public void onQueueTitleChanged(CharSequence title) { |
| queueTitleRef.set(title); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| mSession.getMockPlayer().setPlaylist(playlist); |
| mSession.getMockPlayer().setPlaylistMetadata(playlistMetadata); |
| mSession.getMockPlayer().notifyPlaylistChanged(); |
| |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| |
| List<QueueItem> queue = mControllerCompat.getQueue(); |
| assertNotNull(queue); |
| assertEquals(playlist.size(), queue.size()); |
| for (int i = 0; i < playlist.size(); i++) { |
| assertEquals(playlist.get(i).getMediaId(), queue.get(i).getDescription().getMediaId()); |
| } |
| assertEquals(playlistTitle, queueTitleRef.get().toString()); |
| } |
| |
| @Test |
| public void playlistAndPlaylistMetadataChange_longList() throws Exception { |
| String playlistTitle = "playlistTitle"; |
| MediaMetadata playlistMetadata = new MediaMetadata.Builder() |
| .putText(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, playlistTitle).build(); |
| |
| AtomicReference<CharSequence> queueTitleRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(2); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onQueueChanged(List<QueueItem> queue) { |
| latch.countDown(); |
| } |
| |
| @Override |
| public void onQueueTitleChanged(CharSequence title) { |
| queueTitleRef.set(title); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| int listSize = 5000; |
| mSession.getMockPlayer().createAndSetDummyPlaylist(listSize); |
| mSession.getMockPlayer().setPlaylistMetadata(playlistMetadata); |
| mSession.getMockPlayer().notifyPlaylistChanged(); |
| |
| assertTrue(latch.await(3, TimeUnit.SECONDS)); |
| |
| List<QueueItem> queue = mControllerCompat.getQueue(); |
| assertNotNull(queue); |
| |
| if (Build.VERSION.SDK_INT >= 21) { |
| assertEquals(listSize, queue.size()); |
| } else { |
| // Below API 21, only the initial part of the playlist is sent to the |
| // MediaControllerCompat when the list is too long. |
| assertTrue(queue.size() < listSize); |
| } |
| for (int i = 0; i < queue.size(); i++) { |
| assertEquals(TestUtils.getMediaIdInDummyList(i), |
| queue.get(i).getDescription().getMediaId()); |
| } |
| assertEquals(playlistTitle, queueTitleRef.get().toString()); |
| } |
| |
| @Test |
| public void playlistMetadataChange() throws Exception { |
| String playlistTitle = "playlistTitle"; |
| MediaMetadata playlistMetadata = new MediaMetadata.Builder() |
| .putText(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, playlistTitle).build(); |
| |
| AtomicReference<CharSequence> queueTitleRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onQueueTitleChanged(CharSequence title) { |
| queueTitleRef.set(title); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| mSession.getMockPlayer().setPlaylistMetadata(playlistMetadata); |
| mSession.getMockPlayer().notifyPlaylistMetadataChanged(); |
| |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(playlistTitle, queueTitleRef.get().toString()); |
| } |
| |
| @Test |
| public void onAudioInfoChanged_isCalled_byVolumeChange() throws Exception { |
| if (!MediaTestUtils.isServiceToT()) { |
| // TODO(b/156594425): Remove this condition once the previous session becomes to notify |
| // volume changes of RemoteSessionPlayer (b/155059866). |
| return; |
| } |
| |
| Bundle playerConfig = new RemoteMediaSession.MockPlayerConfigBuilder() |
| .setVolumeControlType(RemoteSessionPlayer.VOLUME_CONTROL_ABSOLUTE) |
| .setMaxVolume(10) |
| .setCurrentVolume(1) |
| .build(); |
| mSession.updatePlayer(playerConfig); |
| |
| AtomicReference<MediaControllerCompat.PlaybackInfo> infoRef = new AtomicReference<>(); |
| CountDownLatch latch = new CountDownLatch(1); |
| MediaControllerCompat.Callback callback = new MediaControllerCompat.Callback() { |
| @Override |
| public void onAudioInfoChanged(MediaControllerCompat.PlaybackInfo info) { |
| infoRef.set(info); |
| latch.countDown(); |
| } |
| }; |
| mControllerCompat.registerCallback(callback, sHandler); |
| |
| int targetVolume = 3; |
| mSession.getMockPlayer().notifyVolumeChanged(targetVolume); |
| assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| assertEquals(targetVolume, infoRef.get().getCurrentVolume()); |
| } |
| } |