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 222202 ac8948dcc1efab68f39b19e6ebc15d5085a2e7e1
parent 222201 463fb288e8a99aace0889ec09896c5c543e8bc8a
child 222203 9de0463fb1c721a3423a5275ed60db8b3a16f802
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1054219
milestone34.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 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();