summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authormukai@chromium.org <mukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-13 21:58:21 +0000
committermukai@chromium.org <mukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-13 21:58:21 +0000
commit113891eb855d7e39fec98ef38b8fba5d047379d0 (patch)
treedd09083b93b606c33648d1c41b5a74909b5ae8d7 /chrome
parent3964e57729f597c270361d87cec3a67a9fbde4e6 (diff)
downloadchromium_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')
-rw-r--r--chrome/app/chromeos_strings.grdp3
-rw-r--r--chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc7
-rw-r--r--chrome/browser/resources/app_list/speech_manager.js39
-rw-r--r--chrome/browser/resources/app_list/start_page.js10
-rw-r--r--chrome/browser/resources/options/browser_options.html8
-rw-r--r--chrome/browser/resources/options/browser_options.js2
-rw-r--r--chrome/browser/search/hotword_service.cc33
-rw-r--r--chrome/browser/search/hotword_service.h3
-rw-r--r--chrome/browser/ui/app_list/app_list_view_delegate.cc14
-rw-r--r--chrome/browser/ui/app_list/start_page_service.cc59
-rw-r--r--chrome/browser/ui/app_list/start_page_service.h5
-rw-r--r--chrome/browser/ui/app_list/start_page_service_factory.cc63
-rw-r--r--chrome/browser/ui/app_list/start_page_service_factory.h42
-rw-r--r--chrome/browser/ui/webui/app_list/start_page_handler.cc48
-rw-r--r--chrome/browser/ui/webui/app_list/start_page_handler.h14
-rw-r--r--chrome/browser/ui/webui/options/browser_options_handler.cc11
-rw-r--r--chrome/chrome_browser_ui.gypi2
-rw-r--r--chrome/common/pref_names.cc7
-rw-r--r--chrome/common/pref_names.h4
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