Bug 1347648 - part1 : only request Android audio focus for audible media. draft
authorAlastor Wu <alwu@mozilla.com>
Mon, 27 Mar 2017 10:59:04 +0800
changeset 551569 fe1c16c8294cac93c3c4d166335aa3a5eed8c083
parent 551502 cc53710589fb500610495da5258b7b9221edf681
child 551570 747299f7bb7d75573276b3438fb906ac364d4510
push id51086
push useralwu@mozilla.com
push dateMon, 27 Mar 2017 02:59:50 +0000
bugs1347648
milestone55.0a1
Bug 1347648 - part1 : only request Android audio focus for audible media. For non-audible media, we shouldn't request audio focus because it might interrupt other app who is playing music or podcast. MozReview-Commit-ID: 25iWJktgKUw
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -723,17 +723,18 @@ AndroidBridge::GetGlobalContextRef() {
 }
 
 /* Implementation file */
 NS_IMPL_ISUPPORTS(nsAndroidBridge,
                   nsIAndroidEventDispatcher,
                   nsIAndroidBridge,
                   nsIObserver)
 
-nsAndroidBridge::nsAndroidBridge()
+nsAndroidBridge::nsAndroidBridge() :
+    mAudibleWindowsNum(0)
 {
   if (jni::IsAvailable()) {
     RefPtr<widget::EventDispatcher> dispatcher = new widget::EventDispatcher();
     dispatcher->Attach(java::EventDispatcher::GetInstance(),
                        /* window */ nullptr);
     mEventDispatcher = dispatcher;
   }
 
@@ -798,78 +799,61 @@ NS_IMETHODIMP nsAndroidBridge::IsContent
 }
 
 NS_IMETHODIMP
 nsAndroidBridge::Observe(nsISupports* aSubject, const char* aTopic,
                          const char16_t* aData)
 {
   if (!strcmp(aTopic, "xpcom-shutdown")) {
     RemoveObservers();
-  } else if (!strcmp(aTopic, "media-playback")) {
-    ALOG_BRIDGE("nsAndroidBridge::Observe, get media-playback event.");
-
-    nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
-    if (!wrapper) {
-      return NS_OK;
-    }
-
-    uint64_t windowId = 0;
-    nsresult rv = wrapper->GetData(&windowId);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+  } else if (!strcmp(aTopic, "audio-playback")) {
+    ALOG_BRIDGE("nsAndroidBridge::Observe, get audio-playback event.");
 
     nsAutoString activeStr(aData);
     bool isPlaying = activeStr.EqualsLiteral("active");
-    UpdateAudioPlayingWindows(windowId, isPlaying);
+    UpdateAudioPlayingWindows(isPlaying);
   }
   return NS_OK;
 }
 
 void
-nsAndroidBridge::UpdateAudioPlayingWindows(uint64_t aWindowId,
-                                           bool aPlaying)
+nsAndroidBridge::UpdateAudioPlayingWindows(bool aPlaying)
 {
   // Request audio focus for the first audio playing window and abandon focus
   // for the last audio playing window.
-  if (aPlaying && !mAudioPlayingWindows.Contains(aWindowId)) {
-    mAudioPlayingWindows.AppendElement(aWindowId);
-    if (mAudioPlayingWindows.Length() == 1) {
-      ALOG_BRIDGE("nsAndroidBridge, request audio focus.");
-      AudioFocusAgent::NotifyStartedPlaying();
-    }
-  } else if (!aPlaying && mAudioPlayingWindows.Contains(aWindowId)) {
-    mAudioPlayingWindows.RemoveElement(aWindowId);
-    if (mAudioPlayingWindows.Length() == 0) {
-      ALOG_BRIDGE("nsAndroidBridge, abandon audio focus.");
-      AudioFocusAgent::NotifyStoppedPlaying();
-    }
+  MOZ_ASSERT(mAudibleWindowsNum >= 0);
+  if (aPlaying && mAudibleWindowsNum++ == 0) {
+    ALOG_BRIDGE("nsAndroidBridge, request audio focus.");
+    AudioFocusAgent::NotifyStartedPlaying();
+  } else if (!aPlaying && --mAudibleWindowsNum == 0) {
+    ALOG_BRIDGE("nsAndroidBridge, abandon audio focus.");
+    AudioFocusAgent::NotifyStoppedPlaying();
   }
 }
 
 void
 nsAndroidBridge::AddObservers()
 {
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     obs->AddObserver(this, "xpcom-shutdown", false);
     if (jni::IsFennec()) { // No AudioFocusAgent in non-Fennec environment.
-        obs->AddObserver(this, "media-playback", false);
+        obs->AddObserver(this, "audio-playback", false);
     }
   }
 }
 
 void
 nsAndroidBridge::RemoveObservers()
 {
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     obs->RemoveObserver(this, "xpcom-shutdown");
     if (jni::IsFennec()) { // No AudioFocusAgent in non-Fennec environment.
-        obs->RemoveObserver(this, "media-playback");
+        obs->RemoveObserver(this, "audio-playback");
     }
   }
 }
 
 uint32_t
 AndroidBridge::GetScreenOrientation()
 {
     ALOG_BRIDGE("AndroidBridge::GetScreenOrientation");
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -400,17 +400,17 @@ public:
   nsAndroidBridge();
 
 private:
   ~nsAndroidBridge();
 
   void AddObservers();
   void RemoveObservers();
 
-  void UpdateAudioPlayingWindows(uint64_t aWindowId, bool aPlaying);
+  void UpdateAudioPlayingWindows(bool aPlaying);
 
-  nsTArray<uint64_t> mAudioPlayingWindows;
+  int32_t mAudibleWindowsNum;
   nsCOMPtr<nsIAndroidEventDispatcher> mEventDispatcher;
 
 protected:
 };
 
 #endif /* AndroidBridge_h__ */