diff --git a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/MediaPlaybackTest.java b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/MediaPlaybackTest.java new file mode 100644 index 000000000000..430bc660f453 --- /dev/null +++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/MediaPlaybackTest.java @@ -0,0 +1,216 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.tests; + +import org.mozilla.gecko.Actions; +import org.mozilla.gecko.R; +import org.mozilla.gecko.Tab; +import org.mozilla.gecko.Tabs; +import org.mozilla.gecko.media.AudioFocusAgent; +import org.mozilla.gecko.media.AudioFocusAgent.State; +import org.mozilla.gecko.media.MediaControlService; + +import android.content.Intent; +import android.content.Context; + +import android.app.Notification; +import android.app.NotificationManager; +import android.os.Build; +import android.service.notification.StatusBarNotification; + +import com.robotium.solo.Condition; + +abstract class MediaPlaybackTest extends BaseTest { + private Context mContext; + private int mPrevIcon = 0; + private boolean mPrevTabAudioPlaying = false; + + protected void info(String msg) { + mAsserter.dumpLog(msg); + } + + protected Context getContext() { + if (mContext == null) { + mContext = getInstrumentation().getTargetContext(); + } + return mContext; + } + + /** + * Get the system active notification and check whether its UI icon has + * been changed. + */ + protected void waitUntilNotificationUIChanged() { + waitForCondition(new Condition() { + @Override + public boolean isSatisfied() { + NotificationManager notificationManager = (NotificationManager) + getContext().getSystemService(Context.NOTIFICATION_SERVICE); + StatusBarNotification[] sbns = notificationManager.getActiveNotifications(); + // Ensure the UI has been changed. + if (sbns.length == 1 && + sbns[0].getNotification().actions.length == 1) { + if (sbns[0].getNotification().actions[0].icon != mPrevIcon) { + mPrevIcon = sbns[0].getNotification().actions[0].icon ; + return true; + } + } + // The notification was cleared. + else if (mPrevIcon != 0 && sbns.length == 0) { + mPrevIcon = 0; + return true; + } + return false; + } + }, MAX_WAIT_MS); + } + + /** + * Get the selected tab and check whether tab's audio playing state has + * been changed. + */ + protected void waitUntilTabAudioPlayingStateChanged() { + waitForCondition(new Condition() { + @Override + public boolean isSatisfied() { + Tab tab = Tabs.getInstance().getSelectedTab(); + if (tab.isAudioPlaying() != mPrevTabAudioPlaying) { + mPrevTabAudioPlaying = tab.isAudioPlaying(); + return true; + } + return false; + } + }, MAX_WAIT_MS); + } + + /** + * Since we can't testing media control via clicking the media control, we + * directly send intent to service to simulate the behavior. + */ + protected void notifyMediaControlService(String action) { + Intent intent = new Intent(getContext(), MediaControlService.class); + intent.setAction(action); + getContext().startService(intent); + } + + /** + * Use these methods when both media control and audio focus state should + * be changed and you want to check whether the changing are correct or not. + */ + protected void checkIfMediaPlayingSuccess(boolean isTabPlaying) { + checkIfMediaPlayingSuccess(isTabPlaying, false); + } + + protected void checkIfMediaPlayingSuccess(boolean isTabPlaying, + boolean clearNotification) { + checkAudioFocusStateAfterChanged(isTabPlaying); + checkMediaNotificationStatesAfterChanged(isTabPlaying, clearNotification); + } + + /** + * This method is used to check whether notification states are correct or + * not after notification UI changed. + */ + protected void checkMediaNotificationStatesAfterChanged(boolean isTabPlaying, + boolean clearNotification) { + waitUntilNotificationUIChanged(); + + final Tab tab = Tabs.getInstance().getSelectedTab(); + mAsserter.ok(isTabPlaying == tab.isMediaPlaying(), + "Checking the media playing state of tab, isTabPlaying = " + isTabPlaying, + "Tab's media playing state is correct."); + + if (clearNotification) { + checkIfMediaNotificationBeCleared(); + } else { + checkMediaNotificationStates(isTabPlaying); + } + } + + protected void checkMediaNotificationStates(boolean isTabPlaying) { + NotificationManager notificationManager = (NotificationManager) + getContext().getSystemService(Context.NOTIFICATION_SERVICE); + + StatusBarNotification[] sbns = notificationManager.getActiveNotifications(); + mAsserter.is(sbns.length, 1, + "Should only have one notification in system's status bar."); + + Notification notification = sbns[0].getNotification(); + mAsserter.is(notification.actions.length, 1, + "Only has one action in notification."); + + mAsserter.is(notification.actions[0].title, + getContext().getString(isTabPlaying ? R.string.media_pause : R.string.media_play), + "Action has correct title."); + mAsserter.is(notification.actions[0].icon, + isTabPlaying ? R.drawable.ic_media_pause : R.drawable.ic_media_play, + "Action has correct icon."); + } + + protected void checkIfMediaNotificationBeCleared() { + NotificationManager notificationManager = (NotificationManager) + getContext().getSystemService(Context.NOTIFICATION_SERVICE); + StatusBarNotification[] sbns = notificationManager.getActiveNotifications(); + mAsserter.is(sbns.length, 0, + "Should not have notification in system's status bar."); + } + + /** + * This method is used to check whether audio focus state are correct or + * not after tab's audio playing state changed. + */ + protected void checkAudioFocusStateAfterChanged(boolean isTabPlaying) { + waitUntilTabAudioPlayingStateChanged(); + + final Tab tab = Tabs.getInstance().getSelectedTab(); + mAsserter.ok(isTabPlaying == tab.isAudioPlaying(), + "Checking the audio playing state of tab, isTabPlaying = " + isTabPlaying, + "Tab's audio playing state is correct."); + + if (isTabPlaying) { + mAsserter.is(AudioFocusAgent.getInstance().getAudioFocusState(), + State.OWN_FOCUS, + "Audio focus state is correct."); + } else { + boolean isLostFocus = + AudioFocusAgent.getInstance().getAudioFocusState().equals(State.LOST_FOCUS) || + AudioFocusAgent.getInstance().getAudioFocusState().equals(State.LOST_FOCUS_TRANSIENT); + mAsserter.ok(isLostFocus, + "Checking the audio focus when the tab is not playing", + "Audio focus state is correct."); + } + } + + protected AudioFocusAgent getAudioFocusAgent() { + return AudioFocusAgent.getInstance(); + } + + protected void requestAudioFocus() { + getAudioFocusAgent().notifyStartedPlaying(); + if (getAudioFocusAgent().getAudioFocusState() == State.OWN_FOCUS) { + return; + } + + // Request audio focus might fail, depend on the andriod's audio mode. + waitForCondition(new Condition() { + @Override + public boolean isSatisfied() { + getAudioFocusAgent().notifyStartedPlaying(); + return getAudioFocusAgent().getAudioFocusState() == State.OWN_FOCUS; + } + }, MAX_WAIT_MS); + } + + /** + * The method NotificationManager.getActiveNotifications() is only avaiable + * after version 23, so we need to check version ensure running the test on + * the correct version. + */ + protected void checkAndroidVersionForMediaControlTest() { + mAsserter.ok(Build.VERSION.SDK_INT >= 23, + "Checking the android version for media control testing", + "The API to check system notification is only available after version 23."); + } +} diff --git a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAudioFocus.java b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAudioFocus.java index 93afd2d1b1d3..7ceaa0523183 100644 --- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAudioFocus.java +++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testAudioFocus.java @@ -4,19 +4,11 @@ package org.mozilla.gecko.tests; -import org.mozilla.gecko.Actions; -import org.mozilla.gecko.Tab; -import org.mozilla.gecko.Tabs; -import org.mozilla.gecko.media.AudioFocusAgent; import org.mozilla.gecko.media.AudioFocusAgent.State; import android.media.AudioManager; -import com.robotium.solo.Condition; - -public class testAudioFocus extends BaseTest { - private boolean mPrevTabAudioPlaying = false; - +public class testAudioFocus extends MediaPlaybackTest { public void testAudioFocus() { info("- wait for gecko ready -"); blockForGeckoReady(); @@ -160,7 +152,7 @@ public class testAudioFocus extends BaseTest { final String BLANK_URL = getAbsoluteUrl(mStringHelper.ROBOCOP_BLANK_PAGE_01_URL); addTab(BLANK_URL); - info("- should still own the audio focus -"); + info("- should still own the audio focus -"); mAsserter.is(getAudioFocusAgent().getAudioFocusState(), State.OWN_FOCUS, "Should own audio focus."); @@ -168,45 +160,4 @@ public class testAudioFocus extends BaseTest { info("- close tab -"); closeAllTabs(); } - - /** - * Testing tool functions - */ - private void info(String msg) { - mAsserter.dumpLog(msg); - } - - private AudioFocusAgent getAudioFocusAgent() { - return AudioFocusAgent.getInstance(); - } - - private void requestAudioFocus() { - getAudioFocusAgent().notifyStartedPlaying(); - if (getAudioFocusAgent().getAudioFocusState() == State.OWN_FOCUS) { - return; - } - - // Request audio focus might fail, depend on the andriod's audio mode. - waitForCondition(new Condition() { - @Override - public boolean isSatisfied() { - getAudioFocusAgent().notifyStartedPlaying(); - return getAudioFocusAgent().getAudioFocusState() == State.OWN_FOCUS; - } - }, MAX_WAIT_MS); - } - - private void waitUntilTabAudioPlayingStateChanged() { - final Tab tab = Tabs.getInstance().getSelectedTab(); - waitForCondition(new Condition() { - @Override - public boolean isSatisfied() { - if (tab.isAudioPlaying() != mPrevTabAudioPlaying) { - mPrevTabAudioPlaying = tab.isAudioPlaying(); - return true; - } - return false; - } - }, MAX_WAIT_MS); - } } diff --git a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testMediaControl.java b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testMediaControl.java index e19dc8f7b3a8..6a309a0ae689 100644 --- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testMediaControl.java +++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testMediaControl.java @@ -4,42 +4,18 @@ package org.mozilla.gecko.tests; -import org.mozilla.gecko.Actions; -import org.mozilla.gecko.R; -import org.mozilla.gecko.Tab; -import org.mozilla.gecko.Tabs; -import org.mozilla.gecko.media.AudioFocusAgent; -import org.mozilla.gecko.media.AudioFocusAgent.State; import org.mozilla.gecko.media.MediaControlService; -import android.content.Intent; -import android.content.Context; import android.media.AudioManager; -import android.app.Notification; -import android.app.NotificationManager; -import android.os.Build; -import android.service.notification.StatusBarNotification; - -import com.robotium.solo.Condition; - -public class testMediaControl extends BaseTest { - private Context mContext; - private int mPrevIcon = 0; - private boolean mPrevTabAudioPlaying = false; - +public class testMediaControl extends MediaPlaybackTest { public void testMediaControl() { - // The API to check system notification is available after version 23. - if (Build.VERSION.SDK_INT < 23) { - return; - } + info("- ensure the test is running on correct Android version -"); + checkAndroidVersionForMediaControlTest(); info("- wait for gecko ready -"); blockForGeckoReady(); - info("- setup testing memeber variable -"); - setupForTesting(); - info("- load URL -"); final String MEDIA_URL = getAbsoluteUrl(mStringHelper.ROBOCOP_MEDIA_PLAYBACK_LOOP_URL); loadUrlAndWait(MEDIA_URL); @@ -125,149 +101,33 @@ public class testMediaControl extends BaseTest { final String BLANK_URL = getAbsoluteUrl(mStringHelper.ROBOCOP_BLANK_PAGE_01_URL); addTab(BLANK_URL); - info("- the media control should still be displayed in status bar -"); - checkDisplayedNotificationStates(true /* playing */); + info("- the media control shouldn't be changed -"); + checkMediaNotificationStates(true /* playing */); + + info("- close tab -"); + closeAllTabs(); + + info("- run next test : testCloseTab -"); + testCloseTab(); + } + + private void testCloseTab() { + info("- load URL -"); + final String MEDIA_URL = getAbsoluteUrl(mStringHelper.ROBOCOP_MEDIA_PLAYBACK_LOOP_URL); + loadUrlAndWait(MEDIA_URL); + + info("- check whether audio starts playing -"); + checkIfMediaPlayingSuccess(true /* playing */); + + info("- close audible tab -"); + final Tab tab = Tabs.getInstance().getFirstTabForUrl(MEDIA_URL); + Tabs.getInstance().closeTab(tab); + + info("- media control should disappear -"); + waitUntilNotificationUIChanged(); + checkIfMediaNotificationBeCleared(); info("- close tab -"); closeAllTabs(); } - - /** - * Testing tool functions - */ - private void info(String msg) { - mAsserter.dumpLog(msg); - } - - private void setupForTesting() { - mContext = getInstrumentation().getTargetContext(); - } - - private void waitUntilNotificationUIChanged() { - waitForCondition(new Condition() { - @Override - public boolean isSatisfied() { - NotificationManager notificationManager = (NotificationManager) - mContext.getSystemService(Context.NOTIFICATION_SERVICE); - StatusBarNotification[] sbns = notificationManager.getActiveNotifications(); - if (sbns.length == 1 && - sbns[0].getNotification().actions.length == 1) { - // Ensure the UI has been changed. - if (sbns[0].getNotification().actions[0].icon != mPrevIcon) { - mPrevIcon = sbns[0].getNotification().actions[0].icon ; - return true; - } - } - return false; - } - }, MAX_WAIT_MS); - } - - private void waitUntilTabAudioPlayingStateChanged() { - final Tab tab = Tabs.getInstance().getSelectedTab(); - waitForCondition(new Condition() { - @Override - public boolean isSatisfied() { - if (tab.isAudioPlaying() != mPrevTabAudioPlaying) { - mPrevTabAudioPlaying = tab.isAudioPlaying(); - return true; - } - return false; - } - }, MAX_WAIT_MS); - } - - private void notifyMediaControlService(String action) { - Intent intent = new Intent(mContext, MediaControlService.class); - intent.setAction(action); - mContext.startService(intent); - } - - private void checkIfMediaPlayingSuccess(boolean isTabPlaying) { - checkIfMediaPlayingSuccess(isTabPlaying, false); - } - - private void checkIfMediaPlayingSuccess(boolean isTabPlaying, - boolean clearNotification) { - checkAudioFocusStateChanged(isTabPlaying); - checkMediaNotificationStatesChanged(isTabPlaying, clearNotification); - } - - /** - * This method is used to check whether notification states are correct or - * not after notification UI changed. - */ - private void checkMediaNotificationStatesChanged(boolean isTabPlaying, - boolean clearNotification) { - waitUntilNotificationUIChanged(); - - final Tab tab = Tabs.getInstance().getSelectedTab(); - mAsserter.ok(isTabPlaying == tab.isMediaPlaying(), - "Checking the media playing state of tab, isTabPlaying = " + isTabPlaying, - "Tab's media playing state is correct."); - - if (clearNotification) { - checkIfNotificationBeCleared(); - } else { - checkDisplayedNotificationStates(isTabPlaying); - } - } - - private void checkDisplayedNotificationStates(boolean isTabPlaying) { - NotificationManager notificationManager = (NotificationManager) - mContext.getSystemService(Context.NOTIFICATION_SERVICE); - - StatusBarNotification[] sbns = notificationManager.getActiveNotifications(); - mAsserter.is(sbns.length, 1, - "Should only have one notification in system's status bar."); - - Notification notification = sbns[0].getNotification(); - mAsserter.is(notification.actions.length, 1, - "Only has one action in notification."); - - mAsserter.is(notification.actions[0].title, - mContext.getString(isTabPlaying ? R.string.media_pause : R.string.media_play), - "Action has correct title."); - mAsserter.is(notification.actions[0].icon, - isTabPlaying ? R.drawable.ic_media_pause : R.drawable.ic_media_play, - "Action has correct icon."); - } - - private void checkIfNotificationBeCleared() { - NotificationManager notificationManager = (NotificationManager) - mContext.getSystemService(Context.NOTIFICATION_SERVICE); - StatusBarNotification[] sbns = notificationManager.getActiveNotifications(); - mAsserter.is(sbns.length, 0, - "Should not have notification in system's status bar."); - } - - /** - * This method is used to check whether audio focus state are correct or - * not after tab's audio playing state changed. - */ - private void checkAudioFocusStateChanged(boolean isTabPlaying) { - waitUntilTabAudioPlayingStateChanged(); - - final Tab tab = Tabs.getInstance().getSelectedTab(); - mAsserter.ok(isTabPlaying == tab.isAudioPlaying(), - "Checking the audio playing state of tab, isTabPlaying = " + isTabPlaying, - "Tab's audio playing state is correct."); - - if (isTabPlaying) { - mAsserter.is(AudioFocusAgent.getInstance().getAudioFocusState(), - State.OWN_FOCUS, - "Audio focus state is correct."); - } else { - boolean isLostFocus = - AudioFocusAgent.getInstance().getAudioFocusState().equals(State.LOST_FOCUS) || - AudioFocusAgent.getInstance().getAudioFocusState().equals(State.LOST_FOCUS_TRANSIENT); - mAsserter.ok(isLostFocus, - "Checking the audio focus when the tab is not playing", - "Audio focus state is correct."); - } - } - - private AudioFocusAgent getAudioFocusAgent() { - return AudioFocusAgent.getInstance(); - } }