diff options
Diffstat (limited to 'dom/media/webspeech/synth/ipc')
-rw-r--r-- | dom/media/webspeech/synth/ipc/PSpeechSynthesis.ipdl | 49 | ||||
-rw-r--r-- | dom/media/webspeech/synth/ipc/PSpeechSynthesisRequest.ipdl | 46 | ||||
-rw-r--r-- | dom/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp | 213 | ||||
-rw-r--r-- | dom/media/webspeech/synth/ipc/SpeechSynthesisChild.h | 106 | ||||
-rw-r--r-- | dom/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp | 234 | ||||
-rw-r--r-- | dom/media/webspeech/synth/ipc/SpeechSynthesisParent.h | 108 |
6 files changed, 756 insertions, 0 deletions
diff --git a/dom/media/webspeech/synth/ipc/PSpeechSynthesis.ipdl b/dom/media/webspeech/synth/ipc/PSpeechSynthesis.ipdl new file mode 100644 index 000000000..7b66034e4 --- /dev/null +++ b/dom/media/webspeech/synth/ipc/PSpeechSynthesis.ipdl @@ -0,0 +1,49 @@ +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include protocol PContent; +include protocol PSpeechSynthesisRequest; + +namespace mozilla { +namespace dom { + +struct RemoteVoice { + nsString voiceURI; + nsString name; + nsString lang; + bool localService; + bool queued; +}; + +sync protocol PSpeechSynthesis +{ + manager PContent; + manages PSpeechSynthesisRequest; + +child: + + async VoiceAdded(RemoteVoice aVoice); + + async VoiceRemoved(nsString aUri); + + async SetDefaultVoice(nsString aUri, bool aIsDefault); + + async IsSpeakingChanged(bool aIsSpeaking); + + async NotifyVoicesChanged(); + +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 diff --git a/dom/media/webspeech/synth/ipc/PSpeechSynthesisRequest.ipdl b/dom/media/webspeech/synth/ipc/PSpeechSynthesisRequest.ipdl new file mode 100644 index 000000000..9ffea29f5 --- /dev/null +++ b/dom/media/webspeech/synth/ipc/PSpeechSynthesisRequest.ipdl @@ -0,0 +1,46 @@ +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include protocol PSpeechSynthesis; + +namespace mozilla { +namespace dom { + +async protocol PSpeechSynthesisRequest +{ + manager PSpeechSynthesis; + + parent: + + async __delete__(); + + async Pause(); + + async Resume(); + + async Cancel(); + + async ForceEnd(); + + async SetAudioOutputVolume(float aVolume); + + child: + + async OnEnd(bool aIsError, float aElapsedTime, uint32_t aCharIndex); + + async OnStart(nsString aUri); + + async OnPause(float aElapsedTime, uint32_t aCharIndex); + + async OnResume(float aElapsedTime, uint32_t aCharIndex); + + async OnBoundary(nsString aName, float aElapsedTime, uint32_t aCharIndex); + + async OnMark(nsString aName, float aElapsedTime, uint32_t aCharIndex); +}; + +} // namespace dom +} // namespace mozilla diff --git a/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp b/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp new file mode 100644 index 000000000..d1cb8bf0e --- /dev/null +++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp @@ -0,0 +1,213 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "SpeechSynthesisChild.h" +#include "nsSynthVoiceRegistry.h" + +namespace mozilla { +namespace dom { + +SpeechSynthesisChild::SpeechSynthesisChild() +{ + MOZ_COUNT_CTOR(SpeechSynthesisChild); +} + +SpeechSynthesisChild::~SpeechSynthesisChild() +{ + MOZ_COUNT_DTOR(SpeechSynthesisChild); +} + +bool +SpeechSynthesisChild::RecvVoiceAdded(const RemoteVoice& aVoice) +{ + nsSynthVoiceRegistry::RecvAddVoice(aVoice); + return true; +} + +bool +SpeechSynthesisChild::RecvVoiceRemoved(const nsString& aUri) +{ + nsSynthVoiceRegistry::RecvRemoveVoice(aUri); + return true; +} + +bool +SpeechSynthesisChild::RecvSetDefaultVoice(const nsString& aUri, + const bool& aIsDefault) +{ + nsSynthVoiceRegistry::RecvSetDefaultVoice(aUri, aIsDefault); + return true; +} + +bool +SpeechSynthesisChild::RecvIsSpeakingChanged(const bool& aIsSpeaking) +{ + nsSynthVoiceRegistry::RecvIsSpeakingChanged(aIsSpeaking); + return true; +} + +bool +SpeechSynthesisChild::RecvNotifyVoicesChanged() +{ + nsSynthVoiceRegistry::RecvNotifyVoicesChanged(); + return true; +} + +PSpeechSynthesisRequestChild* +SpeechSynthesisChild::AllocPSpeechSynthesisRequestChild(const nsString& aText, + const nsString& aLang, + const nsString& aUri, + const float& aVolume, + const float& aRate, + const float& aPitch) +{ + MOZ_CRASH("Caller is supposed to manually construct a request!"); +} + +bool +SpeechSynthesisChild::DeallocPSpeechSynthesisRequestChild(PSpeechSynthesisRequestChild* aActor) +{ + delete aActor; + return true; +} + +// SpeechSynthesisRequestChild + +SpeechSynthesisRequestChild::SpeechSynthesisRequestChild(SpeechTaskChild* aTask) + : mTask(aTask) +{ + mTask->mActor = this; + MOZ_COUNT_CTOR(SpeechSynthesisRequestChild); +} + +SpeechSynthesisRequestChild::~SpeechSynthesisRequestChild() +{ + MOZ_COUNT_DTOR(SpeechSynthesisRequestChild); +} + +bool +SpeechSynthesisRequestChild::RecvOnStart(const nsString& aUri) +{ + mTask->DispatchStartImpl(aUri); + return true; +} + +bool +SpeechSynthesisRequestChild::RecvOnEnd(const bool& aIsError, + const float& aElapsedTime, + const uint32_t& aCharIndex) +{ + SpeechSynthesisRequestChild* actor = mTask->mActor; + mTask->mActor = nullptr; + + if (aIsError) { + mTask->DispatchErrorImpl(aElapsedTime, aCharIndex); + } else { + mTask->DispatchEndImpl(aElapsedTime, aCharIndex); + } + + actor->Send__delete__(actor); + + return true; +} + +bool +SpeechSynthesisRequestChild::RecvOnPause(const float& aElapsedTime, + const uint32_t& aCharIndex) +{ + mTask->DispatchPauseImpl(aElapsedTime, aCharIndex); + return true; +} + +bool +SpeechSynthesisRequestChild::RecvOnResume(const float& aElapsedTime, + const uint32_t& aCharIndex) +{ + mTask->DispatchResumeImpl(aElapsedTime, aCharIndex); + return true; +} + +bool +SpeechSynthesisRequestChild::RecvOnBoundary(const nsString& aName, + const float& aElapsedTime, + const uint32_t& aCharIndex) +{ + mTask->DispatchBoundaryImpl(aName, aElapsedTime, aCharIndex); + return true; +} + +bool +SpeechSynthesisRequestChild::RecvOnMark(const nsString& aName, + const float& aElapsedTime, + const uint32_t& aCharIndex) +{ + mTask->DispatchMarkImpl(aName, aElapsedTime, aCharIndex); + return true; +} + +// SpeechTaskChild + +SpeechTaskChild::SpeechTaskChild(SpeechSynthesisUtterance* aUtterance) + : nsSpeechTask(aUtterance) +{ +} + +NS_IMETHODIMP +SpeechTaskChild::Setup(nsISpeechTaskCallback* aCallback, + uint32_t aChannels, uint32_t aRate, uint8_t argc) +{ + MOZ_CRASH("Should never be called from child"); +} + +NS_IMETHODIMP +SpeechTaskChild::SendAudio(JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aLandmarks, + JSContext* aCx) +{ + MOZ_CRASH("Should never be called from child"); +} + +NS_IMETHODIMP +SpeechTaskChild::SendAudioNative(int16_t* aData, uint32_t aDataLen) +{ + MOZ_CRASH("Should never be called from child"); +} + +void +SpeechTaskChild::Pause() +{ + MOZ_ASSERT(mActor); + mActor->SendPause(); +} + +void +SpeechTaskChild::Resume() +{ + MOZ_ASSERT(mActor); + mActor->SendResume(); +} + +void +SpeechTaskChild::Cancel() +{ + MOZ_ASSERT(mActor); + mActor->SendCancel(); +} + +void +SpeechTaskChild::ForceEnd() +{ + MOZ_ASSERT(mActor); + mActor->SendForceEnd(); +} + +void +SpeechTaskChild::SetAudioOutputVolume(float aVolume) +{ + if (mActor) { + mActor->SendSetAudioOutputVolume(aVolume); + } +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.h b/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.h new file mode 100644 index 000000000..01e9ffbdd --- /dev/null +++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.h @@ -0,0 +1,106 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_SpeechSynthesisChild_h +#define mozilla_dom_SpeechSynthesisChild_h + +#include "mozilla/Attributes.h" +#include "mozilla/dom/PSpeechSynthesisChild.h" +#include "mozilla/dom/PSpeechSynthesisRequestChild.h" +#include "nsSpeechTask.h" + +namespace mozilla { +namespace dom { + +class nsSynthVoiceRegistry; +class SpeechSynthesisRequestChild; +class SpeechTaskChild; + +class SpeechSynthesisChild : public PSpeechSynthesisChild +{ + friend class nsSynthVoiceRegistry; + +public: + bool RecvVoiceAdded(const RemoteVoice& aVoice) override; + + bool RecvVoiceRemoved(const nsString& aUri) override; + + bool RecvSetDefaultVoice(const nsString& aUri, const bool& aIsDefault) override; + + bool RecvIsSpeakingChanged(const bool& aIsSpeaking) override; + + bool RecvNotifyVoicesChanged() override; + +protected: + SpeechSynthesisChild(); + virtual ~SpeechSynthesisChild(); + + PSpeechSynthesisRequestChild* AllocPSpeechSynthesisRequestChild(const nsString& aLang, + const nsString& aUri, + const nsString& aText, + const float& aVolume, + const float& aPitch, + const float& aRate) override; + bool DeallocPSpeechSynthesisRequestChild(PSpeechSynthesisRequestChild* aActor) override; +}; + +class SpeechSynthesisRequestChild : public PSpeechSynthesisRequestChild +{ +public: + explicit SpeechSynthesisRequestChild(SpeechTaskChild* aTask); + virtual ~SpeechSynthesisRequestChild(); + +protected: + bool RecvOnStart(const nsString& aUri) override; + + bool RecvOnEnd(const bool& aIsError, + const float& aElapsedTime, + const uint32_t& aCharIndex) override; + + bool RecvOnPause(const float& aElapsedTime, const uint32_t& aCharIndex) override; + + bool RecvOnResume(const float& aElapsedTime, const uint32_t& aCharIndex) override; + + bool RecvOnBoundary(const nsString& aName, const float& aElapsedTime, + const uint32_t& aCharIndex) override; + + bool RecvOnMark(const nsString& aName, const float& aElapsedTime, + const uint32_t& aCharIndex) override; + + RefPtr<SpeechTaskChild> mTask; +}; + +class SpeechTaskChild : public nsSpeechTask +{ + friend class SpeechSynthesisRequestChild; +public: + + explicit SpeechTaskChild(SpeechSynthesisUtterance* aUtterance); + + NS_IMETHOD Setup(nsISpeechTaskCallback* aCallback, + uint32_t aChannels, uint32_t aRate, uint8_t argc) override; + + NS_IMETHOD SendAudio(JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aLandmarks, + JSContext* aCx) override; + + NS_IMETHOD SendAudioNative(int16_t* aData, uint32_t aDataLen) override; + + void Pause() override; + + void Resume() override; + + void Cancel() override; + + void ForceEnd() override; + + void SetAudioOutputVolume(float aVolume) override; + +private: + SpeechSynthesisRequestChild* mActor; +}; + +} // namespace dom +} // namespace mozilla + +#endif diff --git a/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp b/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp new file mode 100644 index 000000000..8dc70e872 --- /dev/null +++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp @@ -0,0 +1,234 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "SpeechSynthesisParent.h" +#include "nsSynthVoiceRegistry.h" + +namespace mozilla { +namespace dom { + +SpeechSynthesisParent::SpeechSynthesisParent() +{ + MOZ_COUNT_CTOR(SpeechSynthesisParent); +} + +SpeechSynthesisParent::~SpeechSynthesisParent() +{ + MOZ_COUNT_DTOR(SpeechSynthesisParent); +} + +void +SpeechSynthesisParent::ActorDestroy(ActorDestroyReason aWhy) +{ + // Implement me! Bug 1005141 +} + +bool +SpeechSynthesisParent::RecvReadVoicesAndState(InfallibleTArray<RemoteVoice>* aVoices, + InfallibleTArray<nsString>* aDefaults, + bool* aIsSpeaking) +{ + nsSynthVoiceRegistry::GetInstance()->SendVoicesAndState(aVoices, aDefaults, + aIsSpeaking); + return true; +} + +PSpeechSynthesisRequestParent* +SpeechSynthesisParent::AllocPSpeechSynthesisRequestParent(const nsString& aText, + const nsString& aLang, + const nsString& aUri, + const float& aVolume, + const float& aRate, + const float& aPitch) +{ + RefPtr<SpeechTaskParent> task = new SpeechTaskParent(aVolume, aText); + SpeechSynthesisRequestParent* actor = new SpeechSynthesisRequestParent(task); + return actor; +} + +bool +SpeechSynthesisParent::DeallocPSpeechSynthesisRequestParent(PSpeechSynthesisRequestParent* aActor) +{ + delete aActor; + return true; +} + +bool +SpeechSynthesisParent::RecvPSpeechSynthesisRequestConstructor(PSpeechSynthesisRequestParent* aActor, + const nsString& aText, + const nsString& aLang, + const nsString& aUri, + const float& aVolume, + const float& aRate, + const float& aPitch) +{ + MOZ_ASSERT(aActor); + SpeechSynthesisRequestParent* actor = + static_cast<SpeechSynthesisRequestParent*>(aActor); + nsSynthVoiceRegistry::GetInstance()->Speak(aText, aLang, aUri, aVolume, aRate, + aPitch, actor->mTask); + return true; +} + +// SpeechSynthesisRequestParent + +SpeechSynthesisRequestParent::SpeechSynthesisRequestParent(SpeechTaskParent* aTask) + : mTask(aTask) +{ + mTask->mActor = this; + MOZ_COUNT_CTOR(SpeechSynthesisRequestParent); +} + +SpeechSynthesisRequestParent::~SpeechSynthesisRequestParent() +{ + if (mTask) { + mTask->mActor = nullptr; + // If we still have a task, cancel it. + mTask->Cancel(); + } + MOZ_COUNT_DTOR(SpeechSynthesisRequestParent); +} + +void +SpeechSynthesisRequestParent::ActorDestroy(ActorDestroyReason aWhy) +{ + // Implement me! Bug 1005141 +} + +bool +SpeechSynthesisRequestParent::RecvPause() +{ + MOZ_ASSERT(mTask); + mTask->Pause(); + return true; +} + +bool +SpeechSynthesisRequestParent::Recv__delete__() +{ + MOZ_ASSERT(mTask); + mTask->mActor = nullptr; + mTask = nullptr; + return true; +} + +bool +SpeechSynthesisRequestParent::RecvResume() +{ + MOZ_ASSERT(mTask); + mTask->Resume(); + return true; +} + +bool +SpeechSynthesisRequestParent::RecvCancel() +{ + MOZ_ASSERT(mTask); + mTask->Cancel(); + return true; +} + +bool +SpeechSynthesisRequestParent::RecvForceEnd() +{ + MOZ_ASSERT(mTask); + mTask->ForceEnd(); + return true; +} + +bool +SpeechSynthesisRequestParent::RecvSetAudioOutputVolume(const float& aVolume) +{ + MOZ_ASSERT(mTask); + mTask->SetAudioOutputVolume(aVolume); + return true; +} + +// SpeechTaskParent + +nsresult +SpeechTaskParent::DispatchStartImpl(const nsAString& aUri) +{ + MOZ_ASSERT(mActor); + if(NS_WARN_IF(!(mActor->SendOnStart(nsString(aUri))))) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult +SpeechTaskParent::DispatchEndImpl(float aElapsedTime, uint32_t aCharIndex) +{ + if (!mActor) { + // Child is already gone. + return NS_OK; + } + + if(NS_WARN_IF(!(mActor->SendOnEnd(false, aElapsedTime, aCharIndex)))) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult +SpeechTaskParent::DispatchPauseImpl(float aElapsedTime, uint32_t aCharIndex) +{ + MOZ_ASSERT(mActor); + if(NS_WARN_IF(!(mActor->SendOnPause(aElapsedTime, aCharIndex)))) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult +SpeechTaskParent::DispatchResumeImpl(float aElapsedTime, uint32_t aCharIndex) +{ + MOZ_ASSERT(mActor); + if(NS_WARN_IF(!(mActor->SendOnResume(aElapsedTime, aCharIndex)))) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult +SpeechTaskParent::DispatchErrorImpl(float aElapsedTime, uint32_t aCharIndex) +{ + MOZ_ASSERT(mActor); + if(NS_WARN_IF(!(mActor->SendOnEnd(true, aElapsedTime, aCharIndex)))) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult +SpeechTaskParent::DispatchBoundaryImpl(const nsAString& aName, + float aElapsedTime, uint32_t aCharIndex) +{ + MOZ_ASSERT(mActor); + if(NS_WARN_IF(!(mActor->SendOnBoundary(nsString(aName), aElapsedTime, aCharIndex)))) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult +SpeechTaskParent::DispatchMarkImpl(const nsAString& aName, + float aElapsedTime, uint32_t aCharIndex) +{ + MOZ_ASSERT(mActor); + if(NS_WARN_IF(!(mActor->SendOnMark(nsString(aName), aElapsedTime, aCharIndex)))) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.h b/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.h new file mode 100644 index 000000000..2edd7e28e --- /dev/null +++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.h @@ -0,0 +1,108 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_SpeechSynthesisParent_h +#define mozilla_dom_SpeechSynthesisParent_h + +#include "mozilla/dom/PSpeechSynthesisParent.h" +#include "mozilla/dom/PSpeechSynthesisRequestParent.h" +#include "nsSpeechTask.h" + +namespace mozilla { +namespace dom { + +class ContentParent; +class SpeechTaskParent; +class SpeechSynthesisRequestParent; + +class SpeechSynthesisParent : public PSpeechSynthesisParent +{ + friend class ContentParent; + friend class SpeechSynthesisRequestParent; + +public: + void ActorDestroy(ActorDestroyReason aWhy) override; + + bool RecvReadVoicesAndState(InfallibleTArray<RemoteVoice>* aVoices, + InfallibleTArray<nsString>* aDefaults, + bool* aIsSpeaking) override; + +protected: + SpeechSynthesisParent(); + virtual ~SpeechSynthesisParent(); + PSpeechSynthesisRequestParent* AllocPSpeechSynthesisRequestParent(const nsString& aText, + const nsString& aLang, + const nsString& aUri, + const float& aVolume, + const float& aRate, + const float& aPitch) + override; + + bool DeallocPSpeechSynthesisRequestParent(PSpeechSynthesisRequestParent* aActor) override; + + bool RecvPSpeechSynthesisRequestConstructor(PSpeechSynthesisRequestParent* aActor, + const nsString& aText, + const nsString& aLang, + const nsString& aUri, + const float& aVolume, + const float& aRate, + const float& aPitch) override; +}; + +class SpeechSynthesisRequestParent : public PSpeechSynthesisRequestParent +{ +public: + explicit SpeechSynthesisRequestParent(SpeechTaskParent* aTask); + virtual ~SpeechSynthesisRequestParent(); + + RefPtr<SpeechTaskParent> mTask; + +protected: + + void ActorDestroy(ActorDestroyReason aWhy) override; + + bool RecvPause() override; + + bool RecvResume() override; + + bool RecvCancel() override; + + bool RecvForceEnd() override; + + bool RecvSetAudioOutputVolume(const float& aVolume) override; + + bool Recv__delete__() override; +}; + +class SpeechTaskParent : public nsSpeechTask +{ + friend class SpeechSynthesisRequestParent; +public: + SpeechTaskParent(float aVolume, const nsAString& aUtterance) + : nsSpeechTask(aVolume, aUtterance) {} + + nsresult DispatchStartImpl(const nsAString& aUri); + + nsresult DispatchEndImpl(float aElapsedTime, uint32_t aCharIndex); + + nsresult DispatchPauseImpl(float aElapsedTime, uint32_t aCharIndex); + + nsresult DispatchResumeImpl(float aElapsedTime, uint32_t aCharIndex); + + nsresult DispatchErrorImpl(float aElapsedTime, uint32_t aCharIndex); + + nsresult DispatchBoundaryImpl(const nsAString& aName, + float aElapsedTime, uint32_t aCharIndex); + + nsresult DispatchMarkImpl(const nsAString& aName, + float aElapsedTime, uint32_t aCharIndex); + +private: + SpeechSynthesisRequestParent* mActor; +}; + +} // namespace dom +} // namespace mozilla + +#endif |