MediaSessionTest: Add CTS for the play/pause double tap as next track
Bug: 36575213
Test: Run MediaSessionTest
Change-Id: Ib721321582529f407b4b0e67ae19636cc2742d90
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionTest.java b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
index 58a643d..bb1a501 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
@@ -39,10 +39,14 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
public class MediaSessionTest extends AndroidTestCase {
- // The maximum time to wait for an operation.
+ // The maximum time to wait for an operation that is expected to succeed.
private static final long TIME_OUT_MS = 3000L;
+ // The maximum time to wait for an operation that is expected to fail.
+ private static final long WAIT_MS = 100L;
private static final int MAX_AUDIO_INFO_CHANGED_CALLBACK_COUNT = 10;
private static final String TEST_SESSION_TAG = "test-session-tag";
private static final String TEST_KEY = "test-key";
@@ -322,71 +326,106 @@
PendingIntent pi = PendingIntent.getBroadcast(getContext(), 0, mediaButtonIntent, 0);
mSession.setMediaButtonReceiver(pi);
- long supportedActions = PlaybackState.ACTION_PLAY | PlaybackState.ACTION_PAUSE
- | PlaybackState.ACTION_PLAY_PAUSE | PlaybackState.ACTION_STOP
- | PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_SKIP_TO_PREVIOUS
- | PlaybackState.ACTION_FAST_FORWARD | PlaybackState.ACTION_REWIND;
-
// Set state to STATE_PLAYING to get higher priority.
- PlaybackState defaultState = new PlaybackState.Builder().setActions(supportedActions)
- .setState(PlaybackState.STATE_PLAYING, 0L, 0.0f).build();
- mSession.setPlaybackState(defaultState);
+ setPlaybackState(PlaybackState.STATE_PLAYING);
// A media playback is also needed to receive media key events.
Utils.assertMediaPlaybackStarted(getContext());
+ sessionCallback.reset(1);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertEquals(1, sessionCallback.mOnPlayCalledCount);
+
+ sessionCallback.reset(1);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PAUSE);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertTrue(sessionCallback.mOnPauseCalled);
+
+ sessionCallback.reset(1);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_NEXT);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertTrue(sessionCallback.mOnSkipToNextCalled);
+
+ sessionCallback.reset(1);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertTrue(sessionCallback.mOnSkipToPreviousCalled);
+
+ sessionCallback.reset(1);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_STOP);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertTrue(sessionCallback.mOnStopCalled);
+
+ sessionCallback.reset(1);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertTrue(sessionCallback.mOnFastForwardCalled);
+
+ sessionCallback.reset(1);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_REWIND);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertTrue(sessionCallback.mOnRewindCalled);
+
+ // Test PLAY_PAUSE button twice.
+ // First, simulate PLAY_PAUSE button while in STATE_PAUSED.
+ sessionCallback.reset(1);
+ setPlaybackState(PlaybackState.STATE_PAUSED);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertEquals(1, sessionCallback.mOnPlayCalledCount);
+
+ // Next, simulate PLAY_PAUSE button while in STATE_PLAYING.
+ sessionCallback.reset(1);
+ setPlaybackState(PlaybackState.STATE_PLAYING);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertTrue(sessionCallback.mOnPauseCalled);
+
+ // Double tap of PLAY_PAUSE is the next track instead of changing PLAY/PAUSE.
+ sessionCallback.reset(2);
+ setPlaybackState(PlaybackState.STATE_PLAYING);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ assertFalse(sessionCallback.await(WAIT_MS));
+ assertTrue(sessionCallback.mOnSkipToNextCalled);
+ assertEquals(0, sessionCallback.mOnPlayCalledCount);
+ assertFalse(sessionCallback.mOnPauseCalled);
+
+ // Test if PLAY_PAUSE double tap is considered as two single taps when another media
+ // key is pressed.
+ sessionCallback.reset(3);
+ setPlaybackState(PlaybackState.STATE_PAUSED);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_STOP);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertEquals(2, sessionCallback.mOnPlayCalledCount);
+ assertTrue(sessionCallback.mOnStopCalled);
+
+ // Test if media keys are handled in order.
+ sessionCallback.reset(2);
+ setPlaybackState(PlaybackState.STATE_PAUSED);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_STOP);
+ assertTrue(sessionCallback.await(TIME_OUT_MS));
+ assertEquals(1, sessionCallback.mOnPlayCalledCount);
+ assertTrue(sessionCallback.mOnStopCalled);
synchronized (mWaitLock) {
- sessionCallback.reset();
- simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY);
- mWaitLock.wait(TIME_OUT_MS);
- assertTrue(sessionCallback.mOnPlayCalled);
+ assertEquals(PlaybackState.STATE_STOPPED,
+ mSession.getController().getPlaybackState().getState());
+ }
+ }
- sessionCallback.reset();
- simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PAUSE);
- mWaitLock.wait(TIME_OUT_MS);
- assertTrue(sessionCallback.mOnPauseCalled);
-
- sessionCallback.reset();
- simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_NEXT);
- mWaitLock.wait(TIME_OUT_MS);
- assertTrue(sessionCallback.mOnSkipToNextCalled);
-
- sessionCallback.reset();
- simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
- mWaitLock.wait(TIME_OUT_MS);
- assertTrue(sessionCallback.mOnSkipToPreviousCalled);
-
- sessionCallback.reset();
- simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_STOP);
- mWaitLock.wait(TIME_OUT_MS);
- assertTrue(sessionCallback.mOnStopCalled);
-
- sessionCallback.reset();
- simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD);
- mWaitLock.wait(TIME_OUT_MS);
- assertTrue(sessionCallback.mOnFastForwardCalled);
-
- sessionCallback.reset();
- simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_REWIND);
- mWaitLock.wait(TIME_OUT_MS);
- assertTrue(sessionCallback.mOnRewindCalled);
-
- // Test PLAY_PAUSE button twice.
- // First, simulate PLAY_PAUSE button while in STATE_PAUSED.
- sessionCallback.reset();
- mSession.setPlaybackState(new PlaybackState.Builder().setActions(supportedActions)
- .setState(PlaybackState.STATE_PAUSED, 0L, 0.0f).build());
- simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
- mWaitLock.wait(TIME_OUT_MS);
- assertTrue(sessionCallback.mOnPlayCalled);
-
- // Next, simulate PLAY_PAUSE button while in STATE_PLAYING.
- sessionCallback.reset();
- mSession.setPlaybackState(new PlaybackState.Builder().setActions(supportedActions)
- .setState(PlaybackState.STATE_PLAYING, 0L, 0.0f).build());
- simulateMediaKeyInput(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
- mWaitLock.wait(TIME_OUT_MS);
- assertTrue(sessionCallback.mOnPauseCalled);
+ private void setPlaybackState(int state) {
+ final long allActions = PlaybackState.ACTION_PLAY | PlaybackState.ACTION_PAUSE
+ | PlaybackState.ACTION_PLAY_PAUSE | PlaybackState.ACTION_STOP
+ | PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_SKIP_TO_PREVIOUS
+ | PlaybackState.ACTION_FAST_FORWARD | PlaybackState.ACTION_REWIND;
+ PlaybackState playbackState = new PlaybackState.Builder().setActions(allActions)
+ .setState(state, 0L, 0.0f).build();
+ synchronized (mWaitLock) {
+ mSession.setPlaybackState(playbackState);
}
}
@@ -576,7 +615,8 @@
}
private class MediaSessionCallback extends MediaSession.Callback {
- private boolean mOnPlayCalled;
+ private CountDownLatch mLatch;
+ private int mOnPlayCalledCount;
private boolean mOnPauseCalled;
private boolean mOnStopCalled;
private boolean mOnFastForwardCalled;
@@ -584,8 +624,9 @@
private boolean mOnSkipToPreviousCalled;
private boolean mOnSkipToNextCalled;
- public void reset() {
- mOnPlayCalled = false;
+ public void reset(int count) {
+ mLatch = new CountDownLatch(count);
+ mOnPlayCalledCount = 0;
mOnPauseCalled = false;
mOnStopCalled = false;
mOnFastForwardCalled = false;
@@ -594,60 +635,57 @@
mOnSkipToNextCalled = false;
}
+ public boolean await(long waitMs) {
+ try {
+ return mLatch.await(waitMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
@Override
public void onPlay() {
- synchronized (mWaitLock) {
- mOnPlayCalled = true;
- mWaitLock.notify();
- }
+ mOnPlayCalledCount++;
+ setPlaybackState(PlaybackState.STATE_PLAYING);
+ mLatch.countDown();
}
@Override
public void onPause() {
- synchronized (mWaitLock) {
- mOnPauseCalled = true;
- mWaitLock.notify();
- }
+ mOnPauseCalled = true;
+ setPlaybackState(PlaybackState.STATE_PAUSED);
+ mLatch.countDown();
}
@Override
public void onStop() {
- synchronized (mWaitLock) {
- mOnStopCalled = true;
- mWaitLock.notify();
- }
+ mOnStopCalled = true;
+ setPlaybackState(PlaybackState.STATE_STOPPED);
+ mLatch.countDown();
}
@Override
public void onFastForward() {
- synchronized (mWaitLock) {
- mOnFastForwardCalled = true;
- mWaitLock.notify();
- }
+ mOnFastForwardCalled = true;
+ mLatch.countDown();
}
@Override
public void onRewind() {
- synchronized (mWaitLock) {
- mOnRewindCalled = true;
- mWaitLock.notify();
- }
+ mOnRewindCalled = true;
+ mLatch.countDown();
}
@Override
public void onSkipToPrevious() {
- synchronized (mWaitLock) {
- mOnSkipToPreviousCalled = true;
- mWaitLock.notify();
- }
+ mOnSkipToPreviousCalled = true;
+ mLatch.countDown();
}
@Override
public void onSkipToNext() {
- synchronized (mWaitLock) {
- mOnSkipToNextCalled = true;
- mWaitLock.notify();
- }
+ mOnSkipToNextCalled = true;
+ mLatch.countDown();
}
}
}