summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzqzhang <zqzhang@chromium.org>2015-12-12 11:53:50 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-12 19:54:42 +0000
commitd0b0d5fe705a29ff989dd3708d61154e8c600024 (patch)
tree7242765f12d8d309506d4858c16d25f13ef75d18
parentf696e12b2cb0f829849cf56974d3efa67b437512 (diff)
downloadchromium_src-d0b0d5fe705a29ff989dd3708d61154e8c600024.zip
chromium_src-d0b0d5fe705a29ff989dd3708d61154e8c600024.tar.gz
chromium_src-d0b0d5fe705a29ff989dd3708d61154e8c600024.tar.bz2
Update media notification when page title changes
This CL makes the media notification keep in sync when the page title changes. BUG=550424 Review URL: https://codereview.chromium.org/1417743005 Cr-Commit-Position: refs/heads/master@{#364938}
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java8
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java10
-rw-r--r--chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java132
-rw-r--r--chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java7
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java7
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java9
-rw-r--r--content/public/android/java/src/org/chromium/content_public/browser/WebContents.java7
7 files changed, 177 insertions, 3 deletions
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
index ad4bd08..90d84a2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -327,6 +327,14 @@ public class MediaNotificationManager {
return getManager(notificationId) != null;
}
+ @VisibleForTesting
+ @Nullable
+ protected static MediaNotificationInfo getNotificationInfoForTesting(int notificationId) {
+ MediaNotificationManager manager = getManager(notificationId);
+ if (manager == null) return null;
+ return manager.mMediaNotificationInfo;
+ }
+
private final Context mContext;
// ListenerService running for the notification. Only non-null when showing.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
index 4dce275..b0f07d4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
@@ -142,6 +142,16 @@ public class MediaSessionTabHelper {
}
@Override
+ public void onTitleUpdated(Tab tab) {
+ assert tab == mTab;
+ if (mNotificationInfoBuilder == null) return;
+
+ mNotificationInfoBuilder.setTitle(sanitizeMediaTitle(mTab.getTitle()));
+ MediaNotificationManager.show(ApplicationStatus.getApplicationContext(),
+ mNotificationInfoBuilder.build());
+ }
+
+ @Override
public void onDestroyed(Tab tab) {
assert mTab == tab;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java
new file mode 100644
index 0000000..d505fbe
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java
@@ -0,0 +1,132 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.media.ui;
+
+import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE;
+import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_PHONE;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.ObserverList;
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.Restriction;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.test.ChromeActivityTestCaseBase;
+import org.chromium.chrome.test.util.browser.TabTitleObserver;
+import org.chromium.content.browser.test.util.JavaScriptUtils;
+import org.chromium.content_public.browser.WebContentsObserver;
+
+/**
+ * Test of media notifications to see whether the text updates when the tab title changes
+ */
+public class NotificationTitleUpdatedTest extends ChromeActivityTestCaseBase<ChromeActivity> {
+ private static final int NOTIFICATION_ID = R.id.media_playback_notification;
+
+ private Tab mTab;
+
+ public NotificationTitleUpdatedTest() {
+ super(ChromeActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTab = getActivity().getActivityTab();
+ simulateUpdateTitle(mTab, "title1");
+ }
+
+ @SmallTest
+ public void testSessionStatePlaying() throws InterruptedException {
+ simulateMediaSessionStateChanged(mTab, true, false);
+ assertTitleMatches("title1");
+ simulateUpdateTitle(mTab, "title2");
+ assertTitleMatches("title2");
+ }
+
+ @SmallTest
+ public void testSessionStatePaused() {
+ simulateMediaSessionStateChanged(mTab, true, true);
+ assertTitleMatches("title1");
+ simulateUpdateTitle(mTab, "title2");
+ assertTitleMatches("title2");
+ }
+
+ @SmallTest
+ public void testSessionStateUncontrollable() {
+ simulateMediaSessionStateChanged(mTab, true, false);
+ assertTitleMatches("title1");
+ simulateMediaSessionStateChanged(mTab, false, false);
+ simulateUpdateTitle(mTab, "title2");
+ }
+
+ /**
+ * Test if a notification accepts the title update from another tab, using the following steps:
+ * 1. set the title of mTab, start the media session, a notification should show up;
+ * 2. stop the media session of mTab, the notification shall hide;
+ * 3. create newTab, set the title of mTab, start the media session of mTab,
+ * a notification should show up;
+ * 4. change the title of newTab and then mTab to different names,
+ * the notification should have the title of newTab.
+ */
+ @SmallTest
+ @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
+ public void testMultipleTabs() throws Throwable {
+ simulateMediaSessionStateChanged(mTab, true, false);
+ assertTitleMatches("title1");
+ simulateMediaSessionStateChanged(mTab, false, false);
+
+ Tab newTab = loadUrlInNewTab("about:blank");
+ assertNotNull(newTab);
+
+ simulateMediaSessionStateChanged(newTab, true, false);
+ simulateUpdateTitle(newTab, "title3");
+ simulateUpdateTitle(mTab, "title2");
+ assertTitleMatches("title3");
+ }
+
+ @Override
+ public void startMainActivity() throws InterruptedException {
+ startMainActivityOnBlankPage();
+ }
+
+ private void simulateMediaSessionStateChanged(
+ final Tab tab, final boolean isControllable, final boolean isSuspended) {
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+ @Override
+ public void run() {
+ ObserverList.RewindableIterator<WebContentsObserver> observers =
+ tab.getWebContents().getObserversForTesting();
+ while (observers.hasNext()) {
+ observers.next().mediaSessionStateChanged(
+ isControllable, isSuspended);
+ }
+ }
+ });
+ }
+
+ private void simulateUpdateTitle(Tab tab, String title) {
+ try {
+ TabTitleObserver observer = new TabTitleObserver(tab, title);
+ JavaScriptUtils.executeJavaScriptAndWaitForResult(
+ tab.getWebContents(),
+ "document.title = '" + title + "';");
+ observer.waitForTitleUpdate(5);
+ } catch (Exception e) {
+ throw new RuntimeException(e + "failed to update title");
+ }
+ }
+
+ void assertTitleMatches(final String title) {
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+ @Override
+ public void run() {
+ assertEquals(title, MediaNotificationManager
+ .getNotificationInfoForTesting(NOTIFICATION_ID).title);
+ }
+ });
+ }
+}
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java
index 006b0d5..16a6b3a 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java
@@ -352,8 +352,8 @@ public abstract class ChromeActivityTestCaseBase<T extends ChromeActivity>
* Load a url in a new tab. The {@link Tab} will pretend to be created from a link.
* @param url The url of the page to load.
*/
- public void loadUrlInNewTab(final String url) throws InterruptedException {
- loadUrlInNewTab(url, false);
+ public Tab loadUrlInNewTab(final String url) throws InterruptedException {
+ return loadUrlInNewTab(url, false);
}
/**
@@ -361,7 +361,7 @@ public abstract class ChromeActivityTestCaseBase<T extends ChromeActivity>
* @param url The url of the page to load.
* @param incognito Whether the new tab should be incognito.
*/
- public void loadUrlInNewTab(final String url, final boolean incognito)
+ public Tab loadUrlInNewTab(final String url, final boolean incognito)
throws InterruptedException {
Tab tab = null;
if (FeatureUtilities.isDocumentMode(getInstrumentation().getContext())) {
@@ -405,6 +405,7 @@ public abstract class ChromeActivityTestCaseBase<T extends ChromeActivity>
}
ChromeTabUtils.waitForTabPageLoaded(tab, url);
getInstrumentation().waitForIdleSync();
+ return tab;
}
/**
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
index e2d6cef..04c3745 100644
--- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -12,6 +12,7 @@ import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.Parcelable;
+import org.chromium.base.ObserverList;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
@@ -425,6 +426,12 @@ import java.util.UUID;
mObserverProxy.removeObserver(observer);
}
+ @VisibleForTesting
+ @Override
+ public ObserverList.RewindableIterator<WebContentsObserver> getObserversForTesting() {
+ return mObserverProxy.getObserversForTesting();
+ }
+
@Override
public void getContentBitmapAsync(Bitmap.Config config, float scale, Rect srcRect,
ContentBitmapCallback callback) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java
index 1c36430..9521812 100644
--- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java
+++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java
@@ -7,6 +7,7 @@ package org.chromium.content.browser.webcontents;
import org.chromium.base.ObserverList;
import org.chromium.base.ObserverList.RewindableIterator;
import org.chromium.base.ThreadUtils;
+import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
@@ -61,6 +62,14 @@ class WebContentsObserverProxy extends WebContentsObserver {
return !mObservers.isEmpty();
}
+ /**
+ * @return The list of proxied observers.
+ */
+ @VisibleForTesting
+ public ObserverList.RewindableIterator<WebContentsObserver> getObserversForTesting() {
+ return mObservers.rewindableIterator();
+ }
+
@Override
@CalledByNative
public void renderViewReady() {
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
index 4a1729b..e58dd60 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
@@ -8,6 +8,7 @@ import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Parcelable;
+import org.chromium.base.ObserverList;
import org.chromium.base.VisibleForTesting;
/**
@@ -323,6 +324,12 @@ public interface WebContents extends Parcelable {
void removeObserver(WebContentsObserver observer);
/**
+ * @return The list of observers.
+ */
+ @VisibleForTesting
+ ObserverList.RewindableIterator<WebContentsObserver> getObserversForTesting();
+
+ /**
* Called when context menu gets opened.
*/
void onContextMenuOpened();