Commit 7e93806b authored by amistry's avatar amistry Committed by Commit bot

Add OAuth2 authentication for speech recognition requests from the launcher,...

Add OAuth2 authentication for speech recognition requests from the launcher, when audio-history is opted-into.

Audio history allows a user to see the speech recognition result at https://history.google.com/history/audio. This change will attach an auth (OAuth2) token to the recognition request, which is used to associate the request with the user. This only happens when the user opts-in to audio history, and only on speech recognition from the app launcher.

This change adds a helper class that handles retrieving and refreshing the auth token, and plumbs that token into the speech recognition request.

BUG=397019

Review URL: https://codereview.chromium.org/778393002

Cr-Commit-Position: refs/heads/master@{#308270}
parent b8472db8
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/app_list/speech_auth_helper.h"
#include <string>
#include "base/bind.h"
#include "base/time/clock.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "content/public/browser/browser_thread.h"
namespace app_list {
static const char* kAuthScope =
"https://www.googleapis.com/auth/webhistory";
static const int kMinTokenRefreshDelaySeconds = 300; // 5 minutes
SpeechAuthHelper::SpeechAuthHelper(Profile* profile, base::Clock* clock)
: OAuth2TokenService::Consumer(kAuthScope),
profile_(profile),
clock_(clock),
token_service_(ProfileOAuth2TokenServiceFactory::GetForProfile(profile)),
weak_factory_(this) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// If token_service_ is NULL, we can't do anything. This might be NULL if the
// profile is a guest user.
if (!token_service_)
return;
SigninManagerBase* signin_manager =
SigninManagerFactory::GetForProfile(profile);
// Again, this might be NULL, and if it is, we can't proceed.
if (!signin_manager)
return;
authenticated_account_id_ = signin_manager->GetAuthenticatedAccountId();
if (!token_service_->RefreshTokenIsAvailable(authenticated_account_id_)) {
// Wait for the OAuth2 refresh token to be available before trying to obtain
// a speech token.
token_service_->AddObserver(this);
} else {
FetchAuthToken();
}
}
SpeechAuthHelper::~SpeechAuthHelper() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (token_service_)
token_service_->RemoveObserver(this);
}
void SpeechAuthHelper::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
auth_token_ = access_token;
auth_token_request_.reset();
base::Time now = clock_->Now();
base::TimeDelta delay = expiration_time - now;
if (delay.InSeconds() < kMinTokenRefreshDelaySeconds)
delay = base::TimeDelta::FromSeconds(kMinTokenRefreshDelaySeconds);
ScheduleTokenFetch(delay);
}
void SpeechAuthHelper::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
auth_token_ = "";
auth_token_request_.reset();
// Try again later.
// TODO(amistry): Implement backoff.
ScheduleTokenFetch(
base::TimeDelta::FromSeconds(kMinTokenRefreshDelaySeconds));
}
void SpeechAuthHelper::OnRefreshTokenAvailable(const std::string& account_id) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (authenticated_account_id_ == account_id)
FetchAuthToken();
}
void SpeechAuthHelper::ScheduleTokenFetch(const base::TimeDelta& fetch_delay) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
content::BrowserThread::PostDelayedTask(
content::BrowserThread::UI,
FROM_HERE,
base::Bind(&SpeechAuthHelper::FetchAuthToken,
weak_factory_.GetWeakPtr()),
fetch_delay);
}
void SpeechAuthHelper::FetchAuthToken() {
// The process of fetching and refreshing OAuth tokens is started from the
// consustructor, and so token_service_ and authenticated_account_id_ are
// guaranteed to be valid at this point.
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
OAuth2TokenService::ScopeSet scopes;
scopes.insert(kAuthScope);
auth_token_request_ = token_service_->StartRequest(
authenticated_account_id_,
scopes,
this);
}
std::string SpeechAuthHelper::GetToken() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
return auth_token_;
}
std::string SpeechAuthHelper::GetScope() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
return kAuthScope;
}
} // namespace app_list
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_APP_LIST_SPEECH_AUTH_HELPER_H_
#define CHROME_BROWSER_UI_APP_LIST_SPEECH_AUTH_HELPER_H_
#include <string>
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
class Profile;
class ProfileOAuth2TokenService;
namespace base {
class Clock;
}
namespace app_list {
// SpeechAuthHelper is a helper class to generate oauth tokens for audio
// history. This encalsulates generating and refreshing the auth token for a
// given profile. All functions should be called on the UI thread.
class SpeechAuthHelper : public OAuth2TokenService::Consumer,
public OAuth2TokenService::Observer {
public:
explicit SpeechAuthHelper(Profile* profile, base::Clock* clock);
~SpeechAuthHelper();
// Returns the current auth token. If the auth service is not available, or
// there was a failure in obtaining a token, return the empty string.
std::string GetToken();
// Returns the OAuth scope associated with the auth token.
std::string GetScope();
private:
// Overridden from OAuth2TokenService::Consumer:
void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) override;
void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) override;
// Overridden from OAuth2TokenService::Observer:
void OnRefreshTokenAvailable(const std::string& account_id) override;
void ScheduleTokenFetch(const base::TimeDelta& fetch_delay);
void FetchAuthToken();
Profile* profile_;
base::Clock* clock_;
ProfileOAuth2TokenService* token_service_;
std::string authenticated_account_id_;
std::string auth_token_;
scoped_ptr<OAuth2TokenService::Request> auth_token_request_;
base::WeakPtrFactory<SpeechAuthHelper> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SpeechAuthHelper);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SPEECH_AUTH_HELPER_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/app_list/speech_auth_helper.h"
#include <utility>
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/simple_test_clock.h"
#include "chrome/browser/prefs/pref_service_syncable.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/signin/core/browser/signin_manager.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace app_list {
static const char* kTestUser = "test.user@chromium.org.test";
static const char* kScope = "https://www.googleapis.com/auth/webhistory";
static const char* kAccessToken = "fake_access_token";
class SpeechAuthHelperTest : public testing::Test {
public:
SpeechAuthHelperTest()
: testing_profile_manager_(new TestingProfileManager(
TestingBrowserProcess::GetGlobal())) {
}
void SetUp() override {
// Set up FakeProfileOAuth2TokenService.
TestingProfile::TestingFactories factories;
factories.push_back(std::make_pair(
ProfileOAuth2TokenServiceFactory::GetInstance(),
&BuildAutoIssuingFakeProfileOAuth2TokenService));
ASSERT_TRUE(testing_profile_manager_->SetUp());
profile_ = testing_profile_manager_->CreateTestingProfile(
kTestUser,
scoped_ptr<PrefServiceSyncable>(),
base::UTF8ToUTF16(kTestUser),
0,
std::string(),
factories);
// Set up the authenticated user name and ID.
SigninManagerFactory::GetForProfile(profile_)->SetAuthenticatedUsername(
kTestUser);
}
protected:
void SetupRefreshToken() {
GetFakeProfileOAuth2TokenService()->IssueRefreshTokenForUser(
kTestUser, "fake_refresh_token");
}
FakeProfileOAuth2TokenService* GetFakeProfileOAuth2TokenService() {
return static_cast<FakeProfileOAuth2TokenService*>(
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_));
}
base::SimpleTestClock test_clock_;
content::TestBrowserThreadBundle thread_bundle;
scoped_ptr<TestingProfileManager> testing_profile_manager_;
Profile* profile_;
scoped_ptr<SpeechAuthHelper> auth_helper_;
};
TEST_F(SpeechAuthHelperTest, TokenFetch) {
SetupRefreshToken();
SpeechAuthHelper helper(profile_, &test_clock_);
EXPECT_TRUE(helper.GetToken().empty());
OAuth2TokenService::ScopeSet scopes;
scopes.insert(kScope);
GetFakeProfileOAuth2TokenService()->IssueTokenForScope(scopes,
kAccessToken,
base::Time::Max());
EXPECT_EQ(kAccessToken, helper.GetToken());
EXPECT_EQ(kScope, helper.GetScope());
}
TEST_F(SpeechAuthHelperTest, TokenFetchDelayedRefreshToken) {
SpeechAuthHelper helper(profile_, &test_clock_);
SetupRefreshToken();
EXPECT_TRUE(helper.GetToken().empty());
OAuth2TokenService::ScopeSet scopes;
scopes.insert(kScope);
GetFakeProfileOAuth2TokenService()->IssueTokenForScope(scopes,
kAccessToken,
base::Time::Max());
EXPECT_EQ(kAccessToken, helper.GetToken());
EXPECT_EQ(kScope, helper.GetScope());
}
TEST_F(SpeechAuthHelperTest, TokenFetchFailed) {
SetupRefreshToken();
SpeechAuthHelper helper(profile_, &test_clock_);
EXPECT_TRUE(helper.GetToken().empty());
OAuth2TokenService::ScopeSet scopes;
scopes.insert(kScope);
GetFakeProfileOAuth2TokenService()->IssueErrorForScope(
scopes, GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR));
EXPECT_TRUE(helper.GetToken().empty());
EXPECT_EQ(kScope, helper.GetScope());
}
} // namespace app_list
...@@ -43,7 +43,9 @@ class SpeechRecognizer::EventListener ...@@ -43,7 +43,9 @@ class SpeechRecognizer::EventListener
net::URLRequestContextGetter* url_request_context_getter, net::URLRequestContextGetter* url_request_context_getter,
const std::string& locale); const std::string& locale);
void StartOnIOThread(int render_process_id); void StartOnIOThread(int render_process_id,
const std::string& auth_scope,
const std::string& auth_token);
void StopOnIOThread(); void StopOnIOThread();
private: private:
...@@ -104,7 +106,10 @@ SpeechRecognizer::EventListener::~EventListener() { ...@@ -104,7 +106,10 @@ SpeechRecognizer::EventListener::~EventListener() {
DCHECK(!speech_timeout_.IsRunning()); DCHECK(!speech_timeout_.IsRunning());
} }
void SpeechRecognizer::EventListener::StartOnIOThread(int render_process_id) { void SpeechRecognizer::EventListener::StartOnIOThread(
int render_process_id,
const std::string& auth_scope,
const std::string& auth_token) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (session_ != kInvalidSessionId) if (session_ != kInvalidSessionId)
StopOnIOThread(); StopOnIOThread();
...@@ -119,6 +124,8 @@ void SpeechRecognizer::EventListener::StartOnIOThread(int render_process_id) { ...@@ -119,6 +124,8 @@ void SpeechRecognizer::EventListener::StartOnIOThread(int render_process_id) {
config.url_request_context_getter = url_request_context_getter_; config.url_request_context_getter = url_request_context_getter_;
config.event_listener = weak_factory_.GetWeakPtr(); config.event_listener = weak_factory_.GetWeakPtr();
config.initial_context.render_process_id = render_process_id; config.initial_context.render_process_id = render_process_id;
config.auth_scope = auth_scope;
config.auth_token = auth_token;
auto speech_instance = content::SpeechRecognitionManager::GetInstance(); auto speech_instance = content::SpeechRecognitionManager::GetInstance();
session_ = speech_instance->CreateSession(config); session_ = speech_instance->CreateSession(config);
...@@ -251,7 +258,7 @@ SpeechRecognizer::SpeechRecognizer( ...@@ -251,7 +258,7 @@ SpeechRecognizer::SpeechRecognizer(
const std::string& locale) const std::string& locale)
: delegate_(delegate), : delegate_(delegate),
speech_event_listener_(new EventListener( speech_event_listener_(new EventListener(
delegate, url_request_context_getter, locale)){ delegate, url_request_context_getter, locale)) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
} }
...@@ -271,12 +278,18 @@ void SpeechRecognizer::Start() { ...@@ -271,12 +278,18 @@ void SpeechRecognizer::Start() {
if (!contents) if (!contents)
return; return;
std::string auth_scope;
std::string auth_token;
delegate_->GetSpeechAuthParameters(&auth_scope, &auth_token);
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::IO, content::BrowserThread::IO,
FROM_HERE, FROM_HERE,
base::Bind(&SpeechRecognizer::EventListener::StartOnIOThread, base::Bind(&SpeechRecognizer::EventListener::StartOnIOThread,
speech_event_listener_, speech_event_listener_,
contents->GetRenderProcessHost()->GetID())); contents->GetRenderProcessHost()->GetID(),
auth_scope,
auth_token));
} }
void SpeechRecognizer::Stop() { void SpeechRecognizer::Stop() {
......
...@@ -37,6 +37,7 @@ class MockSpeechRecognizerDelegate : public SpeechRecognizerDelegate { ...@@ -37,6 +37,7 @@ class MockSpeechRecognizerDelegate : public SpeechRecognizerDelegate {
MOCK_METHOD1(OnSpeechSoundLevelChanged, void(int16_t)); MOCK_METHOD1(OnSpeechSoundLevelChanged, void(int16_t));
MOCK_METHOD1(OnSpeechRecognitionStateChanged, void(SpeechRecognitionState)); MOCK_METHOD1(OnSpeechRecognitionStateChanged, void(SpeechRecognitionState));
MOCK_METHOD0(GetSpeechContents, content::WebContents*()); MOCK_METHOD0(GetSpeechContents, content::WebContents*());
MOCK_METHOD2(GetSpeechAuthParameters, void(std::string*, std::string*));
private: private:
base::WeakPtrFactory<MockSpeechRecognizerDelegate> weak_factory_; base::WeakPtrFactory<MockSpeechRecognizerDelegate> weak_factory_;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_APP_LIST_SPEECH_RECOGNIZER_DELEGATE_H_ #define CHROME_BROWSER_UI_APP_LIST_SPEECH_RECOGNIZER_DELEGATE_H_
#include <stdint.h> #include <stdint.h>
#include <string>
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "ui/app_list/speech_ui_model_observer.h" #include "ui/app_list/speech_ui_model_observer.h"
...@@ -37,6 +38,11 @@ class SpeechRecognizerDelegate { ...@@ -37,6 +38,11 @@ class SpeechRecognizerDelegate {
// necessary. Somehow, eliminate this dependency. // necessary. Somehow, eliminate this dependency.
virtual content::WebContents* GetSpeechContents() = 0; virtual content::WebContents* GetSpeechContents() = 0;
// Get the OAuth2 scope and token to pass to the speech recognizer. Does not
// modify the arguments if no auth token is available or allowed.
virtual void GetSpeechAuthParameters(std::string* auth_scope,
std::string* auth_token) = 0;
protected: protected:
virtual ~SpeechRecognizerDelegate() {} virtual ~SpeechRecognizerDelegate() {}
}; };
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "chrome/browser/search/hotword_service.h" #include "chrome/browser/search/hotword_service.h"
#include "chrome/browser/search/hotword_service_factory.h" #include "chrome/browser/search/hotword_service_factory.h"
#include "chrome/browser/ui/app_list/recommended_apps.h" #include "chrome/browser/ui/app_list/recommended_apps.h"
#include "chrome/browser/ui/app_list/speech_auth_helper.h"
#include "chrome/browser/ui/app_list/speech_recognizer.h" #include "chrome/browser/ui/app_list/speech_recognizer.h"
#include "chrome/browser/ui/app_list/start_page_observer.h" #include "chrome/browser/ui/app_list/start_page_observer.h"
#include "chrome/browser/ui/app_list/start_page_service_factory.h" #include "chrome/browser/ui/app_list/start_page_service_factory.h"
...@@ -161,6 +162,7 @@ StartPageService::StartPageService(Profile* profile) ...@@ -161,6 +162,7 @@ StartPageService::StartPageService(Profile* profile)
speech_button_toggled_manually_(false), speech_button_toggled_manually_(false),
speech_result_obtained_(false), speech_result_obtained_(false),
webui_finished_loading_(false), webui_finished_loading_(false),
speech_auth_helper_(new SpeechAuthHelper(profile, &clock_)),
weak_factory_(this) { weak_factory_(this) {
// If experimental hotwording is enabled, then we're always "ready". // If experimental hotwording is enabled, then we're always "ready".
// Transitioning into the "hotword recognizing" state is handled by the // Transitioning into the "hotword recognizing" state is handled by the
...@@ -344,11 +346,26 @@ content::WebContents* StartPageService::GetSpeechContents() { ...@@ -344,11 +346,26 @@ content::WebContents* StartPageService::GetSpeechContents() {
return GetSpeechRecognitionContents(); return GetSpeechRecognitionContents();
} }
void StartPageService::GetSpeechAuthParameters(std::string* auth_scope,
std::string* auth_token) {
if (HotwordService::IsExperimentalHotwordingEnabled()) {
HotwordService* service = HotwordServiceFactory::GetForProfile(profile_);
if (service &&
service->IsOptedIntoAudioLogging() &&
!speech_auth_helper_->GetToken().empty()) {
*auth_scope = speech_auth_helper_->GetScope();
*auth_token = speech_auth_helper_->GetToken();
}
}
}
void StartPageService::Shutdown() { void StartPageService::Shutdown() {
UnloadContents(); UnloadContents();
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
audio_status_.reset(); audio_status_.reset();
#endif #endif
speech_auth_helper_.reset();
} }
void StartPageService::WebUILoaded() { void StartPageService::WebUILoaded() {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_APP_LIST_START_PAGE_SERVICE_H_ #define CHROME_BROWSER_UI_APP_LIST_START_PAGE_SERVICE_H_
#include <stdint.h> #include <stdint.h>
#include <string>
#include <vector> #include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
...@@ -15,6 +16,7 @@ ...@@ -15,6 +16,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/time/default_clock.h"
#include "chrome/browser/ui/app_list/speech_recognizer_delegate.h" #include "chrome/browser/ui/app_list/speech_recognizer_delegate.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
...@@ -29,6 +31,7 @@ class Profile; ...@@ -29,6 +31,7 @@ class Profile;
namespace app_list { namespace app_list {
class RecommendedApps; class RecommendedApps;
class SpeechAuthHelper;
class SpeechRecognizer; class SpeechRecognizer;
class StartPageObserver; class StartPageObserver;
...@@ -70,6 +73,8 @@ class StartPageService : public KeyedService, ...@@ -70,6 +73,8 @@ class StartPageService : public KeyedService,
void OnSpeechRecognitionStateChanged( void OnSpeechRecognitionStateChanged(
SpeechRecognitionState new_state) override; SpeechRecognitionState new_state) override;
content::WebContents* GetSpeechContents() override; content::WebContents* GetSpeechContents() override;
void GetSpeechAuthParameters(std::string* auth_scope,
std::string* auth_token) override;
protected: protected:
// Protected for testing. // Protected for testing.
...@@ -113,7 +118,9 @@ class StartPageService : public KeyedService, ...@@ -113,7 +118,9 @@ class StartPageService : public KeyedService,
bool webui_finished_loading_; bool webui_finished_loading_;
std::vector<base::Closure> pending_webui_callbacks_; std::vector<base::Closure> pending_webui_callbacks_;
base::DefaultClock clock_;
scoped_ptr<SpeechRecognizer> speech_recognizer_; scoped_ptr<SpeechRecognizer> speech_recognizer_;
scoped_ptr<SpeechAuthHelper> speech_auth_helper_;
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
scoped_ptr<AudioStatus> audio_status_; scoped_ptr<AudioStatus> audio_status_;
......
...@@ -1203,6 +1203,8 @@ ...@@ -1203,6 +1203,8 @@
'browser/ui/app_list/search/webstore/webstore_provider.h', 'browser/ui/app_list/search/webstore/webstore_provider.h',
'browser/ui/app_list/search/webstore/webstore_result.cc', 'browser/ui/app_list/search/webstore/webstore_result.cc',
'browser/ui/app_list/search/webstore/webstore_result.h', 'browser/ui/app_list/search/webstore/webstore_result.h',
'browser/ui/app_list/speech_auth_helper.cc',
'browser/ui/app_list/speech_auth_helper.h',
'browser/ui/app_list/speech_recognizer.cc', 'browser/ui/app_list/speech_recognizer.cc',
'browser/ui/app_list/speech_recognizer.h', 'browser/ui/app_list/speech_recognizer.h',
'browser/ui/app_list/speech_recognizer_delegate.h', 'browser/ui/app_list/speech_recognizer_delegate.h',
......
...@@ -889,6 +889,7 @@ ...@@ -889,6 +889,7 @@
'browser/ui/app_list/model_pref_updater_unittest.cc', 'browser/ui/app_list/model_pref_updater_unittest.cc',
'browser/ui/app_list/profile_loader_unittest.cc', 'browser/ui/app_list/profile_loader_unittest.cc',
'browser/ui/app_list/search/suggestions/suggestions_search_provider_unittest.cc', 'browser/ui/app_list/search/suggestions/suggestions_search_provider_unittest.cc',
'browser/ui/app_list/speech_auth_helper_unittest.cc',
'browser/ui/app_list/test/fake_profile.cc', 'browser/ui/app_list/test/fake_profile.cc',
'browser/ui/app_list/test/fake_profile.h', 'browser/ui/app_list/test/fake_profile.h',
'browser/ui/app_list/test/fake_profile_store.cc', 'browser/ui/app_list/test/fake_profile_store.cc',
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "content/browser/speech/google_streaming_remote_engine.h" #include "content/browser/speech/google_streaming_remote_engine.h"
#include <algorithm>
#include <vector> #include <vector>
#include "base/bind.h" #include "base/bind.h"
...@@ -342,7 +343,12 @@ GoogleStreamingRemoteEngine::ConnectBothStreams(const FSMEventArgs&) { ...@@ -342,7 +343,12 @@ GoogleStreamingRemoteEngine::ConnectBothStreams(const FSMEventArgs&) {
upstream_args.push_back("continuous"); upstream_args.push_back("continuous");
if (config_.interim_results) if (config_.interim_results)
upstream_args.push_back("interim"); upstream_args.push_back("interim");
if (!config_.auth_token.empty() && !config_.auth_scope.empty()) {
upstream_args.push_back(
"authScope=" + net::EscapeQueryParamValue(config_.auth_scope, true));
upstream_args.push_back(
"authToken=" + net::EscapeQueryParamValue(config_.auth_token, true));
}
GURL upstream_url(std::string(kWebServiceBaseUrl) + GURL upstream_url(std::string(kWebServiceBaseUrl) +
std::string(kUpstreamUrl) + std::string(kUpstreamUrl) +
JoinString(upstream_args, '&')); JoinString(upstream_args, '&'));
......
...@@ -59,6 +59,8 @@ class SpeechRecognitionEngine { ...@@ -59,6 +59,8 @@ class SpeechRecognitionEngine {
std::string origin_url; std::string origin_url;
int audio_sample_rate; int audio_sample_rate;
int audio_num_bits_per_sample; int audio_num_bits_per_sample;
std::string auth_token;
std::string auth_scope;
}; };
virtual ~SpeechRecognitionEngine() {} virtual ~SpeechRecognitionEngine() {}
......
...@@ -132,6 +132,8 @@ int SpeechRecognitionManagerImpl::CreateSession( ...@@ -132,6 +132,8 @@ int SpeechRecognitionManagerImpl::CreateSession(
remote_engine_config.hardware_info = hardware_info; remote_engine_config.hardware_info = hardware_info;
remote_engine_config.origin_url = remote_engine_config.origin_url =
can_report_metrics ? config.origin_url : std::string(); can_report_metrics ? config.origin_url : std::string();
remote_engine_config.auth_token = config.auth_token;
remote_engine_config.auth_scope = config.auth_scope;
SpeechRecognitionEngine* google_remote_engine; SpeechRecognitionEngine* google_remote_engine;
if (config.is_legacy_api) { if (config.is_legacy_api) {
...@@ -434,7 +436,7 @@ int SpeechRecognitionManagerImpl::GetSession( ...@@ -434,7 +436,7 @@ int SpeechRecognitionManagerImpl::GetSession(
int render_process_id, int render_view_id, int request_id) const { int render_process_id, int render_view_id, int request_id) const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
SessionsTable::const_iterator iter; SessionsTable::const_iterator iter;
for(iter = sessions_.begin(); iter != sessions_.end(); ++iter) { for (iter = sessions_.begin(); iter != sessions_.end(); ++iter) {
const int session_id = iter->first; const int session_id = iter->first;
const SpeechRecognitionSessionContext& context = iter->second->context; const SpeechRecognitionSessionContext& context = iter->second->context;
if (context.render_process_id == render_process_id && if (context.render_process_id == render_process_id &&
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CONTENT_PUBLIC_BROWSER_SPEECH_RECOGNITION_SESSION_CONFIG_H_ #ifndef CONTENT_PUBLIC_BROWSER_SPEECH_RECOGNITION_SESSION_CONFIG_H_
#define CONTENT_PUBLIC_BROWSER_SPEECH_RECOGNITION_SESSION_CONFIG_H_ #define CONTENT_PUBLIC_BROWSER_SPEECH_RECOGNITION_SESSION_CONFIG_H_
#include <string>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
...@@ -32,6 +34,8 @@ struct CONTENT_EXPORT SpeechRecognitionSessionConfig { ...@@ -32,6 +34,8 @@ struct CONTENT_EXPORT SpeechRecognitionSessionConfig {
bool continuous; bool continuous;
bool interim_results; bool interim_results;
uint32 max_hypotheses; uint32 max_hypotheses;
std::string auth_token;
std::string auth_scope;
SpeechRecognitionSessionContext initial_context; SpeechRecognitionSessionContext initial_context;
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter; scoped_refptr<net::URLRequestContextGetter> url_request_context_getter;
base::WeakPtr<SpeechRecognitionEventListener> event_listener; base::WeakPtr<SpeechRecognitionEventListener> event_listener;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment