Bug 1060659 - SpeechGrammarList should both initialize SpeechRecognitionService and set a grammar on it. r=smaug
authorAndre Natal <anatal@gmail.com>
Wed, 01 Oct 2014 21:37:00 +0200
changeset 208918 8b8a64a58627d469bfcbfd9ef691effe68425bbe
parent 208917 b00ca413f85b32ef54a71063ddbf7ba3496f7a34
child 208919 094128a6d5a6aa4ebb128d5fbc013344986d567c
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssmaug
bugs1060659
milestone35.0a1
Bug 1060659 - SpeechGrammarList should both initialize SpeechRecognitionService and set a grammar on it. r=smaug
content/media/webspeech/recognition/SpeechGrammarList.cpp
content/media/webspeech/recognition/SpeechGrammarList.h
content/media/webspeech/recognition/SpeechRecognition.cpp
content/media/webspeech/recognition/SpeechRecognition.h
content/media/webspeech/recognition/nsISpeechRecognitionService.idl
content/media/webspeech/recognition/test/FakeSpeechRecognitionService.cpp
content/media/webspeech/recognition/test/FakeSpeechRecognitionService.h
dom/webidl/SpeechGrammarList.webidl
--- a/content/media/webspeech/recognition/SpeechGrammarList.cpp
+++ b/content/media/webspeech/recognition/SpeechGrammarList.cpp
@@ -3,43 +3,56 @@
 /* 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 "SpeechGrammarList.h"
 
 #include "mozilla/dom/SpeechGrammarListBinding.h"
 #include "mozilla/ErrorResult.h"
+#include "nsCOMPtr.h"
+#include "nsXPCOMStrings.h"
+#include "SpeechRecognition.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SpeechGrammarList, mParent)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(SpeechGrammarList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(SpeechGrammarList)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SpeechGrammarList)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-SpeechGrammarList::SpeechGrammarList(nsISupports* aParent)
+SpeechGrammarList::SpeechGrammarList(nsISupports* aParent, nsISpeechRecognitionService* aRecognitionService)
   : mParent(aParent)
 {
+  this->mRecognitionService = aRecognitionService;
   SetIsDOMBinding();
 }
 
 SpeechGrammarList::~SpeechGrammarList()
 {
 }
 
-SpeechGrammarList*
+already_AddRefed<SpeechGrammarList>
 SpeechGrammarList::Constructor(const GlobalObject& aGlobal,
                                ErrorResult& aRv)
 {
-  return new SpeechGrammarList(aGlobal.GetAsSupports());
+  nsCOMPtr<nsISpeechRecognitionService> recognitionService;
+  recognitionService = GetSpeechRecognitionService();
+  if (!recognitionService) {
+    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    return nullptr;
+  } else {
+    nsRefPtr<SpeechGrammarList> speechGrammarList =
+      new SpeechGrammarList(aGlobal.GetAsSupports(), recognitionService);
+    return speechGrammarList.forget();
+  }
 }
 
 JSObject*
 SpeechGrammarList::WrapObject(JSContext* aCx)
 {
   return SpeechGrammarListBinding::Wrap(aCx, this);
 }
 
@@ -71,17 +84,17 @@ SpeechGrammarList::AddFromURI(const nsAS
   return;
 }
 
 void
 SpeechGrammarList::AddFromString(const nsAString& aString,
                                  const Optional<float>& aWeight,
                                  ErrorResult& aRv)
 {
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+  mRecognitionService->ValidateAndSetGrammarList(this, nullptr);
   return;
 }
 
 already_AddRefed<SpeechGrammar>
 SpeechGrammarList::IndexedGetter(uint32_t aIndex, bool& aPresent,
                                  ErrorResult& aRv)
 {
   aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
--- a/content/media/webspeech/recognition/SpeechGrammarList.h
+++ b/content/media/webspeech/recognition/SpeechGrammarList.h
@@ -6,16 +6,17 @@
 
 #ifndef mozilla_dom_SpeechGrammarList_h
 #define mozilla_dom_SpeechGrammarList_h
 
 #include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
+#include "nsISpeechRecognitionService.h"
 
 struct JSContext;
 
 namespace mozilla {
 
 class ErrorResult;
 
 namespace dom {
@@ -23,38 +24,39 @@ namespace dom {
 class GlobalObject;
 class SpeechGrammar;
 template<typename> class Optional;
 
 class SpeechGrammarList MOZ_FINAL : public nsISupports,
                                     public nsWrapperCache
 {
 public:
-  explicit SpeechGrammarList(nsISupports* aParent);
+  explicit SpeechGrammarList(nsISupports* aParent, nsISpeechRecognitionService* aRecognitionService);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(SpeechGrammarList)
 
-  SpeechGrammarList* Constructor(const GlobalObject& aGlobal,
-                                 ErrorResult& aRv);
+  static already_AddRefed<SpeechGrammarList> Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
 
   nsISupports* GetParentObject() const;
 
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   uint32_t Length() const;
 
   already_AddRefed<SpeechGrammar> Item(uint32_t aIndex, ErrorResult& aRv);
 
   void AddFromURI(const nsAString& aSrc, const Optional<float>& aWeight, ErrorResult& aRv);
 
   void AddFromString(const nsAString& aString, const Optional<float>& aWeight, ErrorResult& aRv);
 
   already_AddRefed<SpeechGrammar> IndexedGetter(uint32_t aIndex, bool& aPresent, ErrorResult& aRv);
 
+  nsCOMPtr<nsISpeechRecognitionService> mRecognitionService;
+
 private:
   ~SpeechGrammarList();
 
   nsCOMPtr<nsISupports> mParent;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/media/webspeech/recognition/SpeechRecognition.cpp
+++ b/content/media/webspeech/recognition/SpeechRecognition.cpp
@@ -52,16 +52,46 @@ GetSpeechRecognitionLog()
 
   return sLog;
 }
 #define SR_LOG(...) PR_LOG(GetSpeechRecognitionLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
 #define SR_LOG(...)
 #endif
 
+already_AddRefed<nsISpeechRecognitionService>
+GetSpeechRecognitionService()
+{
+  nsAutoCString speechRecognitionServiceCID;
+
+  nsAdoptingCString prefValue =
+  Preferences::GetCString(PREFERENCE_DEFAULT_RECOGNITION_SERVICE);
+  nsAutoCString speechRecognitionService;
+
+  if (!prefValue.get() || prefValue.IsEmpty()) {
+    speechRecognitionService = DEFAULT_RECOGNITION_SERVICE;
+  } else {
+    speechRecognitionService = prefValue;
+  }
+
+  if (!SpeechRecognition::mTestConfig.mFakeRecognitionService){
+    speechRecognitionServiceCID =
+      NS_LITERAL_CSTRING(NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX) +
+      speechRecognitionService;
+  } else {
+    speechRecognitionServiceCID =
+      NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX "fake";
+  }
+
+  nsresult aRv;
+  nsCOMPtr<nsISpeechRecognitionService> recognitionService;
+  recognitionService = do_GetService(speechRecognitionServiceCID.get(), &aRv);
+  return recognitionService.forget();
+}
+
 NS_INTERFACE_MAP_BEGIN(SpeechRecognition)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(SpeechRecognition, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(SpeechRecognition, DOMEventTargetHelper)
 
 struct SpeechRecognition::TestConfig SpeechRecognition::mTestConfig;
@@ -323,43 +353,16 @@ SpeechRecognition::ProcessAudioSegment(A
     samples += iterator->GetDuration();
     iterator.Next();
   }
 
   mRecognitionService->ProcessAudioSegment(aSegment, aTrackRate);
   return samples;
 }
 
-void
-SpeechRecognition::GetRecognitionServiceCID(nsACString& aResultCID)
-{
-  if (mTestConfig.mFakeRecognitionService) {
-    aResultCID =
-      NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX "fake";
-
-    return;
-  }
-
-  nsAdoptingCString prefValue =
-    Preferences::GetCString(PREFERENCE_DEFAULT_RECOGNITION_SERVICE);
-
-  nsAutoCString speechRecognitionService;
-  if (!prefValue.get() || prefValue.IsEmpty()) {
-    speechRecognitionService = DEFAULT_RECOGNITION_SERVICE;
-  } else {
-    speechRecognitionService = prefValue;
-  }
-
-  aResultCID =
-    NS_LITERAL_CSTRING(NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX) +
-    speechRecognitionService;
-
-  return;
-}
-
 /****************************************************************************
  * FSM Transition functions
  *
  * If a transition function may cause a DOM event to be fired,
  * it may also be re-entered, since the event handler may cause the
  * event loop to spin and new SpeechEvents to be processed.
  *
  * Rules:
@@ -686,23 +689,20 @@ SpeechRecognition::SetServiceURI(const n
 void
 SpeechRecognition::Start(const Optional<NonNull<DOMMediaStream>>& aStream, ErrorResult& aRv)
 {
   if (mCurrentState != STATE_IDLE) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
-  nsAutoCString speechRecognitionServiceCID;
-  GetRecognitionServiceCID(speechRecognitionServiceCID);
+  mRecognitionService = GetSpeechRecognitionService();
+  NS_ENSURE_TRUE_VOID(mRecognitionService);
 
   nsresult rv;
-  mRecognitionService = do_GetService(speechRecognitionServiceCID.get(), &rv);
-  NS_ENSURE_SUCCESS_VOID(rv);
-
   rv = mRecognitionService->Initialize(this);
   NS_ENSURE_SUCCESS_VOID(rv);
 
   MediaStreamConstraints constraints;
   constraints.mAudio.SetAsBoolean() = true;
 
   if (aStream.WasPassed()) {
     StartRecording(&aStream.Value());
--- a/content/media/webspeech/recognition/SpeechRecognition.h
+++ b/content/media/webspeech/recognition/SpeechRecognition.h
@@ -48,16 +48,18 @@ class SpeechEvent;
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetSpeechRecognitionLog();
 #define SR_LOG(...) PR_LOG(GetSpeechRecognitionLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
 #define SR_LOG(...)
 #endif
 
+already_AddRefed<nsISpeechRecognitionService> GetSpeechRecognitionService();
+
 class SpeechRecognition MOZ_FINAL : public DOMEventTargetHelper,
                                     public nsIObserver,
                                     public SupportsWeakPtr<SpeechRecognition>
 {
 public:
   MOZ_DECLARE_REFCOUNTED_TYPENAME(SpeechRecognition)
   explicit SpeechRecognition(nsPIDOMWindow* aOwnerWindow);
 
@@ -229,18 +231,16 @@ private:
   void DoNothing(SpeechEvent* aEvent);
   void AbortSilently(SpeechEvent* aEvent);
   void AbortError(SpeechEvent* aEvent);
 
   nsRefPtr<DOMMediaStream> mDOMStream;
   nsRefPtr<SpeechStreamListener> mSpeechListener;
   nsCOMPtr<nsISpeechRecognitionService> mRecognitionService;
 
-  void GetRecognitionServiceCID(nsACString& aResultCID);
-
   FSMState mCurrentState;
 
   Endpointer mEndpointer;
   uint32_t mEstimationSamples;
 
   uint32_t mAudioSamplesPerChunk;
 
   // buffer holds one chunk of mAudioSamplesPerChunk
--- a/content/media/webspeech/recognition/nsISpeechRecognitionService.idl
+++ b/content/media/webspeech/recognition/nsISpeechRecognitionService.idl
@@ -2,24 +2,42 @@
 /* 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 "nsISupports.idl"
 
 %{C++
 #include "mozilla/WeakPtr.h"
+
+namespace mozilla {
+class AudioSegment;
+namespace dom {
+class SpeechRecognition;
+class SpeechRecognitionResultList;
+class SpeechGrammarList;
+class SpeechGrammar;
+}
+}
 %}
 
 native SpeechRecognitionWeakPtr(mozilla::WeakPtr<mozilla::dom::SpeechRecognition>);
 [ptr] native AudioSegmentPtr(mozilla::AudioSegment);
+[ptr] native SpeechGrammarListPtr(mozilla::dom::SpeechGrammarList);
+[ptr] native SpeechGrammarPtr(mozilla::dom::SpeechGrammar);
+
+[uuid(374583f0-4507-11e4-a183-164230d1df67)]
+interface nsISpeechGrammarCompilationCallback : nsISupports {
+    void grammarCompilationEnd(in SpeechGrammarPtr grammarObject, in boolean success);
+};
 
 [uuid(857f3fa2-a980-4d3e-a959-a2f53af74232)]
 interface nsISpeechRecognitionService : nsISupports {
     void initialize(in SpeechRecognitionWeakPtr aSpeechRecognition);
     void processAudioSegment(in AudioSegmentPtr aAudioSegment, in long aSampleRate);
+    void validateAndSetGrammarList(in SpeechGrammarListPtr aSpeechGramarList, in nsISpeechGrammarCompilationCallback aCallback);
     void soundEnd();
     void abort();
 };
 
 %{C++
 #define NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX "@mozilla.org/webspeech/service;1?name="
 %}
--- a/content/media/webspeech/recognition/test/FakeSpeechRecognitionService.cpp
+++ b/content/media/webspeech/recognition/test/FakeSpeechRecognitionService.cpp
@@ -47,16 +47,22 @@ FakeSpeechRecognitionService::ProcessAud
 
 NS_IMETHODIMP
 FakeSpeechRecognitionService::SoundEnd()
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
+FakeSpeechRecognitionService::ValidateAndSetGrammarList(mozilla::dom::SpeechGrammarList*, nsISpeechGrammarCompilationCallback*)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 FakeSpeechRecognitionService::Abort()
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FakeSpeechRecognitionService::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
 {
--- a/content/media/webspeech/recognition/test/FakeSpeechRecognitionService.h
+++ b/content/media/webspeech/recognition/test/FakeSpeechRecognitionService.h
@@ -4,27 +4,16 @@
  * 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_FakeSpeechRecognitionService_h
 #define mozilla_dom_FakeSpeechRecognitionService_h
 
 #include "nsCOMPtr.h"
 #include "nsIObserver.h"
-
-// nsISpeechRecognitionService needs these declarations
-namespace mozilla {
-  class AudioSegment;
-
-  namespace dom {
-    class SpeechRecognition;
-    class SpeechRecognitionResultList;
-  }
-}
-
 #include "nsISpeechRecognitionService.h"
 
 #define NS_FAKE_SPEECH_RECOGNITION_SERVICE_CID \
   {0x48c345e7, 0x9929, 0x4f9a, {0xa5, 0x63, 0xf4, 0x78, 0x22, 0x2d, 0xab, 0xcd}};
 
 namespace mozilla {
 
 class FakeSpeechRecognitionService : public nsISpeechRecognitionService,
--- a/dom/webidl/SpeechGrammarList.webidl
+++ b/dom/webidl/SpeechGrammarList.webidl
@@ -5,17 +5,17 @@
  *
  * The origin of this IDL file is
  * http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-[Pref="media.webspeech.recognition.enable"]
+[Constructor, Pref="media.webspeech.recognition.enable"]
 interface SpeechGrammarList {
     readonly attribute unsigned long length;
     [Throws]
     getter SpeechGrammar item(unsigned long index);
     [Throws]
     void addFromURI(DOMString src, optional float weight);
     [Throws]
     void addFromString(DOMString string, optional float weight);