Bug 1178738 - Update nsISpeechTask.DispatchError to provide error code. r?smaug draft
authorEitan Isaacson <eitan@monotonous.org>
Wed, 18 May 2016 10:07:48 -0700
changeset 374072 4c028764b8d8403367d650a845a01f4695fa4ee9
parent 373935 111970c738234569c8c180319155327316335deb
child 374073 c9d7f153a8234534bae6394701689f40fb08772f
push id19917
push userbmo:eitan@monotonous.org
push dateWed, 01 Jun 2016 19:05:35 +0000
reviewerssmaug
bugs1178738
milestone49.0a1
Bug 1178738 - Update nsISpeechTask.DispatchError to provide error code. r?smaug MozReview-Commit-ID: DcOcexjYfje
dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.mm
dom/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
dom/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp
dom/media/webspeech/synth/ipc/SpeechSynthesisParent.h
dom/media/webspeech/synth/nsISpeechService.idl
dom/media/webspeech/synth/nsSpeechTask.cpp
dom/media/webspeech/synth/nsSpeechTask.h
dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
dom/media/webspeech/synth/test/nsFakeSynthServices.cpp
--- a/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.mm
+++ b/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerService.mm
@@ -6,16 +6,17 @@
 
 #include "nsISupports.h"
 #include "nsServiceManagerUtils.h"
 #include "nsObjCExceptions.h"
 #include "nsCocoaUtils.h"
 #include "nsThreadUtils.h"
 #include "mozilla/dom/nsSynthVoiceRegistry.h"
 #include "mozilla/dom/nsSpeechTask.h"
+#include "mozilla/dom/SpeechSynthesisErrorEvent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Assertions.h"
 #include "OSXSpeechSynthesizerService.h"
 
 #import <Cocoa/Cocoa.h>
 
 // We can escape the default delimiters ("[[" and "]]") by temporarily
 // changing the delimiters just before they appear, and changing them back
@@ -148,17 +149,20 @@ SpeechTaskCallback::OnWillSpeakWord(uint
 }
 
 void
 SpeechTaskCallback::OnError(uint32_t aIndex)
 {
   if (!mTask) {
     return;
   }
-  mTask->DispatchError(GetTimeDurationFromStart(), aIndex);
+
+  // XXX: Provide more specific error messages
+  mTask->DispatchError(GetTimeDurationFromStart(), aIndex,
+    uint32_t(dom::SpeechSynthesisErrorCode::Synthesis_failed));
 }
 
 void
 SpeechTaskCallback::OnDidFinishSpeaking()
 {
   mTask->DispatchEnd(GetTimeDurationFromStart(), mCurrentIndex);
   // no longer needed
   [mSpeechSynthesizer setDelegate:nil];
--- a/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
+++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisChild.cpp
@@ -97,17 +97,17 @@ 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);
+    mTask->DispatchErrorImpl(aElapsedTime, aCharIndex, 0);
   } else {
     mTask->DispatchEndImpl(aElapsedTime, aCharIndex);
   }
 
   actor->Send__delete__(actor);
 
   return true;
 }
--- a/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp
+++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp
@@ -191,17 +191,17 @@ SpeechTaskParent::DispatchResumeImpl(flo
   if(NS_WARN_IF(!(mActor->SendOnResume(aElapsedTime, aCharIndex)))) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 nsresult
-SpeechTaskParent::DispatchErrorImpl(float aElapsedTime, uint32_t aCharIndex)
+SpeechTaskParent::DispatchErrorImpl(float aElapsedTime, uint32_t aCharIndex, uint32_t aError)
 {
   MOZ_ASSERT(mActor);
   if(NS_WARN_IF(!(mActor->SendOnEnd(true, aElapsedTime, aCharIndex)))) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
--- a/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.h
+++ b/dom/media/webspeech/synth/ipc/SpeechSynthesisParent.h
@@ -85,17 +85,17 @@ public:
   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 DispatchErrorImpl(float aElapsedTime, uint32_t aCharIndex, uint32_t aError);
 
   nsresult DispatchBoundaryImpl(const nsAString& aName,
                                 float aElapsedTime, uint32_t aCharIndex);
 
   nsresult DispatchMarkImpl(const nsAString& aName,
                             float aElapsedTime, uint32_t aCharIndex);
 
 private:
--- a/dom/media/webspeech/synth/nsISpeechService.idl
+++ b/dom/media/webspeech/synth/nsISpeechService.idl
@@ -37,17 +37,17 @@ interface nsISpeechTaskCallback : nsISup
   void onVolumeChanged(in float aVolume);
 };
 
 
 /**
  * A task is associated with a single utterance. It is provided by the browser
  * to the service in the speak() method.
  */
-[scriptable, builtinclass, uuid(ad59949c-2437-4b35-8eeb-d760caab75c5)]
+[scriptable, builtinclass, uuid(6a918df5-4821-40bf-be28-a7abccaee15a)]
 interface nsISpeechTask : nsISupports
 {
   /**
    * Prepare browser for speech.
    *
    * @param aCallback callback object for mid-speech operations.
    * @param aChannels number of audio channels. Only required
    *                    in direct audio services
@@ -99,18 +99,20 @@ interface nsISpeechTask : nsISupports
    */
   void dispatchResume(in float aElapsedTime, in unsigned long aCharIndex);
 
   /**
    * Dispatch error event.
    *
    * @param aElapsedTime time in seconds since speech has started.
    * @param aCharIndex   offset of spoken characters.
+   * @param aError       error code as detailed in the enum in
+   *                       SpeechSynthesisErrorEvent.webidl
    */
-  void dispatchError(in float aElapsedTime, in unsigned long aCharIndex);
+  void dispatchError(in float aElapsedTime, in unsigned long aCharIndex, in unsigned long aError);
 
   /**
    * Dispatch boundary event.
    *
    * @param aName        name of boundary, 'word' or 'sentence'
    * @param aElapsedTime time in seconds since speech has started.
    * @param aCharIndex   offset of spoken characters.
    */
--- a/dom/media/webspeech/synth/nsSpeechTask.cpp
+++ b/dom/media/webspeech/synth/nsSpeechTask.cpp
@@ -499,34 +499,34 @@ nsSpeechTask::DispatchResumeImpl(float a
                                              aCharIndex, aElapsedTime,
                                              EmptyString());
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSpeechTask::DispatchError(float aElapsedTime, uint32_t aCharIndex)
+nsSpeechTask::DispatchError(float aElapsedTime, uint32_t aCharIndex, uint32_t aError)
 {
   LOG(LogLevel::Debug, ("nsSpeechTask::DispatchError"));
 
   if (!mIndirectAudio) {
     NS_WARNING("Can't call DispatchError() from a direct audio speech service");
     return NS_ERROR_FAILURE;
   }
 
   if (!mPreCanceled) {
     nsSynthVoiceRegistry::GetInstance()->SpeakNext();
   }
 
-  return DispatchErrorImpl(aElapsedTime, aCharIndex);
+  return DispatchErrorImpl(aElapsedTime, aCharIndex, aError);
 }
 
 nsresult
-nsSpeechTask::DispatchErrorImpl(float aElapsedTime, uint32_t aCharIndex)
+nsSpeechTask::DispatchErrorImpl(float aElapsedTime, uint32_t aCharIndex, uint32_t aError)
 {
   MOZ_ASSERT(mUtterance);
   if(NS_WARN_IF(mUtterance->mState == SpeechSynthesisUtterance::STATE_ENDED)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   if (mSpeechSynthesis) {
     mSpeechSynthesis->OnEnd(this);
--- a/dom/media/webspeech/synth/nsSpeechTask.h
+++ b/dom/media/webspeech/synth/nsSpeechTask.h
@@ -74,17 +74,17 @@ protected:
   virtual nsresult DispatchStartImpl(const nsAString& aUri);
 
   virtual nsresult DispatchEndImpl(float aElapsedTime, uint32_t aCharIndex);
 
   virtual nsresult DispatchPauseImpl(float aElapsedTime, uint32_t aCharIndex);
 
   virtual nsresult DispatchResumeImpl(float aElapsedTime, uint32_t aCharIndex);
 
-  virtual nsresult DispatchErrorImpl(float aElapsedTime, uint32_t aCharIndex);
+  virtual nsresult DispatchErrorImpl(float aElapsedTime, uint32_t aCharIndex, uint32_t aError);
 
   virtual nsresult DispatchBoundaryImpl(const nsAString& aName,
                                         float aElapsedTime,
                                         uint32_t aCharIndex);
 
   virtual nsresult DispatchMarkImpl(const nsAString& aName,
                                     float aElapsedTime, uint32_t aCharIndex);
 
--- a/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
+++ b/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
@@ -15,16 +15,17 @@
 #include "nsSynthVoiceRegistry.h"
 #include "nsSpeechTask.h"
 #include "AudioChannelService.h"
 
 #include "nsString.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
+#include "mozilla/dom/SpeechSynthesisErrorEvent.h"
 #include "mozilla/unused.h"
 
 #include "SpeechSynthesisChild.h"
 #include "SpeechSynthesisParent.h"
 
 #undef LOG
 extern mozilla::LogModule* GetSpeechSynthLog();
 #define LOG(type, msg) MOZ_LOG(GetSpeechSynthLog(), type, msg)
@@ -699,17 +700,18 @@ nsSynthVoiceRegistry::Speak(const nsAStr
                             nsSpeechTask* aTask)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
 
   VoiceData* voice = FindBestMatch(aUri, aLang);
 
   if (!voice) {
     NS_WARNING("No voices found.");
-    aTask->DispatchError(0, 0);
+    aTask->DispatchError(0, 0,
+      uint32_t(SpeechSynthesisErrorCode::Voice_unavailable));
     return;
   }
 
   aTask->SetChosenVoiceURI(voice->mUri);
 
   if (mUseGlobalQueue || MediaPrefs::WebSpeechForceGlobal()) {
     LOG(LogLevel::Debug,
         ("nsSynthVoiceRegistry::Speak queueing text='%s' lang='%s' uri='%s' rate=%f pitch=%f",
@@ -820,16 +822,17 @@ nsSynthVoiceRegistry::SpeakImpl(VoiceDat
     aTask->InitIndirectAudio();
   } else {
     aTask->InitDirectAudio();
   }
 
   if (NS_FAILED(aVoice->mService->Speak(aText, aVoice->mUri, aVolume, aRate,
                                         aPitch, aTask))) {
     if (serviceType == nsISpeechService::SERVICETYPE_INDIRECT_AUDIO) {
-      aTask->DispatchError(0, 0);
+      aTask->DispatchError(
+        0, 0, uint32_t(SpeechSynthesisErrorCode::Synthesis_failed));
     }
     // XXX When using direct audio, no way to dispatch error
   }
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/webspeech/synth/test/nsFakeSynthServices.cpp
+++ b/dom/media/webspeech/synth/test/nsFakeSynthServices.cpp
@@ -8,16 +8,17 @@
 #include "nsFakeSynthServices.h"
 #include "nsPrintfCString.h"
 #include "nsIWeakReferenceUtils.h"
 #include "SharedBuffer.h"
 #include "nsISimpleEnumerator.h"
 
 #include "mozilla/dom/nsSynthVoiceRegistry.h"
 #include "mozilla/dom/nsSpeechTask.h"
+#include "mozilla/dom/SpeechSynthesisErrorEvent.h"
 
 #include "nsThreadUtils.h"
 #include "prenv.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/DebugOnly.h"
 
 #define CHANNELS 1
 #define SAMPLERATE 1600
@@ -245,17 +246,19 @@ FakeIndirectAudioSynth::Speak(const nsAS
   public:
     DispatchError(nsISpeechTask* aTask, const nsAString& aText) :
       mTask(aTask), mText(aText)
     {
     }
 
     NS_IMETHOD Run() override
     {
-      mTask->DispatchError(mText.Length()/2, mText.Length());
+      mTask->DispatchError(
+        mText.Length()/2, mText.Length(),
+        uint32_t(SpeechSynthesisErrorCode::Synthesis_failed));
 
       return NS_OK;
     }
 
   private:
     nsCOMPtr<nsISpeechTask> mTask;
     nsString mText;
   };