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