Bug 902145 - Ignore all speech events while aborting. r=smaug
authorGuilherme Gonçalves <ggp@mozilla.com>
Tue, 10 Sep 2013 13:12:54 -0400
changeset 146360 86594e931122e6f3cd6f7555938df44ce5b8177e
parent 146359 27785ee9e9e0b7b5a7807e9ed82ed7f382bccd56
child 146361 bfb6901822f6c80b56634e79db50239769b43c08
push id2574
push userryanvm@gmail.com
push dateTue, 10 Sep 2013 17:13:03 +0000
treeherderfx-team@bfb6901822f6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs902145
milestone26.0a1
Bug 902145 - Ignore all speech events while aborting. r=smaug
content/media/webspeech/recognition/SpeechRecognition.cpp
content/media/webspeech/recognition/SpeechRecognition.h
--- a/content/media/webspeech/recognition/SpeechRecognition.cpp
+++ b/content/media/webspeech/recognition/SpeechRecognition.cpp
@@ -133,16 +133,21 @@ SpeechRecognition::GetParentObject() con
 
 void
 SpeechRecognition::ProcessEvent(SpeechEvent* aEvent)
 {
   SR_LOG("Processing %s, current state is %s",
          GetName(aEvent),
          GetName(mCurrentState));
 
+  if (mAborted && aEvent->mType != EVENT_ABORT) {
+    // ignore all events while aborting
+    return;
+  }
+
   Transition(aEvent);
 }
 
 void
 SpeechRecognition::Transition(SpeechEvent* aEvent)
 {
   switch (mCurrentState) {
     case STATE_IDLE:
@@ -292,19 +297,16 @@ SpeechRecognition::Transition(SpeechEven
         case EVENT_START:
         case EVENT_RECOGNITIONSERVICE_INTERMEDIATE_RESULT:
           SR_LOG("STATE_WAITING_FOR_RESULT: Unhandled aEvent %s", GetName(aEvent));
           MOZ_CRASH();
         case EVENT_COUNT:
           MOZ_CRASH("Invalid event EVENT_COUNT");
       }
       break;
-    case STATE_ABORTING:
-      DoNothing(aEvent);
-      break;
     case STATE_COUNT:
       MOZ_CRASH("Invalid state STATE_COUNT");
   }
 
   return;
 }
 
 /*
@@ -372,16 +374,17 @@ SpeechRecognition::GetRecognitionService
 void
 SpeechRecognition::Reset()
 {
   SetState(STATE_IDLE);
   mRecognitionService = nullptr;
   mEstimationSamples = 0;
   mBufferedSamples = 0;
   mSpeechDetectionTimer->Cancel();
+  mAborted = false;
 }
 
 void
 SpeechRecognition::ResetAndEnd()
 {
   Reset();
   DispatchTrustedEvent(NS_LITERAL_STRING("end"));
 }
@@ -485,19 +488,16 @@ SpeechRecognition::DoNothing(SpeechEvent
 {
 }
 
 void
 SpeechRecognition::AbortSilently(SpeechEvent* aEvent)
 {
   bool stopRecording = StateBetween(STATE_ESTIMATING, STATE_RECOGNIZING);
 
-  // prevent reentrancy from DOM events
-  SetState(STATE_ABORTING);
-
   if (mRecognitionService) {
     mRecognitionService->Abort();
   }
 
   if (stopRecording) {
     StopRecording();
   }
 
@@ -729,16 +729,21 @@ SpeechRecognition::Stop()
 {
   nsRefPtr<SpeechEvent> event = new SpeechEvent(this, EVENT_STOP);
   NS_DispatchToMainThread(event);
 }
 
 void
 SpeechRecognition::Abort()
 {
+  if (mAborted) {
+    return;
+  }
+
+  mAborted = true;
   nsRefPtr<SpeechEvent> event = new SpeechEvent(this, EVENT_ABORT);
   NS_DispatchToMainThread(event);
 }
 
 void
 SpeechRecognition::DispatchError(EventType aErrorType,
                                  SpeechRecognitionErrorCode aErrorCode,
                                  const nsAString& aMessage)
@@ -886,17 +891,16 @@ SpeechRecognition::GetName(FSMState aId)
 {
   static const char* names[] = {
     "STATE_IDLE",
     "STATE_STARTING",
     "STATE_ESTIMATING",
     "STATE_WAITING_FOR_SPEECH",
     "STATE_RECOGNIZING",
     "STATE_WAITING_FOR_RESULT",
-    "STATE_ABORTING"
   };
 
   MOZ_ASSERT(aId < STATE_COUNT);
   MOZ_ASSERT(ArrayLength(names) == STATE_COUNT);
   return names[aId];
 }
 
 const char*
--- a/content/media/webspeech/recognition/SpeechRecognition.h
+++ b/content/media/webspeech/recognition/SpeechRecognition.h
@@ -165,17 +165,16 @@ public:
 private:
   enum FSMState {
     STATE_IDLE,
     STATE_STARTING,
     STATE_ESTIMATING,
     STATE_WAITING_FOR_SPEECH,
     STATE_RECOGNIZING,
     STATE_WAITING_FOR_RESULT,
-    STATE_ABORTING,
     STATE_COUNT
   };
 
   void SetState(FSMState state);
   bool StateBetween(FSMState begin, FSMState end);
 
   class GetUserMediaStreamOptions : public nsIMediaStreamOptions
   {
@@ -255,16 +254,17 @@ private:
   uint32_t mAudioSamplesPerChunk;
 
   // buffer holds one chunk of mAudioSamplesPerChunk
   // samples before feeding it to mEndpointer
   nsRefPtr<SharedBuffer> mAudioSamplesBuffer;
   uint32_t mBufferedSamples;
 
   nsCOMPtr<nsITimer> mSpeechDetectionTimer;
+  bool mAborted;
 
   void ProcessTestEventRequest(nsISupports* aSubject, const nsAString& aEventName);
 
   const char* GetName(FSMState aId);
   const char* GetName(SpeechEvent* aId);
 };
 
 class SpeechEvent : public nsRunnable