Commit 113891eb authored by mukai@chromium.org's avatar mukai@chromium.org

Fine tuned availability of hotword plugin.

This CL adds several changes:
- enables the JS handler to turn on and off the hotword recognizer
- adds a pref 'hotword.app_list_enabled' to customize the plugin usage
- synchronization logic, so if the user explicitly turns off
  hotword.search_enabled, hotword.app_list_enabled goes off too
- extract the language check of HotwordService as a static method
  and let StartPageHandler check it, because our hotword
  "Ok, Google" is US-English only

BUG=341710, 341779
R=xiyuan@chromium.org, rlp@chromium.org, estade@chromium.org
TBR=samarth@chromium.org
TEST=manually

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@251142 0039d316-1c4b-4281-b951-d872f2087c98
parent 3964e577
...@@ -2451,6 +2451,9 @@ Press any key to continue exploring. ...@@ -2451,6 +2451,9 @@ Press any key to continue exploring.
<message name="IDS_OPTIONS_ENABLE_CONTENT_PROTECTION_ATTESTATION" desc="description label for verified access about premium contents"> <message name="IDS_OPTIONS_ENABLE_CONTENT_PROTECTION_ATTESTATION" desc="description label for verified access about premium contents">
Enable Verified Access Enable Verified Access
</message> </message>
<message name="IDS_OPTIONS_ENABLE_HOTWORD_APP_LIST" desc="description label for the checkbox to enable/disable hotword in the app list search">
Enable "Ok, Google" to start a voice search in the app launcher.
</message>
<message name="IDS_NETWORK_RECONNECT_TITLE" desc="In network menu, title of the reconnect button that allows user to retry connection on error."> <message name="IDS_NETWORK_RECONNECT_TITLE" desc="In network menu, title of the reconnect button that allows user to retry connection on error.">
Reconnect Reconnect
</message> </message>
......
...@@ -166,6 +166,10 @@ ...@@ -166,6 +166,10 @@
#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h" #include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h"
#endif #endif
#if defined(ENABLE_APP_LIST)
#include "chrome/browser/ui/app_list/start_page_service_factory.h"
#endif
#if defined(ENABLE_SPELLCHECK) #if defined(ENABLE_SPELLCHECK)
#include "chrome/browser/extensions/api/spellcheck/spellcheck_api.h" #include "chrome/browser/extensions/api/spellcheck/spellcheck_api.h"
#include "chrome/browser/spellchecker/spellcheck_factory.h" #include "chrome/browser/spellchecker/spellcheck_factory.h"
...@@ -203,6 +207,9 @@ ChromeBrowserMainExtraPartsProfiles::~ChromeBrowserMainExtraPartsProfiles() { ...@@ -203,6 +207,9 @@ ChromeBrowserMainExtraPartsProfiles::~ChromeBrowserMainExtraPartsProfiles() {
void ChromeBrowserMainExtraPartsProfiles:: void ChromeBrowserMainExtraPartsProfiles::
EnsureBrowserContextKeyedServiceFactoriesBuilt() { EnsureBrowserContextKeyedServiceFactoriesBuilt() {
AboutSigninInternalsFactory::GetInstance(); AboutSigninInternalsFactory::GetInstance();
#if defined(ENABLE_APP_LIST)
app_list::StartPageServiceFactory::GetInstance();
#endif
autofill::PersonalDataManagerFactory::GetInstance(); autofill::PersonalDataManagerFactory::GetInstance();
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
AutomaticProfileResetterFactory::GetInstance(); AutomaticProfileResetterFactory::GetInstance();
......
...@@ -127,8 +127,8 @@ cr.define('speech', function() { ...@@ -127,8 +127,8 @@ cr.define('speech', function() {
this.setState_(SpeechState.HOTWORD_RECOGNIZING); this.setState_(SpeechState.HOTWORD_RECOGNIZING);
} else { } else {
this.audioManager_.stop(); this.audioManager_.stop();
this.setState_(SpeechState.READY);
} }
chrome.send('setSpeechRecognitionState', ['off']);
}; };
/** /**
...@@ -158,19 +158,30 @@ cr.define('speech', function() { ...@@ -158,19 +158,30 @@ cr.define('speech', function() {
}; };
/** /**
* Initialize the hotword plugin manager, or do nothing if already * Changes the availability of the hotword plugin.
* initialization is on. *
*/ * @param {boolean} enabled Whether enabled or not.
SpeechManager.prototype.maybeInitializePlugin = function() { */
if ($('recognizer')) SpeechManager.prototype.setHotwordEnabled = function(enabled) {
return; var recognizer = $('recognizer');
if (enabled) {
var pluginManager = new speech.PluginManager( if (recognizer)
this.onHotwordRecognizerReady_.bind(this), return;
this.onHotwordRecognized_.bind(this));
pluginManager.scheduleInitialize( var pluginManager = new speech.PluginManager(
this.audioManager_.getSampleRate(), this.onHotwordRecognizerReady_.bind(this),
'chrome://app-list/okgoogle_hotword.config'); this.onHotwordRecognized_.bind(this));
pluginManager.scheduleInitialize(
this.audioManager_.getSampleRate(),
'chrome://app-list/okgoogle_hotword.config');
} else {
if (!recognizer)
return;
document.body.removeChild(recognizer);
this.pluginManager_ = null;
if (this.state == SpeechState.HOTWORD_RECOGNIZING)
this.setState(SpeechState.READY);
}
}; };
/** /**
......
...@@ -67,10 +67,12 @@ cr.define('appList.startPage', function() { ...@@ -67,10 +67,12 @@ cr.define('appList.startPage', function() {
} }
/** /**
* Invoked when the hotword plugin should be loaded. * Invoked when the hotword plugin availability is changed.
*
* @param {boolean} enabled Whether the plugin is enabled or not.
*/ */
function maybeInitializePlugin() { function setHotwordEnabled(enabled) {
speechManager.maybeInitializePlugin(); speechManager.setHotwordEnabled(enabled);
} }
/** /**
...@@ -98,7 +100,7 @@ cr.define('appList.startPage', function() { ...@@ -98,7 +100,7 @@ cr.define('appList.startPage', function() {
return { return {
initialize: initialize, initialize: initialize,
setRecommendedApps: setRecommendedApps, setRecommendedApps: setRecommendedApps,
maybeInitializePlugin: maybeInitializePlugin, setHotwordEnabled: setHotwordEnabled,
onAppListShown: onAppListShown, onAppListShown: onAppListShown,
onAppListHidden: onAppListHidden, onAppListHidden: onAppListHidden,
toggleSpeechRecognition: toggleSpeechRecognition toggleSpeechRecognition: toggleSpeechRecognition
......
...@@ -352,8 +352,14 @@ ...@@ -352,8 +352,14 @@
</span> </span>
</span> </span>
</div> </div>
<div id="hotword-app-list" class="checkbox" hidden>
<label>
<input pref="hotword.app_list_enabled" type="checkbox">
<span i18n-content="enableHotwordAppList"></span>
</label>
</div>
</if> </if>
<div id ="hotword-search" hidden> <div id="hotword-search" hidden>
<div class="checkbox"> <div class="checkbox">
<span class="controlled-setting-with-label"> <span class="controlled-setting-with-label">
<input id="hotword-search-enable" pref="hotword.search_enabled" <input id="hotword-search-enable" pref="hotword.search_enabled"
......
...@@ -230,6 +230,8 @@ cr.define('options', function() { ...@@ -230,6 +230,8 @@ cr.define('options', function() {
chrome.send('coreOptionsUserMetricsAction', chrome.send('coreOptionsUserMetricsAction',
['Options_ManageAccounts']); ['Options_ManageAccounts']);
}; };
$('hotword-app-list').hidden =
!loadTimeData.getBoolean('shouldShowAppListHotword');
} else { } else {
$('import-data').onclick = function(event) { $('import-data').onclick = function(event) {
ImportDataOverlay.show(); ImportDataOverlay.show();
......
...@@ -26,6 +26,21 @@ const char kHotwordFieldTrialName[] = "VoiceTrigger"; ...@@ -26,6 +26,21 @@ const char kHotwordFieldTrialName[] = "VoiceTrigger";
const char kHotwordFieldTrialDisabledGroupName[] = "Disabled"; const char kHotwordFieldTrialDisabledGroupName[] = "Disabled";
} // namespace hotword_internal } // namespace hotword_internal
// static
bool HotwordService::DoesHotwordSupportLanguage(Profile* profile) {
std::string locale =
#if defined(OS_CHROMEOS)
// On ChromeOS locale is per-profile.
profile->GetPrefs()->GetString(prefs::kApplicationLocale);
#else
g_browser_process->GetApplicationLocale();
#endif
// Only available for English now.
std::string normalized_locale = l10n_util::NormalizeLocale(locale);
return normalized_locale == "en" || normalized_locale == "en_us" ||
normalized_locale =="en_US";
}
HotwordService::HotwordService(Profile* profile) HotwordService::HotwordService(Profile* profile)
: profile_(profile) { : profile_(profile) {
} }
...@@ -72,19 +87,7 @@ bool HotwordService::IsServiceAvailable() { ...@@ -72,19 +87,7 @@ bool HotwordService::IsServiceAvailable() {
bool HotwordService::IsHotwordAllowed() { bool HotwordService::IsHotwordAllowed() {
std::string group = base::FieldTrialList::FindFullName( std::string group = base::FieldTrialList::FindFullName(
hotword_internal::kHotwordFieldTrialName); hotword_internal::kHotwordFieldTrialName);
if (!group.empty() && return !group.empty() &&
group != hotword_internal::kHotwordFieldTrialDisabledGroupName) { group != hotword_internal::kHotwordFieldTrialDisabledGroupName &&
std::string locale = DoesHotwordSupportLanguage(profile_);
#if defined(OS_CHROMEOS)
// On ChromeOS locale is per-profile.
profile_->GetPrefs()->GetString(prefs::kApplicationLocale);
#else
g_browser_process->GetApplicationLocale();
#endif
// Only available for English now.
std::string normalized_locale = l10n_util::NormalizeLocale(locale);
return normalized_locale == "en" || normalized_locale == "en_us" ||
normalized_locale =="en_US";
}
return false;
} }
...@@ -20,6 +20,9 @@ extern const char kHotwordFieldTrialDisabledGroupName[]; ...@@ -20,6 +20,9 @@ extern const char kHotwordFieldTrialDisabledGroupName[];
// search. // search.
class HotwordService : public BrowserContextKeyedService { class HotwordService : public BrowserContextKeyedService {
public: public:
// Returns true if the hotword supports the current system language.
static bool DoesHotwordSupportLanguage(Profile* profile);
explicit HotwordService(Profile* profile); explicit HotwordService(Profile* profile);
virtual ~HotwordService(); virtual ~HotwordService();
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include "content/public/browser/page_navigator.h" #include "content/public/browser/page_navigator.h"
#include "content/public/browser/user_metrics.h" #include "content/public/browser/user_metrics.h"
#include "grit/theme_resources.h" #include "grit/theme_resources.h"
#include "ui/app_list/app_list_switches.h"
#include "ui/app_list/app_list_view_delegate_observer.h" #include "ui/app_list/app_list_view_delegate_observer.h"
#include "ui/app_list/search_box_model.h" #include "ui/app_list/search_box_model.h"
#include "ui/app_list/speech_ui_model.h" #include "ui/app_list/speech_ui_model.h"
...@@ -96,15 +95,10 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile, ...@@ -96,15 +95,10 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile,
RegisterForNotifications(); RegisterForNotifications();
g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(this); g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(this);
// Hotword listening is on by default in ChromeOS right now. Here shouldn't app_list::StartPageService* service =
// use the current state in the webui because it will be changed to 'hotword app_list::StartPageService::Get(profile_);
// listening' state from 'ready' after the view is initialized.
speech_ui_.reset(new app_list::SpeechUIModel( speech_ui_.reset(new app_list::SpeechUIModel(
#if defined(OS_CHROMEOS) service ? service->state() : app_list::SPEECH_RECOGNITION_OFF));
app_list::switches::IsVoiceSearchEnabled() ?
app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING :
#endif
app_list::SPEECH_RECOGNITION_OFF));
#if defined(GOOGLE_CHROME_BUILD) #if defined(GOOGLE_CHROME_BUILD)
speech_ui_->set_logo( speech_ui_->set_logo(
...@@ -113,8 +107,6 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile, ...@@ -113,8 +107,6 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile,
#endif #endif
OnProfileChanged(); // sets model_ OnProfileChanged(); // sets model_
app_list::StartPageService* service =
app_list::StartPageService::Get(profile_);
if (service) if (service)
service->AddObserver(this); service->AddObserver(this);
} }
......
...@@ -9,16 +9,13 @@ ...@@ -9,16 +9,13 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_system_factory.h"
#include "chrome/browser/extensions/install_tracker_factory.h"
#include "chrome/browser/media/media_stream_infobar_delegate.h" #include "chrome/browser/media/media_stream_infobar_delegate.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.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/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/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
#include "content/public/browser/notification_details.h" #include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
...@@ -31,46 +28,6 @@ ...@@ -31,46 +28,6 @@
namespace app_list { namespace app_list {
class StartPageService::Factory : public BrowserContextKeyedServiceFactory {
public:
static StartPageService* GetForProfile(Profile* profile) {
if (!CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kShowAppListStartPage) &&
!app_list::switches::IsVoiceSearchEnabled()) {
return NULL;
}
return static_cast<StartPageService*>(
GetInstance()->GetServiceForBrowserContext(profile, true));
}
static Factory* GetInstance() {
return Singleton<Factory>::get();
}
private:
friend struct DefaultSingletonTraits<Factory>;
Factory()
: BrowserContextKeyedServiceFactory(
"AppListStartPageService",
BrowserContextDependencyManager::GetInstance()) {
DependsOn(extensions::ExtensionSystemFactory::GetInstance());
DependsOn(extensions::InstallTrackerFactory::GetInstance());
}
virtual ~Factory() {}
// BrowserContextKeyedServiceFactory overrides:
virtual BrowserContextKeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const OVERRIDE {
Profile* profile = static_cast<Profile*>(context);
return new StartPageService(profile);
}
DISALLOW_COPY_AND_ASSIGN(Factory);
};
class StartPageService::ProfileDestroyObserver class StartPageService::ProfileDestroyObserver
: public content::NotificationObserver { : public content::NotificationObserver {
public: public:
...@@ -118,13 +75,22 @@ class StartPageService::StartPageWebContentsDelegate ...@@ -118,13 +75,22 @@ class StartPageService::StartPageWebContentsDelegate
// static // static
StartPageService* StartPageService::Get(Profile* profile) { StartPageService* StartPageService::Get(Profile* profile) {
return Factory::GetForProfile(profile); return StartPageServiceFactory::GetForProfile(profile);
} }
StartPageService::StartPageService(Profile* profile) StartPageService::StartPageService(Profile* profile)
: profile_(profile), : profile_(profile),
profile_destroy_observer_(new ProfileDestroyObserver(this)), profile_destroy_observer_(new ProfileDestroyObserver(this)),
recommended_apps_(new RecommendedApps(profile)) { recommended_apps_(new RecommendedApps(profile)),
state_(app_list::SPEECH_RECOGNITION_OFF) {
#if defined(OS_CHROMEOS)
// Updates the default state to hotword listening, because this is
// the default behavior. This will be updated when the page is loaded and
// the nacl module is loaded.
if (app_list::switches::IsVoiceSearchEnabled())
state_ = app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING;
#endif
contents_.reset(content::WebContents::Create( contents_.reset(content::WebContents::Create(
content::WebContents::CreateParams(profile_))); content::WebContents::CreateParams(profile_)));
contents_delegate_.reset(new StartPageWebContentsDelegate()); contents_delegate_.reset(new StartPageWebContentsDelegate());
...@@ -183,6 +149,7 @@ void StartPageService::OnSpeechSoundLevelChanged(int16 level) { ...@@ -183,6 +149,7 @@ void StartPageService::OnSpeechSoundLevelChanged(int16 level) {
void StartPageService::OnSpeechRecognitionStateChanged( void StartPageService::OnSpeechRecognitionStateChanged(
SpeechRecognitionState new_state) { SpeechRecognitionState new_state) {
state_ = new_state;
FOR_EACH_OBSERVER(StartPageObserver, FOR_EACH_OBSERVER(StartPageObserver,
observers_, observers_,
OnSpeechRecognitionStateChanged(new_state)); OnSpeechRecognitionStateChanged(new_state));
......
...@@ -48,13 +48,13 @@ class StartPageService : public BrowserContextKeyedService { ...@@ -48,13 +48,13 @@ class StartPageService : public BrowserContextKeyedService {
RecommendedApps* recommended_apps() { return recommended_apps_.get(); } RecommendedApps* recommended_apps() { return recommended_apps_.get(); }
Profile* profile() { return profile_; } Profile* profile() { return profile_; }
SpeechRecognitionState state() { return state_; }
void OnSpeechResult(const base::string16& query, bool is_final); void OnSpeechResult(const base::string16& query, bool is_final);
void OnSpeechSoundLevelChanged(int16 level); void OnSpeechSoundLevelChanged(int16 level);
void OnSpeechRecognitionStateChanged(SpeechRecognitionState new_state); void OnSpeechRecognitionStateChanged(SpeechRecognitionState new_state);
private: private:
// A BrowserContextKeyedServiceFactory for this service. friend class StartPageServiceFactory;
class Factory;
// ProfileDestroyObserver to shutdown the service on exiting. WebContents // ProfileDestroyObserver to shutdown the service on exiting. WebContents
// depends on the profile and needs to be closed before the profile and its // depends on the profile and needs to be closed before the profile and its
...@@ -76,6 +76,7 @@ class StartPageService : public BrowserContextKeyedService { ...@@ -76,6 +76,7 @@ class StartPageService : public BrowserContextKeyedService {
scoped_ptr<StartPageWebContentsDelegate> contents_delegate_; scoped_ptr<StartPageWebContentsDelegate> contents_delegate_;
scoped_ptr<ProfileDestroyObserver> profile_destroy_observer_; scoped_ptr<ProfileDestroyObserver> profile_destroy_observer_;
scoped_ptr<RecommendedApps> recommended_apps_; scoped_ptr<RecommendedApps> recommended_apps_;
SpeechRecognitionState state_;
ObserverList<StartPageObserver> observers_; ObserverList<StartPageObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(StartPageService); DISALLOW_COPY_AND_ASSIGN(StartPageService);
......
// 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/start_page_service_factory.h"
#include "base/command_line.h"
#include "chrome/browser/extensions/extension_system_factory.h"
#include "chrome/browser/extensions/install_tracker_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/start_page_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "ui/app_list/app_list_switches.h"
namespace app_list {
// static
StartPageService* StartPageServiceFactory::GetForProfile(Profile* profile) {
if (!CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kShowAppListStartPage) &&
!app_list::switches::IsVoiceSearchEnabled()) {
return NULL;
}
return static_cast<StartPageService*>(
GetInstance()->GetServiceForBrowserContext(profile, true));
}
// static
StartPageServiceFactory* StartPageServiceFactory::GetInstance() {
return Singleton<StartPageServiceFactory>::get();
}
StartPageServiceFactory::StartPageServiceFactory()
: BrowserContextKeyedServiceFactory(
"AppListStartPageService",
BrowserContextDependencyManager::GetInstance()) {
DependsOn(extensions::ExtensionSystemFactory::GetInstance());
DependsOn(extensions::InstallTrackerFactory::GetInstance());
}
StartPageServiceFactory::~StartPageServiceFactory() {}
BrowserContextKeyedService* StartPageServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
Profile* profile = static_cast<Profile*>(context);
return new StartPageService(profile);
}
void StartPageServiceFactory::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
#if defined(OS_CHROMEOS)
registry->RegisterBooleanPref(
prefs::kHotwordAppListEnabled,
true,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
#endif
}
} // 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_START_PAGE_SERVICE_FACTORY_H_
#define CHROME_BROWSER_UI_APP_LIST_START_PAGE_SERVICE_FACTORY_H_
#include "base/memory/singleton.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
class Profile;
namespace app_list {
class StartPageService;
// Singleton factory to create StartPageService.
class StartPageServiceFactory : public BrowserContextKeyedServiceFactory {
public:
// Gets or creates the instance of StartPageService for |profile|.
static StartPageService* GetForProfile(Profile* profile);
// Gets the singleton instance of this factory.
static StartPageServiceFactory* GetInstance();
private:
friend struct DefaultSingletonTraits<StartPageServiceFactory>;
StartPageServiceFactory();
virtual ~StartPageServiceFactory();
// BrowserContextKeyedServiceFactory overrides:
virtual BrowserContextKeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const OVERRIDE;
virtual void RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(StartPageServiceFactory);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_START_PAGE_SERVICE_FACTORY_H_
...@@ -8,10 +8,12 @@ ...@@ -8,10 +8,12 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/prefs/pref_service.h"
#include "base/sys_info.h" #include "base/sys_info.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/hotword_service.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/app_list/app_list_service.h" #include "chrome/browser/ui/app_list/app_list_service.h"
#include "chrome/browser/ui/app_list/recommended_apps.h" #include "chrome/browser/ui/app_list/recommended_apps.h"
...@@ -19,6 +21,7 @@ ...@@ -19,6 +21,7 @@
#include "chrome/browser/ui/host_desktop.h" #include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
#include "chrome/common/extensions/extension_icon_set.h" #include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/web_contents_view.h" #include "content/public/browser/web_contents_view.h"
#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui.h"
#include "extensions/browser/extension_system.h" #include "extensions/browser/extension_system.h"
...@@ -97,6 +100,36 @@ void StartPageHandler::SendRecommendedApps() { ...@@ -97,6 +100,36 @@ void StartPageHandler::SendRecommendedApps() {
recommended_list); recommended_list);
} }
#if defined(OS_CHROMEOS)
bool StartPageHandler::HotwordEnabled() {
Profile* profile = Profile::FromWebUI(web_ui());
return HotwordService::DoesHotwordSupportLanguage(profile) &&
profile->GetPrefs()->GetBoolean(prefs::kHotwordAppListEnabled);
}
void StartPageHandler::OnHotwordEnabledChanged() {
web_ui()->CallJavascriptFunction(
"appList.startPage.setHotwordEnabled",
base::FundamentalValue(HotwordEnabled()));
}
void StartPageHandler::SynchronizeHotwordEnabled() {
Profile* profile = Profile::FromWebUI(web_ui());
PrefService* pref_service = profile->GetPrefs();
const PrefService::Preference* pref =
pref_service->FindPreference(prefs::kHotwordSearchEnabled);
if (!pref || pref->IsDefaultValue())
return;
bool search_enabled = false;
if (!pref->GetValue()->GetAsBoolean(&search_enabled))
return;
if (pref_service->GetBoolean(prefs::kHotwordAppListEnabled) != search_enabled)
pref_service->SetBoolean(prefs::kHotwordAppListEnabled, search_enabled);
}
#endif
void StartPageHandler::HandleInitialize(const base::ListValue* args) { void StartPageHandler::HandleInitialize(const base::ListValue* args) {
Profile* profile = Profile::FromWebUI(web_ui()); Profile* profile = Profile::FromWebUI(web_ui());
StartPageService* service = StartPageService::Get(profile); StartPageService* service = StartPageService::Get(profile);
...@@ -109,11 +142,20 @@ void StartPageHandler::HandleInitialize(const base::ListValue* args) { ...@@ -109,11 +142,20 @@ void StartPageHandler::HandleInitialize(const base::ListValue* args) {
SendRecommendedApps(); SendRecommendedApps();
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
// TODO(mukai): respect the configuration of the availability of the hotword
// plugin.
if (app_list::switches::IsVoiceSearchEnabled() && if (app_list::switches::IsVoiceSearchEnabled() &&
HotwordService::DoesHotwordSupportLanguage(profile) &&
base::SysInfo::IsRunningOnChromeOS()) { base::SysInfo::IsRunningOnChromeOS()) {
web_ui()->CallJavascriptFunction("appList.startPage.maybeInitializePlugin"); SynchronizeHotwordEnabled();
OnHotwordEnabledChanged();
pref_change_registrar_.Init(profile->GetPrefs());
pref_change_registrar_.Add(
prefs::kHotwordSearchEnabled,
base::Bind(&StartPageHandler::SynchronizeHotwordEnabled,
base::Unretained(this)));
pref_change_registrar_.Add(
prefs::kHotwordAppListEnabled,
base::Bind(&StartPageHandler::OnHotwordEnabledChanged,
base::Unretained(this)));
} }
#endif #endif
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/prefs/pref_change_registrar.h"
#include "chrome/browser/ui/app_list/recommended_apps_observer.h" #include "chrome/browser/ui/app_list/recommended_apps_observer.h"
#include "content/public/browser/web_ui_message_handler.h" #include "content/public/browser/web_ui_message_handler.h"
...@@ -35,6 +36,18 @@ class StartPageHandler : public content::WebUIMessageHandler, ...@@ -35,6 +36,18 @@ class StartPageHandler : public content::WebUIMessageHandler,
// Creates a ListValue for the recommended apps and sends it to js side. // Creates a ListValue for the recommended apps and sends it to js side.
void SendRecommendedApps(); void SendRecommendedApps();
#if defined(OS_CHROMEOS)
// Returns true if the hotword is enabled.
bool HotwordEnabled();
// Called when the pref has been changed.
void OnHotwordEnabledChanged();
// Called when the availability of the hotword for NTP is changed. The new
// value has to be propagated.
void SynchronizeHotwordEnabled();
#endif
// JS callbacks. // JS callbacks.
void HandleInitialize(const base::ListValue* args); void HandleInitialize(const base::ListValue* args);
void HandleLaunchApp(const base::ListValue* args); void HandleLaunchApp(const base::ListValue* args);
...@@ -43,6 +56,7 @@ class StartPageHandler : public content::WebUIMessageHandler, ...@@ -43,6 +56,7 @@ class StartPageHandler : public content::WebUIMessageHandler,
void HandleSpeechRecognition(const base::ListValue* args); void HandleSpeechRecognition(const base::ListValue* args);
RecommendedApps* recommended_apps_; // Not owned. RecommendedApps* recommended_apps_; // Not owned.
PrefChangeRegistrar pref_change_registrar_;
DISALLOW_COPY_AND_ASSIGN(StartPageHandler); DISALLOW_COPY_AND_ASSIGN(StartPageHandler);
}; };
......
...@@ -379,6 +379,7 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { ...@@ -379,6 +379,7 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) {
IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DELAY_VERY_LONG }, IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DELAY_VERY_LONG },
{ "enableContentProtectionAttestation", { "enableContentProtectionAttestation",
IDS_OPTIONS_ENABLE_CONTENT_PROTECTION_ATTESTATION }, IDS_OPTIONS_ENABLE_CONTENT_PROTECTION_ATTESTATION },
{ "enableHotwordAppList", IDS_OPTIONS_ENABLE_HOTWORD_APP_LIST },
{ "factoryResetHeading", IDS_OPTIONS_FACTORY_RESET_HEADING }, { "factoryResetHeading", IDS_OPTIONS_FACTORY_RESET_HEADING },
{ "factoryResetTitle", IDS_OPTIONS_FACTORY_RESET }, { "factoryResetTitle", IDS_OPTIONS_FACTORY_RESET },
{ "factoryResetRestart", IDS_OPTIONS_FACTORY_RESET_BUTTON }, { "factoryResetRestart", IDS_OPTIONS_FACTORY_RESET_BUTTON },
...@@ -546,6 +547,12 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { ...@@ -546,6 +547,12 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) {
magnifier_list->Append(option_partial.release()); magnifier_list->Append(option_partial.release());
values->Set("magnifierList", magnifier_list.release()); values->Set("magnifierList", magnifier_list.release());
scoped_ptr<base::FundamentalValue> should_show_app_list_hotword(
new base::FundamentalValue(
HotwordService::DoesHotwordSupportLanguage(profile)));
values->Set(
"shouldShowAppListHotword", should_show_app_list_hotword.release());
#endif #endif
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
...@@ -867,9 +874,9 @@ void BrowserOptionsHandler::InitializePage() { ...@@ -867,9 +874,9 @@ void BrowserOptionsHandler::InitializePage() {
"BrowserOptions.enableFactoryResetSection"); "BrowserOptions.enableFactoryResetSection");
} }
Profile* profile = Profile::FromWebUI(web_ui());
OnAccountPictureManagedChanged( OnAccountPictureManagedChanged(
policy::ProfilePolicyConnectorFactory::GetForProfile( policy::ProfilePolicyConnectorFactory::GetForProfile(profile)->
Profile::FromWebUI(web_ui()))->
policy_service()->GetPolicies( policy_service()->GetPolicies(
policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME,
std::string())) std::string()))
......
...@@ -237,6 +237,8 @@ ...@@ -237,6 +237,8 @@
'browser/ui/app_list/start_page_observer.h', 'browser/ui/app_list/start_page_observer.h',
'browser/ui/app_list/start_page_service.cc', 'browser/ui/app_list/start_page_service.cc',
'browser/ui/app_list/start_page_service.h', 'browser/ui/app_list/start_page_service.h',
'browser/ui/app_list/start_page_service_factory.cc',
'browser/ui/app_list/start_page_service_factory.h',
'browser/ui/app_modal_dialogs/app_modal_dialog.cc', 'browser/ui/app_modal_dialogs/app_modal_dialog.cc',
'browser/ui/app_modal_dialogs/app_modal_dialog.h', 'browser/ui/app_modal_dialogs/app_modal_dialog.h',
'browser/ui/app_modal_dialogs/app_modal_dialog_queue.cc', 'browser/ui/app_modal_dialogs/app_modal_dialog_queue.cc',
......
...@@ -2148,6 +2148,13 @@ const char kHotwordSearchEnabled[] = "hotword.search_enabled"; ...@@ -2148,6 +2148,13 @@ const char kHotwordSearchEnabled[] = "hotword.search_enabled";
// longer shown. // longer shown.
const char kHotwordOptInPopupTimesShown[] = "hotword.opt_in_popup_times_shown"; const char kHotwordOptInPopupTimesShown[] = "hotword.opt_in_popup_times_shown";
#if defined(OS_CHROMEOS)
// A boolean pref that controls the enabled-state of hotword search in the
// app-list. This pref cooperates with kHotwordSearchEnabled. If the user
// explicitly turns off kHotwordSearchEnabled, this pref should go off too.
const char kHotwordAppListEnabled[] = "hotword.app_list_enabled";
#endif
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// Boolean that controls the global enabled-state of protected media identifier. // Boolean that controls the global enabled-state of protected media identifier.
const char kProtectedMediaIdentifierEnabled[] = const char kProtectedMediaIdentifierEnabled[] =
......
...@@ -740,6 +740,10 @@ extern const char kVideoCaptureAllowedUrls[]; ...@@ -740,6 +740,10 @@ extern const char kVideoCaptureAllowedUrls[];
extern const char kHotwordSearchEnabled[]; extern const char kHotwordSearchEnabled[];
extern const char kHotwordOptInPopupTimesShown[]; extern const char kHotwordOptInPopupTimesShown[];
#if defined(OS_CHROMEOS)
extern const char kHotwordAppListEnabled[];
#endif
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
extern const char kProtectedMediaIdentifierEnabled[]; extern const char kProtectedMediaIdentifierEnabled[];
#endif #endif
......
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