Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc

Issue 9972011: Speech refactoring: Reimplemented SpeechRecognitionManagerImpl as a FSM. (CL1.7) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed according to jam@ review (2/2) Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/tab_contents/tab_util.h" 16 #include "chrome/browser/tab_contents/tab_util.h"
17 #include "chrome/common/pref_names.h" 17 #include "chrome/common/pref_names.h"
18 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/browser/render_view_host_delegate.h"
19 #include "content/public/browser/resource_context.h" 21 #include "content/public/browser/resource_context.h"
20 #include "content/public/browser/speech_recognition_manager.h" 22 #include "content/public/browser/speech_recognition_manager.h"
23 #include "content/public/browser/speech_recognition_session_context.h"
21 #include "content/public/common/speech_recognition_error.h" 24 #include "content/public/common/speech_recognition_error.h"
22 #include "content/public/common/speech_recognition_result.h" 25 #include "content/public/common/speech_recognition_result.h"
23 #include "grit/generated_resources.h" 26 #include "grit/generated_resources.h"
24 #include "ui/base/l10n/l10n_util.h" 27 #include "ui/base/l10n/l10n_util.h"
25 28
26 #if defined(OS_WIN) 29 #if defined(OS_WIN)
27 #include "chrome/installer/util/wmi.h" 30 #include "chrome/installer/util/wmi.h"
28 #endif 31 #endif
29 32
30 using content::BrowserThread; 33 using content::BrowserThread;
31 using content::SpeechRecognitionManager; 34 using content::SpeechRecognitionManager;
35 using content::SpeechRecognitionSessionContext;
32 36
33 namespace speech { 37 namespace speech {
34 38
35 // Asynchronously fetches the PC and audio hardware/driver info if 39 // Asynchronously fetches the PC and audio hardware/driver info if
36 // the user has opted into UMA. This information is sent with speech input 40 // the user has opted into UMA. This information is sent with speech input
37 // requests to the server for identifying and improving quality issues with 41 // requests to the server for identifying and improving quality issues with
38 // specific device configurations. 42 // specific device configurations.
39 class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo 43 class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo
40 : public base::RefCountedThreadSafe<OptionalRequestInfo> { 44 : public base::RefCountedThreadSafe<OptionalRequestInfo> {
41 public: 45 public:
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 ChromeSpeechRecognitionManagerDelegate::ChromeSpeechRecognitionManagerDelegate() 102 ChromeSpeechRecognitionManagerDelegate::ChromeSpeechRecognitionManagerDelegate()
99 : bubble_controller_(new SpeechRecognitionBubbleController( 103 : bubble_controller_(new SpeechRecognitionBubbleController(
100 ALLOW_THIS_IN_INITIALIZER_LIST(this))) { 104 ALLOW_THIS_IN_INITIALIZER_LIST(this))) {
101 } 105 }
102 106
103 ChromeSpeechRecognitionManagerDelegate:: 107 ChromeSpeechRecognitionManagerDelegate::
104 ~ChromeSpeechRecognitionManagerDelegate() { 108 ~ChromeSpeechRecognitionManagerDelegate() {
105 } 109 }
106 110
107 void ChromeSpeechRecognitionManagerDelegate::ShowRecognitionRequested( 111 void ChromeSpeechRecognitionManagerDelegate::ShowRecognitionRequested(
108 int session_id, 112 int session_id) {
109 int render_process_id, 113 const SpeechRecognitionSessionContext& context =
110 int render_view_id, 114 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
111 const gfx::Rect& element_rect) { 115 bubble_controller_->CreateBubble(session_id,
112 bubble_controller_->CreateBubble(session_id, render_process_id, 116 context.render_process_id,
113 render_view_id, element_rect); 117 context.render_view_id,
118 context.element_rect);
114 } 119 }
115 120
116 void ChromeSpeechRecognitionManagerDelegate::GetRequestInfo( 121 void ChromeSpeechRecognitionManagerDelegate::GetDiagnosticInformation(
117 bool* can_report_metrics, 122 bool* can_report_metrics,
118 std::string* request_info) { 123 std::string* hardware_info) {
119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
120 if (!optional_request_info_.get()) { 125 if (!optional_request_info_.get()) {
121 optional_request_info_ = new OptionalRequestInfo(); 126 optional_request_info_ = new OptionalRequestInfo();
122 // Since hardware info is optional with speech input requests, we start an 127 // Since hardware info is optional with speech input requests, we start an
123 // asynchronous fetch here and move on with recording audio. This first 128 // asynchronous fetch here and move on with recording audio. This first
124 // speech input request would send an empty string for hardware info and 129 // speech input request would send an empty string for hardware info and
125 // subsequent requests may have the hardware info available if the fetch 130 // subsequent requests may have the hardware info available if the fetch
126 // completed before them. This way we don't end up stalling the user with 131 // completed before them. This way we don't end up stalling the user with
127 // a long wait and disk seeks when they click on a UI element and start 132 // a long wait and disk seeks when they click on a UI element and start
128 // speaking. 133 // speaking.
129 optional_request_info_->Refresh(); 134 optional_request_info_->Refresh();
130 } 135 }
131 *can_report_metrics = optional_request_info_->can_report_metrics(); 136 *can_report_metrics = optional_request_info_->can_report_metrics();
132 *request_info = optional_request_info_->value(); 137 *hardware_info = optional_request_info_->value();
138 }
139
140 void ChromeSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowedAsync(
141 int session_id,
142 base::Callback<void(int session_id, bool is_allowed)> callback) {
143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
144 const SpeechRecognitionSessionContext& context =
145 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
146
147 // The check must be performed in the UI thread. Therefore we defer it,
148 // postingt CheckRenderViewType, which will issue the callback on our behalf.
hans 2012/04/25 13:06:46 nit: s/postingt/posting to/
Primiano Tucci (use gerrit) 2012/04/25 16:55:49 Done.
149 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
150 base::Bind(&CheckRenderViewType,
151 session_id,
152 callback,
153 context.render_process_id,
154 context.render_view_id));
hans 2012/04/25 13:06:46 i think this way of solving the problem of checkin
Primiano Tucci (use gerrit) 2012/04/25 16:55:49 Done.
133 } 155 }
134 156
135 void ChromeSpeechRecognitionManagerDelegate::ShowWarmUp(int session_id) { 157 void ChromeSpeechRecognitionManagerDelegate::ShowWarmUp(int session_id) {
136 bubble_controller_->SetBubbleWarmUpMode(session_id); 158 bubble_controller_->SetBubbleWarmUpMode(session_id);
137 } 159 }
138 160
139 void ChromeSpeechRecognitionManagerDelegate::ShowRecognizing(int session_id) { 161 void ChromeSpeechRecognitionManagerDelegate::ShowRecognizing(int session_id) {
140 bubble_controller_->SetBubbleRecognizingMode(session_id); 162 bubble_controller_->SetBubbleRecognizingMode(session_id);
141 } 163 }
142 164
143 void ChromeSpeechRecognitionManagerDelegate::ShowRecording(int session_id) { 165 void ChromeSpeechRecognitionManagerDelegate::ShowRecording(int session_id) {
144 bubble_controller_->SetBubbleRecordingMode(session_id); 166 bubble_controller_->SetBubbleRecordingMode(session_id);
145 } 167 }
146 168
147 void ChromeSpeechRecognitionManagerDelegate::ShowInputVolume( 169 void ChromeSpeechRecognitionManagerDelegate::ShowInputVolume(
148 int session_id, float volume, float noise_volume) { 170 int session_id, float volume, float noise_volume) {
149 bubble_controller_->SetBubbleInputVolume(session_id, volume, noise_volume); 171 bubble_controller_->SetBubbleInputVolume(session_id, volume, noise_volume);
150 } 172 }
151 173
152 void ChromeSpeechRecognitionManagerDelegate::ShowMicError(int session_id, 174 void ChromeSpeechRecognitionManagerDelegate::ShowError(
153 MicError error) { 175 int session_id, const content::SpeechRecognitionError& error) {
154 switch (error) { 176 int error_message_id = 0;
155 case MIC_ERROR_NO_DEVICE_AVAILABLE: 177 switch (error.code) {
156 bubble_controller_->SetBubbleMessage( 178 case content::SPEECH_RECOGNITION_ERROR_AUDIO:
157 session_id, l10n_util::GetStringUTF16(IDS_SPEECH_INPUT_NO_MIC)); 179 switch (error.details) {
180 case content::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC:
181 error_message_id = IDS_SPEECH_INPUT_NO_MIC;
182 break;
183 case content::SPEECH_AUDIO_ERROR_DETAILS_IN_USE:
184 error_message_id = IDS_SPEECH_INPUT_MIC_IN_USE;
185 break;
186 default:
187 error_message_id = IDS_SPEECH_INPUT_MIC_ERROR;
188 break;
189 }
158 break; 190 break;
159 191 case content::SPEECH_RECOGNITION_ERROR_NO_SPEECH:
160 case MIC_ERROR_DEVICE_IN_USE: 192 error_message_id = IDS_SPEECH_INPUT_NO_SPEECH;
161 bubble_controller_->SetBubbleMessage(
162 session_id, l10n_util::GetStringUTF16(IDS_SPEECH_INPUT_MIC_IN_USE));
163 break; 193 break;
164 194 case content::SPEECH_RECOGNITION_ERROR_NO_MATCH:
195 error_message_id = IDS_SPEECH_INPUT_NO_RESULTS;
196 break;
197 case content::SPEECH_RECOGNITION_ERROR_NETWORK:
198 error_message_id = IDS_SPEECH_INPUT_NET_ERROR;
199 break;
165 default: 200 default:
166 NOTREACHED(); 201 NOTREACHED() << "unknown error " << error.code;
202 return;
167 } 203 }
168 } 204 bubble_controller_->SetBubbleMessage(
169 205 session_id, l10n_util::GetStringUTF16(error_message_id));
170 void ChromeSpeechRecognitionManagerDelegate::ShowRecognizerError(
171 int session_id, content::SpeechRecognitionErrorCode error) {
172 struct ErrorMessageMapEntry {
173 content::SpeechRecognitionErrorCode error;
174 int message_id;
175 };
176 ErrorMessageMapEntry error_message_map[] = {
177 {
178 content::SPEECH_RECOGNITION_ERROR_AUDIO, IDS_SPEECH_INPUT_MIC_ERROR
179 }, {
180 content::SPEECH_RECOGNITION_ERROR_NO_SPEECH, IDS_SPEECH_INPUT_NO_SPEECH
181 }, {
182 content::SPEECH_RECOGNITION_ERROR_NO_MATCH, IDS_SPEECH_INPUT_NO_RESULTS
183 }, {
184 content::SPEECH_RECOGNITION_ERROR_NETWORK, IDS_SPEECH_INPUT_NET_ERROR
185 }
186 };
187 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(error_message_map); ++i) {
188 if (error_message_map[i].error == error) {
189 bubble_controller_->SetBubbleMessage(
190 session_id,
191 l10n_util::GetStringUTF16(error_message_map[i].message_id));
192 return;
193 }
194 }
195
196 NOTREACHED() << "unknown error " << error;
197 } 206 }
198 207
199 void ChromeSpeechRecognitionManagerDelegate::DoClose(int session_id) { 208 void ChromeSpeechRecognitionManagerDelegate::DoClose(int session_id) {
200 bubble_controller_->CloseBubble(session_id); 209 bubble_controller_->CloseBubble(session_id);
201 } 210 }
202 211
203 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked( 212 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked(
204 int session_id, SpeechRecognitionBubble::Button button) { 213 int session_id, SpeechRecognitionBubble::Button button) {
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
206 215
207 if (button == SpeechRecognitionBubble::BUTTON_CANCEL) { 216 if (button == SpeechRecognitionBubble::BUTTON_CANCEL) {
208 SpeechRecognitionManager::GetInstance()->CancelRecognitionForRequest( 217 SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
209 session_id);
210 } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) { 218 } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) {
211 SpeechRecognitionManager::GetInstance()->StartRecognitionForRequest( 219 SpeechRecognitionManager::GetInstance()->StartSession(session_id);
212 session_id);
213 } 220 }
214 } 221 }
215 222
216 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleFocusChanged( 223 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleFocusChanged(
217 int session_id) { 224 int session_id) {
218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
219 SpeechRecognitionManager::GetInstance()->FocusLostForRequest(session_id); 226 SpeechRecognitionManager::GetInstance()->SendSessionToBackground(session_id);
227 }
228
229 void ChromeSpeechRecognitionManagerDelegate::CheckRenderViewType(
230 int session_id,
231 base::Callback<void(int session_id, bool is_allowed)> callback,
232 int render_process_id,
233 int render_view_id) {
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
235 const content::RenderViewHost* render_view_host =
236 content::RenderViewHost::FromID(render_process_id, render_view_id);
237 // For host delegates other than VIEW_TYPE_WEB_CONTENTS we can't reliably show
238 // a popup, including the speech input bubble. In these cases for privacy
239 // reasons we don't want to start recording if the user can't be properly
240 // notified. An example of this is trying to show the speech input bubble
241 // within an extension popup: http://crbug.com/92083. In these situations the
242 // speech input extension API should be used instead.
hans 2012/04/25 13:06:46 i would add a blank line before and after this com
Primiano Tucci (use gerrit) 2012/04/25 16:55:49 Done.
243 const bool allowed = (render_view_host != NULL &&
244 render_view_host->GetDelegate() != NULL &&
245 render_view_host->GetDelegate()->GetRenderViewType() ==
246 content::VIEW_TYPE_WEB_CONTENTS);
247 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
248 base::Bind(callback, session_id, allowed));
220 } 249 }
221 250
222 } // namespace speech 251 } // namespace speech
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698