app_list: Re-enable people search.
[chromium-blink-merge.git] / chrome / browser / extensions / api / hotword_private / hotword_private_api.cc
blob9977dd8eb60a3b04b22b46b5b83fe90a14556a09
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.
5 #include "chrome/browser/extensions/api/hotword_private/hotword_private_api.h"
7 #include <string>
9 #include "base/i18n/rtl.h"
10 #include "base/lazy_instance.h"
11 #include "base/prefs/pref_service.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/search/hotword_audio_history_handler.h"
14 #include "chrome/browser/search/hotword_client.h"
15 #include "chrome/browser/search/hotword_service.h"
16 #include "chrome/browser/search/hotword_service_factory.h"
17 #include "chrome/browser/ui/app_list/app_list_service.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/grit/generated_resources.h"
21 #include "content/public/browser/speech_recognition_session_preamble.h"
22 #include "extensions/browser/event_router.h"
23 #include "ui/base/l10n/l10n_util.h"
25 namespace extensions {
27 namespace hotword_private_constants {
28 const char kHotwordServiceUnavailable[] = "Hotword Service is unavailable.";
29 const char kHotwordEventServiceUnavailable[] =
30 "Hotword Private Event Service is unavailable.";
31 } // hotword_private_constants
33 namespace OnEnabledChanged =
34 api::hotword_private::OnEnabledChanged;
36 static base::LazyInstance<
37 BrowserContextKeyedAPIFactory<HotwordPrivateEventService> > g_factory =
38 LAZY_INSTANCE_INITIALIZER;
40 HotwordPrivateEventService::HotwordPrivateEventService(
41 content::BrowserContext* context)
42 : profile_(Profile::FromBrowserContext(context)) {
43 pref_change_registrar_.Init(profile_->GetPrefs());
44 pref_change_registrar_.Add(
45 prefs::kHotwordSearchEnabled,
46 base::Bind(&HotwordPrivateEventService::OnEnabledChanged,
47 base::Unretained(this)));
48 pref_change_registrar_.Add(
49 prefs::kHotwordAlwaysOnSearchEnabled,
50 base::Bind(&HotwordPrivateEventService::OnEnabledChanged,
51 base::Unretained(this)));
54 HotwordPrivateEventService::~HotwordPrivateEventService() {
57 void HotwordPrivateEventService::Shutdown() {
60 // static
61 BrowserContextKeyedAPIFactory<HotwordPrivateEventService>*
62 HotwordPrivateEventService::GetFactoryInstance() {
63 return g_factory.Pointer();
66 // static
67 const char* HotwordPrivateEventService::service_name() {
68 return "HotwordPrivateEventService";
71 void HotwordPrivateEventService::OnEnabledChanged(
72 const std::string& pref_name) {
73 DCHECK(pref_name == std::string(prefs::kHotwordSearchEnabled) ||
74 pref_name == std::string(prefs::kHotwordAlwaysOnSearchEnabled) ||
75 pref_name == std::string(
76 hotword_internal::kHotwordTrainingEnabled));
77 SignalEvent(OnEnabledChanged::kEventName);
80 void HotwordPrivateEventService::OnHotwordSessionRequested() {
81 SignalEvent(api::hotword_private::OnHotwordSessionRequested::kEventName);
84 void HotwordPrivateEventService::OnHotwordSessionStopped() {
85 SignalEvent(api::hotword_private::OnHotwordSessionStopped::kEventName);
88 void HotwordPrivateEventService::OnFinalizeSpeakerModel() {
89 SignalEvent(api::hotword_private::OnFinalizeSpeakerModel::kEventName);
92 void HotwordPrivateEventService::OnSpeakerModelSaved() {
93 SignalEvent(api::hotword_private::OnSpeakerModelSaved::kEventName);
96 void HotwordPrivateEventService::OnHotwordTriggered() {
97 SignalEvent(api::hotword_private::OnHotwordTriggered::kEventName);
100 void HotwordPrivateEventService::SignalEvent(const std::string& event_name) {
101 EventRouter* router = EventRouter::Get(profile_);
102 if (!router || !router->HasEventListener(event_name))
103 return;
104 scoped_ptr<base::ListValue> args(new base::ListValue());
105 scoped_ptr<Event> event(new Event(event_name, args.Pass()));
106 router->BroadcastEvent(event.Pass());
109 bool HotwordPrivateSetEnabledFunction::RunSync() {
110 scoped_ptr<api::hotword_private::SetEnabled::Params> params(
111 api::hotword_private::SetEnabled::Params::Create(*args_));
112 EXTENSION_FUNCTION_VALIDATE(params.get());
114 PrefService* prefs = GetProfile()->GetPrefs();
115 prefs->SetBoolean(prefs::kHotwordSearchEnabled, params->state);
116 return true;
119 bool HotwordPrivateSetAudioLoggingEnabledFunction::RunSync() {
120 scoped_ptr<api::hotword_private::SetAudioLoggingEnabled::Params> params(
121 api::hotword_private::SetAudioLoggingEnabled::Params::Create(*args_));
122 EXTENSION_FUNCTION_VALIDATE(params.get());
124 // TODO(kcarattini): Sync the chrome pref with the account-level
125 // Audio History setting.
126 PrefService* prefs = GetProfile()->GetPrefs();
127 prefs->SetBoolean(prefs::kHotwordAudioLoggingEnabled, params->state);
128 return true;
131 bool HotwordPrivateSetHotwordAlwaysOnSearchEnabledFunction::RunSync() {
132 scoped_ptr<api::hotword_private::SetHotwordAlwaysOnSearchEnabled::Params>
133 params(api::hotword_private::SetHotwordAlwaysOnSearchEnabled::Params::
134 Create(*args_));
135 EXTENSION_FUNCTION_VALIDATE(params.get());
137 PrefService* prefs = GetProfile()->GetPrefs();
138 prefs->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, params->state);
139 return true;
142 bool HotwordPrivateGetStatusFunction::RunSync() {
143 api::hotword_private::StatusDetails result;
145 HotwordService* hotword_service =
146 HotwordServiceFactory::GetForProfile(GetProfile());
147 if (!hotword_service) {
148 result.available = false;
149 result.enabled = false;
150 result.audio_logging_enabled = false;
151 result.always_on_enabled = false;
152 result.user_is_active = false;
153 } else {
154 result.available = hotword_service->IsServiceAvailable();
155 result.enabled = hotword_service->IsSometimesOnEnabled();
156 result.audio_logging_enabled = hotword_service->IsOptedIntoAudioLogging();
157 result.training_enabled = hotword_service->IsTraining();
158 result.always_on_enabled = hotword_service->IsAlwaysOnEnabled();
159 result.user_is_active = hotword_service->UserIsActive();
162 PrefService* prefs = GetProfile()->GetPrefs();
163 result.enabled_set = prefs->HasPrefPath(prefs::kHotwordSearchEnabled);
164 result.experimental_hotword_enabled =
165 HotwordService::IsExperimentalHotwordingEnabled();
167 SetResult(result.ToValue().release());
168 return true;
171 bool HotwordPrivateSetHotwordSessionStateFunction::RunSync() {
172 scoped_ptr<api::hotword_private::SetHotwordSessionState::Params> params(
173 api::hotword_private::SetHotwordSessionState::Params::Create(*args_));
174 EXTENSION_FUNCTION_VALIDATE(params.get());
176 HotwordService* hotword_service =
177 HotwordServiceFactory::GetForProfile(GetProfile());
178 if (hotword_service &&
179 hotword_service->client() &&
180 !hotword_service->IsTraining())
181 hotword_service->client()->OnHotwordStateChanged(params->started);
182 return true;
185 bool HotwordPrivateNotifyHotwordRecognitionFunction::RunSync() {
186 scoped_ptr<api::hotword_private::NotifyHotwordRecognition::Params> params(
187 api::hotword_private::NotifyHotwordRecognition::Params::Create(*args_));
188 EXTENSION_FUNCTION_VALIDATE(params.get());
190 scoped_refptr<content::SpeechRecognitionSessionPreamble> preamble;
191 if (params->log.get() &&
192 !params->log->buffer.empty() &&
193 params->log->channels == 1) {
194 // TODO(amistry): Convert multi-channel preamble log into mono.
195 preamble = new content::SpeechRecognitionSessionPreamble();
196 preamble->sample_rate = params->log->sample_rate;
197 preamble->sample_depth = params->log->bytes_per_sample;
198 preamble->sample_data.swap(params->log->buffer);
201 HotwordService* hotword_service =
202 HotwordServiceFactory::GetForProfile(GetProfile());
203 if (hotword_service) {
204 if (hotword_service->IsTraining()) {
205 hotword_service->NotifyHotwordTriggered();
206 } else if (hotword_service->client()) {
207 hotword_service->client()->OnHotwordRecognized(preamble);
208 } else if (HotwordService::IsExperimentalHotwordingEnabled() &&
209 hotword_service->IsAlwaysOnEnabled()) {
210 Browser* browser = GetCurrentBrowser();
211 // If a Browser does not exist, fall back to the universally available,
212 // but not recommended, way.
213 AppListService* app_list_service = AppListService::Get(
214 browser ? browser->host_desktop_type() : chrome::GetActiveDesktop());
215 CHECK(app_list_service);
216 app_list_service->ShowForVoiceSearch(GetProfile(), preamble);
219 return true;
222 bool HotwordPrivateGetLaunchStateFunction::RunSync() {
223 HotwordService* hotword_service =
224 HotwordServiceFactory::GetForProfile(GetProfile());
225 if (!hotword_service) {
226 error_ = hotword_private_constants::kHotwordServiceUnavailable;
227 return false;
230 api::hotword_private::LaunchState result;
231 result.launch_mode =
232 hotword_service->GetHotwordAudioVerificationLaunchMode();
233 SetResult(result.ToValue().release());
234 return true;
237 bool HotwordPrivateStartTrainingFunction::RunSync() {
238 HotwordService* hotword_service =
239 HotwordServiceFactory::GetForProfile(GetProfile());
240 if (!hotword_service) {
241 error_ = hotword_private_constants::kHotwordServiceUnavailable;
242 return false;
245 hotword_service->StartTraining();
246 return true;
249 bool HotwordPrivateFinalizeSpeakerModelFunction::RunSync() {
250 HotwordService* hotword_service =
251 HotwordServiceFactory::GetForProfile(GetProfile());
252 if (!hotword_service) {
253 error_ = hotword_private_constants::kHotwordServiceUnavailable;
254 return false;
257 hotword_service->FinalizeSpeakerModel();
258 return true;
261 bool HotwordPrivateNotifySpeakerModelSavedFunction::RunSync() {
262 HotwordPrivateEventService* event_service =
263 BrowserContextKeyedAPIFactory<HotwordPrivateEventService>::Get(
264 GetProfile());
265 if (!event_service) {
266 error_ = hotword_private_constants::kHotwordEventServiceUnavailable;
267 return false;
270 event_service->OnSpeakerModelSaved();
271 return true;
274 bool HotwordPrivateStopTrainingFunction::RunSync() {
275 HotwordService* hotword_service =
276 HotwordServiceFactory::GetForProfile(GetProfile());
277 if (!hotword_service) {
278 error_ = hotword_private_constants::kHotwordServiceUnavailable;
279 return false;
282 hotword_service->StopTraining();
283 return true;
286 bool HotwordPrivateGetLocalizedStringsFunction::RunSync() {
287 base::DictionaryValue* localized_strings = new base::DictionaryValue();
289 localized_strings->SetString(
290 "close",
291 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_CLOSE));
292 localized_strings->SetString(
293 "cancel",
294 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_CANCEL));
295 localized_strings->SetString(
296 "introTitle",
297 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_INTRO_TITLE));
298 localized_strings->SetString(
299 "introSubtitle",
300 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_INTRO_SUBTITLE));
301 localized_strings->SetString(
302 "introDescription",
303 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_INTRO_DESCRIPTION));
304 localized_strings->SetString(
305 "introDescriptionAudioHistoryEnabled",
306 l10n_util::GetStringUTF16(
307 IDS_HOTWORD_OPT_IN_INTRO_DESCRIPTION_AUDIO_HISTORY_ENABLED));
308 localized_strings->SetString(
309 "introStart",
310 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_INTRO_START));
311 localized_strings->SetString(
312 "audioHistoryTitle",
313 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_AUDIO_HISTORY_TITLE));
314 localized_strings->SetString(
315 "audioHistoryDescription1",
316 l10n_util::GetStringUTF16(
317 IDS_HOTWORD_OPT_IN_AUDIO_HISTORY_DESCRIPTION_1));
318 localized_strings->SetString(
319 "audioHistoryDescription2",
320 l10n_util::GetStringUTF16(
321 IDS_HOTWORD_OPT_IN_AUDIO_HISTORY_DESCRIPTION_2));
322 localized_strings->SetString(
323 "audioHistoryDescription3",
324 l10n_util::GetStringUTF16(
325 IDS_HOTWORD_OPT_IN_AUDIO_HISTORY_DESCRIPTION_3));
326 localized_strings->SetString(
327 "audioHistoryAgree",
328 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_AUDIO_HISTORY_AGREE));
329 localized_strings->SetString(
330 "audioHistoryWait",
331 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_AUDIO_HISTORY_WAIT));
332 localized_strings->SetString(
333 "error",
334 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_ERROR));
335 localized_strings->SetString(
336 "trainingTitle",
337 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_TRAINING_TITLE));
338 localized_strings->SetString(
339 "trainingDescription",
340 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_TRAINING_DESCRIPTION));
341 localized_strings->SetString(
342 "trainingSpeak",
343 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_TRAINING_SPEAK));
344 localized_strings->SetString(
345 "trainingFirstPrompt",
346 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_TRAINING_FIRST_PROMPT));
347 localized_strings->SetString(
348 "trainingMiddlePrompt",
349 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_TRAINING_MIDDLE_PROMPT));
350 localized_strings->SetString(
351 "trainingLastPrompt",
352 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_TRAINING_LAST_PROMPT));
353 localized_strings->SetString(
354 "trainingRecorded",
355 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_TRAINING_RECORDED));
356 localized_strings->SetString(
357 "trainingTimeout",
358 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_TRAINING_TIMEOUT));
359 localized_strings->SetString(
360 "trainingRetry",
361 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_TRAINING_RETRY));
362 localized_strings->SetString(
363 "finishedTitle",
364 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_FINISHED_TITLE));
365 localized_strings->SetString(
366 "finishedListIntro",
367 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_FINISHED_LIST_INTRO));
368 localized_strings->SetString(
369 "finishedListItem1",
370 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_FINISHED_LIST_ITEM_1));
371 localized_strings->SetString(
372 "finishedListItem2",
373 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_FINISHED_LIST_ITEM_2));
374 localized_strings->SetString(
375 "finishedSettings",
376 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_FINISHED_SETTINGS));
377 localized_strings->SetString(
378 "finishedAudioHistory",
379 l10n_util::GetStringUTF16(
380 IDS_HOTWORD_OPT_IN_FINISHED_AUDIO_HISTORY));
381 localized_strings->SetString(
382 "finish",
383 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_FINISH));
384 localized_strings->SetString(
385 "finishedWait",
386 l10n_util::GetStringUTF16(IDS_HOTWORD_OPT_IN_FINISHED_WAIT));
388 localized_strings->SetString("textdirection",
389 base::i18n::IsRTL() ? "rtl" : "ltr");
391 SetResult(localized_strings);
392 return true;
395 bool HotwordPrivateSetAudioHistoryEnabledFunction::RunAsync() {
396 scoped_ptr<api::hotword_private::SetAudioHistoryEnabled::Params> params(
397 api::hotword_private::SetAudioHistoryEnabled::Params::Create(*args_));
398 EXTENSION_FUNCTION_VALIDATE(params.get());
400 HotwordService* hotword_service =
401 HotwordServiceFactory::GetForProfile(GetProfile());
402 if (!hotword_service || !hotword_service->GetAudioHistoryHandler()) {
403 error_ = hotword_private_constants::kHotwordServiceUnavailable;
404 return false;
407 hotword_service->GetAudioHistoryHandler()->SetAudioHistoryEnabled(
408 params->enabled,
409 base::Bind(
410 &HotwordPrivateSetAudioHistoryEnabledFunction::SetResultAndSendResponse,
411 this));
412 return true;
415 void HotwordPrivateSetAudioHistoryEnabledFunction::SetResultAndSendResponse(
416 bool success, bool new_enabled_value) {
417 api::hotword_private::AudioHistoryState result;
418 result.success = success;
419 result.enabled = new_enabled_value;
420 SetResult(result.ToValue().release());
421 SendResponse(true);
424 bool HotwordPrivateGetAudioHistoryEnabledFunction::RunAsync() {
425 HotwordService* hotword_service =
426 HotwordServiceFactory::GetForProfile(GetProfile());
427 if (!hotword_service || !hotword_service->GetAudioHistoryHandler()) {
428 error_ = hotword_private_constants::kHotwordServiceUnavailable;
429 return false;
432 hotword_service->GetAudioHistoryHandler()->GetAudioHistoryEnabled(base::Bind(
433 &HotwordPrivateGetAudioHistoryEnabledFunction::SetResultAndSendResponse,
434 this));
436 return true;
439 void HotwordPrivateGetAudioHistoryEnabledFunction::SetResultAndSendResponse(
440 bool success, bool new_enabled_value) {
441 api::hotword_private::AudioHistoryState result;
442 result.success = success;
443 result.enabled = new_enabled_value;
444 SetResult(result.ToValue().release());
445 SendResponse(true);
448 } // namespace extensions