1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_SPEECH_SPEECH_INPUT_EXTENSION_MANAGER_H_
6 #define CHROME_BROWSER_SPEECH_SPEECH_INPUT_EXTENSION_MANAGER_H_
10 #include "base/callback_forward.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/synchronization/lock.h"
14 #include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
15 #include "content/public/browser/notification_observer.h"
16 #include "content/public/browser/speech_recognition_event_listener.h"
25 class NotificationRegistrar
;
26 struct SpeechRecognitionError
;
27 class SpeechRecognitionManager
;
28 struct SpeechRecognitionResult
;
32 class URLRequestContextGetter
;
35 // Used for API tests.
36 class SpeechInputExtensionInterface
{
38 SpeechInputExtensionInterface();
39 virtual ~SpeechInputExtensionInterface();
41 // Called from the IO thread.
42 virtual void StartRecording(
43 content::SpeechRecognitionEventListener
* listener
,
44 net::URLRequestContextGetter
* context_getter
,
45 const std::string
& extension_name
,
46 const std::string
& language
,
47 const std::string
& grammar
,
48 bool filter_profanities
,
49 int render_process_id
) = 0;
51 virtual void StopRecording(bool recognition_failed
) = 0;
52 virtual bool HasAudioInputDevices() = 0;
53 virtual bool IsCapturingAudio() = 0;
55 // Called from the UI thread.
56 virtual bool HasValidRecognizer() = 0;
59 // Manages the speech input requests and responses from the extensions
60 // associated to the given profile.
61 class SpeechInputExtensionManager
62 : public base::RefCountedThreadSafe
<SpeechInputExtensionManager
>,
63 public content::SpeechRecognitionEventListener
,
64 public content::NotificationObserver
,
65 private SpeechInputExtensionInterface
{
72 kShutdown
// Internal sink state when the profile is destroyed on shutdown.
75 // Structure containing the details of the speech input failed notification.
76 struct ExtensionError
{
77 std::string extension_id_
;
80 ExtensionError(const std::string
& extension_id
, const std::string
& error
)
81 : extension_id_(extension_id
), error_(error
) {}
84 typedef base::Callback
<void(bool)> IsRecordingCallback
;
86 // Should not be used directly. Managed by a ProfileKeyedServiceFactory.
87 explicit SpeechInputExtensionManager(Profile
* profile
);
89 // Returns the corresponding manager for the given profile, creating
90 // a new one if required.
91 static SpeechInputExtensionManager
* GetForProfile(Profile
* profile
);
93 // Request to start speech recognition for the provided extension.
94 bool Start(const std::string
& extension_id
,
95 const std::string
& language
,
96 const std::string
& grammar
,
97 bool filter_profanities
,
100 // Request to stop an ongoing speech recognition.
101 bool Stop(const std::string
& extension_id
, std::string
* error
);
103 // Retrieve the actual state of the API manager.
104 State
state() const { return state_
; }
106 // Check if recording is currently ongoing in Chrome.
107 // This method is expected to be called from the UI thread.
108 // The callback will be invoked with the result on this same thread.
109 void IsRecording(const IsRecordingCallback
& callback
);
111 // Called by internal ProfileKeyedService class.
112 void ShutdownOnUIThread();
114 // Methods from content::NotificationObserver.
115 virtual void Observe(int type
,
116 const content::NotificationSource
& source
,
117 const content::NotificationDetails
& details
) OVERRIDE
;
119 // Methods from SpeechRecognitionEventListener.
120 virtual void OnRecognitionStart(int session_id
) OVERRIDE
;
121 virtual void OnAudioStart(int session_id
) OVERRIDE
;
122 virtual void OnEnvironmentEstimationComplete(int session_id
) OVERRIDE
;
123 virtual void OnSoundStart(int session_id
) OVERRIDE
;
124 virtual void OnSoundEnd(int session_id
) OVERRIDE
;
125 virtual void OnAudioEnd(int session_id
) OVERRIDE
;
126 virtual void OnRecognitionResults(
127 int session_id
, const content::SpeechRecognitionResults
& result
) OVERRIDE
;
128 virtual void OnRecognitionError(
129 int session_id
, const content::SpeechRecognitionError
& error
) OVERRIDE
;
130 virtual void OnAudioLevelsChange(int session_id
, float volume
,
131 float noise_volume
) OVERRIDE
;
132 virtual void OnRecognitionEnd(int session_id
) OVERRIDE
;
134 // Methods for API testing.
135 void SetSpeechInputExtensionInterface(
136 SpeechInputExtensionInterface
* speech_interface
);
138 SpeechInputExtensionInterface
* GetSpeechInputExtensionInterface();
141 // SpeechInputExtensionInterface methods:
142 virtual bool IsCapturingAudio() OVERRIDE
;
143 virtual bool HasAudioInputDevices() OVERRIDE
;
144 virtual bool HasValidRecognizer() OVERRIDE
;
145 virtual void StartRecording(
146 content::SpeechRecognitionEventListener
* listener
,
147 net::URLRequestContextGetter
* context_getter
,
148 const std::string
& extension_name
,
149 const std::string
& language
,
150 const std::string
& grammar
,
151 bool filter_profanities
,
152 int render_process_id
) OVERRIDE
;
154 virtual void StopRecording(bool recognition_failed
) OVERRIDE
;
157 void StartOnIOThread(
158 scoped_refptr
<net::URLRequestContextGetter
> context_getter
,
159 const std::string
& extension_name
,
160 const std::string
& language
,
161 const std::string
& grammar
,
162 bool filter_profanities
,
163 int render_process_id
);
164 void ForceStopOnIOThread();
165 void IsRecordingOnIOThread(const IsRecordingCallback
& callback
);
167 void SetRecognitionResultsOnUIThread(
168 const content::SpeechRecognitionResults
& result
,
169 const std::string
& extension_id
);
170 void DidStartReceivingAudioOnUIThread();
171 void StopSucceededOnUIThread();
172 void IsRecordingOnUIThread(const IsRecordingCallback
& callback
, bool result
);
174 void DispatchError(const std::string
& error
, bool dispatch_event
);
175 void DispatchEventToExtension(const std::string
& extension_id
,
176 const std::string
& event
,
177 scoped_ptr
<base::ListValue
> event_args
);
178 void ExtensionUnloaded(const std::string
& extension_id
);
180 void ResetToIdleState();
182 void AbortAllSessionsOnIOThread();
184 int GetRenderProcessIDForExtension(const std::string
& extension_id
) const;
186 virtual ~SpeechInputExtensionManager();
188 friend class base::RefCountedThreadSafe
<SpeechInputExtensionManager
>;
190 // Lock used to allow exclusive access to the state variable and methods that
191 // either read or write on it. This is required since the speech code
192 // operates in the IO thread while the extension code uses the UI thread.
193 base::Lock state_lock_
;
195 // Used in the UI thread but also its raw value as notification
196 // source in the IO thread, guarded by the state lock and value.
199 // Used in both threads, guarded by the state lock.
201 std::string extension_id_in_use_
;
203 // Used in the UI thread.
204 scoped_ptr
<content::NotificationRegistrar
> registrar_
;
205 SpeechInputExtensionInterface
* speech_interface_
;
207 // Used in the IO thread.
208 bool is_recognition_in_progress_
;
209 int speech_recognition_session_id_
;
212 namespace extensions
{
214 class SpeechInputAPI
: public ProfileKeyedAPI
{
216 explicit SpeechInputAPI(Profile
* profile
);
217 virtual ~SpeechInputAPI();
219 // Convenience method to get the SpeechInputExtensionAPI for a profile.
220 static SpeechInputAPI
* GetForProfile(Profile
* profile
);
222 // ProfileKeyedAPI implementation.
223 static ProfileKeyedAPIFactory
<SpeechInputAPI
>* GetFactoryInstance();
225 SpeechInputExtensionManager
* manager() const { return manager_
.get(); }
228 friend class ProfileKeyedAPIFactory
<SpeechInputAPI
>;
230 // ProfileKeyedAPI implementation.
231 static const char* service_name() {
232 return "SpeechInputAPI";
234 static const bool kServiceIsNULLWhileTesting
= true;
235 static const bool kServiceIsCreatedWithProfile
= true;
236 // Methods from ProfileKeyedService.
237 virtual void Shutdown() OVERRIDE
;
239 scoped_refptr
<SpeechInputExtensionManager
> manager_
;
242 } // namespace extensions
244 #endif // CHROME_BROWSER_SPEECH_SPEECH_INPUT_EXTENSION_MANAGER_H_