Bug 1337077 - Remove sync state transfer of SpeechSynthesis. r=smaug
authorEitan Isaacson <eitan@monotonous.org>
Thu, 23 Feb 2017 10:18:21 -0500
changeset 373562 1ef637e0cf2048d5e99e6a01a03c59f186f0e6cf
parent 373561 aa4f4a00727d2879c9a949382211c52caf0d5f79
child 373563 3901e2bf125afa316c01f90f2fc159ebf5c0b345
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1337077
milestone54.0a1
Bug 1337077 - Remove sync state transfer of SpeechSynthesis. r=smaug MozReview-Commit-ID: LMjZOEjeg8Q
dom/ipc/ContentParent.cpp
dom/media/webspeech/synth/ipc/PSpeechSynthesis.ipdl
dom/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
dom/media/webspeech/synth/ipc/SpeechSynthesisChild.h
dom/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp
dom/media/webspeech/synth/ipc/SpeechSynthesisParent.h
dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
dom/media/webspeech/synth/nsSynthVoiceRegistry.h
ipc/ipdl/sync-messages.ini
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3234,16 +3234,19 @@ ContentParent::DeallocPSpeechSynthesisPa
   return false;
 #endif
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvPSpeechSynthesisConstructor(PSpeechSynthesisParent* aActor)
 {
 #ifdef MOZ_WEBSPEECH
+  if (!static_cast<SpeechSynthesisParent*>(aActor)->SendInit()) {
+    return IPC_FAIL_NO_REASON(this);
+  }
   return IPC_OK();
 #else
   return IPC_FAIL_NO_REASON(this);
 #endif
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvStartVisitedQuery(const URIParams& aURI)
--- a/dom/media/webspeech/synth/ipc/PSpeechSynthesis.ipdl
+++ b/dom/media/webspeech/synth/ipc/PSpeechSynthesis.ipdl
@@ -30,20 +30,20 @@ child:
     async VoiceRemoved(nsString aUri);
 
     async SetDefaultVoice(nsString aUri, bool aIsDefault);
 
     async IsSpeakingChanged(bool aIsSpeaking);
 
     async NotifyVoicesChanged();
 
+    async InitialVoicesAndState(RemoteVoice[] aVoices, nsString[] aDefaults,
+                                bool aIsSpeaking);
+
 parent:
     async __delete__();
 
     async PSpeechSynthesisRequest(nsString aText, nsString aUri, nsString aLang,
                                   float aVolume, float aRate, float aPitch);
-
-    sync ReadVoicesAndState() returns (RemoteVoice[] aVoices,
-                                       nsString[] aDefaults, bool aIsSpeaking);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
+++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
@@ -14,16 +14,25 @@ SpeechSynthesisChild::SpeechSynthesisChi
 }
 
 SpeechSynthesisChild::~SpeechSynthesisChild()
 {
   MOZ_COUNT_DTOR(SpeechSynthesisChild);
 }
 
 mozilla::ipc::IPCResult
+SpeechSynthesisChild::RecvInitialVoicesAndState(nsTArray<RemoteVoice>&& aVoices,
+                                                nsTArray<nsString>&& aDefaults,
+                                                const bool& aIsSpeaking)
+{
+  nsSynthVoiceRegistry::RecvInitialVoicesAndState(aVoices, aDefaults, aIsSpeaking);
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
 SpeechSynthesisChild::RecvVoiceAdded(const RemoteVoice& aVoice)
 {
   nsSynthVoiceRegistry::RecvAddVoice(aVoice);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 SpeechSynthesisChild::RecvVoiceRemoved(const nsString& aUri)
--- a/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.h
+++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.h
@@ -17,16 +17,20 @@ class nsSynthVoiceRegistry;
 class SpeechSynthesisRequestChild;
 class SpeechTaskChild;
 
 class SpeechSynthesisChild : public PSpeechSynthesisChild
 {
   friend class nsSynthVoiceRegistry;
 
 public:
+  mozilla::ipc::IPCResult RecvInitialVoicesAndState(nsTArray<RemoteVoice>&& aVoices,
+                                                    nsTArray<nsString>&& aDefaults,
+                                                    const bool& aIsSpeaking) override;
+
   mozilla::ipc::IPCResult RecvVoiceAdded(const RemoteVoice& aVoice) override;
 
   mozilla::ipc::IPCResult RecvVoiceRemoved(const nsString& aUri) override;
 
   mozilla::ipc::IPCResult RecvSetDefaultVoice(const nsString& aUri, const bool& aIsDefault) override;
 
   mozilla::ipc::IPCResult RecvIsSpeakingChanged(const bool& aIsSpeaking) override;
 
--- a/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp
+++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp
@@ -19,24 +19,20 @@ SpeechSynthesisParent::~SpeechSynthesisP
 }
 
 void
 SpeechSynthesisParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   // Implement me! Bug 1005141
 }
 
-mozilla::ipc::IPCResult
-SpeechSynthesisParent::RecvReadVoicesAndState(InfallibleTArray<RemoteVoice>* aVoices,
-                                              InfallibleTArray<nsString>* aDefaults,
-                                              bool* aIsSpeaking)
+bool
+SpeechSynthesisParent::SendInit()
 {
-  nsSynthVoiceRegistry::GetInstance()->SendVoicesAndState(aVoices, aDefaults,
-                                                          aIsSpeaking);
-  return IPC_OK();
+  return nsSynthVoiceRegistry::GetInstance()->SendInitialVoicesAndState(this);
 }
 
 PSpeechSynthesisRequestParent*
 SpeechSynthesisParent::AllocPSpeechSynthesisRequestParent(const nsString& aText,
                                                           const nsString& aLang,
                                                           const nsString& aUri,
                                                           const float& aVolume,
                                                           const float& aRate,
--- a/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.h
+++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.h
@@ -19,19 +19,17 @@ class SpeechSynthesisRequestParent;
 class SpeechSynthesisParent : public PSpeechSynthesisParent
 {
   friend class ContentParent;
   friend class SpeechSynthesisRequestParent;
 
 public:
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
-  mozilla::ipc::IPCResult RecvReadVoicesAndState(InfallibleTArray<RemoteVoice>* aVoices,
-                                                 InfallibleTArray<nsString>* aDefaults,
-                                                 bool* aIsSpeaking) override;
+  bool SendInit();
 
 protected:
   SpeechSynthesisParent();
   virtual ~SpeechSynthesisParent();
   PSpeechSynthesisRequestParent* AllocPSpeechSynthesisRequestParent(const nsString& aText,
                                                                     const nsString& aLang,
                                                                     const nsString& aUri,
                                                                     const float& aVolume,
--- a/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
+++ b/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
@@ -144,35 +144,16 @@ nsSynthVoiceRegistry::nsSynthVoiceRegist
   : mSpeechSynthChild(nullptr)
   , mUseGlobalQueue(false)
   , mIsSpeaking(false)
 {
   if (XRE_IsContentProcess()) {
 
     mSpeechSynthChild = new SpeechSynthesisChild();
     ContentChild::GetSingleton()->SendPSpeechSynthesisConstructor(mSpeechSynthChild);
-
-    InfallibleTArray<RemoteVoice> voices;
-    InfallibleTArray<nsString> defaults;
-    bool isSpeaking;
-
-    mSpeechSynthChild->SendReadVoicesAndState(&voices, &defaults, &isSpeaking);
-
-    for (uint32_t i = 0; i < voices.Length(); ++i) {
-      RemoteVoice voice = voices[i];
-      AddVoiceImpl(nullptr, voice.voiceURI(),
-                   voice.name(), voice.lang(),
-                   voice.localService(), voice.queued());
-    }
-
-    for (uint32_t i = 0; i < defaults.Length(); ++i) {
-      SetDefaultVoice(defaults[i], true);
-    }
-
-    mIsSpeaking = isSpeaking;
   }
 }
 
 nsSynthVoiceRegistry::~nsSynthVoiceRegistry()
 {
   LOG(LogLevel::Debug, ("~nsSynthVoiceRegistry"));
 
   // mSpeechSynthChild's lifecycle is managed by the Content protocol.
@@ -209,33 +190,63 @@ nsSynthVoiceRegistry::GetInstanceForServ
 void
 nsSynthVoiceRegistry::Shutdown()
 {
   LOG(LogLevel::Debug, ("[%s] nsSynthVoiceRegistry::Shutdown()",
                         (XRE_IsContentProcess()) ? "Content" : "Default"));
   gSynthVoiceRegistry = nullptr;
 }
 
-void
-nsSynthVoiceRegistry::SendVoicesAndState(InfallibleTArray<RemoteVoice>* aVoices,
-                                         InfallibleTArray<nsString>* aDefaults,
-                                         bool* aIsSpeaking)
+bool
+nsSynthVoiceRegistry::SendInitialVoicesAndState(SpeechSynthesisParent* aParent)
 {
+  MOZ_ASSERT(XRE_IsParentProcess());
+
+  InfallibleTArray<RemoteVoice> voices;
+  InfallibleTArray<nsString> defaults;
+
   for (uint32_t i=0; i < mVoices.Length(); ++i) {
     RefPtr<VoiceData> voice = mVoices[i];
 
-    aVoices->AppendElement(RemoteVoice(voice->mUri, voice->mName, voice->mLang,
-                                       voice->mIsLocal, voice->mIsQueued));
+    voices.AppendElement(RemoteVoice(voice->mUri, voice->mName, voice->mLang,
+                                     voice->mIsLocal, voice->mIsQueued));
   }
 
   for (uint32_t i=0; i < mDefaultVoices.Length(); ++i) {
-    aDefaults->AppendElement(mDefaultVoices[i]->mUri);
+    defaults.AppendElement(mDefaultVoices[i]->mUri);
   }
 
-  *aIsSpeaking = IsSpeaking();
+  return aParent->SendInitialVoicesAndState(voices, defaults, IsSpeaking());
+}
+
+void
+nsSynthVoiceRegistry::RecvInitialVoicesAndState(const nsTArray<RemoteVoice>& aVoices,
+                                                const nsTArray<nsString>& aDefaults,
+                                                const bool& aIsSpeaking)
+{
+  // We really should have a local instance since this is a directed response to
+  // an Init() call.
+  MOZ_ASSERT(gSynthVoiceRegistry);
+
+  for (uint32_t i = 0; i < aVoices.Length(); ++i) {
+    RemoteVoice voice = aVoices[i];
+    gSynthVoiceRegistry->AddVoiceImpl(nullptr, voice.voiceURI(),
+                                      voice.name(), voice.lang(),
+                                      voice.localService(), voice.queued());
+  }
+
+  for (uint32_t i = 0; i < aDefaults.Length(); ++i) {
+    gSynthVoiceRegistry->SetDefaultVoice(aDefaults[i], true);
+  }
+
+  gSynthVoiceRegistry->mIsSpeaking = aIsSpeaking;
+
+  if (aVoices.Length()) {
+    gSynthVoiceRegistry->NotifyVoicesChanged();
+  }
 }
 
 void
 nsSynthVoiceRegistry::RecvRemoveVoice(const nsAString& aUri)
 {
   // If we dont have a local instance of the registry yet, we will recieve current
   // voices at contruction time.
   if(!gSynthVoiceRegistry) {
--- a/dom/media/webspeech/synth/nsSynthVoiceRegistry.h
+++ b/dom/media/webspeech/synth/nsSynthVoiceRegistry.h
@@ -15,16 +15,17 @@
 class nsISpeechService;
 
 namespace mozilla {
 namespace dom {
 
 class RemoteVoice;
 class SpeechSynthesisUtterance;
 class SpeechSynthesisChild;
+class SpeechSynthesisParent;
 class nsSpeechTask;
 class VoiceData;
 class GlobalQueueItem;
 
 class nsSynthVoiceRegistry final : public nsISynthVoiceRegistry
 {
 public:
   NS_DECL_ISUPPORTS
@@ -34,32 +35,34 @@ public:
 
   already_AddRefed<nsSpeechTask> SpeakUtterance(SpeechSynthesisUtterance& aUtterance,
                                                 const nsAString& aDocLang);
 
   void Speak(const nsAString& aText, const nsAString& aLang,
              const nsAString& aUri, const float& aVolume,  const float& aRate,
              const float& aPitch, nsSpeechTask* aTask);
 
-  void SendVoicesAndState(InfallibleTArray<RemoteVoice>* aVoices,
-                          InfallibleTArray<nsString>* aDefaults,
-                          bool* aIsSpeaking);
+  bool SendInitialVoicesAndState(SpeechSynthesisParent* aParent);
 
   void SpeakNext();
 
   void ResumeQueue();
 
   bool IsSpeaking();
 
   void SetIsSpeaking(bool aIsSpeaking);
 
   static nsSynthVoiceRegistry* GetInstance();
 
   static already_AddRefed<nsSynthVoiceRegistry> GetInstanceForService();
 
+  static void RecvInitialVoicesAndState(const nsTArray<RemoteVoice>& aVoices,
+                                        const nsTArray<nsString>& aDefaults,
+                                        const bool& aIsSpeaking);
+
   static void RecvRemoveVoice(const nsAString& aUri);
 
   static void RecvAddVoice(const RemoteVoice& aVoice);
 
   static void RecvSetDefaultVoice(const nsAString& aUri, bool aIsDefault);
 
   static void RecvIsSpeakingChanged(bool aIsSpeaking);
 
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -852,18 +852,16 @@ description =
 [PGMPVideoDecoder::NeedShmem]
 description =
 [PGMPVideoEncoder::NeedShmem]
 description =
 [PVideoDecoderManager::PVideoDecoder]
 description =
 [PVideoDecoderManager::Readback]
 description =
-[PSpeechSynthesis::ReadVoicesAndState]
-description =
 [PBrowserStream::NPN_RequestRead]
 description =
 [PStorage::Preload]
 description =
 [PRemoteSpellcheckEngine::Check]
 description =
 [PRemoteSpellcheckEngine::CheckAndSuggest]
 description =