diff options
author | satish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-19 08:32:02 +0000 |
---|---|---|
committer | satish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-19 08:32:02 +0000 |
commit | 562d634ceb3ec6ff5b9891456d6ea10e1a481213 (patch) | |
tree | dd64a86650f86be596239ed9792ca9f0f6f95312 /chrome | |
parent | dd17f6bd436e1acd886dbf4f3856b00af64708de (diff) | |
download | chromium_src-562d634ceb3ec6ff5b9891456d6ea10e1a481213.zip chromium_src-562d634ceb3ec6ff5b9891456d6ea10e1a481213.tar.gz chromium_src-562d634ceb3ec6ff5b9891456d6ea10e1a481213.tar.bz2 |
On windows, send audio hardware info with speech input requests if user consented.
This may help identify quality issues.
BUG=61677
TEST=none
Review URL: http://codereview.chromium.org/4724001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66749 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/speech/speech_input_manager.cc | 79 | ||||
-rw-r--r-- | chrome/browser/speech/speech_recognition_request.cc | 9 | ||||
-rw-r--r-- | chrome/browser/speech/speech_recognition_request.h | 1 | ||||
-rw-r--r-- | chrome/browser/speech/speech_recognition_request_unittest.cc | 3 | ||||
-rw-r--r-- | chrome/browser/speech/speech_recognizer.cc | 6 | ||||
-rw-r--r-- | chrome/browser/speech/speech_recognizer.h | 5 | ||||
-rw-r--r-- | chrome/browser/speech/speech_recognizer_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/chrome_dll.gypi | 1 | ||||
-rw-r--r-- | chrome/installer/util/wmi.cc | 40 | ||||
-rw-r--r-- | chrome/installer/util/wmi.h | 9 |
10 files changed, 146 insertions, 9 deletions
diff --git a/chrome/browser/speech/speech_input_manager.cc b/chrome/browser/speech/speech_input_manager.cc index 181234e..7149223 100644 --- a/chrome/browser/speech/speech_input_manager.cc +++ b/chrome/browser/speech/speech_input_manager.cc @@ -5,18 +5,82 @@ #include "chrome/browser/speech/speech_input_manager.h" #include "app/l10n_util.h" +#include "base/lock.h" #include "base/ref_counted.h" #include "base/singleton.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_thread.h" +#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/speech/speech_input_bubble_controller.h" #include "chrome/browser/speech/speech_recognizer.h" #include "chrome/browser/tab_contents/infobar_delegate.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_util.h" +#include "chrome/common/pref_names.h" #include "grit/generated_resources.h" #include "media/audio/audio_manager.h" #include <map> +#if defined(OS_WIN) +#include "chrome/installer/util/wmi.h" +#endif + +namespace { + +// Asynchronously fetches the PC and audio hardware/driver info on windows if +// the user has opted into UMA. This information is sent with speech input +// requests to the server for identifying and improving quality issues with +// specific device configurations. +class HardwareInfo : public base::RefCountedThreadSafe<HardwareInfo> { + public: + HardwareInfo() {} + +#if defined(OS_WIN) + void Refresh() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + // UMA opt-in can be checked only from the UI thread, so switch to that. + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + NewRunnableMethod(this, &HardwareInfo::CheckUMAAndGetHardwareInfo)); + } + + void CheckUMAAndGetHardwareInfo() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (g_browser_process->local_state()->GetBoolean( + prefs::kMetricsReportingEnabled)) { + // Access potentially slow OS calls from the FILE thread. + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, + NewRunnableMethod(this, &HardwareInfo::GetHardwareInfo)); + } + } + + void GetHardwareInfo() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + AutoLock lock(lock_); + value_ = UTF16ToUTF8( + installer::WMIComputerSystem::GetModel() + L"|" + + AudioManager::GetAudioManager()->GetAudioInputDeviceModel()); + } + + std::string value() { + AutoLock lock(lock_); + return value_; + } + + private: + Lock lock_; + std::string value_; + +#else // defined(OS_WIN) + void Refresh() {} + std::string value() { return std::string(); } +#endif // defined(OS_WIN) + + DISALLOW_COPY_AND_ASSIGN(HardwareInfo); +}; + +} + namespace speech_input { class SpeechInputManagerImpl : public SpeechInputManager, @@ -75,6 +139,7 @@ class SpeechInputManagerImpl : public SpeechInputManager, SpeechRecognizerMap requests_; int recording_caller_id_; scoped_refptr<SpeechInputBubbleController> bubble_controller_; + scoped_refptr<HardwareInfo> hardware_info_; }; SpeechInputManager* SpeechInputManager::Get() { @@ -114,10 +179,22 @@ void SpeechInputManagerImpl::StartRecognition( bubble_controller_->CreateBubble(caller_id, render_process_id, render_view_id, element_rect); + if (!hardware_info_.get()) { + hardware_info_ = new HardwareInfo(); + // Since hardware info is optional with speech input requests, we start an + // asynchronous fetch here and move on with recording audio. This first + // speech input request would send an empty string for hardware info and + // subsequent requests may have the hardware info available if the fetch + // completed before them. This way we don't end up stalling the user with + // a long wait and disk seeks when they click on a UI element and start + // speaking. + hardware_info_->Refresh(); + } + SpeechInputRequest* request = &requests_[caller_id]; request->delegate = delegate; request->recognizer = new SpeechRecognizer(this, caller_id, language, - grammar); + grammar, hardware_info_->value()); request->is_active = false; StartRecognitionForRequest(caller_id); diff --git a/chrome/browser/speech/speech_recognition_request.cc b/chrome/browser/speech/speech_recognition_request.cc index b9ee40b..63a6c92 100644 --- a/chrome/browser/speech/speech_recognition_request.cc +++ b/chrome/browser/speech/speech_recognition_request.cc @@ -9,7 +9,6 @@ #include "app/l10n_util.h" #include "base/json/json_reader.h" #include "base/string_util.h" -#include "base/utf_string_conversions.h" #include "base/values.h" #include "chrome/common/net/url_request_context_getter.h" #include "net/base/escape.h" @@ -20,7 +19,7 @@ namespace { const char* const kDefaultSpeechRecognitionUrl = - "http://www.google.com/speech-api/v1/recognize?client=chromium&"; + "https://www.google.com/speech-api/v1/recognize?client=chromium&"; const char* const kHypothesesString = "hypotheses"; const char* const kUtteranceString = "utterance"; const char* const kConfidenceString = "confidence"; @@ -123,6 +122,7 @@ SpeechRecognitionRequest::~SpeechRecognitionRequest() {} bool SpeechRecognitionRequest::Send(const std::string& language, const std::string& grammar, + const std::string& hardware_info, const std::string& content_type, const std::string& audio_data) { DCHECK(!url_fetcher_.get()); @@ -145,7 +145,10 @@ bool SpeechRecognitionRequest::Send(const std::string& language, parts.push_back("lang=" + EscapeQueryParamValue(lang_param, true)); if (!grammar.empty()) - parts.push_back("grammar=" + EscapeQueryParamValue(grammar, true)); + parts.push_back("lm=" + EscapeQueryParamValue(grammar, true)); + if (!hardware_info.empty()) + parts.push_back("xhw=" + EscapeQueryParamValue(hardware_info, true)); + GURL url(std::string(kDefaultSpeechRecognitionUrl) + JoinString(parts, '&')); url_fetcher_.reset(URLFetcher::Create(url_fetcher_id_for_tests, diff --git a/chrome/browser/speech/speech_recognition_request.h b/chrome/browser/speech/speech_recognition_request.h index 89beed1..585b0a4 100644 --- a/chrome/browser/speech/speech_recognition_request.h +++ b/chrome/browser/speech/speech_recognition_request.h @@ -46,6 +46,7 @@ class SpeechRecognitionRequest : public URLFetcher::Delegate { // previous request has completed. bool Send(const std::string& language, const std::string& grammar, + const std::string& hardware_info, const std::string& content_type, const std::string& audio_data); diff --git a/chrome/browser/speech/speech_recognition_request_unittest.cc b/chrome/browser/speech/speech_recognition_request_unittest.cc index a87bba8..e328eb4 100644 --- a/chrome/browser/speech/speech_recognition_request_unittest.cc +++ b/chrome/browser/speech/speech_recognition_request_unittest.cc @@ -45,7 +45,8 @@ class SpeechRecognitionRequestTest : public SpeechRecognitionRequestDelegate, void SpeechRecognitionRequestTest::CreateAndTestRequest( bool success, const std::string& http_response) { SpeechRecognitionRequest request(NULL, this); - request.Send(std::string(), std::string(), std::string(), std::string()); + request.Send(std::string(), std::string(), std::string(), std::string(), + std::string()); TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); ASSERT_TRUE(fetcher); URLRequestStatus status; diff --git a/chrome/browser/speech/speech_recognizer.cc b/chrome/browser/speech/speech_recognizer.cc index d56013a..4905914 100644 --- a/chrome/browser/speech/speech_recognizer.cc +++ b/chrome/browser/speech/speech_recognizer.cc @@ -110,11 +110,13 @@ void SpeexEncoder::Encode(const short* samples, SpeechRecognizer::SpeechRecognizer(Delegate* delegate, int caller_id, const std::string& language, - const std::string& grammar) + const std::string& grammar, + const std::string& hardware_info) : delegate_(delegate), caller_id_(caller_id), language_(language), grammar_(grammar), + hardware_info_(hardware_info), encoder_(new SpeexEncoder()), endpointer_(kAudioSampleRate), num_samples_recorded_(0), @@ -216,7 +218,7 @@ void SpeechRecognizer::StopRecording() { DCHECK(!request_.get()); request_.reset(new SpeechRecognitionRequest( Profile::GetDefaultRequestContext(), this)); - request_->Send(language_, grammar_, kContentTypeSpeex, data); + request_->Send(language_, grammar_, hardware_info_, kContentTypeSpeex, data); ReleaseAudioBuffers(); // No need to keep the audio anymore. } diff --git a/chrome/browser/speech/speech_recognizer.h b/chrome/browser/speech/speech_recognizer.h index 61226f4..3b0f707 100644 --- a/chrome/browser/speech/speech_recognizer.h +++ b/chrome/browser/speech/speech_recognizer.h @@ -76,7 +76,8 @@ class SpeechRecognizer SpeechRecognizer(Delegate* delegate, int caller_id, const std::string& language, - const std::string& grammar); + const std::string& grammar, + const std::string& hardware_info); ~SpeechRecognizer(); // Starts audio recording and does recognition after recording ends. The same @@ -112,6 +113,7 @@ class SpeechRecognizer private: void ReleaseAudioBuffers(); void InformErrorAndCancelRecognition(ErrorCode error); + void SendRecordedAudioToServer(); void HandleOnError(int error_code); // Handles OnError in the IO thread. @@ -122,6 +124,7 @@ class SpeechRecognizer int caller_id_; std::string language_; std::string grammar_; + std::string hardware_info_; // Buffer holding the recorded audio. Owns the strings inside the list. typedef std::list<std::string*> AudioBufferQueue; diff --git a/chrome/browser/speech/speech_recognizer_unittest.cc b/chrome/browser/speech/speech_recognizer_unittest.cc index d71876f..44967b1 100644 --- a/chrome/browser/speech/speech_recognizer_unittest.cc +++ b/chrome/browser/speech/speech_recognizer_unittest.cc @@ -24,7 +24,7 @@ class SpeechRecognizerTest : public SpeechRecognizerDelegate, : io_thread_(BrowserThread::IO, &message_loop_), ALLOW_THIS_IN_INITIALIZER_LIST( recognizer_(new SpeechRecognizer(this, 1, std::string(), - std::string()))), + std::string(), std::string()))), recording_complete_(false), recognition_complete_(false), result_received_(false), diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi index 3fbacbb..36b9af0 100644 --- a/chrome/chrome_dll.gypi +++ b/chrome/chrome_dll.gypi @@ -35,6 +35,7 @@ 'urlmon.dll', 'imm32.dll', 'iphlpapi.dll', + 'setupapi.dll', ], # Set /SUBSYSTEM:WINDOWS for chrome.dll (for consistency). 'SubSystem': '2', diff --git a/chrome/installer/util/wmi.cc b/chrome/installer/util/wmi.cc index fca2076..e873277 100644 --- a/chrome/installer/util/wmi.cc +++ b/chrome/installer/util/wmi.cc @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/win/scoped_bstr.h" #include "base/win/scoped_comptr.h" +#include "base/win/scoped_variant.h" #pragma comment(lib, "wbemuuid.lib") @@ -150,4 +151,43 @@ bool WMIProcess::Launch(const std::wstring& command_line, int* process_id) { return true; } +string16 WMIComputerSystem::GetModel() { + base::win::ScopedComPtr<IWbemServices> services; + if (!WMI::CreateLocalConnection(true, services.Receive())) + return string16(); + + base::win::ScopedBstr query_language(L"WQL"); + base::win::ScopedBstr query(L"SELECT * FROM Win32_ComputerSystem"); + base::win::ScopedComPtr<IEnumWbemClassObject> enumerator; + HRESULT hr = services->ExecQuery( + query_language, query, + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, + enumerator.Receive()); + if (FAILED(hr) || !enumerator) + return string16(); + + base::win::ScopedComPtr<IWbemClassObject> class_object; + ULONG items_returned = 0; + hr = enumerator->Next(WBEM_INFINITE, 1, class_object.Receive(), + &items_returned); + if (!items_returned) + return string16(); + + base::win::ScopedVariant manufacturer; + class_object->Get(L"Manufacturer", 0, manufacturer.Receive(), 0, 0); + base::win::ScopedVariant model; + class_object->Get(L"Model", 0, model.Receive(), 0, 0); + + string16 model_string; + if (manufacturer.type() == VT_BSTR) { + model_string = V_BSTR(&manufacturer); + if (model.type() == VT_BSTR) + model_string += L" "; + } + if (model.type() == VT_BSTR) + model_string += V_BSTR(&model); + + return model_string; +} + } // namespace installer diff --git a/chrome/installer/util/wmi.h b/chrome/installer/util/wmi.h index 5d0a1a9..03106dc 100644 --- a/chrome/installer/util/wmi.h +++ b/chrome/installer/util/wmi.h @@ -21,6 +21,7 @@ #define CHROME_INSTALLER_UTIL_WMI_H_ #pragma once +#include "base/string16.h" #include <string> #include <wbemidl.h> @@ -73,6 +74,14 @@ class WMIProcess { static bool Launch(const std::wstring& command_line, int* process_id); }; +// This class contains functionality of the WMI class 'Win32_ComputerSystem' +// more info: http://msdn.microsoft.com/en-us/library/aa394102(VS.85).aspx +class WMIComputerSystem { + public: + // Returns a human readable string for the model/make of this computer. + static string16 GetModel(); +}; + } // namespace installer #endif // CHROME_INSTALLER_UTIL_WMI_H_ |