Bug 1322114 - Add test cases for MediaControlService r=sebastian
authorJulian_Chu <walkingice0204@gmail.com>
Thu, 12 Jan 2017 15:44:19 +0800
changeset 377738 c69a94671a4afc639d5969b7a744ba4ae6e0b239
parent 377737 daf0f6eccbb6cf6e5f5ab74c99c569e174168ec8
child 377739 442d75009799000429ce0f0b012dbccda63e37d4
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssebastian
bugs1322114
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1322114 - Add test cases for MediaControlService r=sebastian Also refactor MediaControlService to be test-friendly. MozReview-Commit-ID: 344cEEuVroG
mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
mobile/android/tests/background/junit4/src/org/mozilla/gecko/media/TestMediaControlService.java
--- a/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
@@ -14,16 +14,17 @@ import android.graphics.Paint;
 import android.graphics.Rect;
 import android.media.AudioManager;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.support.annotation.CheckResult;
+import android.support.annotation.VisibleForTesting;
 import android.support.v4.app.NotificationManagerCompat;
 import android.util.Log;
 
 import org.mozilla.gecko.BrowserApp;
 import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.PrefsHelper;
 import org.mozilla.gecko.R;
@@ -367,30 +368,41 @@ public class MediaControlService extends
         } else {
             stopForeground(false);
             NotificationManagerCompat.from(this)
                 .notify(MEDIA_CONTROL_ID, notification);
         }
     }
 
     private Notification.Action createNotificationAction() {
-        boolean isPlayAction = mMediaState.equals(State.PAUSED);
+        final Intent intent = createIntentUponState(mMediaState);
+        boolean isPlayAction = intent.getAction().equals(ACTION_RESUME);
 
         int icon = isPlayAction ? R.drawable.ic_media_play : R.drawable.ic_media_pause;
         String title = getString(isPlayAction ? R.string.media_play : R.string.media_pause);
-        String action = isPlayAction ? ACTION_RESUME : ACTION_PAUSE;
 
-        final Intent intent = new Intent(getApplicationContext(), MediaControlService.class);
-        intent.setAction(action);
         final PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
 
         //noinspection deprecation - The new constructor is only for API > 23
         return new Notification.Action.Builder(icon, title, pendingIntent).build();
     }
 
+    /**
+     * This method encapsulated UI logic. For PLAYING state, UI should display a PAUSE icon.
+     * @param state The expected current state of MediaControlService
+     * @return corresponding Intent to be used for Notification
+     */
+    @VisibleForTesting
+    protected Intent createIntentUponState(State state) {
+        String action = state.equals(State.PLAYING) ? ACTION_PAUSE : ACTION_RESUME;
+        final Intent intent = new Intent(getApplicationContext(), MediaControlService.class);
+        intent.setAction(action);
+        return intent;
+    }
+
     private PendingIntent createContentIntent(int tabId) {
         Intent intent = new Intent(getApplicationContext(), BrowserApp.class);
         intent.setAction(GeckoApp.ACTION_SWITCH_TAB);
         intent.putExtra("TabId", tabId);
         return PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     private PendingIntent createDeleteIntent() {
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/media/TestMediaControlService.java
@@ -0,0 +1,78 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+package org.mozilla.gecko.media;
+
+import android.content.Intent;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.internal.util.reflection.Whitebox;
+import org.mozilla.gecko.Tab;
+import org.mozilla.gecko.Tabs;
+import org.mozilla.gecko.background.testhelpers.TestRunner;
+import org.mozilla.gecko.media.MediaControlService.State;
+import org.robolectric.Robolectric;
+
+import java.lang.ref.WeakReference;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
+@RunWith(TestRunner.class)
+public class TestMediaControlService {
+
+    private MediaControlService mSpyService;
+    private Tab mMockTab;
+
+    @Before
+    public void setUp() {
+        MediaControlService service = Robolectric.buildService(MediaControlService.class).get();
+        mSpyService = spy(service);
+        mMockTab = mock(Tab.class);
+        // We should use White-box as less as possible. But this is not avoidable so far.
+        Whitebox.setInternalState(mSpyService, "mInitialize", true);
+    }
+
+    @Test
+    public void testTabPlayingMedia() throws Exception {
+        // If tab is playing media and got another MEDIA_PLAYING_CHANGE
+        // state should be PLAYING
+        Whitebox.setInternalState(mSpyService, "mTabReference", new WeakReference<>(mMockTab));
+        doReturn(true).when(mMockTab).isMediaPlaying();
+
+        mSpyService.onTabChanged(mMockTab, Tabs.TabEvents.MEDIA_PLAYING_CHANGE, "");
+        State state = (State) Whitebox.getInternalState(mSpyService, "mMediaState");
+        Assert.assertEquals(state, State.PLAYING);
+    }
+
+    @Test
+    public void testTabNotPlayingMedia() throws Exception {
+        // If tab is not playing media and got another MEDIA_PLAYING_CHANGE
+        // state should be STOPPED
+        Whitebox.setInternalState(mSpyService, "mTabReference", new WeakReference<>(mMockTab));
+        doReturn(false).when(mMockTab).isMediaPlaying();
+
+        mSpyService.onTabChanged(mMockTab, Tabs.TabEvents.MEDIA_PLAYING_CHANGE, "");
+        State state = (State) Whitebox.getInternalState(mSpyService, "mMediaState");
+        Assert.assertEquals(state, State.STOPPED);
+    }
+
+    @Test
+    public void testIntentForPlayingState() throws Exception {
+        // For PLAYING state, should create an PAUSE intent for notification
+        Intent intent = mSpyService.createIntentUponState(State.PLAYING);
+        Assert.assertEquals(intent.getAction(), MediaControlService.ACTION_PAUSE);
+    }
+
+    @Test
+    public void testIntentForPausedState() throws Exception {
+        // For PAUSED state, should create an RESUME intent for notification
+        Intent intent = mSpyService.createIntentUponState(State.PAUSED);
+        Assert.assertEquals(intent.getAction(), MediaControlService.ACTION_RESUME);
+    }
+}