summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorsatish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-19 08:32:02 +0000
committersatish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-19 08:32:02 +0000
commit562d634ceb3ec6ff5b9891456d6ea10e1a481213 (patch)
treedd64a86650f86be596239ed9792ca9f0f6f95312 /chrome
parentdd17f6bd436e1acd886dbf4f3856b00af64708de (diff)
downloadchromium_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.cc79
-rw-r--r--chrome/browser/speech/speech_recognition_request.cc9
-rw-r--r--chrome/browser/speech/speech_recognition_request.h1
-rw-r--r--chrome/browser/speech/speech_recognition_request_unittest.cc3
-rw-r--r--chrome/browser/speech/speech_recognizer.cc6
-rw-r--r--chrome/browser/speech/speech_recognizer.h5
-rw-r--r--chrome/browser/speech/speech_recognizer_unittest.cc2
-rw-r--r--chrome/chrome_dll.gypi1
-rw-r--r--chrome/installer/util/wmi.cc40
-rw-r--r--chrome/installer/util/wmi.h9
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_