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

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: Nit Created 4 years 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 }
213 if (index < 0 || index >= list_controller_.table_model()->RowCount()) 265 if (index < 0 || index >= list_controller_.table_model()->RowCount())
214 return; 266 return;
215 267
216 list_controller_.MakeDefaultTemplateURL(index); 268 list_controller_.MakeDefaultTemplateURL(index);
217 269
270 // If the new search engine is not Google, disable hotword search.
271 // TODO(stevenjb): Investigate migrating this logic to
272 // MakeDefaultTemplateURL.
273 if (!IsGoogleDefaultSearch(profile_)) {
274 HotwordService* hotword_service =
275 HotwordServiceFactory::GetForProfile(profile_);
276 if (hotword_service)
277 hotword_service->DisableHotwordPreferences();
278 }
279 // Hotword status may have changed.
280 SendHotwordInfo();
281
218 content::RecordAction( 282 content::RecordAction(
219 base::UserMetricsAction("Options_SearchEngineSetDefault")); 283 base::UserMetricsAction("Options_SearchEngineSetDefault"));
220 } 284 }
221 285
222 void SearchEnginesHandler::HandleRemoveSearchEngine( 286 void SearchEnginesHandler::HandleRemoveSearchEngine(
223 const base::ListValue* args) { 287 const base::ListValue* args) {
224 int index; 288 int index;
225 if (!ExtractIntegerValue(args, &index)) { 289 if (!ExtractIntegerValue(args, &index)) {
226 NOTREACHED(); 290 NOTREACHED();
227 return; 291 return;
(...skipping 96 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 388 // 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. 389 // user calls the right JS functions directly from the web inspector.
326 if (CheckFieldValidity(kSearchEngineField, search_engine) && 390 if (CheckFieldValidity(kSearchEngineField, search_engine) &&
327 CheckFieldValidity(kKeywordField, keyword) && 391 CheckFieldValidity(kKeywordField, keyword) &&
328 CheckFieldValidity(kQueryUrlField, query_url)) { 392 CheckFieldValidity(kQueryUrlField, query_url)) {
329 edit_controller_->AcceptAddOrEdit(base::UTF8ToUTF16(search_engine), 393 edit_controller_->AcceptAddOrEdit(base::UTF8ToUTF16(search_engine),
330 base::UTF8ToUTF16(keyword), query_url); 394 base::UTF8ToUTF16(keyword), query_url);
331 } 395 }
332 } 396 }
333 397
398 void SearchEnginesHandler::HandleGetHotwordInfo(const base::ListValue* args) {
399 AllowJavascript();
400
401 std::unique_ptr<base::Value> callback_id;
402 if (args) {
403 CHECK_EQ(1U, args->GetSize());
404 const base::Value* id;
405 CHECK(args->Get(0, &id));
406 callback_id = id->CreateDeepCopy();
407 }
408
409 std::unique_ptr<base::DictionaryValue> status = GetHotwordInfo();
410 bool enabled = false;
411 status->GetBoolean(kHotwordSatusEnabled, &enabled);
412 bool always_on = false;
413 status->GetBoolean(kHotwordStatusAlwaysOn, &always_on);
414 if (!enabled || !always_on) {
415 HotwordInfoComplete(callback_id.get(), *status);
416 return;
417 }
418
419 // OnGetHotwordAudioHistoryEnabled will call HotwordInfoComplete().
420 HotwordServiceFactory::GetForProfile(profile_)
421 ->GetAudioHistoryHandler()
422 ->GetAudioHistoryEnabled(
423 base::Bind(&SearchEnginesHandler::OnGetHotwordAudioHistoryEnabled,
424 weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback_id),
425 base::Passed(&status)));
426 }
427
428 std::unique_ptr<base::DictionaryValue> SearchEnginesHandler::GetHotwordInfo() {
429 auto status = base::MakeUnique<base::DictionaryValue>();
430 if (!IsGoogleDefaultSearch(profile_)) {
431 status->SetBoolean(kHotwordSatusAllowed, false);
432 return status;
433 }
434
435 status->SetBoolean(kHotwordSatusAllowed,
436 HotwordServiceFactory::IsHotwordAllowed(profile_));
437
438 HotwordServiceFactory::IsServiceAvailable(profile_); // Update error value.
439 int hotword_error = HotwordServiceFactory::GetCurrentError(profile_);
440 if (hotword_error) {
441 base::string16 hotword_error_message;
442 if (hotword_error != IDS_HOTWORD_GENERIC_ERROR_MESSAGE) {
443 hotword_error_message = l10n_util::GetStringUTF16(hotword_error);
444 } else {
445 hotword_error_message = l10n_util::GetStringFUTF16(
446 hotword_error, base::ASCIIToUTF16(chrome::kHotwordLearnMoreURL));
447 }
448 status->SetString(kHotwordSatusErrorMessage, hotword_error_message);
449 }
450
451 if (!HotwordServiceFactory::GetForProfile(profile_)) {
452 status->SetBoolean(kHotwordSatusEnabled, false);
453 return status;
454 }
455
456 bool always_on = GetHotwordAlwaysOn(profile_);
457 status->SetBoolean(kHotwordStatusAlwaysOn, always_on);
458
459 std::string pref_name = always_on ? prefs::kHotwordAlwaysOnSearchEnabled
460 : prefs::kHotwordSearchEnabled;
461 bool enabled = profile_->GetPrefs()->GetBoolean(pref_name);
462 status->SetBoolean(kHotwordSatusEnabled, enabled);
463 if (!enabled)
464 return status;
465
466 SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile_);
467 std::string user_display_name =
468 signin ? signin->GetAuthenticatedAccountInfo().email : "";
469 status->SetString(kHotwordSatusUserUserName, user_display_name);
470 return status;
471 }
472
473 void SearchEnginesHandler::OnGetHotwordAudioHistoryEnabled(
474 std::unique_ptr<base::Value> callback_id,
475 std::unique_ptr<base::DictionaryValue> status,
476 bool success,
477 bool logging_enabled) {
478 if (success)
479 status->SetBoolean(kHotwordSatusHistoryEnabled, logging_enabled);
480 HotwordInfoComplete(callback_id.get(), *status);
481 }
482
483 void SearchEnginesHandler::HotwordInfoComplete(
484 const base::Value* callback_id,
485 const base::DictionaryValue& status) {
486 if (callback_id) {
487 ResolveJavascriptCallback(*callback_id, status);
488 } else {
489 CallJavascriptFunction("cr.webUIListenerCallback",
490 base::StringValue("hotword-info-update"), status);
491 }
492 }
493
494 void SearchEnginesHandler::SendHotwordInfo() {
495 HandleGetHotwordInfo(nullptr);
496 }
497
498 void SearchEnginesHandler::HandleSetHotwordSearchEnabled(
499 const base::ListValue* args) {
500 CHECK_EQ(1U, args->GetSize());
501 bool enabled;
502 CHECK(args->GetBoolean(0, &enabled));
503
504 bool always_on = GetHotwordAlwaysOn(profile_);
505 if (!always_on) {
506 profile_->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, enabled);
507 return;
508 }
509
510 HotwordService* hotword_service =
511 HotwordServiceFactory::GetForProfile(profile_);
512 if (!enabled || !hotword_service) {
513 profile_->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled,
514 false);
515 return;
516 }
517
518 bool was_enabled =
519 profile_->GetPrefs()->GetBoolean(prefs::kHotwordAlwaysOnSearchEnabled);
520 HotwordService::LaunchMode launch_mode;
521 if (was_enabled) {
522 launch_mode = HotwordService::RETRAIN;
523 } else {
524 bool logging_enabled =
525 profile_->GetPrefs()->GetBoolean(prefs::kHotwordAudioLoggingEnabled);
526 launch_mode = logging_enabled ? HotwordService::HOTWORD_ONLY
527 : HotwordService::HOTWORD_AND_AUDIO_HISTORY;
528 }
529 hotword_service->OptIntoHotwording(launch_mode);
530 SendHotwordInfo();
531 }
532
334 } // namespace settings 533 } // namespace settings
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/settings/search_engines_handler.h ('k') | chrome/test/data/webui/settings/search_page_test.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698