diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0ef8a29254b25b39642d9e77bd9ffc201dbed2cb --- /dev/null +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/GPMWrapperTest.java @@ -0,0 +1,116 @@ +/* + * Copyright 2023 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 com.android.bluetooth.audio_util; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.media.MediaDescription; +import android.media.MediaMetadata; +import android.media.session.MediaSession; +import android.media.session.PlaybackState; + +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class GPMWrapperTest { + + private Context mContext; + private MediaController mMediaController; + + @Before + public void setUp() throws Exception { + mContext = InstrumentationRegistry.getTargetContext(); + mMediaController = mock(MediaController.class); + } + + @Test + public void isMetadataSynced_whenQueueIsNull_returnsFalse() { + when(mMediaController.getQueue()).thenReturn(null); + + GPMWrapper wrapper = new GPMWrapper(mContext, mMediaController, null); + + assertThat(wrapper.isMetadataSynced()).isFalse(); + } + + @Test + public void isMetadataSynced_whenOutOfSync_returnsFalse() { + long activeQueueItemId = 3; + PlaybackState state = new PlaybackState.Builder() + .setActiveQueueItemId(activeQueueItemId).build(); + when(mMediaController.getPlaybackState()).thenReturn(state); + + List<MediaSession.QueueItem> queue = new ArrayList<>(); + MediaDescription description = new MediaDescription.Builder() + .setTitle("Title from queue item") + .build(); + MediaSession.QueueItem queueItem = new MediaSession.QueueItem( + description, activeQueueItemId); + queue.add(queueItem); + when(mMediaController.getQueue()).thenReturn(queue); + + MediaMetadata metadata = new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_TITLE, + "Different Title from MediaMetadata") + .build(); + when(mMediaController.getMetadata()).thenReturn(metadata); + + GPMWrapper wrapper = new GPMWrapper(mContext, mMediaController, null); + + assertThat(wrapper.isMetadataSynced()).isFalse(); + } + + @Test + public void isMetadataSynced_whenSynced_returnsTrue() { + String title = "test_title"; + + long activeQueueItemId = 3; + PlaybackState state = new PlaybackState.Builder() + .setActiveQueueItemId(activeQueueItemId).build(); + when(mMediaController.getPlaybackState()).thenReturn(state); + + List<MediaSession.QueueItem> queue = new ArrayList<>(); + MediaDescription description = new MediaDescription.Builder() + .setTitle(title) + .build(); + MediaSession.QueueItem queueItem = new MediaSession.QueueItem( + description, activeQueueItemId); + queue.add(queueItem); + when(mMediaController.getQueue()).thenReturn(queue); + + MediaMetadata metadata = new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_TITLE, title) + .build(); + when(mMediaController.getMetadata()).thenReturn(metadata); + + GPMWrapper wrapper = new GPMWrapper(mContext, mMediaController, null); + + assertThat(wrapper.isMetadataSynced()).isFalse(); + } +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java index 16ba20159ceae060f5f60043e803eb277b7847de..2940d00e846f3fc84bba0e19af578aa32a311b11 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/MediaPlayerWrapperTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.audio_util; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.*; import android.content.Context; @@ -717,4 +719,144 @@ public class MediaPlayerWrapperTest { Assert.assertFalse(wrapper.getTimeoutHandler().hasMessages(MSG_TIMEOUT)); verify(mFailHandler, never()).onTerribleFailure(any(), any(), anyBoolean()); } + + @Test + public void pauseCurrent() { + MediaController.TransportControls transportControls + = mock(MediaController.TransportControls.class); + when(mMockController.getTransportControls()).thenReturn(transportControls); + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + wrapper.pauseCurrent(); + + verify(transportControls).pause(); + } + + @Test + public void playCurrent() { + MediaController.TransportControls transportControls + = mock(MediaController.TransportControls.class); + when(mMockController.getTransportControls()).thenReturn(transportControls); + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + wrapper.playCurrent(); + + verify(transportControls).play(); + } + + @Test + public void playItemFromQueue() { + MediaController.TransportControls transportControls + = mock(MediaController.TransportControls.class); + when(mMockController.getTransportControls()).thenReturn(transportControls); + when(mMockController.getQueue()).thenReturn(new ArrayList<>()); + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + long queueItemId = 4; + wrapper.playItemFromQueue(queueItemId); + + verify(transportControls).skipToQueueItem(queueItemId); + } + + @Test + public void rewind() { + MediaController.TransportControls transportControls + = mock(MediaController.TransportControls.class); + when(mMockController.getTransportControls()).thenReturn(transportControls); + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + wrapper.rewind(); + + verify(transportControls).rewind(); + } + + @Test + public void seekTo() { + MediaController.TransportControls transportControls + = mock(MediaController.TransportControls.class); + when(mMockController.getTransportControls()).thenReturn(transportControls); + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + long position = 50; + wrapper.seekTo(position); + + verify(transportControls).seekTo(position); + } + + @Test + public void setPlaybackSpeed() { + MediaController.TransportControls transportControls + = mock(MediaController.TransportControls.class); + when(mMockController.getTransportControls()).thenReturn(transportControls); + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + float speed = 2.0f; + wrapper.setPlaybackSpeed(speed); + + verify(transportControls).setPlaybackSpeed(speed); + } + + @Test + public void skipToNext() { + MediaController.TransportControls transportControls + = mock(MediaController.TransportControls.class); + when(mMockController.getTransportControls()).thenReturn(transportControls); + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + wrapper.skipToNext(); + + verify(transportControls).skipToNext(); + } + + @Test + public void skipToPrevious() { + MediaController.TransportControls transportControls + = mock(MediaController.TransportControls.class); + when(mMockController.getTransportControls()).thenReturn(transportControls); + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + wrapper.skipToPrevious(); + + verify(transportControls).skipToPrevious(); + } + + @Test + public void stopCurrent() { + MediaController.TransportControls transportControls + = mock(MediaController.TransportControls.class); + when(mMockController.getTransportControls()).thenReturn(transportControls); + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + wrapper.stopCurrent(); + + verify(transportControls).stop(); + } + + @Test + public void toggleRepeat_andToggleShuffle_doesNotCrash() { + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + wrapper.toggleRepeat(true); + wrapper.toggleRepeat(false); + wrapper.toggleShuffle(true); + wrapper.toggleShuffle(false); + } + + @Test + public void toString_doesNotCrash() { + MediaPlayerWrapper wrapper = + MediaPlayerWrapperFactory.wrap(mMockContext, mMockController, mThread.getLooper()); + + assertThat(wrapper.toString()).isNotEmpty(); + } }