OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "content/browser/speech/speech_recognition_dispatcher_host.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/command_line.h" | |
9 #include "base/lazy_instance.h" | |
10 #include "content/browser/speech/speech_recognition_manager_impl.h" | |
11 #include "content/common/speech_recognition_messages.h" | |
12 #include "content/public/browser/speech_recognition_preferences.h" | |
13 #include "content/public/browser/speech_recognition_session_config.h" | |
14 #include "content/public/browser/speech_recognition_session_context.h" | |
15 #include "content/public/common/content_switches.h" | |
16 | |
17 using content::BrowserThread; | |
18 using content::SpeechRecognitionSessionConfig; | |
19 using content::SpeechRecognitionSessionContext; | |
20 | |
21 namespace speech { | |
22 SpeechRecognitionManagerImpl* | |
23 SpeechRecognitionDispatcherHost::manager_for_tests_; | |
24 | |
25 void SpeechRecognitionDispatcherHost::set_manager( | |
26 SpeechRecognitionManagerImpl* manager) { | |
27 manager_for_tests_ = manager; | |
28 } | |
29 | |
30 SpeechRecognitionDispatcherHost::SpeechRecognitionDispatcherHost( | |
31 int render_process_id, | |
32 net::URLRequestContextGetter* context_getter, | |
33 content::SpeechRecognitionPreferences* recognition_preferences) | |
34 : render_process_id_(render_process_id), | |
35 may_have_pending_requests_(false), | |
36 context_getter_(context_getter), | |
37 recognition_preferences_(recognition_preferences) { | |
38 // This is initialized by Browser. Do not add any non-trivial | |
hans
2012/05/14 14:04:52
not sure if "by Browser" makes sense.. everything
| |
39 // initialization here, instead do it lazily when required (e.g. see the | |
40 // method |manager()|) or add an Init() method. | |
41 } | |
42 | |
43 SpeechRecognitionDispatcherHost::~SpeechRecognitionDispatcherHost() { | |
44 // If the renderer crashed for some reason or if we didn't receive a proper | |
45 // Cancel/Stop call for an existing session, cancel such active sessions now. | |
46 // We first check if this dispatcher received any speech IPC request so that | |
47 // we don't end up creating the speech input manager for web pages which don't | |
48 // use speech input. | |
49 // TODO(primiano) depending on how CL1.10 will end up, this might not be | |
50 // needed anymore as the manager might be created anyway. | |
51 if (may_have_pending_requests_) | |
52 manager()->AbortAllSessionsForListener(this); | |
53 } | |
54 | |
55 SpeechRecognitionManagerImpl* SpeechRecognitionDispatcherHost::manager() { | |
56 if (manager_for_tests_) | |
57 return manager_for_tests_; | |
58 | |
59 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
60 if (command_line.HasSwitch(switches::kEnableScriptedSpeech)) | |
61 return SpeechRecognitionManagerImpl::GetInstance(); | |
62 | |
63 return NULL; | |
64 } | |
65 | |
66 bool SpeechRecognitionDispatcherHost::OnMessageReceived( | |
67 const IPC::Message& message, bool* message_was_ok) { | |
68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
69 bool handled = true; | |
70 IPC_BEGIN_MESSAGE_MAP_EX(SpeechRecognitionDispatcherHost, message, | |
71 *message_was_ok) | |
72 IPC_MESSAGE_HANDLER(SpeechRecognitionHostMsg_StartRequest, | |
73 OnStartRequest) | |
74 IPC_MESSAGE_HANDLER(SpeechRecognitionHostMsg_AbortRequest, | |
75 OnAbortRequest) | |
76 IPC_MESSAGE_HANDLER(SpeechRecognitionHostMsg_StopCaptureRequest, | |
77 OnStopCaptureRequest) | |
78 IPC_MESSAGE_UNHANDLED(handled = false) | |
79 IPC_END_MESSAGE_MAP() | |
80 if (handled) | |
81 may_have_pending_requests_ = true; | |
82 return handled; | |
83 } | |
84 | |
85 void SpeechRecognitionDispatcherHost::OnStartRequest( | |
86 const SpeechRecognitionHostMsg_StartRequest_Params& params) { | |
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
88 | |
89 SpeechRecognitionSessionContext context; | |
90 context.render_process_id = render_process_id_; | |
91 context.render_view_id = params.render_view_id; | |
92 context.js_handle_id = params.js_handle_id; | |
93 | |
94 SpeechRecognitionSessionConfig config; | |
95 config.is_one_shot = params.is_one_shot; | |
96 config.language = params.language; | |
97 config.grammars = params.grammars; | |
98 config.origin_url = params.origin_url; | |
99 config.initial_context = context; | |
100 config.url_request_context_getter = context_getter_.get(); | |
101 config.filter_profanities = recognition_preferences_->FilterProfanities(); | |
102 | |
103 int session_id = manager()->CreateSession(config, this); | |
104 DCHECK_NE(session_id, content::SpeechRecognitionManager::kSessionIDInvalid); | |
105 manager()->StartSession(session_id); | |
106 } | |
107 | |
108 namespace { | |
109 bool IsSameContext(int render_process_id, | |
110 int render_view_id, | |
111 int js_handle_id, | |
112 const SpeechRecognitionSessionContext& context) { | |
113 return context.render_process_id == render_process_id && | |
114 context.render_view_id == render_view_id && | |
115 context.js_handle_id == js_handle_id; | |
116 } | |
117 } // namespace | |
118 | |
119 void SpeechRecognitionDispatcherHost::OnAbortRequest(int render_view_id, | |
120 int js_handle_id) { | |
121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
122 int session_id = manager()->LookupSessionByContext( | |
123 base::Bind(&IsSameContext, | |
124 render_process_id_, | |
125 render_view_id, | |
126 js_handle_id)); | |
127 if (session_id != content::SpeechRecognitionManager::kSessionIDInvalid) | |
128 manager()->AbortSession(session_id); | |
129 } | |
130 | |
131 void SpeechRecognitionDispatcherHost::OnStopCaptureRequest( | |
132 int render_view_id, int js_handle_id) { | |
133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
134 int session_id = manager()->LookupSessionByContext( | |
135 base::Bind(&IsSameContext, | |
136 render_process_id_, | |
137 render_view_id, | |
138 js_handle_id)); | |
139 if (session_id != content::SpeechRecognitionManager::kSessionIDInvalid) | |
140 manager()->StopAudioCaptureForSession(session_id); | |
141 } | |
142 | |
143 // -------- SpeechRecognitionEventListener interface implementation ----------- | |
144 | |
145 void SpeechRecognitionDispatcherHost::OnRecognitionStart(int session_id) { | |
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
147 const SpeechRecognitionSessionContext& context = | |
148 manager()->GetSessionContext(session_id); | |
149 Send(new SpeechRecognitionMsg_Started(context.render_view_id, | |
150 context.js_handle_id)); | |
151 } | |
152 | |
153 void SpeechRecognitionDispatcherHost::OnAudioStart(int session_id) { | |
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
155 const SpeechRecognitionSessionContext& context = | |
156 manager()->GetSessionContext(session_id); | |
157 Send(new SpeechRecognitionMsg_AudioStarted(context.render_view_id, | |
158 context.js_handle_id)); | |
159 } | |
160 | |
161 void SpeechRecognitionDispatcherHost::OnSoundStart(int session_id) { | |
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
163 const SpeechRecognitionSessionContext& context = | |
164 manager()->GetSessionContext(session_id); | |
165 Send(new SpeechRecognitionMsg_SoundStarted(context.render_view_id, | |
166 context.js_handle_id)); | |
167 } | |
168 | |
169 void SpeechRecognitionDispatcherHost::OnSoundEnd(int session_id) { | |
170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
171 const SpeechRecognitionSessionContext& context = | |
172 manager()->GetSessionContext(session_id); | |
173 Send(new SpeechRecognitionMsg_SoundEnded(context.render_view_id, | |
174 context.js_handle_id)); | |
175 } | |
176 | |
177 void SpeechRecognitionDispatcherHost::OnAudioEnd(int session_id) { | |
178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
179 const SpeechRecognitionSessionContext& context = | |
180 manager()->GetSessionContext(session_id); | |
181 Send(new SpeechRecognitionMsg_AudioEnded(context.render_view_id, | |
182 context.js_handle_id)); | |
183 } | |
184 | |
185 void SpeechRecognitionDispatcherHost::OnRecognitionEnd(int session_id) { | |
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
187 const SpeechRecognitionSessionContext& context = | |
188 manager()->GetSessionContext(session_id); | |
189 Send(new SpeechRecognitionMsg_Ended(context.render_view_id, | |
190 context.js_handle_id)); | |
191 } | |
192 | |
193 void SpeechRecognitionDispatcherHost::OnRecognitionResult( | |
194 int session_id, const content::SpeechRecognitionResult& result) { | |
195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
196 const SpeechRecognitionSessionContext& context = | |
197 manager()->GetSessionContext(session_id); | |
198 Send(new SpeechRecognitionMsg_ResultRetrieved(context.render_view_id, | |
199 context.js_handle_id, | |
200 result)); | |
201 } | |
202 | |
203 void SpeechRecognitionDispatcherHost::OnRecognitionError( | |
204 int session_id, const content::SpeechRecognitionError& error) { | |
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
206 const SpeechRecognitionSessionContext& context = | |
207 manager()->GetSessionContext(session_id); | |
208 Send(new SpeechRecognitionMsg_ErrorOccurred(context.render_view_id, | |
209 context.js_handle_id, | |
210 error)); | |
211 } | |
212 | |
213 // The events below are currently not used by speech JS APIs implementation. | |
214 void SpeechRecognitionDispatcherHost::OnAudioLevelsChange( | |
215 int session_id, float volume, float noise_volume) {} | |
216 void SpeechRecognitionDispatcherHost::OnEnvironmentEstimationComplete( | |
217 int session_id) {} | |
218 | |
219 } // namespace speech | |
OLD | NEW |