OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/speech_input_manager.h" | 5 #include "chrome/browser/speech/speech_input_manager.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "app/l10n_util.h" | 10 #include "app/l10n_util.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "chrome/browser/browser_process.h" | 30 #include "chrome/browser/browser_process.h" |
31 #include "chrome/installer/util/wmi.h" | 31 #include "chrome/installer/util/wmi.h" |
32 #endif | 32 #endif |
33 | 33 |
34 namespace { | 34 namespace { |
35 | 35 |
36 // Asynchronously fetches the PC and audio hardware/driver info on windows if | 36 // Asynchronously fetches the PC and audio hardware/driver info on windows if |
37 // the user has opted into UMA. This information is sent with speech input | 37 // the user has opted into UMA. This information is sent with speech input |
38 // requests to the server for identifying and improving quality issues with | 38 // requests to the server for identifying and improving quality issues with |
39 // specific device configurations. | 39 // specific device configurations. |
40 class HardwareInfo : public base::RefCountedThreadSafe<HardwareInfo> { | 40 class OptionalRequestInfo |
| 41 : public base::RefCountedThreadSafe<OptionalRequestInfo> { |
41 public: | 42 public: |
42 HardwareInfo() {} | 43 OptionalRequestInfo() : can_report_metrics_(false) {} |
43 | 44 |
44 #if defined(OS_WIN) | 45 #if defined(OS_WIN) |
45 void Refresh() { | 46 void Refresh() { |
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
47 // UMA opt-in can be checked only from the UI thread, so switch to that. | 48 // UMA opt-in can be checked only from the UI thread, so switch to that. |
48 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 49 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
49 NewRunnableMethod(this, &HardwareInfo::CheckUMAAndGetHardwareInfo)); | 50 NewRunnableMethod(this, |
| 51 &OptionalRequestInfo::CheckUMAAndGetHardwareInfo)); |
50 } | 52 } |
51 | 53 |
52 void CheckUMAAndGetHardwareInfo() { | 54 void CheckUMAAndGetHardwareInfo() { |
53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 55 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
54 if (g_browser_process->local_state()->GetBoolean( | 56 if (g_browser_process->local_state()->GetBoolean( |
55 prefs::kMetricsReportingEnabled)) { | 57 prefs::kMetricsReportingEnabled)) { |
56 // Access potentially slow OS calls from the FILE thread. | 58 // Access potentially slow OS calls from the FILE thread. |
57 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 59 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
58 NewRunnableMethod(this, &HardwareInfo::GetHardwareInfo)); | 60 NewRunnableMethod(this, &OptionalRequestInfo::GetHardwareInfo)); |
59 } | 61 } |
60 } | 62 } |
61 | 63 |
62 void GetHardwareInfo() { | 64 void GetHardwareInfo() { |
63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
64 AutoLock lock(lock_); | 66 AutoLock lock(lock_); |
| 67 can_report_metrics_ = true; |
65 value_ = UTF16ToUTF8( | 68 value_ = UTF16ToUTF8( |
66 installer::WMIComputerSystem::GetModel() + L"|" + | 69 installer::WMIComputerSystem::GetModel() + L"|" + |
67 AudioManager::GetAudioManager()->GetAudioInputDeviceModel()); | 70 AudioManager::GetAudioManager()->GetAudioInputDeviceModel()); |
68 } | 71 } |
69 | 72 |
70 std::string value() { | 73 std::string value() { |
71 AutoLock lock(lock_); | 74 AutoLock lock(lock_); |
72 return value_; | 75 return value_; |
73 } | 76 } |
74 | 77 |
| 78 bool can_report_metrics() { |
| 79 AutoLock lock(lock_); |
| 80 return can_report_metrics_; |
| 81 } |
| 82 |
75 private: | 83 private: |
76 Lock lock_; | 84 Lock lock_; |
77 std::string value_; | 85 std::string value_; |
| 86 bool can_report_metrics_; |
78 | 87 |
79 #else // defined(OS_WIN) | 88 #else // defined(OS_WIN) |
80 void Refresh() {} | 89 void Refresh() {} |
81 std::string value() { return std::string(); } | 90 std::string value() { return std::string(); } |
82 #endif // defined(OS_WIN) | 91 #endif // defined(OS_WIN) |
83 | 92 |
84 DISALLOW_COPY_AND_ASSIGN(HardwareInfo); | 93 DISALLOW_COPY_AND_ASSIGN(OptionalRequestInfo); |
85 }; | 94 }; |
86 | 95 |
87 } // namespace | 96 } // namespace |
88 | 97 |
89 namespace speech_input { | 98 namespace speech_input { |
90 | 99 |
91 class SpeechInputManagerImpl : public SpeechInputManager, | 100 class SpeechInputManagerImpl : public SpeechInputManager, |
92 public SpeechInputBubbleControllerDelegate, | 101 public SpeechInputBubbleControllerDelegate, |
93 public SpeechRecognizerDelegate { | 102 public SpeechRecognizerDelegate { |
94 public: | 103 public: |
95 // SpeechInputManager methods. | 104 // SpeechInputManager methods. |
96 virtual void StartRecognition(SpeechInputManagerDelegate* delegate, | 105 virtual void StartRecognition(SpeechInputManagerDelegate* delegate, |
97 int caller_id, | 106 int caller_id, |
98 int render_process_id, | 107 int render_process_id, |
99 int render_view_id, | 108 int render_view_id, |
100 const gfx::Rect& element_rect, | 109 const gfx::Rect& element_rect, |
101 const std::string& language, | 110 const std::string& language, |
102 const std::string& grammar); | 111 const std::string& grammar, |
| 112 const std::string& origin_url); |
103 virtual void CancelRecognition(int caller_id); | 113 virtual void CancelRecognition(int caller_id); |
104 virtual void StopRecording(int caller_id); | 114 virtual void StopRecording(int caller_id); |
105 | 115 |
106 // SpeechRecognizer::Delegate methods. | 116 // SpeechRecognizer::Delegate methods. |
107 virtual void SetRecognitionResult(int caller_id, | 117 virtual void SetRecognitionResult(int caller_id, |
108 bool error, | 118 bool error, |
109 const SpeechInputResultArray& result); | 119 const SpeechInputResultArray& result); |
110 virtual void DidCompleteRecording(int caller_id); | 120 virtual void DidCompleteRecording(int caller_id); |
111 virtual void DidCompleteRecognition(int caller_id); | 121 virtual void DidCompleteRecognition(int caller_id); |
112 virtual void OnRecognizerError(int caller_id, | 122 virtual void OnRecognizerError(int caller_id, |
(...skipping 23 matching lines...) Expand all Loading... |
136 | 146 |
137 void CancelRecognitionAndInformDelegate(int caller_id); | 147 void CancelRecognitionAndInformDelegate(int caller_id); |
138 | 148 |
139 // Starts/restarts recognition for an existing request. | 149 // Starts/restarts recognition for an existing request. |
140 void StartRecognitionForRequest(int caller_id); | 150 void StartRecognitionForRequest(int caller_id); |
141 | 151 |
142 typedef std::map<int, SpeechInputRequest> SpeechRecognizerMap; | 152 typedef std::map<int, SpeechInputRequest> SpeechRecognizerMap; |
143 SpeechRecognizerMap requests_; | 153 SpeechRecognizerMap requests_; |
144 int recording_caller_id_; | 154 int recording_caller_id_; |
145 scoped_refptr<SpeechInputBubbleController> bubble_controller_; | 155 scoped_refptr<SpeechInputBubbleController> bubble_controller_; |
146 scoped_refptr<HardwareInfo> hardware_info_; | 156 scoped_refptr<OptionalRequestInfo> optional_request_info_; |
147 }; | 157 }; |
148 | 158 |
149 static ::base::LazyInstance<SpeechInputManagerImpl> g_speech_input_manager_impl( | 159 static ::base::LazyInstance<SpeechInputManagerImpl> g_speech_input_manager_impl( |
150 base::LINKER_INITIALIZED); | 160 base::LINKER_INITIALIZED); |
151 | 161 |
152 SpeechInputManager* SpeechInputManager::Get() { | 162 SpeechInputManager* SpeechInputManager::Get() { |
153 return g_speech_input_manager_impl.Pointer(); | 163 return g_speech_input_manager_impl.Pointer(); |
154 } | 164 } |
155 | 165 |
156 bool SpeechInputManager::IsFeatureEnabled() { | 166 bool SpeechInputManager::IsFeatureEnabled() { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 return requests_.find(caller_id)->second.delegate; | 203 return requests_.find(caller_id)->second.delegate; |
194 } | 204 } |
195 | 205 |
196 void SpeechInputManagerImpl::StartRecognition( | 206 void SpeechInputManagerImpl::StartRecognition( |
197 SpeechInputManagerDelegate* delegate, | 207 SpeechInputManagerDelegate* delegate, |
198 int caller_id, | 208 int caller_id, |
199 int render_process_id, | 209 int render_process_id, |
200 int render_view_id, | 210 int render_view_id, |
201 const gfx::Rect& element_rect, | 211 const gfx::Rect& element_rect, |
202 const std::string& language, | 212 const std::string& language, |
203 const std::string& grammar) { | 213 const std::string& grammar, |
| 214 const std::string& origin_url) { |
204 DCHECK(!HasPendingRequest(caller_id)); | 215 DCHECK(!HasPendingRequest(caller_id)); |
205 | 216 |
206 bubble_controller_->CreateBubble(caller_id, render_process_id, render_view_id, | 217 bubble_controller_->CreateBubble(caller_id, render_process_id, render_view_id, |
207 element_rect); | 218 element_rect); |
208 | 219 |
209 if (!hardware_info_.get()) { | 220 if (!optional_request_info_.get()) { |
210 hardware_info_ = new HardwareInfo(); | 221 optional_request_info_ = new OptionalRequestInfo(); |
211 // Since hardware info is optional with speech input requests, we start an | 222 // Since hardware info is optional with speech input requests, we start an |
212 // asynchronous fetch here and move on with recording audio. This first | 223 // asynchronous fetch here and move on with recording audio. This first |
213 // speech input request would send an empty string for hardware info and | 224 // speech input request would send an empty string for hardware info and |
214 // subsequent requests may have the hardware info available if the fetch | 225 // subsequent requests may have the hardware info available if the fetch |
215 // completed before them. This way we don't end up stalling the user with | 226 // completed before them. This way we don't end up stalling the user with |
216 // a long wait and disk seeks when they click on a UI element and start | 227 // a long wait and disk seeks when they click on a UI element and start |
217 // speaking. | 228 // speaking. |
218 hardware_info_->Refresh(); | 229 optional_request_info_->Refresh(); |
219 } | 230 } |
220 | 231 |
221 SpeechInputRequest* request = &requests_[caller_id]; | 232 SpeechInputRequest* request = &requests_[caller_id]; |
222 request->delegate = delegate; | 233 request->delegate = delegate; |
223 request->recognizer = new SpeechRecognizer(this, caller_id, language, | 234 request->recognizer = new SpeechRecognizer( |
224 grammar, hardware_info_->value()); | 235 this, caller_id, language, grammar, optional_request_info_->value(), |
| 236 optional_request_info_->can_report_metrics() ? origin_url : ""); |
225 request->is_active = false; | 237 request->is_active = false; |
226 | 238 |
227 StartRecognitionForRequest(caller_id); | 239 StartRecognitionForRequest(caller_id); |
228 } | 240 } |
229 | 241 |
230 void SpeechInputManagerImpl::StartRecognitionForRequest(int caller_id) { | 242 void SpeechInputManagerImpl::StartRecognitionForRequest(int caller_id) { |
231 DCHECK(HasPendingRequest(caller_id)); | 243 DCHECK(HasPendingRequest(caller_id)); |
232 | 244 |
233 // If we are currently recording audio for another caller, abort that cleanly. | 245 // If we are currently recording audio for another caller, abort that cleanly. |
234 if (recording_caller_id_) | 246 if (recording_caller_id_) |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 // to the user, abort it since user has switched focus. Otherwise | 366 // to the user, abort it since user has switched focus. Otherwise |
355 // recognition has started and keep that going so user can start speaking to | 367 // recognition has started and keep that going so user can start speaking to |
356 // another element while this gets the results in parallel. | 368 // another element while this gets the results in parallel. |
357 if (recording_caller_id_ == caller_id || !requests_[caller_id].is_active) { | 369 if (recording_caller_id_ == caller_id || !requests_[caller_id].is_active) { |
358 CancelRecognitionAndInformDelegate(caller_id); | 370 CancelRecognitionAndInformDelegate(caller_id); |
359 } | 371 } |
360 } | 372 } |
361 } | 373 } |
362 | 374 |
363 } // namespace speech_input | 375 } // namespace speech_input |
OLD | NEW |