hotword_service.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file.
48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/search/hotword_service.h"
68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/i18n/case_conversion.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/field_trial.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/prefs/pref_service.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/browser_process.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/pref_names.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kMaxTimesToShowOptInPopup = 10;
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Enum describing the state of the hotword preference.
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This is used for UMA stats -- do not reorder or delete items; only add to
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the end.
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum HotwordEnabled {
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UNSET = 0,  // The hotword preference has not been set.
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ENABLED,    // The hotword preference is enabled.
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISABLED,   // The hotword preference is disabled.
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NUM_HOTWORD_ENABLED_METRICS
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Enum describing the availability state of the hotword extension.
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This is used for UMA stats -- do not reorder or delete items; only add to
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the end.
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum HotwordExtensionAvailability {
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UNAVAILABLE = 0,
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AVAILABLE,
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PENDING_DOWNLOAD,
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISABLED_EXTENSION,
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NUM_HOTWORD_EXTENSION_AVAILABILITY_METRICS
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RecordAvailabilityMetrics(
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ExtensionService* service,
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const extensions::Extension* extension) {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HotwordExtensionAvailability availability_state = UNAVAILABLE;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (extension) {
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    availability_state = AVAILABLE;
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (service->pending_extension_manager() &&
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             service->pending_extension_manager()->IsIdPending(
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 extension_misc::kHotwordExtensionId)) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    availability_state = PENDING_DOWNLOAD;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (!service->IsExtensionEnabled(
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extension_misc::kHotwordExtensionId)) {
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    availability_state = DISABLED_EXTENSION;
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Hotword.HotwordExtensionAvailability",
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            availability_state,
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            NUM_HOTWORD_EXTENSION_AVAILABILITY_METRICS);
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ExtensionService* GetExtensionService(Profile* profile) {
6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  extensions::ExtensionSystem* extension_system =
6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile);
6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (extension_system)
7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return extension_system->extension_service();
7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return NULL;
7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace hotword_internal {
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Constants for the hotword field trial.
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kHotwordFieldTrialName[] = "VoiceTrigger";
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kHotwordFieldTrialDisabledGroupName[] = "Disabled";
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace hotword_internal
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool HotwordService::DoesHotwordSupportLanguage(Profile* profile) {
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string locale =
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // On ChromeOS locale is per-profile.
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      profile->GetPrefs()->GetString(prefs::kApplicationLocale);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->GetApplicationLocale();
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Only available for English now.
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string normalized_locale = l10n_util::NormalizeLocale(locale);
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return normalized_locale == "en" || normalized_locale == "en_us" ||
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      normalized_locale =="en_US";
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)HotwordService::HotwordService(Profile* profile)
988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : profile_(profile) {
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This will be called during profile initialization which is a good time
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to check the user's hotword state.
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HotwordEnabled enabled_state = UNSET;
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (profile_->GetPrefs()->HasPrefPath(prefs::kHotwordSearchEnabled)) {
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled))
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      enabled_state = ENABLED;
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    else
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      enabled_state = DISABLED;
10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else {
10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // If the preference has not been set the hotword extension should
10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // not be running.
11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DisableHotwordExtension(GetExtensionService(profile_));
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Hotword.Enabled", enabled_state,
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            NUM_HOTWORD_ENABLED_METRICS);
11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  pref_registrar_.Init(profile_->GetPrefs());
11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  pref_registrar_.Add(
11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      prefs::kHotwordSearchEnabled,
11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      base::Bind(&HotwordService::OnHotwordSearchEnabledChanged,
11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                 base::Unretained(this)));
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)HotwordService::~HotwordService() {
1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool HotwordService::ShouldShowOptInPopup() {
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (profile_->IsOffTheRecord())
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Profile is not off the record.
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (profile_->GetPrefs()->HasPrefPath(prefs::kHotwordSearchEnabled))
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;  // Already opted in or opted out;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int number_shown = profile_->GetPrefs()->GetInteger(
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      prefs::kHotwordOptInPopupTimesShown);
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return number_shown < MaxNumberTimesToShowOptInPopup();
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int HotwordService::MaxNumberTimesToShowOptInPopup() {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return kMaxTimesToShowOptInPopup;
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void HotwordService::ShowOptInPopup() {
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int number_shown = profile_->GetPrefs()->GetInteger(
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      prefs::kHotwordOptInPopupTimesShown);
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  profile_->GetPrefs()->SetInteger(prefs::kHotwordOptInPopupTimesShown,
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   ++number_shown);
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(rlp): actually show opt in popup when linked up to extension.
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool HotwordService::IsServiceAvailable() {
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ExtensionSystem* system =
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::ExtensionSystem::Get(profile_);
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionService* service = system->extension_service();
15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Include disabled extensions (true parameter) since it may not be enabled
15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // if the user opted out.
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const extensions::Extension* extension =
15723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      service->GetExtensionById(extension_misc::kHotwordExtensionId, true);
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RecordAvailabilityMetrics(service, extension);
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return extension && IsHotwordAllowed();
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool HotwordService::IsHotwordAllowed() {
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string group = base::FieldTrialList::FindFullName(
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      hotword_internal::kHotwordFieldTrialName);
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return !group.empty() &&
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      group != hotword_internal::kHotwordFieldTrialDisabledGroupName &&
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DoesHotwordSupportLanguage(profile_);
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool HotwordService::RetryHotwordExtension() {
17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ExtensionService* extension_service = GetExtensionService(profile_);
17423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!extension_service)
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  extension_service->ReloadExtension(extension_misc::kHotwordExtensionId);
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
18023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
18123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void HotwordService::EnableHotwordExtension(
18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ExtensionService* extension_service) {
18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (extension_service)
18423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    extension_service->EnableExtension(extension_misc::kHotwordExtensionId);
18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
18623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void HotwordService::DisableHotwordExtension(
18823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ExtensionService* extension_service) {
18923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (extension_service) {
19023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    extension_service->DisableExtension(
19123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        extension_misc::kHotwordExtensionId,
19223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        extensions::Extension::DISABLE_USER_ACTION);
19323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
19423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
19523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
19623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void HotwordService::OnHotwordSearchEnabledChanged(
19723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& pref_name) {
19823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK_EQ(pref_name, std::string(prefs::kHotwordSearchEnabled));
19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ExtensionService* extension_service = GetExtensionService(profile_);
20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled))
20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    EnableHotwordExtension(extension_service);
20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  else
20423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DisableHotwordExtension(extension_service);
20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
206