1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/api/hotword_private/hotword_private_api.h" 6 7 #include "base/command_line.h" 8 #include "base/lazy_instance.h" 9 #include "base/prefs/pref_service.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/search/hotword_client.h" 12 #include "chrome/browser/search/hotword_service.h" 13 #include "chrome/browser/search/hotword_service_factory.h" 14 #include "chrome/common/chrome_switches.h" 15 #include "chrome/common/pref_names.h" 16 #include "extensions/browser/event_router.h" 17 18 namespace extensions { 19 20 namespace hotword_private_constants { 21 const char kHotwordServiceUnavailable[] = "Hotword Service is unavailable."; 22 } // hotword_private_constants 23 24 namespace OnEnabledChanged = 25 api::hotword_private::OnEnabledChanged; 26 27 static base::LazyInstance< 28 BrowserContextKeyedAPIFactory<HotwordPrivateEventService> > g_factory = 29 LAZY_INSTANCE_INITIALIZER; 30 31 HotwordPrivateEventService::HotwordPrivateEventService( 32 content::BrowserContext* context) 33 : profile_(Profile::FromBrowserContext(context)) { 34 pref_change_registrar_.Init(profile_->GetPrefs()); 35 pref_change_registrar_.Add( 36 prefs::kHotwordSearchEnabled, 37 base::Bind(&HotwordPrivateEventService::OnEnabledChanged, 38 base::Unretained(this))); 39 pref_change_registrar_.Add( 40 prefs::kHotwordAlwaysOnSearchEnabled, 41 base::Bind(&HotwordPrivateEventService::OnEnabledChanged, 42 base::Unretained(this))); 43 } 44 45 HotwordPrivateEventService::~HotwordPrivateEventService() { 46 } 47 48 void HotwordPrivateEventService::Shutdown() { 49 } 50 51 // static 52 BrowserContextKeyedAPIFactory<HotwordPrivateEventService>* 53 HotwordPrivateEventService::GetFactoryInstance() { 54 return g_factory.Pointer(); 55 } 56 57 // static 58 const char* HotwordPrivateEventService::service_name() { 59 return "HotwordPrivateEventService"; 60 } 61 62 void HotwordPrivateEventService::OnEnabledChanged( 63 const std::string& pref_name) { 64 DCHECK(pref_name == std::string(prefs::kHotwordSearchEnabled) || 65 pref_name == std::string(prefs::kHotwordAlwaysOnSearchEnabled)); 66 SignalEvent(OnEnabledChanged::kEventName); 67 } 68 69 void HotwordPrivateEventService::OnHotwordSessionRequested() { 70 SignalEvent(api::hotword_private::OnHotwordSessionRequested::kEventName); 71 } 72 73 void HotwordPrivateEventService::OnHotwordSessionStopped() { 74 SignalEvent(api::hotword_private::OnHotwordSessionStopped::kEventName); 75 } 76 77 void HotwordPrivateEventService::SignalEvent(const std::string& event_name) { 78 EventRouter* router = EventRouter::Get(profile_); 79 if (!router || !router->HasEventListener(event_name)) 80 return; 81 scoped_ptr<base::ListValue> args(new base::ListValue()); 82 scoped_ptr<Event> event(new Event(event_name, args.Pass())); 83 router->BroadcastEvent(event.Pass()); 84 } 85 86 bool HotwordPrivateSetEnabledFunction::RunSync() { 87 scoped_ptr<api::hotword_private::SetEnabled::Params> params( 88 api::hotword_private::SetEnabled::Params::Create(*args_)); 89 EXTENSION_FUNCTION_VALIDATE(params.get()); 90 91 PrefService* prefs = GetProfile()->GetPrefs(); 92 prefs->SetBoolean(prefs::kHotwordSearchEnabled, params->state); 93 return true; 94 } 95 96 bool HotwordPrivateSetAudioLoggingEnabledFunction::RunSync() { 97 scoped_ptr<api::hotword_private::SetAudioLoggingEnabled::Params> params( 98 api::hotword_private::SetAudioLoggingEnabled::Params::Create(*args_)); 99 EXTENSION_FUNCTION_VALIDATE(params.get()); 100 101 // TODO(kcarattini): Sync the chrome pref with the account-level 102 // Audio History setting. 103 PrefService* prefs = GetProfile()->GetPrefs(); 104 prefs->SetBoolean(prefs::kHotwordAudioLoggingEnabled, params->state); 105 return true; 106 } 107 108 bool HotwordPrivateSetHotwordAlwaysOnSearchEnabledFunction::RunSync() { 109 scoped_ptr<api::hotword_private::SetHotwordAlwaysOnSearchEnabled::Params> 110 params(api::hotword_private::SetHotwordAlwaysOnSearchEnabled::Params:: 111 Create(*args_)); 112 EXTENSION_FUNCTION_VALIDATE(params.get()); 113 114 PrefService* prefs = GetProfile()->GetPrefs(); 115 prefs->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, params->state); 116 return true; 117 } 118 119 bool HotwordPrivateGetStatusFunction::RunSync() { 120 api::hotword_private::StatusDetails result; 121 122 HotwordService* hotword_service = 123 HotwordServiceFactory::GetForProfile(GetProfile()); 124 if (!hotword_service) 125 result.available = false; 126 else 127 result.available = hotword_service->IsServiceAvailable(); 128 129 PrefService* prefs = GetProfile()->GetPrefs(); 130 result.enabled_set = prefs->HasPrefPath(prefs::kHotwordSearchEnabled); 131 result.enabled = prefs->GetBoolean(prefs::kHotwordSearchEnabled); 132 result.always_on_enabled = 133 prefs->GetBoolean(prefs::kHotwordAlwaysOnSearchEnabled); 134 result.audio_logging_enabled = false; 135 CommandLine* command_line = CommandLine::ForCurrentProcess(); 136 result.experimental_hotword_enabled = command_line->HasSwitch( 137 switches::kEnableExperimentalHotwording); 138 if (hotword_service) 139 result.audio_logging_enabled = hotword_service->IsOptedIntoAudioLogging(); 140 141 SetResult(result.ToValue().release()); 142 return true; 143 } 144 145 bool HotwordPrivateSetHotwordSessionStateFunction::RunSync() { 146 scoped_ptr<api::hotword_private::SetHotwordSessionState::Params> params( 147 api::hotword_private::SetHotwordSessionState::Params::Create(*args_)); 148 EXTENSION_FUNCTION_VALIDATE(params.get()); 149 150 HotwordService* hotword_service = 151 HotwordServiceFactory::GetForProfile(GetProfile()); 152 if (hotword_service && hotword_service->client()) 153 hotword_service->client()->OnHotwordStateChanged(params->started); 154 return true; 155 } 156 157 bool HotwordPrivateNotifyHotwordRecognitionFunction::RunSync() { 158 HotwordService* hotword_service = 159 HotwordServiceFactory::GetForProfile(GetProfile()); 160 if (hotword_service && hotword_service->client()) 161 hotword_service->client()->OnHotwordRecognized(); 162 return true; 163 } 164 165 bool HotwordPrivateGetLaunchStateFunction::RunSync() { 166 api::hotword_private::LaunchState result; 167 168 HotwordService* hotword_service = 169 HotwordServiceFactory::GetForProfile(GetProfile()); 170 if (!hotword_service) { 171 error_ = hotword_private_constants::kHotwordServiceUnavailable; 172 return false; 173 } else { 174 result.launch_mode = 175 hotword_service->GetHotwordAudioVerificationLaunchMode(); 176 } 177 178 SetResult(result.ToValue().release()); 179 return true; 180 } 181 182 } // namespace extensions 183