Bug 1054219 - [B2G][SpeakerManager] Avoid to create unnecessary speakerManager instance on child process. r=baku
authorRandy Lin <rlin@mozilla.com>
Wed, 20 Aug 2014 10:25:55 +0800
changeset 214902 ac8948dcc1efab68f39b19e6ebc15d5085a2e7e1
parent 214901 463fb288e8a99aace0889ec09896c5c543e8bc8a
child 214903 9de0463fb1c721a3423a5275ed60db8b3a16f802
push idunknown
push userunknown
push dateunknown
reviewersbaku
bugs1054219
milestone34.0a1
Bug 1054219 - [B2G][SpeakerManager] Avoid to create unnecessary speakerManager instance on child process. r=baku
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/speakermanager/SpeakerManager.cpp
dom/speakermanager/SpeakerManagerService.cpp
dom/speakermanager/SpeakerManagerService.h
dom/speakermanager/SpeakerManagerServiceChild.cpp
dom/speakermanager/SpeakerManagerServiceChild.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -939,16 +939,17 @@ ContentChild::RecvSetProcessSandbox()
 #endif
     return true;
 }
 
 bool
 ContentChild::RecvSpeakerManagerNotify()
 {
 #ifdef MOZ_WIDGET_GONK
+    // Only notify the process which has the SpeakerManager instance.
     nsRefPtr<SpeakerManagerService> service =
         SpeakerManagerService::GetSpeakerManagerService();
     if (service) {
         service->Notify();
     }
     return true;
 #endif
     return false;
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3214,34 +3214,34 @@ ContentParent::RecvPSpeechSynthesisConst
 }
 
 bool
 ContentParent::RecvSpeakerManagerGetSpeakerStatus(bool* aValue)
 {
 #ifdef MOZ_WIDGET_GONK
     *aValue = false;
     nsRefPtr<SpeakerManagerService> service =
-      SpeakerManagerService::GetSpeakerManagerService();
-    if (service) {
-        *aValue = service->GetSpeakerStatus();
-    }
+      SpeakerManagerService::GetOrCreateSpeakerManagerService();
+    MOZ_ASSERT(service);
+
+    *aValue = service->GetSpeakerStatus();
     return true;
 #endif
     return false;
 }
 
 bool
 ContentParent::RecvSpeakerManagerForceSpeaker(const bool& aEnable)
 {
 #ifdef MOZ_WIDGET_GONK
     nsRefPtr<SpeakerManagerService> service =
-      SpeakerManagerService::GetSpeakerManagerService();
-    if (service) {
-        service->ForceSpeaker(aEnable, mChildID);
-    }
+      SpeakerManagerService::GetOrCreateSpeakerManagerService();
+    MOZ_ASSERT(service);
+    service->ForceSpeaker(aEnable, mChildID);
+
     return true;
 #endif
     return false;
 }
 
 bool
 ContentParent::RecvStartVisitedQuery(const URIParams& aURI)
 {
--- a/dom/speakermanager/SpeakerManager.cpp
+++ b/dom/speakermanager/SpeakerManager.cpp
@@ -22,64 +22,62 @@ NS_IMPL_ADDREF_INHERITED(SpeakerManager,
 NS_IMPL_RELEASE_INHERITED(SpeakerManager, DOMEventTargetHelper)
 
 SpeakerManager::SpeakerManager()
   : mForcespeaker(false)
   , mVisible(false)
 {
   SetIsDOMBinding();
   SpeakerManagerService *service =
-    SpeakerManagerService::GetSpeakerManagerService();
-  if (service) {
-    service->RegisterSpeakerManager(this);
-  }
+    SpeakerManagerService::GetOrCreateSpeakerManagerService();
+  MOZ_ASSERT(service);
+  service->RegisterSpeakerManager(this);
 }
 
 SpeakerManager::~SpeakerManager()
 {
-  SpeakerManagerService *service = SpeakerManagerService::GetSpeakerManagerService();
-  if (service) {
-    service->UnRegisterSpeakerManager(this);
-  }
+  SpeakerManagerService *service = SpeakerManagerService::GetOrCreateSpeakerManagerService();
+  MOZ_ASSERT(service);
+
+  service->UnRegisterSpeakerManager(this);
   nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner());
   NS_ENSURE_TRUE_VOID(target);
 
   target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
                                     this,
                                     /* useCapture = */ true);
 }
 
 bool
 SpeakerManager::Speakerforced()
 {
   // If a background app calls forcespeaker=true that doesn't change anything.
   // 'speakerforced' remains false everywhere.
   if (mForcespeaker && !mVisible) {
     return false;
   }
-  SpeakerManagerService *service = SpeakerManagerService::GetSpeakerManagerService();
-  if (service) {
-    return service->GetSpeakerStatus();
-  }
-  return false;
+  SpeakerManagerService *service = SpeakerManagerService::GetOrCreateSpeakerManagerService();
+  MOZ_ASSERT(service);
+  return service->GetSpeakerStatus();
+
 }
 
 bool
 SpeakerManager::Forcespeaker()
 {
   return mForcespeaker;
 }
 
 void
 SpeakerManager::SetForcespeaker(bool aEnable)
 {
-  SpeakerManagerService *service = SpeakerManagerService::GetSpeakerManagerService();
-  if (service) {
-    service->ForceSpeaker(aEnable, mVisible);
-  }
+  SpeakerManagerService *service = SpeakerManagerService::GetOrCreateSpeakerManagerService();
+  MOZ_ASSERT(service);
+
+  service->ForceSpeaker(aEnable, mVisible);
   mForcespeaker = aEnable;
 }
 
 void
 SpeakerManager::DispatchSimpleEvent(const nsAString& aStr)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
   nsresult rv = CheckInnerWindowCorrectness();
@@ -187,18 +185,20 @@ SpeakerManager::HandleEvent(nsIDOMEvent*
   NS_ENSURE_TRUE(docshell, NS_ERROR_FAILURE);
   docshell->GetIsActive(&mVisible);
 
   // If an app that has called forcespeaker=true is switched
   // from the background to the foreground 'speakerforced'
   // switches to true in all apps. I.e. the app doesn't have to
   // call forcespeaker=true again when it comes into foreground.
   SpeakerManagerService *service =
-    SpeakerManagerService::GetSpeakerManagerService();
-  if (service && mVisible && mForcespeaker) {
+    SpeakerManagerService::GetOrCreateSpeakerManagerService();
+  MOZ_ASSERT(service);
+
+  if (mVisible && mForcespeaker) {
     service->ForceSpeaker(mForcespeaker, mVisible);
   }
   // If an application that has called forcespeaker=true, but no audio is
   // currently playing in the app itself, if application switch to
   // the background, we switch 'speakerforced' to false.
   if (!mVisible && mForcespeaker) {
     AudioChannelService* audioChannelService =
       AudioChannelService::GetAudioChannelService();
@@ -209,17 +209,17 @@ SpeakerManager::HandleEvent(nsIDOMEvent*
   return NS_OK;
 }
 
 void
 SpeakerManager::SetAudioChannelActive(bool isActive)
 {
   if (!isActive && !mVisible) {
     SpeakerManagerService *service =
-      SpeakerManagerService::GetSpeakerManagerService();
-    if (service) {
-      service->ForceSpeaker(false, mVisible);
-    }
+      SpeakerManagerService::GetOrCreateSpeakerManagerService();
+    MOZ_ASSERT(service);
+
+    service->ForceSpeaker(false, mVisible);
   }
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/speakermanager/SpeakerManagerService.cpp
+++ b/dom/speakermanager/SpeakerManagerService.cpp
@@ -21,34 +21,46 @@
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 StaticRefPtr<SpeakerManagerService> gSpeakerManagerService;
 
 // static
 SpeakerManagerService*
-SpeakerManagerService::GetSpeakerManagerService()
+SpeakerManagerService::GetOrCreateSpeakerManagerService()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (XRE_GetProcessType() != GeckoProcessType_Default) {
-    return SpeakerManagerServiceChild::GetSpeakerManagerService();
+    return SpeakerManagerServiceChild::GetOrCreateSpeakerManagerService();
   }
 
   // If we already exist, exit early
   if (gSpeakerManagerService) {
     return gSpeakerManagerService;
   }
 
   // Create new instance, register, return
   nsRefPtr<SpeakerManagerService> service = new SpeakerManagerService();
-  NS_ENSURE_TRUE(service, nullptr);
 
   gSpeakerManagerService = service;
+
+  return gSpeakerManagerService;
+}
+
+SpeakerManagerService*
+SpeakerManagerService::GetSpeakerManagerService()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (XRE_GetProcessType() != GeckoProcessType_Default) {
+    return SpeakerManagerServiceChild::GetSpeakerManagerService();
+  }
+
   return gSpeakerManagerService;
 }
 
 void
 SpeakerManagerService::Shutdown()
 {
   if (XRE_GetProcessType() != GeckoProcessType_Default) {
     return SpeakerManagerServiceChild::Shutdown();
--- a/dom/speakermanager/SpeakerManagerService.h
+++ b/dom/speakermanager/SpeakerManagerService.h
@@ -18,18 +18,25 @@
 namespace mozilla {
 namespace dom {
 
 class SpeakerManagerService : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
-
+  /*
+   * Return null or instance which has been created.
+   */
   static SpeakerManagerService* GetSpeakerManagerService();
+  /*
+   * Return SpeakerManagerService instance.
+   * If SpeakerManagerService is not exist, create and return new one.
+   */
+  static SpeakerManagerService* GetOrCreateSpeakerManagerService();
   virtual void ForceSpeaker(bool aEnable, bool aVisible);
   virtual bool GetSpeakerStatus();
   virtual void SetAudioChannelActive(bool aIsActive);
   // Called by child
   void ForceSpeaker(bool enable, uint64_t aChildid);
   // Register the SpeakerManager to service for notify the speakerforcedchange event
   void RegisterSpeakerManager(SpeakerManager* aSpeakerManager)
   {
--- a/dom/speakermanager/SpeakerManagerServiceChild.cpp
+++ b/dom/speakermanager/SpeakerManagerServiceChild.cpp
@@ -17,30 +17,39 @@
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 StaticRefPtr<SpeakerManagerServiceChild> gSpeakerManagerServiceChild;
 
 // static
 SpeakerManagerService*
-SpeakerManagerServiceChild::GetSpeakerManagerService()
+SpeakerManagerServiceChild::GetOrCreateSpeakerManagerService()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // If we already exist, exit early
   if (gSpeakerManagerServiceChild) {
     return gSpeakerManagerServiceChild;
   }
 
   // Create new instance, register, return
   nsRefPtr<SpeakerManagerServiceChild> service = new SpeakerManagerServiceChild();
-  NS_ENSURE_TRUE(service, nullptr);
 
   gSpeakerManagerServiceChild = service;
+
+  return gSpeakerManagerServiceChild;
+}
+
+// static
+SpeakerManagerService*
+SpeakerManagerServiceChild::GetSpeakerManagerService()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
   return gSpeakerManagerServiceChild;
 }
 
 void
 SpeakerManagerServiceChild::ForceSpeaker(bool aEnable, bool aVisible)
 {
   mVisible = aVisible;
   mOrgSpeakerStatus = aEnable;
--- a/dom/speakermanager/SpeakerManagerServiceChild.h
+++ b/dom/speakermanager/SpeakerManagerServiceChild.h
@@ -14,17 +14,25 @@
 namespace mozilla {
 namespace dom {
 /* This class is used to do the IPC to enable/disable speaker status
    Also handle the application speaker competition problem
 */
 class SpeakerManagerServiceChild : public SpeakerManagerService
 {
 public:
+  /*
+   * Return null or instance which has been created.
+   */
   static SpeakerManagerService* GetSpeakerManagerService();
+  /*
+   * Return SpeakerManagerServiceChild instance.
+   * If SpeakerManagerServiceChild is not exist, create and return new one.
+   */
+  static SpeakerManagerService* GetOrCreateSpeakerManagerService();
   static void Shutdown();
   virtual void ForceSpeaker(bool aEnable, bool aVisible) MOZ_OVERRIDE;
   virtual bool GetSpeakerStatus() MOZ_OVERRIDE;
   virtual void SetAudioChannelActive(bool aIsActive) MOZ_OVERRIDE;
   virtual void Notify() MOZ_OVERRIDE;
 protected:
   SpeakerManagerServiceChild();
   virtual ~SpeakerManagerServiceChild();