Bug 1337077 - Remove sync state transfer of SpeechSynthesis. r=smaug
authorEitan Isaacson <eitan@monotonous.org>
Thu, 23 Feb 2017 10:18:21 -0500
changeset 344535 1ef637e0cf2048d5e99e6a01a03c59f186f0e6cf
parent 344534 aa4f4a00727d2879c9a949382211c52caf0d5f79
child 344536 3901e2bf125afa316c01f90f2fc159ebf5c0b345
push id31413
push usercbook@mozilla.com
push dateFri, 24 Feb 2017 10:18:46 +0000
treeherdermozilla-central@c7935d540027 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1337077
milestone54.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 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 =