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