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

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 Satish review. 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 "base/synchronization/waitable_event.h"
Satish 2012/04/23 10:25:17 move up by 2 lines
Primiano Tucci (use gerrit) 2012/04/23 12:52:25 Done.
13 #include "chrome/browser/browser_process.h" 14 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/prefs/pref_service.h" 15 #include "chrome/browser/prefs/pref_service.h"
15 #include "chrome/browser/profiles/profile_manager.h" 16 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/tab_contents/tab_util.h" 17 #include "chrome/browser/tab_contents/tab_util.h"
17 #include "chrome/common/pref_names.h" 18 #include "chrome/common/pref_names.h"
19 #include "content/browser/renderer_host/render_view_host_impl.h"
18 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/render_view_host_delegate.h"
19 #include "content/public/browser/resource_context.h" 22 #include "content/public/browser/resource_context.h"
20 #include "content/public/browser/speech_recognition_manager.h" 23 #include "content/public/browser/speech_recognition_manager.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"
26 #include "content/public/browser/speech_recognition_session_context.h"
23 #include "grit/generated_resources.h" 27 #include "grit/generated_resources.h"
24 #include "ui/base/l10n/l10n_util.h" 28 #include "ui/base/l10n/l10n_util.h"
25 29
26 #if defined(OS_WIN) 30 #if defined(OS_WIN)
27 #include "chrome/installer/util/wmi.h" 31 #include "chrome/installer/util/wmi.h"
28 #endif 32 #endif
29 33
34 using base::WaitableEvent;
30 using content::BrowserThread; 35 using content::BrowserThread;
36 using content::RenderViewHostImpl;
31 using content::SpeechRecognitionManager; 37 using content::SpeechRecognitionManager;
38 using content::SpeechRecognitionSessionContext;
32 39
33 namespace speech { 40 namespace speech {
34 41
35 // Asynchronously fetches the PC and audio hardware/driver info if 42 // Asynchronously fetches the PC and audio hardware/driver info if
36 // the user has opted into UMA. This information is sent with speech input 43 // 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 44 // requests to the server for identifying and improving quality issues with
38 // specific device configurations. 45 // specific device configurations.
39 class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo 46 class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo
40 : public base::RefCountedThreadSafe<OptionalRequestInfo> { 47 : public base::RefCountedThreadSafe<OptionalRequestInfo> {
41 public: 48 public:
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 ChromeSpeechRecognitionManagerDelegate::ChromeSpeechRecognitionManagerDelegate() 105 ChromeSpeechRecognitionManagerDelegate::ChromeSpeechRecognitionManagerDelegate()
99 : bubble_controller_(new SpeechRecognitionBubbleController( 106 : bubble_controller_(new SpeechRecognitionBubbleController(
100 ALLOW_THIS_IN_INITIALIZER_LIST(this))) { 107 ALLOW_THIS_IN_INITIALIZER_LIST(this))) {
101 } 108 }
102 109
103 ChromeSpeechRecognitionManagerDelegate:: 110 ChromeSpeechRecognitionManagerDelegate::
104 ~ChromeSpeechRecognitionManagerDelegate() { 111 ~ChromeSpeechRecognitionManagerDelegate() {
105 } 112 }
106 113
107 void ChromeSpeechRecognitionManagerDelegate::ShowRecognitionRequested( 114 void ChromeSpeechRecognitionManagerDelegate::ShowRecognitionRequested(
108 int session_id, 115 int session_id) {
109 int render_process_id, 116 const SpeechRecognitionSessionContext& context =
110 int render_view_id, 117 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
111 const gfx::Rect& element_rect) { 118 bubble_controller_->CreateBubble(session_id,
112 bubble_controller_->CreateBubble(session_id, render_process_id, 119 context.render_process_id,
113 render_view_id, element_rect); 120 context.render_view_id,
121 context.element_rect);
114 } 122 }
115 123
116 void ChromeSpeechRecognitionManagerDelegate::GetRequestInfo( 124 void ChromeSpeechRecognitionManagerDelegate::GetDiagnosticInformation(
117 bool* can_report_metrics, 125 bool* can_report_metrics,
118 std::string* request_info) { 126 std::string* hardware_info) {
119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
120 if (!optional_request_info_.get()) { 128 if (!optional_request_info_.get()) {
121 optional_request_info_ = new OptionalRequestInfo(); 129 optional_request_info_ = new OptionalRequestInfo();
122 // Since hardware info is optional with speech input requests, we start an 130 // Since hardware info is optional with speech input requests, we start an
123 // asynchronous fetch here and move on with recording audio. This first 131 // asynchronous fetch here and move on with recording audio. This first
124 // speech input request would send an empty string for hardware info and 132 // speech input request would send an empty string for hardware info and
125 // subsequent requests may have the hardware info available if the fetch 133 // 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 134 // 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 135 // a long wait and disk seeks when they click on a UI element and start
128 // speaking. 136 // speaking.
129 optional_request_info_->Refresh(); 137 optional_request_info_->Refresh();
130 } 138 }
131 *can_report_metrics = optional_request_info_->can_report_metrics(); 139 *can_report_metrics = optional_request_info_->can_report_metrics();
132 *request_info = optional_request_info_->value(); 140 *hardware_info = optional_request_info_->value();
141 }
142
143 bool ChromeSpeechRecognitionManagerDelegate::IsRecognitionAllowed(
144 int session_id) {
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
146 const SpeechRecognitionSessionContext& context =
147 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
148 bool check_result = false;
149 WaitableEvent event(false /*manual_reset*/, false /*initially_signaled*/);
150
151 BrowserThread::PostTask(
152 BrowserThread::UI, FROM_HERE,
Satish 2012/04/23 10:25:17 indent by 4 spaces
Primiano Tucci (use gerrit) 2012/04/23 12:52:25 Done.
153 base::Bind(&CheckRenderViewType,
154 context.render_process_id,
155 context.render_view_id,
156 base::Unretained(&check_result),
157 base::Unretained(&event)));
158 event.Wait();
159 return check_result;
133 } 160 }
134 161
135 void ChromeSpeechRecognitionManagerDelegate::ShowWarmUp(int session_id) { 162 void ChromeSpeechRecognitionManagerDelegate::ShowWarmUp(int session_id) {
136 bubble_controller_->SetBubbleWarmUpMode(session_id); 163 bubble_controller_->SetBubbleWarmUpMode(session_id);
137 } 164 }
138 165
139 void ChromeSpeechRecognitionManagerDelegate::ShowRecognizing(int session_id) { 166 void ChromeSpeechRecognitionManagerDelegate::ShowRecognizing(int session_id) {
140 bubble_controller_->SetBubbleRecognizingMode(session_id); 167 bubble_controller_->SetBubbleRecognizingMode(session_id);
141 } 168 }
142 169
143 void ChromeSpeechRecognitionManagerDelegate::ShowRecording(int session_id) { 170 void ChromeSpeechRecognitionManagerDelegate::ShowRecording(int session_id) {
144 bubble_controller_->SetBubbleRecordingMode(session_id); 171 bubble_controller_->SetBubbleRecordingMode(session_id);
145 } 172 }
146 173
147 void ChromeSpeechRecognitionManagerDelegate::ShowInputVolume( 174 void ChromeSpeechRecognitionManagerDelegate::ShowInputVolume(
148 int session_id, float volume, float noise_volume) { 175 int session_id, float volume, float noise_volume) {
149 bubble_controller_->SetBubbleInputVolume(session_id, volume, noise_volume); 176 bubble_controller_->SetBubbleInputVolume(session_id, volume, noise_volume);
150 } 177 }
151 178
152 void ChromeSpeechRecognitionManagerDelegate::ShowMicError(int session_id, 179 void ChromeSpeechRecognitionManagerDelegate::ShowError(
153 MicError error) { 180 int session_id, const content::SpeechRecognitionError& error) {
154 switch (error) { 181 int error_message_id = 0;
155 case MIC_ERROR_NO_DEVICE_AVAILABLE: 182 switch (error.code) {
156 bubble_controller_->SetBubbleMessage( 183 case content::SPEECH_RECOGNITION_ERROR_AUDIO:
157 session_id, l10n_util::GetStringUTF16(IDS_SPEECH_INPUT_NO_MIC)); 184 switch (error.details) {
185 case content::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC:
186 error_message_id = IDS_SPEECH_INPUT_NO_MIC;
187 break;
188 case content::SPEECH_AUDIO_ERROR_DETAILS_IN_USE:
189 error_message_id = IDS_SPEECH_INPUT_MIC_IN_USE;
190 break;
191 default:
192 error_message_id = IDS_SPEECH_INPUT_MIC_ERROR;
193 break;
194 }
158 break; 195 break;
159 196 case content::SPEECH_RECOGNITION_ERROR_NO_SPEECH:
160 case MIC_ERROR_DEVICE_IN_USE: 197 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; 198 break;
164 199 case content::SPEECH_RECOGNITION_ERROR_NO_MATCH:
200 error_message_id = IDS_SPEECH_INPUT_NO_RESULTS;
201 break;
202 case content::SPEECH_RECOGNITION_ERROR_NETWORK:
203 error_message_id = IDS_SPEECH_INPUT_NET_ERROR;
204 break;
165 default: 205 default:
166 NOTREACHED(); 206 NOTREACHED() << "unknown error " << error.code;
207 return;
167 } 208 }
168 } 209 bubble_controller_->SetBubbleMessage(
169 210 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 } 211 }
198 212
199 void ChromeSpeechRecognitionManagerDelegate::DoClose(int session_id) { 213 void ChromeSpeechRecognitionManagerDelegate::DoClose(int session_id) {
200 bubble_controller_->CloseBubble(session_id); 214 bubble_controller_->CloseBubble(session_id);
201 } 215 }
202 216
203 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked( 217 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleButtonClicked(
204 int session_id, SpeechRecognitionBubble::Button button) { 218 int session_id, SpeechRecognitionBubble::Button button) {
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
206 220
207 if (button == SpeechRecognitionBubble::BUTTON_CANCEL) { 221 if (button == SpeechRecognitionBubble::BUTTON_CANCEL) {
208 SpeechRecognitionManager::GetInstance()->CancelRecognitionForRequest( 222 SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
209 session_id);
210 } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) { 223 } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) {
211 SpeechRecognitionManager::GetInstance()->StartRecognitionForRequest( 224 SpeechRecognitionManager::GetInstance()->StartSession(session_id);
212 session_id);
213 } 225 }
214 } 226 }
215 227
216 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleFocusChanged( 228 void ChromeSpeechRecognitionManagerDelegate::InfoBubbleFocusChanged(
217 int session_id) { 229 int session_id) {
218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
219 SpeechRecognitionManager::GetInstance()->FocusLostForRequest(session_id); 231 SpeechRecognitionManager::GetInstance()->DetachSession(session_id);
232 }
233
234 void ChromeSpeechRecognitionManagerDelegate::CheckRenderViewType(
235 int render_process_id,
236 int render_view_id,
237 bool* result,
238 WaitableEvent* event) {
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
240 RenderViewHostImpl* render_view_host =
241 RenderViewHostImpl::FromID(render_process_id, render_view_id);
242 // For host delegates other than VIEW_TYPE_WEB_CONTENTS we can't reliably show
243 // a popup, including the speech input bubble. In these cases for privacy
244 // reasons we don't want to start recording if the user can't be properly
245 // notified. An example of this is trying to show the speech input bubble
246 // within an extension popup: http://crbug.com/92083. In these situations the
247 // speech input extension API should be used instead.
248 if (!render_view_host || !render_view_host->GetDelegate()) {
Satish 2012/04/23 10:25:17 could merge this and the first 'else if' clause
Primiano Tucci (use gerrit) 2012/04/23 12:52:25 Done.
249 *result = false;
250 } else if (render_view_host->GetDelegate()->GetRenderViewType() !=
251 content::VIEW_TYPE_WEB_CONTENTS) {
252 *result = false;
253 } else {
254 *result = true;
255 }
256 event->Signal();
220 } 257 }
221 258
222 } // namespace speech 259 } // namespace speech
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698