Chromium Code Reviews| 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 RequiresBubble(int session_id) { | |
| 46 return SpeechRecognitionManager::GetInstance()-> | |
| 47 GetSessionContext(session_id).use_bubble_on_element; | |
| 48 } | |
| 49 | |
| 50 bool RequiresTrayIcon(int session_id) { | |
| 51 return !RequiresBubble(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 } | 122 } |
| 114 | 123 |
| 115 ChromeSpeechRecognitionManagerDelegate:: | 124 ChromeSpeechRecognitionManagerDelegate:: |
| 116 ~ChromeSpeechRecognitionManagerDelegate() { | 125 ~ChromeSpeechRecognitionManagerDelegate() { |
| 126 if (tray_icon_controller_.get()) | |
| 127 tray_icon_controller_->Hide(); | |
| 128 if (active_bubble_session_id_ != kNoActiveBubble) { | |
| 129 DCHECK(bubble_controller_.get()); | |
| 130 bubble_controller_->CloseBubble(active_bubble_session_id_); | |
| 131 } | |
| 117 } | 132 } |
| 118 | 133 |
| 119 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked( | 134 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked( |
| 120 int session_id, SpeechRecognitionBubble::Button button) { | 135 int session_id, SpeechRecognitionBubble::Button button) { |
| 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 122 DCHECK_EQ(active_bubble_session_id_, session_id); | 137 DCHECK_EQ(active_bubble_session_id_, session_id); |
| 123 | 138 |
| 139 // Note, the session might have been destroyed, therefore avoid calls to the | |
| 140 // manager which imply its existance (e.g., GetSessionContext()). | |
| 141 | |
| 124 if (button == SpeechRecognitionBubble::BUTTON_CANCEL) { | 142 if (button == SpeechRecognitionBubble::BUTTON_CANCEL) { |
| 125 bubble_controller_->CloseBubble(session_id); | 143 BubbleController()->CloseBubble(session_id); |
| 126 last_session_config_.reset(); | 144 last_session_config_.reset(); |
| 127 active_bubble_session_id_ = kNoActiveBubble; | 145 active_bubble_session_id_ = kNoActiveBubble; |
| 128 | 146 |
| 129 // We can safely call AbortSession even if the session has already ended, | 147 // We can safely call AbortSession even if the session has already ended, |
| 130 // the manager's public methods are reliable and will handle it properly. | 148 // the manager's public methods are reliable and will handle it properly. |
| 131 SpeechRecognitionManager::GetInstance()->AbortSession(session_id); | 149 SpeechRecognitionManager::GetInstance()->AbortSession(session_id); |
| 132 } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) { | 150 } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) { |
| 133 bubble_controller_->CloseBubble(session_id); | 151 BubbleController()->CloseBubble(session_id); |
| 134 active_bubble_session_id_ = kNoActiveBubble; | 152 active_bubble_session_id_ = kNoActiveBubble; |
| 135 RestartLastSession(); | 153 RestartLastSession(); |
| 136 } | 154 } |
| 137 } | 155 } |
| 138 | 156 |
| 139 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleFocusChanged( | 157 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleFocusChanged( |
| 140 int session_id) { | 158 int session_id) { |
| 141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 142 DCHECK_EQ(active_bubble_session_id_, session_id); | 160 DCHECK_EQ(active_bubble_session_id_, session_id); |
| 143 | 161 |
| 144 bubble_controller_->CloseBubble(session_id); | 162 // Note, the session might have been destroyed (see InfoBubbleButtonClicked). |
|
Satish
2012/05/20 21:40:26
Yes the session might have been destroyed, so what
Primiano Tucci (use gerrit)
2012/05/21 16:03:13
Done.
| |
| 163 | |
| 164 BubbleController()->CloseBubble(session_id); | |
| 145 last_session_config_.reset(); | 165 last_session_config_.reset(); |
| 146 active_bubble_session_id_ = kNoActiveBubble; | 166 active_bubble_session_id_ = kNoActiveBubble; |
| 147 | 167 |
| 148 // If the user clicks outside the bubble while capturing audio we abort the | 168 // If the user clicks outside the bubble while capturing audio we abort the |
| 149 // session. Otherwise, i.e. audio capture is ended and we are just waiting for | 169 // session. Otherwise, i.e. audio capture is ended and we are just waiting for |
| 150 // results, this activity is carried silently in background. | 170 // results, this activity is carried silently in background. |
| 151 if (SpeechRecognitionManager::GetInstance()->IsCapturingAudio()) | 171 if (SpeechRecognitionManager::GetInstance()->IsCapturingAudio()) |
| 152 SpeechRecognitionManager::GetInstance()->AbortSession(session_id); | 172 SpeechRecognitionManager::GetInstance()->AbortSession(session_id); |
| 153 } | 173 } |
| 154 | 174 |
| 155 void ChromeSpeechRecognitionManagerDelegate::RestartLastSession() { | 175 void ChromeSpeechRecognitionManagerDelegate::RestartLastSession() { |
| 156 DCHECK(last_session_config_.get()); | 176 DCHECK(last_session_config_.get()); |
| 157 SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance(); | 177 SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance(); |
| 158 const int new_session_id = manager->CreateSession(*last_session_config_); | 178 const int new_session_id = manager->CreateSession(*last_session_config_); |
| 159 DCHECK_NE(new_session_id, kNoActiveBubble); | 179 DCHECK_NE(new_session_id, kNoActiveBubble); |
| 160 last_session_config_.reset(); | 180 last_session_config_.reset(); |
| 161 manager->StartSession(new_session_id); | 181 manager->StartSession(new_session_id); |
| 162 } | 182 } |
| 163 | 183 |
| 164 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart( | 184 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart( |
| 165 int session_id) { | 185 int session_id) { |
| 166 // Copy the configuration of the session (for the "try again" button). | 186 SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance(); |
| 167 last_session_config_.reset(new content::SpeechRecognitionSessionConfig( | 187 const content::SpeechRecognitionSessionContext& context = |
| 168 SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id))); | 188 manager->GetSessionContext(session_id); |
| 169 | 189 |
| 170 // Create and show the bubble. | 190 if (RequiresBubble(session_id)) { |
| 171 DCHECK_EQ(active_bubble_session_id_, kNoActiveBubble); | 191 // Copy the configuration of the session (for the "try again" button). |
| 172 active_bubble_session_id_ = session_id; | 192 last_session_config_.reset(new content::SpeechRecognitionSessionConfig( |
| 173 const content::SpeechRecognitionSessionContext& context = | 193 manager->GetSessionConfig(session_id))); |
| 174 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id); | 194 |
| 175 bubble_controller_->CreateBubble(session_id, | 195 // Create and show the bubble. |
| 176 context.render_process_id, | 196 DCHECK_EQ(active_bubble_session_id_, kNoActiveBubble); |
| 177 context.render_view_id, | 197 active_bubble_session_id_ = session_id; |
| 178 context.element_rect); | 198 BubbleController()->CreateBubble(session_id, |
| 179 // TODO(primiano) Why not create directly the bubble in warmup mode? | 199 context.render_process_id, |
| 180 bubble_controller_->SetBubbleWarmUpMode(session_id); | 200 context.render_view_id, |
| 201 context.element_rect); | |
| 202 | |
| 203 // TODO(primiano) Why not creating directly the bubble in warmup mode? | |
| 204 BubbleController()->SetBubbleWarmUpMode(session_id); | |
| 205 } else if (RequiresTrayIcon(session_id)) { | |
| 206 TrayIconController()->Show(context.context_name, | |
| 207 context.show_security_balloon); | |
| 208 } | |
| 181 } | 209 } |
| 182 | 210 |
| 183 void ChromeSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) { | 211 void ChromeSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) { |
| 184 bubble_controller_->SetBubbleRecordingMode(session_id); | 212 if (RequiresBubble(session_id)) |
| 213 BubbleController()->SetBubbleRecordingMode(session_id); | |
| 185 } | 214 } |
| 186 | 215 |
| 187 void ChromeSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete( | 216 void ChromeSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete( |
| 188 int session_id) { | 217 int session_id) { |
| 189 } | 218 } |
| 190 | 219 |
| 191 void ChromeSpeechRecognitionManagerDelegate::OnSoundStart(int session_id) { | 220 void ChromeSpeechRecognitionManagerDelegate::OnSoundStart(int session_id) { |
| 192 } | 221 } |
| 193 | 222 |
| 194 void ChromeSpeechRecognitionManagerDelegate::OnSoundEnd(int session_id) { | 223 void ChromeSpeechRecognitionManagerDelegate::OnSoundEnd(int session_id) { |
| 195 } | 224 } |
| 196 | 225 |
| 197 void ChromeSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) { | 226 void ChromeSpeechRecognitionManagerDelegate::OnAudioEnd(int session_id) { |
| 198 // OnAudioEnd can be also raised after an abort, when the bubble has already | 227 // OnAudioEnd can be also raised after an abort, when the bubble has already |
| 199 // been closed. | 228 // been closed. |
| 200 if (active_bubble_session_id_ == session_id) | 229 if (RequiresBubble(session_id) && active_bubble_session_id_ == session_id) |
| 201 bubble_controller_->SetBubbleRecognizingMode(session_id); | 230 BubbleController()->SetBubbleRecognizingMode(session_id); |
| 202 } | 231 } |
| 203 | 232 |
| 204 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionResult( | 233 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionResult( |
| 205 int session_id, const content::SpeechRecognitionResult& result) { | 234 int session_id, const content::SpeechRecognitionResult& result) { |
| 206 // A result can be dispatched when the bubble is not visible anymore (e.g., | 235 // A result can be dispatched when the bubble is not visible anymore (e.g., |
| 207 // lost focus while waiting for a result, thus continuing in background). | 236 // lost focus while waiting for a result, thus continuing in background). |
| 208 if (active_bubble_session_id_ == session_id) { | 237 if (RequiresBubble(session_id) && active_bubble_session_id_ == session_id) { |
| 209 bubble_controller_->CloseBubble(session_id); | 238 BubbleController()->CloseBubble(session_id); |
| 210 last_session_config_.reset(); | 239 last_session_config_.reset(); |
| 211 active_bubble_session_id_ = kNoActiveBubble; | 240 active_bubble_session_id_ = kNoActiveBubble; |
| 212 } | 241 } |
| 213 } | 242 } |
| 214 | 243 |
| 215 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionError( | 244 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionError( |
| 216 int session_id, const content::SpeechRecognitionError& error) { | 245 int session_id, const content::SpeechRecognitionError& error) { |
| 217 // An error can be dispatched when the bubble is not visible anymore. | 246 // An error can be dispatched when the bubble is not visible anymore. |
| 218 if (active_bubble_session_id_ != session_id) | 247 if (active_bubble_session_id_ != session_id) |
| 219 return; | 248 return; |
| 249 DCHECK(RequiresBubble(session_id)); | |
| 220 | 250 |
| 221 int error_message_id = 0; | 251 int error_message_id = 0; |
| 222 switch (error.code) { | 252 switch (error.code) { |
| 223 case content::SPEECH_RECOGNITION_ERROR_AUDIO: | 253 case content::SPEECH_RECOGNITION_ERROR_AUDIO: |
| 224 switch (error.details) { | 254 switch (error.details) { |
| 225 case content::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC: | 255 case content::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC: |
| 226 error_message_id = IDS_SPEECH_INPUT_NO_MIC; | 256 error_message_id = IDS_SPEECH_INPUT_NO_MIC; |
| 227 break; | 257 break; |
| 228 case content::SPEECH_AUDIO_ERROR_DETAILS_IN_USE: | 258 case content::SPEECH_AUDIO_ERROR_DETAILS_IN_USE: |
| 229 error_message_id = IDS_SPEECH_INPUT_MIC_IN_USE; | 259 error_message_id = IDS_SPEECH_INPUT_MIC_IN_USE; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 242 case content::SPEECH_RECOGNITION_ERROR_NO_MATCH: | 272 case content::SPEECH_RECOGNITION_ERROR_NO_MATCH: |
| 243 error_message_id = IDS_SPEECH_INPUT_NO_RESULTS; | 273 error_message_id = IDS_SPEECH_INPUT_NO_RESULTS; |
| 244 break; | 274 break; |
| 245 case content::SPEECH_RECOGNITION_ERROR_NETWORK: | 275 case content::SPEECH_RECOGNITION_ERROR_NETWORK: |
| 246 error_message_id = IDS_SPEECH_INPUT_NET_ERROR; | 276 error_message_id = IDS_SPEECH_INPUT_NET_ERROR; |
| 247 break; | 277 break; |
| 248 default: | 278 default: |
| 249 NOTREACHED() << "unknown error " << error.code; | 279 NOTREACHED() << "unknown error " << error.code; |
| 250 return; | 280 return; |
| 251 } | 281 } |
| 252 bubble_controller_->SetBubbleMessage( | 282 BubbleController()->SetBubbleMessage( |
| 253 session_id, l10n_util::GetStringUTF16(error_message_id)); | 283 session_id, l10n_util::GetStringUTF16(error_message_id)); |
| 254 } | 284 } |
| 255 | 285 |
| 256 void ChromeSpeechRecognitionManagerDelegate::OnAudioLevelsChange( | 286 void ChromeSpeechRecognitionManagerDelegate::OnAudioLevelsChange( |
| 257 int session_id, float volume, float noise_volume) { | 287 int session_id, float volume, float noise_volume) { |
| 258 if (active_bubble_session_id_ == session_id) | 288 if (active_bubble_session_id_ == session_id) { |
| 259 bubble_controller_->SetBubbleInputVolume(session_id, volume, noise_volume); | 289 DCHECK(RequiresBubble(session_id)); |
| 290 BubbleController()->SetBubbleInputVolume(session_id, volume, noise_volume); | |
| 291 } else if (RequiresTrayIcon(session_id)) { | |
| 292 TrayIconController()->SetVUMeterVolume(volume); | |
| 293 } | |
| 260 } | 294 } |
| 261 | 295 |
| 262 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionEnd(int session_id) { | 296 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionEnd(int session_id) { |
| 297 if (RequiresTrayIcon(session_id)) | |
|
Satish
2012/05/20 21:40:26
are there race conditions where one session with t
Primiano Tucci (use gerrit)
2012/05/21 16:03:13
Yes, it was wrong. Now the tray icon is shown only
| |
| 298 TrayIconController()->Hide(); | |
| 299 // No need to remove the bubble here, since: | |
|
Satish
2012/05/20 21:40:26
it isn't clear that the following are actually eit
Primiano Tucci (use gerrit)
2012/05/21 16:03:13
Done.
| |
| 300 // - A previous OnRecognitionResult event already closed the bubble. | |
| 301 // - An error occurred, so the bubble is showing the error and will be closed | |
| 302 // when it will lose focus (by InfoBubbleFocusChanged()). | |
| 303 // - The bubble lost focus or the user pressed the Cancel button, thus it has | |
| 304 // been closed by InfoBubbleFocusChanged(), which triggered an AbortSession. | |
| 263 } | 305 } |
| 264 | 306 |
| 265 void ChromeSpeechRecognitionManagerDelegate::GetDiagnosticInformation( | 307 void ChromeSpeechRecognitionManagerDelegate::GetDiagnosticInformation( |
| 266 bool* can_report_metrics, | 308 bool* can_report_metrics, |
| 267 std::string* hardware_info) { | 309 std::string* hardware_info) { |
| 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 269 if (!optional_request_info_.get()) { | 311 if (!optional_request_info_.get()) { |
| 270 optional_request_info_ = new OptionalRequestInfo(); | 312 optional_request_info_ = new OptionalRequestInfo(); |
| 271 // Since hardware info is optional with speech input requests, we start an | 313 // Since hardware info is optional with speech input requests, we start an |
| 272 // asynchronous fetch here and move on with recording audio. This first | 314 // asynchronous fetch here and move on with recording audio. This first |
| 273 // speech input request would send an empty string for hardware info and | 315 // speech input request would send an empty string for hardware info and |
| 274 // subsequent requests may have the hardware info available if the fetch | 316 // subsequent requests may have the hardware info available if the fetch |
| 275 // completed before them. This way we don't end up stalling the user with | 317 // completed before them. This way we don't end up stalling the user with |
| 276 // a long wait and disk seeks when they click on a UI element and start | 318 // a long wait and disk seeks when they click on a UI element and start |
| 277 // speaking. | 319 // speaking. |
| 278 optional_request_info_->Refresh(); | 320 optional_request_info_->Refresh(); |
| 279 } | 321 } |
| 280 *can_report_metrics = optional_request_info_->can_report_metrics(); | 322 *can_report_metrics = optional_request_info_->can_report_metrics(); |
| 281 *hardware_info = optional_request_info_->value(); | 323 *hardware_info = optional_request_info_->value(); |
| 282 } | 324 } |
| 283 | 325 |
| 284 void ChromeSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed( | 326 void ChromeSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed( |
| 285 int session_id, | 327 int session_id, |
| 286 base::Callback<void(int session_id, bool is_allowed)> callback) { | 328 base::Callback<void(int session_id, bool is_allowed)> callback) { |
| 287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 330 | |
| 331 // We don't need any particular check for sessions not using a bubble. In such | |
| 332 // cases, we just notify it to the manager (calling-back synchronously, since | |
| 333 // we remain in the IO thread). | |
| 334 if (RequiresTrayIcon(session_id)) { | |
| 335 callback.Run(session_id, true /* is_allowed */); | |
| 336 return; | |
| 337 } | |
| 338 | |
| 339 // Sessions using bubbles, conversely, need a check on the renderer view type. | |
| 340 // The check must be performed in the UI thread. We defer it posting to | |
| 341 // CheckRenderViewType, which will issue the callback on our behalf. | |
| 288 const content::SpeechRecognitionSessionContext& context = | 342 const content::SpeechRecognitionSessionContext& context = |
| 289 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id); | 343 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id); |
| 290 | |
| 291 // The check must be performed in the UI thread. We defer it posting to | |
| 292 // CheckRenderViewType, which will issue the callback on our behalf. | |
| 293 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 344 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 294 base::Bind(&CheckRenderViewType, | 345 base::Bind(&CheckRenderViewType, |
| 295 session_id, | 346 session_id, |
| 296 callback, | 347 callback, |
| 297 context.render_process_id, | 348 context.render_process_id, |
| 298 context.render_view_id)); | 349 context.render_view_id)); |
| 299 } | 350 } |
| 300 | 351 |
| 301 content::SpeechRecognitionEventListener* | 352 content::SpeechRecognitionEventListener* |
| 302 ChromeSpeechRecognitionManagerDelegate::GetEventListener() { | 353 ChromeSpeechRecognitionManagerDelegate::GetEventListener() { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 320 // speech input extension API should be used instead. | 371 // speech input extension API should be used instead. |
| 321 | 372 |
| 322 const bool allowed = (render_view_host != NULL && | 373 const bool allowed = (render_view_host != NULL && |
| 323 render_view_host->GetDelegate() != NULL && | 374 render_view_host->GetDelegate() != NULL && |
| 324 render_view_host->GetDelegate()->GetRenderViewType() == | 375 render_view_host->GetDelegate()->GetRenderViewType() == |
| 325 chrome::VIEW_TYPE_TAB_CONTENTS); | 376 chrome::VIEW_TYPE_TAB_CONTENTS); |
| 326 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 377 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 327 base::Bind(callback, session_id, allowed)); | 378 base::Bind(callback, session_id, allowed)); |
| 328 } | 379 } |
| 329 | 380 |
| 381 SpeechRecognitionBubbleController* | |
| 382 ChromeSpeechRecognitionManagerDelegate::BubbleController() { | |
| 383 if (!bubble_controller_.get()) | |
| 384 bubble_controller_ = new SpeechRecognitionBubbleController(this); | |
| 385 return bubble_controller_.get(); | |
| 386 } | |
| 387 | |
| 388 SpeechRecognitionTrayIconController* | |
| 389 ChromeSpeechRecognitionManagerDelegate::TrayIconController() { | |
| 390 if (!tray_icon_controller_.get()) | |
| 391 tray_icon_controller_ = new SpeechRecognitionTrayIconController(); | |
| 392 return tray_icon_controller_.get(); | |
| 393 } | |
| 394 | |
| 395 | |
| 330 } // namespace speech | 396 } // namespace speech |
| OLD | NEW |