OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h" | 5 #include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
11 #include "base/threading/thread_restrictions.h" | 11 #include "base/threading/thread_restrictions.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/prefs/pref_service.h" | 14 #include "chrome/browser/prefs/pref_service.h" |
15 #include "chrome/browser/profiles/profile_manager.h" | 15 #include "chrome/browser/profiles/profile_manager.h" |
16 #include "chrome/browser/speech/speech_recognition_tray_icon_controller.h" | |
16 #include "chrome/browser/tab_contents/tab_util.h" | 17 #include "chrome/browser/tab_contents/tab_util.h" |
17 #include "chrome/common/chrome_view_type.h" | 18 #include "chrome/common/chrome_view_type.h" |
18 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
19 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
20 #include "content/public/browser/render_view_host.h" | 21 #include "content/public/browser/render_view_host.h" |
21 #include "content/public/browser/render_view_host_delegate.h" | 22 #include "content/public/browser/render_view_host_delegate.h" |
22 #include "content/public/browser/resource_context.h" | 23 #include "content/public/browser/resource_context.h" |
23 #include "content/public/browser/speech_recognition_manager.h" | 24 #include "content/public/browser/speech_recognition_manager.h" |
24 #include "content/public/browser/speech_recognition_session_config.h" | 25 #include "content/public/browser/speech_recognition_session_config.h" |
25 #include "content/public/browser/speech_recognition_session_context.h" | 26 #include "content/public/browser/speech_recognition_session_context.h" |
26 #include "content/public/common/speech_recognition_error.h" | 27 #include "content/public/common/speech_recognition_error.h" |
27 #include "content/public/common/speech_recognition_result.h" | 28 #include "content/public/common/speech_recognition_result.h" |
28 #include "grit/generated_resources.h" | 29 #include "grit/generated_resources.h" |
29 #include "net/url_request/url_request_context_getter.h" | 30 #include "net/url_request/url_request_context_getter.h" |
30 #include "ui/base/l10n/l10n_util.h" | 31 #include "ui/base/l10n/l10n_util.h" |
31 | 32 |
32 #if defined(OS_WIN) | 33 #if defined(OS_WIN) |
33 #include "chrome/installer/util/wmi.h" | 34 #include "chrome/installer/util/wmi.h" |
34 #endif | 35 #endif |
35 | 36 |
36 using content::BrowserThread; | 37 using content::BrowserThread; |
37 using content::SpeechRecognitionManager; | 38 using content::SpeechRecognitionManager; |
39 using content::SpeechRecognitionSessionContext; | |
38 | 40 |
39 namespace { | 41 namespace { |
40 const int kNoActiveBubble = | 42 const int kNoActiveBubble = |
41 content::SpeechRecognitionManager::kSessionIDInvalid; | 43 content::SpeechRecognitionManager::kSessionIDInvalid; |
44 | |
45 bool IsRequiredBubble(int session_id) { | |
46 return SpeechRecognitionManager::GetInstance()-> | |
47 GetSessionContext(session_id).use_bubble_on_element; | |
48 } | |
49 | |
50 bool IsRequiredTrayIcon(int session_id) { | |
hans
2012/05/15 13:35:17
these names (this and IsRequiredBubble) aren't gre
Primiano Tucci (use gerrit)
2012/05/16 10:16:00
Done.
| |
51 return !IsRequiredBubble(session_id); | |
52 } | |
42 } // namespace | 53 } // namespace |
43 | 54 |
44 namespace speech { | 55 namespace speech { |
45 | 56 |
46 // Asynchronously fetches the PC and audio hardware/driver info if | 57 // Asynchronously fetches the PC and audio hardware/driver info if |
47 // the user has opted into UMA. This information is sent with speech input | 58 // the user has opted into UMA. This information is sent with speech input |
48 // requests to the server for identifying and improving quality issues with | 59 // requests to the server for identifying and improving quality issues with |
49 // specific device configurations. | 60 // specific device configurations. |
50 class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo | 61 class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo |
51 : public base::RefCountedThreadSafe<OptionalRequestInfo> { | 62 : public base::RefCountedThreadSafe<OptionalRequestInfo> { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 ~OptionalRequestInfo() {} | 111 ~OptionalRequestInfo() {} |
101 | 112 |
102 base::Lock lock_; | 113 base::Lock lock_; |
103 std::string value_; | 114 std::string value_; |
104 bool can_report_metrics_; | 115 bool can_report_metrics_; |
105 | 116 |
106 DISALLOW_COPY_AND_ASSIGN(OptionalRequestInfo); | 117 DISALLOW_COPY_AND_ASSIGN(OptionalRequestInfo); |
107 }; | 118 }; |
108 | 119 |
109 ChromeSpeechRecognitionManagerDelegate::ChromeSpeechRecognitionManagerDelegate() | 120 ChromeSpeechRecognitionManagerDelegate::ChromeSpeechRecognitionManagerDelegate() |
110 : bubble_controller_(new SpeechRecognitionBubbleController( | 121 : active_bubble_session_id_(kNoActiveBubble) { |
111 ALLOW_THIS_IN_INITIALIZER_LIST(this))), | |
112 active_bubble_session_id_(kNoActiveBubble) { | |
113 SpeechRecognitionManager::GetInstance()->SetDelegate(this); | 122 SpeechRecognitionManager::GetInstance()->SetDelegate(this); |
114 } | 123 } |
115 | 124 |
116 ChromeSpeechRecognitionManagerDelegate:: | 125 ChromeSpeechRecognitionManagerDelegate:: |
117 ~ChromeSpeechRecognitionManagerDelegate() { | 126 ~ChromeSpeechRecognitionManagerDelegate() { |
118 SpeechRecognitionManager::GetInstance()->SetDelegate(NULL); | 127 SpeechRecognitionManager::GetInstance()->SetDelegate(NULL); |
128 if (tray_icon_controller_.get()) | |
129 tray_icon_controller_->Hide(); | |
119 if (active_bubble_session_id_ != kNoActiveBubble) { | 130 if (active_bubble_session_id_ != kNoActiveBubble) { |
120 DCHECK(bubble_controller_.get()); | 131 DCHECK(bubble_controller_.get()); |
121 bubble_controller_->CloseBubble(active_bubble_session_id_); | 132 bubble_controller_->CloseBubble(active_bubble_session_id_); |
122 } | 133 } |
123 } | 134 } |
124 | 135 |
125 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked( | 136 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked( |
126 int session_id, SpeechRecognitionBubble::Button button) { | 137 int session_id, SpeechRecognitionBubble::Button button) { |
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
128 DCHECK_EQ(active_bubble_session_id_, session_id); | 139 DCHECK_EQ(active_bubble_session_id_, session_id); |
129 | 140 |
141 // Note, the session might have been destroyed, therefore avoid calls to the | |
142 // manager which imply its existance (e.g., GetSessionContext()). | |
143 | |
130 if (button == SpeechRecognitionBubble::BUTTON_CANCEL) { | 144 if (button == SpeechRecognitionBubble::BUTTON_CANCEL) { |
131 bubble_controller_->CloseBubble(session_id); | 145 BubbleController()->CloseBubble(session_id); |
132 last_session_config_.reset(); | 146 last_session_config_.reset(); |
133 active_bubble_session_id_ = kNoActiveBubble; | 147 active_bubble_session_id_ = kNoActiveBubble; |
134 | 148 |
135 // We can safely call AbortSession even if the session has already ended, | 149 // We can safely call AbortSession even if the session has already ended, |
136 // the manager's public methods are reliable and will handle it properly. | 150 // the manager's public methods are reliable and will handle it properly. |
137 SpeechRecognitionManager::GetInstance()->AbortSession(session_id); | 151 SpeechRecognitionManager::GetInstance()->AbortSession(session_id); |
138 } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) { | 152 } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) { |
139 bubble_controller_->CloseBubble(session_id); | 153 BubbleController()->CloseBubble(session_id); |
140 active_bubble_session_id_ = kNoActiveBubble; | 154 active_bubble_session_id_ = kNoActiveBubble; |
141 RestartLastSession(); | 155 RestartLastSession(); |
142 } | 156 } |
143 } | 157 } |
144 | 158 |
145 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleFocusChanged( | 159 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleFocusChanged( |
146 int session_id) { | 160 int session_id) { |
147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
148 DCHECK_EQ(active_bubble_session_id_, session_id); | 162 DCHECK_EQ(active_bubble_session_id_, session_id); |
149 | 163 |
150 bubble_controller_->CloseBubble(session_id); | 164 // Note, the session might have been destroyed (see InfoBubbleButtonClicked). |
165 | |
166 BubbleController()->CloseBubble(session_id); | |
151 last_session_config_.reset(); | 167 last_session_config_.reset(); |
152 active_bubble_session_id_ = kNoActiveBubble; | 168 active_bubble_session_id_ = kNoActiveBubble; |
153 | 169 |
154 // If the user clicks outside the bubble while capturing audio we abort the | 170 // If the user clicks outside the bubble while capturing audio we abort the |
155 // session. Otherwise, i.e. audio capture is ended and we are just waiting for | 171 // session. Otherwise, i.e. audio capture is ended and we are just waiting for |
156 // results, this activity is carried silently in background. | 172 // results, this activity is carried silently in background. |
157 if (SpeechRecognitionManager::GetInstance()->IsCapturingAudio()) | 173 if (SpeechRecognitionManager::GetInstance()->IsCapturingAudio()) |
158 SpeechRecognitionManager::GetInstance()->AbortSession(session_id); | 174 SpeechRecognitionManager::GetInstance()->AbortSession(session_id); |
159 } | 175 } |
160 | 176 |
161 void ChromeSpeechRecognitionManagerDelegate::RestartLastSession() { | 177 void ChromeSpeechRecognitionManagerDelegate::RestartLastSession() { |
162 DCHECK(last_session_config_.get()); | 178 DCHECK(last_session_config_.get()); |
163 SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance(); | 179 SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance(); |
164 const int new_session_id = manager->CreateSession(*last_session_config_); | 180 const int new_session_id = manager->CreateSession(*last_session_config_); |
165 DCHECK_NE(new_session_id, kNoActiveBubble); | 181 DCHECK_NE(new_session_id, kNoActiveBubble); |
166 last_session_config_.reset(); | 182 last_session_config_.reset(); |
167 manager->StartSession(new_session_id); | 183 manager->StartSession(new_session_id); |
168 } | 184 } |
169 | 185 |
170 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart( | 186 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart( |
171 int session_id) { | 187 int session_id) { |
172 // Copy the configuration of the session (for the "try again" button). | 188 SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance(); |
173 last_session_config_.reset(new content::SpeechRecognitionSessionConfig( | 189 const content::SpeechRecognitionSessionContext& context = |
174 SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id))); | 190 manager->GetSessionContext(session_id); |
175 | 191 |
176 // Create and show the bubble. | 192 if (IsRequiredBubble(session_id)) { |
177 DCHECK_EQ(active_bubble_session_id_, kNoActiveBubble); | 193 // Copy the configuration of the session (for the "try again" button). |
178 active_bubble_session_id_ = session_id; | 194 last_session_config_.reset(new content::SpeechRecognitionSessionConfig( |
179 const content::SpeechRecognitionSessionContext& context = | 195 manager->GetSessionConfig(session_id))); |
180 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id); | 196 |
181 bubble_controller_->CreateBubble(session_id, | 197 // Create and show the bubble. |
182 context.render_process_id, | 198 DCHECK_EQ(active_bubble_session_id_, kNoActiveBubble); |
183 context.render_view_id, | 199 active_bubble_session_id_ = session_id; |
184 context.element_rect); | 200 BubbleController()->CreateBubble(session_id, |
185 // TODO(primiano) Why not create directly the bubble in warmup mode? | 201 context.render_process_id, |
186 bubble_controller_->SetBubbleWarmUpMode(session_id); | 202 context.render_view_id, |
203 context.element_rect); | |
204 | |
205 // TODO(primiano) Why not creating directly the bubble in warmup mode? | |
206 BubbleController()->SetBubbleWarmUpMode(session_id); | |
207 } else if (IsRequiredTrayIcon(session_id)) { | |
208 TrayIconController()->Show(context.context_name, | |
209 context.show_security_balloon); | |
210 } | |
187 } | 211 } |
188 | 212 |
189 void ChromeSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) { | 213 void ChromeSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) { |
190 bubble_controller_->SetBubbleRecordingMode(session_id); | 214 if (IsRequiredBubble(session_id)) |
215 BubbleController()->SetBubbleRecordingMode(session_id); | |
191 } | 216 } |
192 | 217 |
193 void ChromeSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete( | 218 void ChromeSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete( |
194 int session_id) { | 219 int session_id) { |
195 } | 220 } |
196 | 221 |
197 void ChromeSpeechRecognitionManagerDelegate::OnSoundStart(int session_id) { | 222 void ChromeSpeechRecognitionManagerDelegate::OnSoundStart(int session_id) { |
198 } | 223 } |
199 | 224 |
200 void ChromeSpeechRecognitionManagerDelegate::OnSoundEnd(int session_id) { | 225 void ChromeSpeechRecognitionManagerDelegate::OnSoundEnd(int session_id) { |
201 } | 226 } |
202 | 227 |
203 void ChromeSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) { | 228 void ChromeSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) { |
204 // OnAudioEnd can be also raised after an abort, when the bubble has already | 229 // OnAudioEnd can be also raised after an abort, when the bubble has already |
205 // been closed. | 230 // been closed. |
206 if (active_bubble_session_id_ == session_id) | 231 if (IsRequiredBubble(session_id) && active_bubble_session_id_ == session_id) |
207 bubble_controller_->SetBubbleRecognizingMode(session_id); | 232 BubbleController()->SetBubbleRecognizingMode(session_id); |
208 } | 233 } |
209 | 234 |
210 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionResult( | 235 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionResult( |
211 int session_id, const content::SpeechRecognitionResult& result) { | 236 int session_id, const content::SpeechRecognitionResult& result) { |
212 // A result can be dispatched when the bubble is not visible anymore (e.g., | 237 // A result can be dispatched when the bubble is not visible anymore (e.g., |
213 // lost focus while waiting for a result, thus continuing in background). | 238 // lost focus while waiting for a result, thus continuing in background). |
214 if (active_bubble_session_id_ == session_id) { | 239 if (IsRequiredBubble(session_id) && active_bubble_session_id_ == session_id) { |
215 bubble_controller_->CloseBubble(session_id); | 240 BubbleController()->CloseBubble(session_id); |
216 last_session_config_.reset(); | 241 last_session_config_.reset(); |
217 active_bubble_session_id_ = kNoActiveBubble; | 242 active_bubble_session_id_ = kNoActiveBubble; |
218 } | 243 } |
219 } | 244 } |
220 | 245 |
221 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionError( | 246 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionError( |
222 int session_id, const content::SpeechRecognitionError& error) { | 247 int session_id, const content::SpeechRecognitionError& error) { |
223 // An error can be dispatched when the bubble is not visible anymore. | 248 // An error can be dispatched when the bubble is not visible anymore. |
224 if (active_bubble_session_id_ != session_id) | 249 if (active_bubble_session_id_ != session_id) |
225 return; | 250 return; |
251 DCHECK(IsRequiredBubble(session_id)); | |
226 | 252 |
227 int error_message_id = 0; | 253 int error_message_id = 0; |
228 switch (error.code) { | 254 switch (error.code) { |
229 case content::SPEECH_RECOGNITION_ERROR_AUDIO: | 255 case content::SPEECH_RECOGNITION_ERROR_AUDIO: |
230 switch (error.details) { | 256 switch (error.details) { |
231 case content::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC: | 257 case content::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC: |
232 error_message_id = IDS_SPEECH_INPUT_NO_MIC; | 258 error_message_id = IDS_SPEECH_INPUT_NO_MIC; |
233 break; | 259 break; |
234 case content::SPEECH_AUDIO_ERROR_DETAILS_IN_USE: | 260 case content::SPEECH_AUDIO_ERROR_DETAILS_IN_USE: |
235 error_message_id = IDS_SPEECH_INPUT_MIC_IN_USE; | 261 error_message_id = IDS_SPEECH_INPUT_MIC_IN_USE; |
(...skipping 12 matching lines...) Expand all Loading... | |
248 case content::SPEECH_RECOGNITION_ERROR_NO_MATCH: | 274 case content::SPEECH_RECOGNITION_ERROR_NO_MATCH: |
249 error_message_id = IDS_SPEECH_INPUT_NO_RESULTS; | 275 error_message_id = IDS_SPEECH_INPUT_NO_RESULTS; |
250 break; | 276 break; |
251 case content::SPEECH_RECOGNITION_ERROR_NETWORK: | 277 case content::SPEECH_RECOGNITION_ERROR_NETWORK: |
252 error_message_id = IDS_SPEECH_INPUT_NET_ERROR; | 278 error_message_id = IDS_SPEECH_INPUT_NET_ERROR; |
253 break; | 279 break; |
254 default: | 280 default: |
255 NOTREACHED() << "unknown error " << error.code; | 281 NOTREACHED() << "unknown error " << error.code; |
256 return; | 282 return; |
257 } | 283 } |
258 bubble_controller_->SetBubbleMessage( | 284 BubbleController()->SetBubbleMessage( |
259 session_id, l10n_util::GetStringUTF16(error_message_id)); | 285 session_id, l10n_util::GetStringUTF16(error_message_id)); |
260 } | 286 } |
261 | 287 |
262 void ChromeSpeechRecognitionManagerDelegate::OnAudioLevelsChange( | 288 void ChromeSpeechRecognitionManagerDelegate::OnAudioLevelsChange( |
263 int session_id, float volume, float noise_volume) { | 289 int session_id, float volume, float noise_volume) { |
264 if (active_bubble_session_id_ == session_id) | 290 if (active_bubble_session_id_ == session_id) { |
265 bubble_controller_->SetBubbleInputVolume(session_id, volume, noise_volume); | 291 DCHECK(IsRequiredBubble(session_id)); |
292 BubbleController()->SetBubbleInputVolume(session_id, volume, noise_volume); | |
293 } else if (IsRequiredTrayIcon(session_id)) { | |
294 TrayIconController()->SetVUMeterVolume(volume); | |
295 } | |
266 } | 296 } |
267 | 297 |
268 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionEnd(int session_id) { | 298 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionEnd(int session_id) { |
299 if (IsRequiredTrayIcon(session_id)) | |
300 TrayIconController()->Hide(); | |
301 // No need to remove the bubble here, since: | |
302 // - A previous OnRecognitionResult event already closed the bubble. | |
303 // - An error occurred, so the bubble is showing the error and will be closed | |
304 // when it will lose focus (by InfoBubbleFocusChanged()). | |
305 // - The bubble lost focus or the user pressed the Cancel button, thus it has | |
306 // been closed by InfoBubbleFocusChanged(), which triggered an AbortSession. | |
hans
2012/05/15 13:35:17
so could we add a DCHECK that the bubble is closed
Primiano Tucci (use gerrit)
2012/05/16 10:16:00
I am afraid not. See point 2 in the code comment.
| |
269 } | 307 } |
270 | 308 |
271 void ChromeSpeechRecognitionManagerDelegate::GetDiagnosticInformation( | 309 void ChromeSpeechRecognitionManagerDelegate::GetDiagnosticInformation( |
272 bool* can_report_metrics, | 310 bool* can_report_metrics, |
273 std::string* hardware_info) { | 311 std::string* hardware_info) { |
274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
275 if (!optional_request_info_.get()) { | 313 if (!optional_request_info_.get()) { |
276 optional_request_info_ = new OptionalRequestInfo(); | 314 optional_request_info_ = new OptionalRequestInfo(); |
277 // Since hardware info is optional with speech input requests, we start an | 315 // Since hardware info is optional with speech input requests, we start an |
278 // asynchronous fetch here and move on with recording audio. This first | 316 // asynchronous fetch here and move on with recording audio. This first |
279 // speech input request would send an empty string for hardware info and | 317 // speech input request would send an empty string for hardware info and |
280 // subsequent requests may have the hardware info available if the fetch | 318 // subsequent requests may have the hardware info available if the fetch |
281 // completed before them. This way we don't end up stalling the user with | 319 // completed before them. This way we don't end up stalling the user with |
282 // a long wait and disk seeks when they click on a UI element and start | 320 // a long wait and disk seeks when they click on a UI element and start |
283 // speaking. | 321 // speaking. |
284 optional_request_info_->Refresh(); | 322 optional_request_info_->Refresh(); |
285 } | 323 } |
286 *can_report_metrics = optional_request_info_->can_report_metrics(); | 324 *can_report_metrics = optional_request_info_->can_report_metrics(); |
287 *hardware_info = optional_request_info_->value(); | 325 *hardware_info = optional_request_info_->value(); |
288 } | 326 } |
289 | 327 |
290 void ChromeSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed( | 328 void ChromeSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed( |
291 int session_id, | 329 int session_id, |
292 base::Callback<void(int session_id, bool is_allowed)> callback) { | 330 base::Callback<void(int session_id, bool is_allowed)> callback) { |
293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
332 | |
333 // We don't need any particular check for sessions not using a bubble. In such | |
334 // cases, we just notify it to the manager (calling-back synchronously, since | |
335 // we remain in the IO thread). | |
336 if (IsRequiredTrayIcon(session_id)) { | |
337 callback.Run(session_id, true /* is_allowed */); | |
338 return; | |
339 } | |
340 | |
341 // Sessions using bubbles, conversely, need a check on the renderer view type. | |
342 // The check must be performed in the UI thread. We defer it posting to | |
343 // CheckRenderViewType, which will issue the callback on our behalf. | |
294 const content::SpeechRecognitionSessionContext& context = | 344 const content::SpeechRecognitionSessionContext& context = |
295 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id); | 345 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id); |
296 | |
297 // The check must be performed in the UI thread. We defer it posting to | |
298 // CheckRenderViewType, which will issue the callback on our behalf. | |
299 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 346 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
300 base::Bind(&CheckRenderViewType, | 347 base::Bind(&CheckRenderViewType, |
301 session_id, | 348 session_id, |
302 callback, | 349 callback, |
303 context.render_process_id, | 350 context.render_process_id, |
304 context.render_view_id)); | 351 context.render_view_id)); |
305 } | 352 } |
306 | 353 |
307 content::SpeechRecognitionEventListener* | 354 content::SpeechRecognitionEventListener* |
308 ChromeSpeechRecognitionManagerDelegate::GetEventListener() { | 355 ChromeSpeechRecognitionManagerDelegate::GetEventListener() { |
(...skipping 17 matching lines...) Expand all Loading... | |
326 // speech input extension API should be used instead. | 373 // speech input extension API should be used instead. |
327 | 374 |
328 const bool allowed = (render_view_host != NULL && | 375 const bool allowed = (render_view_host != NULL && |
329 render_view_host->GetDelegate() != NULL && | 376 render_view_host->GetDelegate() != NULL && |
330 render_view_host->GetDelegate()->GetRenderViewType() == | 377 render_view_host->GetDelegate()->GetRenderViewType() == |
331 chrome::VIEW_TYPE_TAB_CONTENTS); | 378 chrome::VIEW_TYPE_TAB_CONTENTS); |
332 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 379 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
333 base::Bind(callback, session_id, allowed)); | 380 base::Bind(callback, session_id, allowed)); |
334 } | 381 } |
335 | 382 |
383 SpeechRecognitionBubbleController* | |
384 ChromeSpeechRecognitionManagerDelegate::BubbleController() { | |
385 if (!bubble_controller_.get()) | |
386 bubble_controller_ = new SpeechRecognitionBubbleController(this); | |
387 return bubble_controller_.get(); | |
388 } | |
389 | |
390 SpeechRecognitionTrayIconController* | |
391 ChromeSpeechRecognitionManagerDelegate::TrayIconController() { | |
392 if (!tray_icon_controller_.get()) | |
393 tray_icon_controller_ = new SpeechRecognitionTrayIconController(); | |
394 return tray_icon_controller_.get(); | |
395 } | |
396 | |
397 | |
336 } // namespace speech | 398 } // namespace speech |
OLD | NEW |