diff options
author | mukai@chromium.org <mukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-13 21:58:21 +0000 |
---|---|---|
committer | mukai@chromium.org <mukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-13 21:58:21 +0000 |
commit | 113891eb855d7e39fec98ef38b8fba5d047379d0 (patch) | |
tree | dd09083b93b606c33648d1c41b5a74909b5ae8d7 /chrome | |
parent | 3964e57729f597c270361d87cec3a67a9fbde4e6 (diff) | |
download | chromium_src-113891eb855d7e39fec98ef38b8fba5d047379d0.zip chromium_src-113891eb855d7e39fec98ef38b8fba5d047379d0.tar.gz chromium_src-113891eb855d7e39fec98ef38b8fba5d047379d0.tar.bz2 |
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
Diffstat (limited to 'chrome')
19 files changed, 276 insertions, 98 deletions
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 33c5423..dc076e9 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp @@ -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"> Enable Verified Access </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."> Reconnect </message> diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 4f35567..c62bef0 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc @@ -166,6 +166,10 @@ #include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h" #endif +#if defined(ENABLE_APP_LIST) +#include "chrome/browser/ui/app_list/start_page_service_factory.h" +#endif + #if defined(ENABLE_SPELLCHECK) #include "chrome/browser/extensions/api/spellcheck/spellcheck_api.h" #include "chrome/browser/spellchecker/spellcheck_factory.h" @@ -203,6 +207,9 @@ ChromeBrowserMainExtraPartsProfiles::~ChromeBrowserMainExtraPartsProfiles() { void ChromeBrowserMainExtraPartsProfiles:: EnsureBrowserContextKeyedServiceFactoriesBuilt() { AboutSigninInternalsFactory::GetInstance(); +#if defined(ENABLE_APP_LIST) + app_list::StartPageServiceFactory::GetInstance(); +#endif autofill::PersonalDataManagerFactory::GetInstance(); #if !defined(OS_ANDROID) AutomaticProfileResetterFactory::GetInstance(); diff --git a/chrome/browser/resources/app_list/speech_manager.js b/chrome/browser/resources/app_list/speech_manager.js index d58a53f..ebb3afe 100644 --- a/chrome/browser/resources/app_list/speech_manager.js +++ b/chrome/browser/resources/app_list/speech_manager.js @@ -127,8 +127,8 @@ cr.define('speech', function() { this.setState_(SpeechState.HOTWORD_RECOGNIZING); } else { this.audioManager_.stop(); + this.setState_(SpeechState.READY); } - chrome.send('setSpeechRecognitionState', ['off']); }; /** @@ -158,19 +158,30 @@ cr.define('speech', function() { }; /** - * Initialize the hotword plugin manager, or do nothing if already - * initialization is on. - */ - SpeechManager.prototype.maybeInitializePlugin = function() { - if ($('recognizer')) - return; - - var pluginManager = new speech.PluginManager( - this.onHotwordRecognizerReady_.bind(this), - this.onHotwordRecognized_.bind(this)); - pluginManager.scheduleInitialize( - this.audioManager_.getSampleRate(), - 'chrome://app-list/okgoogle_hotword.config'); + * Changes the availability of the hotword plugin. + * + * @param {boolean} enabled Whether enabled or not. + */ + SpeechManager.prototype.setHotwordEnabled = function(enabled) { + var recognizer = $('recognizer'); + if (enabled) { + if (recognizer) + return; + + var pluginManager = new speech.PluginManager( + this.onHotwordRecognizerReady_.bind(this), + 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); + } }; /** diff --git a/chrome/browser/resources/app_list/start_page.js b/chrome/browser/resources/app_list/start_page.js index cc7953c..e1f586e 100644 --- a/chrome/browser/resources/app_list/start_page.js +++ b/chrome/browser/resources/app_list/start_page.js @@ -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() { - speechManager.maybeInitializePlugin(); + function setHotwordEnabled(enabled) { + speechManager.setHotwordEnabled(enabled); } /** @@ -98,7 +100,7 @@ cr.define('appList.startPage', function() { return { initialize: initialize, setRecommendedApps: setRecommendedApps, - maybeInitializePlugin: maybeInitializePlugin, + setHotwordEnabled: setHotwordEnabled, onAppListShown: onAppListShown, onAppListHidden: onAppListHidden, toggleSpeechRecognition: toggleSpeechRecognition diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html index 076c39e..036876a 100644 --- a/chrome/browser/resources/options/browser_options.html +++ b/chrome/browser/resources/options/browser_options.html @@ -352,8 +352,14 @@ </span> </span> </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> - <div id ="hotword-search" hidden> + <div id="hotword-search" hidden> <div class="checkbox"> <span class="controlled-setting-with-label"> <input id="hotword-search-enable" pref="hotword.search_enabled" diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js index cc01414..dfa6bc8 100644 --- a/chrome/browser/resources/options/browser_options.js +++ b/chrome/browser/resources/options/browser_options.js @@ -230,6 +230,8 @@ cr.define('options', function() { chrome.send('coreOptionsUserMetricsAction', ['Options_ManageAccounts']); }; + $('hotword-app-list').hidden = + !loadTimeData.getBoolean('shouldShowAppListHotword'); } else { $('import-data').onclick = function(event) { ImportDataOverlay.show(); diff --git a/chrome/browser/search/hotword_service.cc b/chrome/browser/search/hotword_service.cc index 713f9f8..544974f 100644 --- a/chrome/browser/search/hotword_service.cc +++ b/chrome/browser/search/hotword_service.cc @@ -26,6 +26,21 @@ const char kHotwordFieldTrialName[] = "VoiceTrigger"; const char kHotwordFieldTrialDisabledGroupName[] = "Disabled"; } // 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) : profile_(profile) { } @@ -72,19 +87,7 @@ bool HotwordService::IsServiceAvailable() { bool HotwordService::IsHotwordAllowed() { std::string group = base::FieldTrialList::FindFullName( hotword_internal::kHotwordFieldTrialName); - if (!group.empty() && - group != hotword_internal::kHotwordFieldTrialDisabledGroupName) { - 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"; - } - return false; + return !group.empty() && + group != hotword_internal::kHotwordFieldTrialDisabledGroupName && + DoesHotwordSupportLanguage(profile_); } diff --git a/chrome/browser/search/hotword_service.h b/chrome/browser/search/hotword_service.h index 6dbd6cd..ef587a3 100644 --- a/chrome/browser/search/hotword_service.h +++ b/chrome/browser/search/hotword_service.h @@ -20,6 +20,9 @@ extern const char kHotwordFieldTrialDisabledGroupName[]; // search. class HotwordService : public BrowserContextKeyedService { public: + // Returns true if the hotword supports the current system language. + static bool DoesHotwordSupportLanguage(Profile* profile); + explicit HotwordService(Profile* profile); virtual ~HotwordService(); diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc index 2de89ad..0c2b274 100644 --- a/chrome/browser/ui/app_list/app_list_view_delegate.cc +++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc @@ -35,7 +35,6 @@ #include "content/public/browser/page_navigator.h" #include "content/public/browser/user_metrics.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/search_box_model.h" #include "ui/app_list/speech_ui_model.h" @@ -96,15 +95,10 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile, RegisterForNotifications(); g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(this); - // Hotword listening is on by default in ChromeOS right now. Here shouldn't - // use the current state in the webui because it will be changed to 'hotword - // listening' state from 'ready' after the view is initialized. + app_list::StartPageService* service = + app_list::StartPageService::Get(profile_); speech_ui_.reset(new app_list::SpeechUIModel( -#if defined(OS_CHROMEOS) - app_list::switches::IsVoiceSearchEnabled() ? - app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING : -#endif - app_list::SPEECH_RECOGNITION_OFF)); + service ? service->state() : app_list::SPEECH_RECOGNITION_OFF)); #if defined(GOOGLE_CHROME_BUILD) speech_ui_->set_logo( @@ -113,8 +107,6 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile, #endif OnProfileChanged(); // sets model_ - app_list::StartPageService* service = - app_list::StartPageService::Get(profile_); if (service) service->AddObserver(this); } diff --git a/chrome/browser/ui/app_list/start_page_service.cc b/chrome/browser/ui/app_list/start_page_service.cc index 151bd65..6c897bf 100644 --- a/chrome/browser/ui/app_list/start_page_service.cc +++ b/chrome/browser/ui/app_list/start_page_service.cc @@ -9,16 +9,13 @@ #include "base/command_line.h" #include "base/memory/singleton.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/profiles/profile.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_service_factory.h" #include "chrome/common/chrome_switches.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_observer.h" #include "content/public/browser/notification_registrar.h" @@ -31,46 +28,6 @@ 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 : public content::NotificationObserver { public: @@ -118,13 +75,22 @@ class StartPageService::StartPageWebContentsDelegate // static StartPageService* StartPageService::Get(Profile* profile) { - return Factory::GetForProfile(profile); + return StartPageServiceFactory::GetForProfile(profile); } StartPageService::StartPageService(Profile* profile) : profile_(profile), 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( content::WebContents::CreateParams(profile_))); contents_delegate_.reset(new StartPageWebContentsDelegate()); @@ -183,6 +149,7 @@ void StartPageService::OnSpeechSoundLevelChanged(int16 level) { void StartPageService::OnSpeechRecognitionStateChanged( SpeechRecognitionState new_state) { + state_ = new_state; FOR_EACH_OBSERVER(StartPageObserver, observers_, OnSpeechRecognitionStateChanged(new_state)); diff --git a/chrome/browser/ui/app_list/start_page_service.h b/chrome/browser/ui/app_list/start_page_service.h index bd21967..d1be3e7 100644 --- a/chrome/browser/ui/app_list/start_page_service.h +++ b/chrome/browser/ui/app_list/start_page_service.h @@ -48,13 +48,13 @@ class StartPageService : public BrowserContextKeyedService { RecommendedApps* recommended_apps() { return recommended_apps_.get(); } Profile* profile() { return profile_; } + SpeechRecognitionState state() { return state_; } void OnSpeechResult(const base::string16& query, bool is_final); void OnSpeechSoundLevelChanged(int16 level); void OnSpeechRecognitionStateChanged(SpeechRecognitionState new_state); private: - // A BrowserContextKeyedServiceFactory for this service. - class Factory; + friend class StartPageServiceFactory; // ProfileDestroyObserver to shutdown the service on exiting. WebContents // depends on the profile and needs to be closed before the profile and its @@ -76,6 +76,7 @@ class StartPageService : public BrowserContextKeyedService { scoped_ptr<StartPageWebContentsDelegate> contents_delegate_; scoped_ptr<ProfileDestroyObserver> profile_destroy_observer_; scoped_ptr<RecommendedApps> recommended_apps_; + SpeechRecognitionState state_; ObserverList<StartPageObserver> observers_; DISALLOW_COPY_AND_ASSIGN(StartPageService); diff --git a/chrome/browser/ui/app_list/start_page_service_factory.cc b/chrome/browser/ui/app_list/start_page_service_factory.cc new file mode 100644 index 0000000..0e65866 --- /dev/null +++ b/chrome/browser/ui/app_list/start_page_service_factory.cc @@ -0,0 +1,63 @@ +// 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 diff --git a/chrome/browser/ui/app_list/start_page_service_factory.h b/chrome/browser/ui/app_list/start_page_service_factory.h new file mode 100644 index 0000000..01ee036 --- /dev/null +++ b/chrome/browser/ui/app_list/start_page_service_factory.h @@ -0,0 +1,42 @@ +// 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_ diff --git a/chrome/browser/ui/webui/app_list/start_page_handler.cc b/chrome/browser/ui/webui/app_list/start_page_handler.cc index 976cc18..d38aa3e 100644 --- a/chrome/browser/ui/webui/app_list/start_page_handler.cc +++ b/chrome/browser/ui/webui/app_list/start_page_handler.cc @@ -8,10 +8,12 @@ #include "base/bind.h" #include "base/memory/scoped_ptr.h" +#include "base/prefs/pref_service.h" #include "base/sys_info.h" #include "base/values.h" #include "chrome/browser/extensions/extension_service.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_service.h" #include "chrome/browser/ui/app_list/recommended_apps.h" @@ -19,6 +21,7 @@ #include "chrome/browser/ui/host_desktop.h" #include "chrome/browser/ui/webui/extensions/extension_icon_source.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_ui.h" #include "extensions/browser/extension_system.h" @@ -97,6 +100,36 @@ void StartPageHandler::SendRecommendedApps() { 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) { Profile* profile = Profile::FromWebUI(web_ui()); StartPageService* service = StartPageService::Get(profile); @@ -109,11 +142,20 @@ void StartPageHandler::HandleInitialize(const base::ListValue* args) { SendRecommendedApps(); #if defined(OS_CHROMEOS) - // TODO(mukai): respect the configuration of the availability of the hotword - // plugin. if (app_list::switches::IsVoiceSearchEnabled() && + HotwordService::DoesHotwordSupportLanguage(profile) && 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 } diff --git a/chrome/browser/ui/webui/app_list/start_page_handler.h b/chrome/browser/ui/webui/app_list/start_page_handler.h index c3d35bb..b444f75 100644 --- a/chrome/browser/ui/webui/app_list/start_page_handler.h +++ b/chrome/browser/ui/webui/app_list/start_page_handler.h @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/prefs/pref_change_registrar.h" #include "chrome/browser/ui/app_list/recommended_apps_observer.h" #include "content/public/browser/web_ui_message_handler.h" @@ -35,6 +36,18 @@ class StartPageHandler : public content::WebUIMessageHandler, // Creates a ListValue for the recommended apps and sends it to js side. 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. void HandleInitialize(const base::ListValue* args); void HandleLaunchApp(const base::ListValue* args); @@ -43,6 +56,7 @@ class StartPageHandler : public content::WebUIMessageHandler, void HandleSpeechRecognition(const base::ListValue* args); RecommendedApps* recommended_apps_; // Not owned. + PrefChangeRegistrar pref_change_registrar_; DISALLOW_COPY_AND_ASSIGN(StartPageHandler); }; diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc index 5be4f54..b648de91 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chrome/browser/ui/webui/options/browser_options_handler.cc @@ -379,6 +379,7 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DELAY_VERY_LONG }, { "enableContentProtectionAttestation", IDS_OPTIONS_ENABLE_CONTENT_PROTECTION_ATTESTATION }, + { "enableHotwordAppList", IDS_OPTIONS_ENABLE_HOTWORD_APP_LIST }, { "factoryResetHeading", IDS_OPTIONS_FACTORY_RESET_HEADING }, { "factoryResetTitle", IDS_OPTIONS_FACTORY_RESET }, { "factoryResetRestart", IDS_OPTIONS_FACTORY_RESET_BUTTON }, @@ -546,6 +547,12 @@ void BrowserOptionsHandler::GetLocalizedValues(base::DictionaryValue* values) { magnifier_list->Append(option_partial.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 #if defined(OS_MACOSX) @@ -867,9 +874,9 @@ void BrowserOptionsHandler::InitializePage() { "BrowserOptions.enableFactoryResetSection"); } + Profile* profile = Profile::FromWebUI(web_ui()); OnAccountPictureManagedChanged( - policy::ProfilePolicyConnectorFactory::GetForProfile( - Profile::FromWebUI(web_ui()))-> + policy::ProfilePolicyConnectorFactory::GetForProfile(profile)-> policy_service()->GetPolicies( policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string())) diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 8f093d2..9408442 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -237,6 +237,8 @@ 'browser/ui/app_list/start_page_observer.h', 'browser/ui/app_list/start_page_service.cc', '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.h', 'browser/ui/app_modal_dialogs/app_modal_dialog_queue.cc', diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 22dbe44..fd79501 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -2148,6 +2148,13 @@ const char kHotwordSearchEnabled[] = "hotword.search_enabled"; // longer 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) // Boolean that controls the global enabled-state of protected media identifier. const char kProtectedMediaIdentifierEnabled[] = diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 4508496..27930f8 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -740,6 +740,10 @@ extern const char kVideoCaptureAllowedUrls[]; extern const char kHotwordSearchEnabled[]; extern const char kHotwordOptInPopupTimesShown[]; +#if defined(OS_CHROMEOS) +extern const char kHotwordAppListEnabled[]; +#endif + #if defined(OS_ANDROID) extern const char kProtectedMediaIdentifierEnabled[]; #endif |