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

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

Powered by Google App Engine
This is Rietveld 408576698