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 "content/browser/speech/speech_input_manager.h" | 5 #include "content/browser/speech/speech_input_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "content/browser/browser_main_loop.h" |
8 #include "content/browser/renderer_host/render_view_host.h" | 9 #include "content/browser/renderer_host/render_view_host.h" |
9 #include "content/browser/speech/speech_input_manager_delegate.h" | 10 #include "content/browser/speech/speech_input_manager_delegate.h" |
10 #include "content/browser/speech/speech_recognizer.h" | 11 #include "content/browser/speech/speech_recognizer.h" |
11 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
12 #include "content/public/browser/render_view_host_delegate.h" | 13 #include "content/public/browser/render_view_host_delegate.h" |
13 #include "content/public/browser/resource_context.h" | 14 #include "content/public/browser/resource_context.h" |
14 #include "content/public/browser/speech_input_preferences.h" | 15 #include "content/public/browser/speech_input_preferences.h" |
15 #include "content/public/common/view_type.h" | 16 #include "content/public/common/view_type.h" |
16 #include "media/audio/audio_manager.h" | |
17 | 17 |
| 18 using content::BrowserMainLoop; |
18 using content::BrowserThread; | 19 using content::BrowserThread; |
19 using content::SpeechInputManagerDelegate; | 20 using content::SpeechInputManagerDelegate; |
20 | 21 |
21 namespace speech_input { | 22 namespace speech_input { |
22 | 23 |
23 struct SpeechInputManager::SpeechInputParams { | 24 struct SpeechInputManager::SpeechInputParams { |
24 SpeechInputParams(SpeechInputManagerDelegate* delegate, | 25 SpeechInputParams(SpeechInputManagerDelegate* delegate, |
25 int caller_id, | 26 int caller_id, |
26 int render_process_id, | 27 int render_process_id, |
27 int render_view_id, | 28 int render_view_id, |
28 const gfx::Rect& element_rect, | 29 const gfx::Rect& element_rect, |
29 const std::string& language, | 30 const std::string& language, |
30 const std::string& grammar, | 31 const std::string& grammar, |
31 const std::string& origin_url, | 32 const std::string& origin_url, |
32 net::URLRequestContextGetter* context_getter, | 33 net::URLRequestContextGetter* context_getter, |
33 content::SpeechInputPreferences* speech_input_prefs, | 34 content::SpeechInputPreferences* speech_input_prefs) |
34 AudioManager* audio_manager) | |
35 : delegate(delegate), | 35 : delegate(delegate), |
36 caller_id(caller_id), | 36 caller_id(caller_id), |
37 render_process_id(render_process_id), | 37 render_process_id(render_process_id), |
38 render_view_id(render_view_id), | 38 render_view_id(render_view_id), |
39 element_rect(element_rect), | 39 element_rect(element_rect), |
40 language(language), | 40 language(language), |
41 grammar(grammar), | 41 grammar(grammar), |
42 origin_url(origin_url), | 42 origin_url(origin_url), |
43 context_getter(context_getter), | 43 context_getter(context_getter), |
44 speech_input_prefs(speech_input_prefs), | 44 speech_input_prefs(speech_input_prefs) { |
45 audio_manager_(audio_manager) { | |
46 } | 45 } |
47 | 46 |
48 SpeechInputManagerDelegate* delegate; | 47 SpeechInputManagerDelegate* delegate; |
49 int caller_id; | 48 int caller_id; |
50 int render_process_id; | 49 int render_process_id; |
51 int render_view_id; | 50 int render_view_id; |
52 gfx::Rect element_rect; | 51 gfx::Rect element_rect; |
53 std::string language; | 52 std::string language; |
54 std::string grammar; | 53 std::string grammar; |
55 std::string origin_url; | 54 std::string origin_url; |
56 net::URLRequestContextGetter* context_getter; | 55 net::URLRequestContextGetter* context_getter; |
57 content::SpeechInputPreferences* speech_input_prefs; | 56 content::SpeechInputPreferences* speech_input_prefs; |
58 AudioManager* audio_manager_; | |
59 }; | 57 }; |
60 | 58 |
61 SpeechInputManager::SpeechInputManager() | 59 SpeechInputManager::SpeechInputManager() |
62 : can_report_metrics_(false), | 60 : can_report_metrics_(false), |
63 recording_caller_id_(0) { | 61 recording_caller_id_(0) { |
64 } | 62 } |
65 | 63 |
66 SpeechInputManager::~SpeechInputManager() { | 64 SpeechInputManager::~SpeechInputManager() { |
67 while (requests_.begin() != requests_.end()) | 65 while (requests_.begin() != requests_.end()) |
68 CancelRecognition(requests_.begin()->first); | 66 CancelRecognition(requests_.begin()->first); |
69 } | 67 } |
70 | 68 |
| 69 bool SpeechInputManager::HasAudioInputDevices() { |
| 70 return BrowserMainLoop::GetAudioManager()->HasAudioInputDevices(); |
| 71 } |
| 72 |
| 73 bool SpeechInputManager::IsRecordingInProcess() { |
| 74 return BrowserMainLoop::GetAudioManager()->IsRecordingInProcess(); |
| 75 } |
| 76 |
| 77 string16 SpeechInputManager::GetAudioInputDeviceModel() { |
| 78 return BrowserMainLoop::GetAudioManager()->GetAudioInputDeviceModel(); |
| 79 } |
| 80 |
71 bool SpeechInputManager::HasPendingRequest(int caller_id) const { | 81 bool SpeechInputManager::HasPendingRequest(int caller_id) const { |
72 return requests_.find(caller_id) != requests_.end(); | 82 return requests_.find(caller_id) != requests_.end(); |
73 } | 83 } |
74 | 84 |
75 SpeechInputManagerDelegate* SpeechInputManager::GetDelegate( | 85 SpeechInputManagerDelegate* SpeechInputManager::GetDelegate( |
76 int caller_id) const { | 86 int caller_id) const { |
77 return requests_.find(caller_id)->second.delegate; | 87 return requests_.find(caller_id)->second.delegate; |
78 } | 88 } |
79 | 89 |
80 // static | 90 // static |
81 void SpeechInputManager::ShowAudioInputSettings(AudioManager* audio_manager) { | 91 void SpeechInputManager::ShowAudioInputSettings() { |
82 // Since AudioManager::ShowAudioInputSettings can potentially launch external | 92 // Since AudioManager::ShowAudioInputSettings can potentially launch external |
83 // processes, do that in the FILE thread to not block the calling threads. | 93 // processes, do that in the FILE thread to not block the calling threads. |
84 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { | 94 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { |
85 BrowserThread::PostTask( | 95 BrowserThread::PostTask( |
86 BrowserThread::FILE, FROM_HERE, | 96 BrowserThread::FILE, FROM_HERE, |
87 base::Bind(&SpeechInputManager::ShowAudioInputSettings, | 97 base::Bind(&SpeechInputManager::ShowAudioInputSettings)); |
88 base::Unretained(audio_manager))); | |
89 return; | 98 return; |
90 } | 99 } |
91 | 100 |
| 101 AudioManager* audio_manager = BrowserMainLoop::GetAudioManager(); |
92 DCHECK(audio_manager->CanShowAudioInputSettings()); | 102 DCHECK(audio_manager->CanShowAudioInputSettings()); |
93 if (audio_manager->CanShowAudioInputSettings()) | 103 if (audio_manager->CanShowAudioInputSettings()) |
94 audio_manager->ShowAudioInputSettings(); | 104 audio_manager->ShowAudioInputSettings(); |
95 } | 105 } |
96 | 106 |
97 // static | |
98 void SpeechInputManager::ShowAudioInputSettingsFromUI( | |
99 content::ResourceContext* resource_context) { | |
100 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | |
101 BrowserThread::PostTask( | |
102 BrowserThread::IO, FROM_HERE, | |
103 base::Bind(&SpeechInputManager::ShowAudioInputSettingsFromUI, | |
104 base::Unretained(resource_context))); | |
105 return; | |
106 } | |
107 ShowAudioInputSettings(resource_context->GetAudioManager()); | |
108 } | |
109 | |
110 void SpeechInputManager::StartRecognition( | 107 void SpeechInputManager::StartRecognition( |
111 SpeechInputManagerDelegate* delegate, | 108 SpeechInputManagerDelegate* delegate, |
112 int caller_id, | 109 int caller_id, |
113 int render_process_id, | 110 int render_process_id, |
114 int render_view_id, | 111 int render_view_id, |
115 const gfx::Rect& element_rect, | 112 const gfx::Rect& element_rect, |
116 const std::string& language, | 113 const std::string& language, |
117 const std::string& grammar, | 114 const std::string& grammar, |
118 const std::string& origin_url, | 115 const std::string& origin_url, |
119 net::URLRequestContextGetter* context_getter, | 116 net::URLRequestContextGetter* context_getter, |
120 content::SpeechInputPreferences* speech_input_prefs, | 117 content::SpeechInputPreferences* speech_input_prefs) { |
121 AudioManager* audio_manager) { | |
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
123 BrowserThread::PostTask( | 119 BrowserThread::PostTask( |
124 BrowserThread::UI, FROM_HERE, | 120 BrowserThread::UI, FROM_HERE, |
125 base::Bind(&SpeechInputManager::CheckRenderViewTypeAndStartRecognition, | 121 base::Bind( |
126 base::Unretained(this), SpeechInputParams(delegate, caller_id, | 122 &SpeechInputManager::CheckRenderViewTypeAndStartRecognition, |
127 render_process_id, render_view_id, element_rect, language, grammar, | 123 base::Unretained(this), |
128 origin_url, context_getter, speech_input_prefs, audio_manager))); | 124 SpeechInputParams( |
| 125 delegate, caller_id, render_process_id, render_view_id, |
| 126 element_rect, language, grammar, origin_url, context_getter, |
| 127 speech_input_prefs))); |
129 } | 128 } |
130 | 129 |
131 void SpeechInputManager::CheckRenderViewTypeAndStartRecognition( | 130 void SpeechInputManager::CheckRenderViewTypeAndStartRecognition( |
132 const SpeechInputParams& params) { | 131 const SpeechInputParams& params) { |
133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
134 | 133 |
135 RenderViewHost* render_view_host = RenderViewHost::FromID( | 134 RenderViewHost* render_view_host = RenderViewHost::FromID( |
136 params.render_process_id, params.render_view_id); | 135 params.render_process_id, params.render_view_id); |
137 if (!render_view_host || !render_view_host->delegate()) | 136 if (!render_view_host || !render_view_host->delegate()) |
138 return; | 137 return; |
(...skipping 14 matching lines...) Expand all Loading... |
153 } | 152 } |
154 | 153 |
155 void SpeechInputManager::ProceedStartingRecognition( | 154 void SpeechInputManager::ProceedStartingRecognition( |
156 const SpeechInputParams& params) { | 155 const SpeechInputParams& params) { |
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
158 DCHECK(!HasPendingRequest(params.caller_id)); | 157 DCHECK(!HasPendingRequest(params.caller_id)); |
159 | 158 |
160 ShowRecognitionRequested( | 159 ShowRecognitionRequested( |
161 params.caller_id, params.render_process_id, params.render_view_id, | 160 params.caller_id, params.render_process_id, params.render_view_id, |
162 params.element_rect); | 161 params.element_rect); |
163 GetRequestInfo(params.audio_manager_, &can_report_metrics_, | 162 GetRequestInfo(&can_report_metrics_, &request_info_); |
164 &request_info_); | |
165 | 163 |
166 SpeechInputRequest* request = &requests_[params.caller_id]; | 164 SpeechInputRequest* request = &requests_[params.caller_id]; |
167 request->delegate = params.delegate; | 165 request->delegate = params.delegate; |
168 request->recognizer = new SpeechRecognizer( | 166 request->recognizer = new SpeechRecognizer( |
169 this, params.caller_id, params.language, params.grammar, | 167 this, params.caller_id, params.language, params.grammar, |
170 params.context_getter, params.audio_manager_, | 168 params.context_getter, params.speech_input_prefs->FilterProfanities(), |
171 params.speech_input_prefs->FilterProfanities(), | |
172 request_info_, can_report_metrics_ ? params.origin_url : ""); | 169 request_info_, can_report_metrics_ ? params.origin_url : ""); |
173 request->is_active = false; | 170 request->is_active = false; |
174 | 171 |
175 StartRecognitionForRequest(params.caller_id); | 172 StartRecognitionForRequest(params.caller_id); |
176 } | 173 } |
177 | 174 |
178 void SpeechInputManager::StartRecognitionForRequest(int caller_id) { | 175 void SpeechInputManager::StartRecognitionForRequest(int caller_id) { |
179 SpeechRecognizerMap::iterator request = requests_.find(caller_id); | 176 SpeechRecognizerMap::iterator request = requests_.find(caller_id); |
180 if (request == requests_.end()) { | 177 if (request == requests_.end()) { |
181 NOTREACHED(); | 178 NOTREACHED(); |
182 return; | 179 return; |
183 } | 180 } |
184 | 181 |
185 // If we are currently recording audio for another caller, abort that cleanly. | 182 // If we are currently recording audio for another caller, abort that cleanly. |
186 if (recording_caller_id_) | 183 if (recording_caller_id_) |
187 CancelRecognitionAndInformDelegate(recording_caller_id_); | 184 CancelRecognitionAndInformDelegate(recording_caller_id_); |
188 | 185 |
189 AudioManager* audio_man = request->second.recognizer->audio_manager(); | 186 if (!HasAudioInputDevices()) { |
190 if (!audio_man->HasAudioInputDevices()) { | |
191 ShowMicError(caller_id, kNoDeviceAvailable); | 187 ShowMicError(caller_id, kNoDeviceAvailable); |
192 } else if (audio_man->IsRecordingInProcess()) { | 188 } else if (IsRecordingInProcess()) { |
193 ShowMicError(caller_id, kDeviceInUse); | 189 ShowMicError(caller_id, kDeviceInUse); |
194 } else { | 190 } else { |
195 recording_caller_id_ = caller_id; | 191 recording_caller_id_ = caller_id; |
196 requests_[caller_id].is_active = true; | 192 requests_[caller_id].is_active = true; |
197 requests_[caller_id].recognizer->StartRecording(); | 193 requests_[caller_id].recognizer->StartRecording(); |
198 ShowWarmUp(caller_id); | 194 ShowWarmUp(caller_id); |
199 } | 195 } |
200 } | 196 } |
201 | 197 |
202 void SpeechInputManager::CancelRecognition(int caller_id) { | 198 void SpeechInputManager::CancelRecognition(int caller_id) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 | 304 |
309 SpeechInputManager::SpeechInputRequest::SpeechInputRequest() | 305 SpeechInputManager::SpeechInputRequest::SpeechInputRequest() |
310 : delegate(NULL), | 306 : delegate(NULL), |
311 is_active(false) { | 307 is_active(false) { |
312 } | 308 } |
313 | 309 |
314 SpeechInputManager::SpeechInputRequest::~SpeechInputRequest() { | 310 SpeechInputManager::SpeechInputRequest::~SpeechInputRequest() { |
315 } | 311 } |
316 | 312 |
317 } // namespace speech_input | 313 } // namespace speech_input |
OLD | NEW |