Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(460)

Side by Side Diff: chrome/browser/ui/webui/settings/search_engines_handler.cc

Issue 2507363002: MD Settings: Add Hotword (OK Google) section to search_page (Closed)
Patch Set: Self Review Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/webui/settings/search_engines_handler.h" 5 #include "chrome/browser/ui/webui/settings/search_engines_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h" 11 #include "base/values.h"
12 #include "chrome/browser/extensions/extension_util.h" 12 #include "chrome/browser/extensions/extension_util.h"
13 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/search/hotword_audio_history_handler.h"
15 #include "chrome/browser/search/hotword_service.h"
16 #include "chrome/browser/search/hotword_service_factory.h"
17 #include "chrome/browser/search_engines/template_url_service_factory.h"
14 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" 18 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
19 #include "chrome/browser/signin/signin_manager_factory.h"
15 #include "chrome/browser/ui/search_engines/template_url_table_model.h" 20 #include "chrome/browser/ui/search_engines/template_url_table_model.h"
21 #include "chrome/common/pref_names.h"
16 #include "chrome/common/url_constants.h" 22 #include "chrome/common/url_constants.h"
17 #include "chrome/grit/generated_resources.h" 23 #include "chrome/grit/generated_resources.h"
24 #include "components/prefs/pref_service.h"
18 #include "components/search_engines/template_url.h" 25 #include "components/search_engines/template_url.h"
19 #include "components/search_engines/template_url_service.h" 26 #include "components/search_engines/template_url_service.h"
27 #include "components/signin/core/browser/signin_manager.h"
20 #include "content/public/browser/user_metrics.h" 28 #include "content/public/browser/user_metrics.h"
21 #include "content/public/browser/web_ui.h" 29 #include "content/public/browser/web_ui.h"
22 #include "extensions/browser/extension_registry.h" 30 #include "extensions/browser/extension_registry.h"
23 #include "extensions/common/extension.h" 31 #include "extensions/common/extension.h"
32 #include "ui/base/l10n/l10n_util.h"
24 33
25 namespace { 34 namespace {
26 // The following strings need to match with the IDs of the paper-input elements 35 // The following strings need to match with the IDs of the paper-input elements
27 // at settings/search_engines_page/add_search_engine_dialog.html. 36 // at settings/search_engines_page/add_search_engine_dialog.html.
28 const char kSearchEngineField[] = "searchEngine"; 37 const char kSearchEngineField[] = "searchEngine";
29 const char kKeywordField[] = "keyword"; 38 const char kKeywordField[] = "keyword";
30 const char kQueryUrlField[] = "queryUrl"; 39 const char kQueryUrlField[] = "queryUrl";
31 40
41 // Fields for hotwordUpdateInfo result.
42 const char kHotwordSatusAllowed[] = "allowed";
43 const char kHotwordSatusEnabled[] = "enabled";
44 const char kHotwordStatusAlwaysOn[] = "alwaysOn";
45 const char kHotwordSatusErrorMessage[] = "errorMessage";
46 const char kHotwordSatusUserUserName[] = "userName";
47 const char kHotwordSatusHistoryEnabled[] = "historyEnabled";
48
32 // Dummy number used for indicating that a new search engine is added. 49 // Dummy number used for indicating that a new search engine is added.
33 const int kNewSearchEngineIndex = -1; 50 const int kNewSearchEngineIndex = -1;
51
52 bool IsGoogleDefaultSearch(Profile* profile) {
53 TemplateURLService* template_url_service =
54 TemplateURLServiceFactory::GetForProfile(profile);
55 if (!template_url_service)
56 return false;
57 const TemplateURL* url_template =
58 template_url_service->GetDefaultSearchProvider();
59 return url_template &&
60 url_template->url_ref().HasGoogleBaseURLs(
61 template_url_service->search_terms_data());
62 }
63
64 bool GetHotwordAlwaysOn(Profile* profile) {
65 SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile);
66 return signin && signin->IsAuthenticated() &&
67 HotwordServiceFactory::IsAlwaysOnAvailable();
68 }
69
34 } // namespace 70 } // namespace
35 71
36 namespace settings { 72 namespace settings {
37 73
38 SearchEnginesHandler::SearchEnginesHandler(Profile* profile) 74 SearchEnginesHandler::SearchEnginesHandler(Profile* profile)
39 : profile_(profile), list_controller_(profile) {} 75 : profile_(profile), list_controller_(profile), weak_ptr_factory_(this) {
76 pref_change_registrar_.Init(profile_->GetPrefs());
77 }
40 78
41 SearchEnginesHandler::~SearchEnginesHandler() { 79 SearchEnginesHandler::~SearchEnginesHandler() {
42 // TODO(tommycli): Refactor KeywordEditorController to be compatible with 80 // TODO(tommycli): Refactor KeywordEditorController to be compatible with
43 // ScopedObserver so this is no longer necessary. 81 // ScopedObserver so this is no longer necessary.
44 list_controller_.table_model()->SetObserver(nullptr); 82 list_controller_.table_model()->SetObserver(nullptr);
45 } 83 }
46 84
47 void SearchEnginesHandler::RegisterMessages() { 85 void SearchEnginesHandler::RegisterMessages() {
48 web_ui()->RegisterMessageCallback( 86 web_ui()->RegisterMessageCallback(
49 "getSearchEnginesList", 87 "getSearchEnginesList",
(...skipping 16 matching lines...) Expand all
66 base::Bind(&SearchEnginesHandler::HandleSearchEngineEditStarted, 104 base::Bind(&SearchEnginesHandler::HandleSearchEngineEditStarted,
67 base::Unretained(this))); 105 base::Unretained(this)));
68 web_ui()->RegisterMessageCallback( 106 web_ui()->RegisterMessageCallback(
69 "searchEngineEditCancelled", 107 "searchEngineEditCancelled",
70 base::Bind(&SearchEnginesHandler::HandleSearchEngineEditCancelled, 108 base::Bind(&SearchEnginesHandler::HandleSearchEngineEditCancelled,
71 base::Unretained(this))); 109 base::Unretained(this)));
72 web_ui()->RegisterMessageCallback( 110 web_ui()->RegisterMessageCallback(
73 "searchEngineEditCompleted", 111 "searchEngineEditCompleted",
74 base::Bind(&SearchEnginesHandler::HandleSearchEngineEditCompleted, 112 base::Bind(&SearchEnginesHandler::HandleSearchEngineEditCompleted,
75 base::Unretained(this))); 113 base::Unretained(this)));
114 web_ui()->RegisterMessageCallback(
115 "getHotwordInfo", base::Bind(&SearchEnginesHandler::HandleGetHotwordInfo,
116 base::Unretained(this)));
117 web_ui()->RegisterMessageCallback(
118 "setHotwordSearchEnabled",
119 base::Bind(&SearchEnginesHandler::HandleSetHotwordSearchEnabled,
120 base::Unretained(this)));
76 } 121 }
77 122
78 void SearchEnginesHandler::OnJavascriptAllowed() { 123 void SearchEnginesHandler::OnJavascriptAllowed() {
79 list_controller_.table_model()->SetObserver(this); 124 list_controller_.table_model()->SetObserver(this);
125 pref_change_registrar_.Add(prefs::kHotwordSearchEnabled,
126 base::Bind(&SearchEnginesHandler::SendHotwordInfo,
127 base::Unretained(this)));
128 pref_change_registrar_.Add(prefs::kHotwordAlwaysOnSearchEnabled,
129 base::Bind(&SearchEnginesHandler::SendHotwordInfo,
130 base::Unretained(this)));
80 } 131 }
81 132
82 void SearchEnginesHandler::OnJavascriptDisallowed() { 133 void SearchEnginesHandler::OnJavascriptDisallowed() {
83 list_controller_.table_model()->SetObserver(nullptr); 134 list_controller_.table_model()->SetObserver(nullptr);
135 pref_change_registrar_.RemoveAll();
84 } 136 }
85 137
86 std::unique_ptr<base::DictionaryValue> 138 std::unique_ptr<base::DictionaryValue>
87 SearchEnginesHandler::GetSearchEnginesList() { 139 SearchEnginesHandler::GetSearchEnginesList() {
88 AllowJavascript();
89
90 // Find the default engine. 140 // Find the default engine.
91 const TemplateURL* default_engine = 141 const TemplateURL* default_engine =
92 list_controller_.GetDefaultSearchProvider(); 142 list_controller_.GetDefaultSearchProvider();
93 int default_index = 143 int default_index =
94 list_controller_.table_model()->IndexOfTemplateURL(default_engine); 144 list_controller_.table_model()->IndexOfTemplateURL(default_engine);
95 145
96 // Build the first list (default search engines). 146 // Build the first list (default search engines).
97 std::unique_ptr<base::ListValue> defaults = 147 std::unique_ptr<base::ListValue> defaults =
98 base::MakeUnique<base::ListValue>(); 148 base::MakeUnique<base::ListValue>();
99 int last_default_engine_index = 149 int last_default_engine_index =
(...skipping 23 matching lines...) Expand all
123 std::unique_ptr<base::DictionaryValue> search_engines_info( 173 std::unique_ptr<base::DictionaryValue> search_engines_info(
124 new base::DictionaryValue); 174 new base::DictionaryValue);
125 search_engines_info->Set("defaults", base::WrapUnique(defaults.release())); 175 search_engines_info->Set("defaults", base::WrapUnique(defaults.release()));
126 search_engines_info->Set("others", base::WrapUnique(others.release())); 176 search_engines_info->Set("others", base::WrapUnique(others.release()));
127 search_engines_info->Set("extensions", 177 search_engines_info->Set("extensions",
128 base::WrapUnique(extensions.release())); 178 base::WrapUnique(extensions.release()));
129 return search_engines_info; 179 return search_engines_info;
130 } 180 }
131 181
132 void SearchEnginesHandler::OnModelChanged() { 182 void SearchEnginesHandler::OnModelChanged() {
183 AllowJavascript();
133 CallJavascriptFunction("cr.webUIListenerCallback", 184 CallJavascriptFunction("cr.webUIListenerCallback",
134 base::StringValue("search-engines-changed"), 185 base::StringValue("search-engines-changed"),
135 *GetSearchEnginesList()); 186 *GetSearchEnginesList());
136 } 187 }
137 188
138 void SearchEnginesHandler::OnItemsChanged(int start, int length) { 189 void SearchEnginesHandler::OnItemsChanged(int start, int length) {
139 OnModelChanged(); 190 OnModelChanged();
140 } 191 }
141 192
142 void SearchEnginesHandler::OnItemsAdded(int start, int length) { 193 void SearchEnginesHandler::OnItemsAdded(int start, int length) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 } 244 }
194 } 245 }
195 return dict; 246 return dict;
196 } 247 }
197 248
198 void SearchEnginesHandler::HandleGetSearchEnginesList( 249 void SearchEnginesHandler::HandleGetSearchEnginesList(
199 const base::ListValue* args) { 250 const base::ListValue* args) {
200 CHECK_EQ(1U, args->GetSize()); 251 CHECK_EQ(1U, args->GetSize());
201 const base::Value* callback_id; 252 const base::Value* callback_id;
202 CHECK(args->Get(0, &callback_id)); 253 CHECK(args->Get(0, &callback_id));
254 AllowJavascript();
203 ResolveJavascriptCallback(*callback_id, *GetSearchEnginesList()); 255 ResolveJavascriptCallback(*callback_id, *GetSearchEnginesList());
204 } 256 }
205 257
206 void SearchEnginesHandler::HandleSetDefaultSearchEngine( 258 void SearchEnginesHandler::HandleSetDefaultSearchEngine(
207 const base::ListValue* args) { 259 const base::ListValue* args) {
208 int index; 260 int index;
209 if (!ExtractIntegerValue(args, &index)) { 261 if (!ExtractIntegerValue(args, &index)) {
210 NOTREACHED(); 262 NOTREACHED();
211 return; 263 return;
212 } 264 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 // Recheck validity. It's possible to get here with invalid input if e.g. the 376 // Recheck validity. It's possible to get here with invalid input if e.g. the
325 // user calls the right JS functions directly from the web inspector. 377 // user calls the right JS functions directly from the web inspector.
326 if (CheckFieldValidity(kSearchEngineField, search_engine) && 378 if (CheckFieldValidity(kSearchEngineField, search_engine) &&
327 CheckFieldValidity(kKeywordField, keyword) && 379 CheckFieldValidity(kKeywordField, keyword) &&
328 CheckFieldValidity(kQueryUrlField, query_url)) { 380 CheckFieldValidity(kQueryUrlField, query_url)) {
329 edit_controller_->AcceptAddOrEdit(base::UTF8ToUTF16(search_engine), 381 edit_controller_->AcceptAddOrEdit(base::UTF8ToUTF16(search_engine),
330 base::UTF8ToUTF16(keyword), query_url); 382 base::UTF8ToUTF16(keyword), query_url);
331 } 383 }
332 } 384 }
333 385
386 // TODO: Update hotword enabled and call DisableHotwordPreferences.
michaelpg 2016/11/27 22:25:36 TODO(name)
stevenjb 2016/11/28 20:53:37 Oops. I meant to do this in this CL. I've added th
387
388 void SearchEnginesHandler::HandleGetHotwordInfo(const base::ListValue* args) {
389 AllowJavascript();
390
391 std::unique_ptr<base::Value> callback_id;
392 if (args) {
393 CHECK_EQ(1U, args->GetSize());
394 const base::Value* id;
395 CHECK(args->Get(0, &id));
396 callback_id = id->CreateDeepCopy();
397 }
398
399 std::unique_ptr<base::DictionaryValue> status = GetHotwordInfo();
400 bool enabled = false;
401 status->GetBoolean(kHotwordSatusEnabled, &enabled);
402 bool always_on = false;
403 status->GetBoolean(kHotwordStatusAlwaysOn, &always_on);
404 if (!enabled || !always_on) {
405 HotwordInfoComplete(callback_id.get(), *status);
406 return;
407 }
408
409 // OnGetHotwordAudioHistoryEnabled will call HotwordInfoComplete()..
michaelpg 2016/11/27 22:25:36 remove '.'
stevenjb 2016/11/28 20:53:37 Done.
410 HotwordServiceFactory::GetForProfile(profile_)
411 ->GetAudioHistoryHandler()
412 ->GetAudioHistoryEnabled(
413 base::Bind(&SearchEnginesHandler::OnGetHotwordAudioHistoryEnabled,
414 weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback_id),
415 base::Passed(&status)));
416 }
417
418 std::unique_ptr<base::DictionaryValue> SearchEnginesHandler::GetHotwordInfo() {
419 auto status = base::MakeUnique<base::DictionaryValue>();
420 if (!IsGoogleDefaultSearch(profile_)) {
421 status->SetBoolean(kHotwordSatusAllowed, false);
422 return status;
423 }
424
425 status->SetBoolean(kHotwordSatusAllowed,
426 HotwordServiceFactory::IsHotwordAllowed(profile_));
427
428 HotwordServiceFactory::IsServiceAvailable(profile_); // Update error value.
429 int hotword_error = HotwordServiceFactory::GetCurrentError(profile_);
430 if (hotword_error) {
431 base::string16 hotword_error_message;
432 if (hotword_error != IDS_HOTWORD_GENERIC_ERROR_MESSAGE) {
433 hotword_error_message = l10n_util::GetStringUTF16(hotword_error);
434 } else {
435 hotword_error_message = l10n_util::GetStringFUTF16(
436 hotword_error, base::ASCIIToUTF16(chrome::kHotwordLearnMoreURL));
437 }
438 status->SetString(kHotwordSatusErrorMessage, hotword_error_message);
439 }
440
441 if (!HotwordServiceFactory::GetForProfile(profile_)) {
442 status->SetBoolean(kHotwordSatusEnabled, false);
443 return status;
444 }
445
446 bool always_on = GetHotwordAlwaysOn(profile_);
447 status->SetBoolean(kHotwordStatusAlwaysOn, always_on);
448
449 std::string pref_name = always_on ? prefs::kHotwordAlwaysOnSearchEnabled
450 : prefs::kHotwordSearchEnabled;
451 bool enabled = profile_->GetPrefs()->GetBoolean(pref_name);
452 status->SetBoolean(kHotwordSatusEnabled, enabled);
453 if (!enabled)
454 return status;
455
456 SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile_);
457 std::string user_display_name =
458 signin ? signin->GetAuthenticatedAccountInfo().email : "";
459 status->SetString(kHotwordSatusUserUserName, user_display_name);
460 return status;
461 }
462
463 void SearchEnginesHandler::OnGetHotwordAudioHistoryEnabled(
464 std::unique_ptr<base::Value> callback_id,
465 std::unique_ptr<base::DictionaryValue> status,
466 bool success,
467 bool logging_enabled) {
468 if (success)
469 status->SetBoolean(kHotwordSatusHistoryEnabled, logging_enabled);
470 HotwordInfoComplete(callback_id.get(), *status);
471 }
472
473 void SearchEnginesHandler::HotwordInfoComplete(
474 const base::Value* callback_id,
475 const base::DictionaryValue& status) {
476 if (callback_id) {
477 ResolveJavascriptCallback(*callback_id, status);
478 } else {
479 CallJavascriptFunction("cr.webUIListenerCallback",
480 base::StringValue("hotword-info-update"), status);
481 }
482 }
483
484 void SearchEnginesHandler::SendHotwordInfo() {
485 HandleGetHotwordInfo(nullptr);
486 }
487
488 void SearchEnginesHandler::HandleSetHotwordSearchEnabled(
489 const base::ListValue* args) {
490 CHECK_EQ(1U, args->GetSize());
491 bool enabled;
492 CHECK(args->GetBoolean(0, &enabled));
493
494 bool always_on = GetHotwordAlwaysOn(profile_);
495 if (!always_on) {
496 profile_->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, enabled);
497 return;
498 }
499
500 HotwordService* hotword_service =
501 HotwordServiceFactory::GetForProfile(profile_);
502 std::string pref_name = always_on ? prefs::kHotwordAlwaysOnSearchEnabled
michaelpg 2016/11/27 22:25:37 but, always_on cannot be false due to the early re
stevenjb 2016/11/28 20:53:36 Good point. Removed |pref_name|.
503 : prefs::kHotwordSearchEnabled;
504 if (!enabled || !hotword_service) {
505 profile_->GetPrefs()->SetBoolean(pref_name, false);
506 return;
507 }
508
509 bool was_enabled = profile_->GetPrefs()->GetBoolean(pref_name);
510 HotwordService::LaunchMode launch_mode;
511 if (was_enabled) {
512 launch_mode = HotwordService::RETRAIN;
513 } else {
514 bool logging_enabled =
515 profile_->GetPrefs()->GetBoolean(prefs::kHotwordAudioLoggingEnabled);
516 launch_mode = logging_enabled ? HotwordService::HOTWORD_ONLY
517 : HotwordService::HOTWORD_AND_AUDIO_HISTORY;
518 }
519 hotword_service->OptIntoHotwording(launch_mode);
520 SendHotwordInfo();
521 }
522
334 } // namespace settings 523 } // namespace settings
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698