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

Side by Side Diff: chrome/browser/search_engines/template_url_service.cc

Issue 268643002: Use the DefaultSearchManager as the exclusive authority on DSE, ignoring Web Data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix merge errors. Created 6 years, 7 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/search_engines/template_url_service.h" 5 #include "chrome/browser/search_engines/template_url_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/environment.h" 13 #include "base/environment.h"
14 #include "base/guid.h" 14 #include "base/guid.h"
15 #include "base/i18n/case_conversion.h" 15 #include "base/i18n/case_conversion.h"
16 #include "base/memory/scoped_vector.h" 16 #include "base/memory/scoped_vector.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/prefs/pref_service.h" 18 #include "base/prefs/pref_service.h"
19 #include "base/stl_util.h" 19 #include "base/stl_util.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_split.h" 20 #include "base/strings/string_split.h"
22 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
23 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
24 #include "base/time/time.h" 23 #include "base/time/time.h"
25 #include "chrome/browser/chrome_notification_types.h" 24 #include "chrome/browser/chrome_notification_types.h"
26 #include "chrome/browser/extensions/extension_service.h" 25 #include "chrome/browser/extensions/extension_service.h"
27 #include "chrome/browser/google/google_url_tracker.h" 26 #include "chrome/browser/google/google_url_tracker.h"
28 #include "chrome/browser/history/history_notifications.h" 27 #include "chrome/browser/history/history_notifications.h"
29 #include "chrome/browser/history/history_service.h" 28 #include "chrome/browser/history/history_service.h"
30 #include "chrome/browser/history/history_service_factory.h" 29 #include "chrome/browser/history/history_service_factory.h"
(...skipping 13 matching lines...) Expand all
44 #include "chrome/common/pref_names.h" 43 #include "chrome/common/pref_names.h"
45 #include "chrome/common/url_constants.h" 44 #include "chrome/common/url_constants.h"
46 #include "content/public/browser/notification_service.h" 45 #include "content/public/browser/notification_service.h"
47 #include "extensions/common/constants.h" 46 #include "extensions/common/constants.h"
48 #include "net/base/net_util.h" 47 #include "net/base/net_util.h"
49 #include "sync/api/sync_change.h" 48 #include "sync/api/sync_change.h"
50 #include "sync/api/sync_error_factory.h" 49 #include "sync/api/sync_error_factory.h"
51 #include "sync/protocol/search_engine_specifics.pb.h" 50 #include "sync/protocol/search_engine_specifics.pb.h"
52 #include "sync/protocol/sync.pb.h" 51 #include "sync/protocol/sync.pb.h"
53 #include "ui/base/l10n/l10n_util.h" 52 #include "ui/base/l10n/l10n_util.h"
53 #include "url/gurl.h"
54 54
55 typedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet; 55 typedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet;
56 typedef TemplateURLService::SyncDataMap SyncDataMap; 56 typedef TemplateURLService::SyncDataMap SyncDataMap;
57 57
58 namespace { 58 namespace {
59 59
60 bool IdenticalSyncGUIDs(const TemplateURLData* data, const TemplateURL* turl) {
61 if (!data || !turl)
62 return !data && !turl;
63
64 return data->sync_guid == turl->sync_guid();
65 }
66
60 bool TemplateURLMatchesData(const TemplateURL* url1, 67 bool TemplateURLMatchesData(const TemplateURL* url1,
61 const TemplateURLData* url2) { 68 const TemplateURLData* url2) {
62 if (!url1 || !url2) 69 if (!url1 || !url2)
63 return !url1 && !url2; 70 return !url1 && !url2;
64 71
65 return (url1->short_name() == url2->short_name) && 72 return (url1->short_name() == url2->short_name) &&
66 url1->HasSameKeywordAs(*url2) && 73 url1->HasSameKeywordAs(*url2) &&
67 (url1->url() == url2->url()) && 74 (url1->url() == url2->url()) &&
68 (url1->suggestions_url() == url2->suggestions_url) && 75 (url1->suggestions_url() == url2->suggestions_url) &&
69 (url1->instant_url() == url2->instant_url) && 76 (url1->instant_url() == url2->instant_url) &&
70 (url1->image_url() == url2->image_url) && 77 (url1->image_url() == url2->image_url) &&
71 (url1->new_tab_url() == url2->new_tab_url) && 78 (url1->new_tab_url() == url2->new_tab_url) &&
72 (url1->search_url_post_params() == url2->search_url_post_params) && 79 (url1->search_url_post_params() == url2->search_url_post_params) &&
73 (url1->suggestions_url_post_params() == 80 (url1->suggestions_url_post_params() ==
74 url2->suggestions_url_post_params) && 81 url2->suggestions_url_post_params) &&
75 (url1->instant_url_post_params() == url2->instant_url_post_params) && 82 (url1->instant_url_post_params() == url2->instant_url_post_params) &&
76 (url1->image_url_post_params() == url2->image_url_post_params) && 83 (url1->image_url_post_params() == url2->image_url_post_params) &&
77 (url1->favicon_url() == url2->favicon_url) && 84 (url1->favicon_url() == url2->favicon_url) &&
78 (url1->safe_for_autoreplace() == url2->safe_for_autoreplace) && 85 (url1->safe_for_autoreplace() == url2->safe_for_autoreplace) &&
79 (url1->show_in_default_list() == url2->show_in_default_list) && 86 (url1->show_in_default_list() == url2->show_in_default_list) &&
80 (url1->input_encodings() == url2->input_encodings) && 87 (url1->input_encodings() == url2->input_encodings) &&
81 (url1->alternate_urls() == url2->alternate_urls) && 88 (url1->alternate_urls() == url2->alternate_urls) &&
82 (url1->search_terms_replacement_key() == 89 (url1->search_terms_replacement_key() ==
83 url2->search_terms_replacement_key); 90 url2->search_terms_replacement_key);
84 } 91 }
85 92
86 const char kFirstPotentialEngineHistogramName[] =
87 "Search.FirstPotentialEngineCalled";
88
89 // Values for an enumerated histogram used to track whenever
90 // FirstPotentialDefaultEngine is called, and from where.
91 enum FirstPotentialEngineCaller {
92 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP,
93 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_PROCESSING_SYNC_CHANGES,
94 FIRST_POTENTIAL_CALLSITE_ON_LOAD,
95 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_SYNCING,
96 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_NOT_SYNCING,
97 FIRST_POTENTIAL_CALLSITE_MAX,
98 };
99
100 const char kDeleteSyncedEngineHistogramName[] = 93 const char kDeleteSyncedEngineHistogramName[] =
101 "Search.DeleteSyncedSearchEngine"; 94 "Search.DeleteSyncedSearchEngine";
102 95
103 // Values for an enumerated histogram used to track whenever an ACTION_DELETE is 96 // Values for an enumerated histogram used to track whenever an ACTION_DELETE is
104 // sent to the server for search engines. 97 // sent to the server for search engines.
105 enum DeleteSyncedSearchEngineEvent { 98 enum DeleteSyncedSearchEngineEvent {
106 DELETE_ENGINE_USER_ACTION, 99 DELETE_ENGINE_USER_ACTION,
107 DELETE_ENGINE_PRE_SYNC, 100 DELETE_ENGINE_PRE_SYNC,
108 DELETE_ENGINE_EMPTY_FIELD, 101 DELETE_ENGINE_EMPTY_FIELD,
109 DELETE_ENGINE_MAX, 102 DELETE_ENGINE_MAX,
110 }; 103 };
111 104
112 TemplateURL* FirstPotentialDefaultEngine(
113 const TemplateURLService::TemplateURLVector& template_urls) {
114 for (TemplateURLService::TemplateURLVector::const_iterator i(
115 template_urls.begin()); i != template_urls.end(); ++i) {
116 if ((*i)->ShowInDefaultList() &&
117 ((*i)->GetType() == TemplateURL::NORMAL))
118 return *i;
119 }
120 return NULL;
121 }
122
123 // Returns true iff the change in |change_list| at index |i| should not be sent 105 // Returns true iff the change in |change_list| at index |i| should not be sent
124 // up to the server based on its GUIDs presence in |sync_data| or when compared 106 // up to the server based on its GUIDs presence in |sync_data| or when compared
125 // to changes after it in |change_list|. 107 // to changes after it in |change_list|.
126 // The criteria is: 108 // The criteria is:
127 // 1) It is an ACTION_UPDATE or ACTION_DELETE and the sync_guid associated 109 // 1) It is an ACTION_UPDATE or ACTION_DELETE and the sync_guid associated
128 // with it is NOT found in |sync_data|. We can only update and remove 110 // with it is NOT found in |sync_data|. We can only update and remove
129 // entries that were originally from the Sync server. 111 // entries that were originally from the Sync server.
130 // 2) It is an ACTION_ADD and the sync_guid associated with it is found in 112 // 2) It is an ACTION_ADD and the sync_guid associated with it is found in
131 // |sync_data|. We cannot re-add entries that Sync already knew about. 113 // |sync_data|. We cannot re-add entries that Sync already knew about.
132 // 3) There is an update after an update for the same GUID. We prune earlier 114 // 3) There is an update after an update for the same GUID. We prune earlier
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 // rather "two elements", so we pass the prefix as a fake "element" which has 248 // rather "two elements", so we pass the prefix as a fake "element" which has
267 // a NULL KeywordDataElement pointer. 249 // a NULL KeywordDataElement pointer.
268 bool operator()(const KeywordToTemplateMap::value_type& elem1, 250 bool operator()(const KeywordToTemplateMap::value_type& elem1,
269 const KeywordToTemplateMap::value_type& elem2) const { 251 const KeywordToTemplateMap::value_type& elem2) const {
270 return (elem1.second == NULL) ? 252 return (elem1.second == NULL) ?
271 (elem2.first.compare(0, elem1.first.length(), elem1.first) > 0) : 253 (elem2.first.compare(0, elem1.first.length(), elem1.first) > 0) :
272 (elem1.first < elem2.first); 254 (elem1.first < elem2.first);
273 } 255 }
274 }; 256 };
275 257
258 // static
259 bool TemplateURLService::fallback_search_engines_disabled_ = false;
276 260
277 // TemplateURLService --------------------------------------------------------- 261 // TemplateURLService ---------------------------------------------------------
278 262
279 TemplateURLService::TemplateURLService(Profile* profile) 263 TemplateURLService::TemplateURLService(Profile* profile)
280 : provider_map_(new SearchHostToURLsMap), 264 : provider_map_(new SearchHostToURLsMap),
281 profile_(profile), 265 profile_(profile),
282 loaded_(false), 266 loaded_(false),
283 load_failed_(false), 267 load_failed_(false),
284 load_handle_(0), 268 load_handle_(0),
285 default_search_provider_(NULL), 269 default_search_provider_(NULL),
286 is_default_search_managed_(false),
287 next_id_(kInvalidTemplateURLID + 1), 270 next_id_(kInvalidTemplateURLID + 1),
288 time_provider_(&base::Time::Now), 271 time_provider_(&base::Time::Now),
289 models_associated_(false), 272 models_associated_(false),
290 processing_syncer_changes_(false), 273 processing_syncer_changes_(false),
291 pending_synced_default_search_(false),
292 dsp_change_origin_(DSP_CHANGE_OTHER),
293 default_search_manager_( 274 default_search_manager_(
294 new DefaultSearchManager(GetPrefs(), 275 GetPrefs(),
295 DefaultSearchManager::ObserverCallback())) { 276 base::Bind(&TemplateURLService::OnDefaultSearchChange,
277 base::Unretained(this))) {
296 DCHECK(profile_); 278 DCHECK(profile_);
297 Init(NULL, 0); 279 Init(NULL, 0);
298 } 280 }
299 281
300 TemplateURLService::TemplateURLService(const Initializer* initializers, 282 TemplateURLService::TemplateURLService(const Initializer* initializers,
301 const int count) 283 const int count)
302 : provider_map_(new SearchHostToURLsMap), 284 : provider_map_(new SearchHostToURLsMap),
303 profile_(NULL), 285 profile_(NULL),
304 loaded_(false), 286 loaded_(false),
305 load_failed_(false), 287 load_failed_(false),
306 load_handle_(0), 288 load_handle_(0),
307 service_(NULL), 289 service_(NULL),
308 default_search_provider_(NULL), 290 default_search_provider_(NULL),
309 is_default_search_managed_(false),
310 next_id_(kInvalidTemplateURLID + 1), 291 next_id_(kInvalidTemplateURLID + 1),
311 time_provider_(&base::Time::Now), 292 time_provider_(&base::Time::Now),
312 models_associated_(false), 293 models_associated_(false),
313 processing_syncer_changes_(false), 294 processing_syncer_changes_(false),
314 pending_synced_default_search_(false), 295 default_search_manager_(
315 dsp_change_origin_(DSP_CHANGE_OTHER) { 296 GetPrefs(),
297 base::Bind(&TemplateURLService::OnDefaultSearchChange,
298 base::Unretained(this))) {
316 Init(initializers, count); 299 Init(initializers, count);
317 } 300 }
318 301
319 TemplateURLService::~TemplateURLService() { 302 TemplateURLService::~TemplateURLService() {
320 // |service_| should be deleted during Shutdown(). 303 // |service_| should be deleted during Shutdown().
321 DCHECK(!service_); 304 DCHECK(!service_);
322 STLDeleteElements(&template_urls_); 305 STLDeleteElements(&template_urls_);
323 } 306 }
324 307
325 // static 308 // static
326 bool TemplateURLService::LoadDefaultSearchProviderFromPrefs(
327 PrefService* prefs,
328 scoped_ptr<TemplateURLData>* default_provider_data,
329 bool* is_managed) {
330 if (!prefs || !prefs->HasPrefPath(prefs::kDefaultSearchProviderSearchURL) ||
331 !prefs->HasPrefPath(prefs::kDefaultSearchProviderKeyword))
332 return false;
333
334 const PrefService::Preference* pref =
335 prefs->FindPreference(prefs::kDefaultSearchProviderSearchURL);
336 *is_managed = pref && pref->IsManaged();
337
338 if (!prefs->GetBoolean(prefs::kDefaultSearchProviderEnabled)) {
339 // The user doesn't want a default search provider.
340 default_provider_data->reset(NULL);
341 return true;
342 }
343
344 base::string16 name =
345 base::UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderName));
346 base::string16 keyword =
347 base::UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderKeyword));
348 if (keyword.empty())
349 return false;
350 std::string search_url =
351 prefs->GetString(prefs::kDefaultSearchProviderSearchURL);
352 // Force URL to be non-empty. We've never supported this case, but past bugs
353 // might have resulted in it slipping through; eventually this code can be
354 // replaced with a DCHECK(!search_url.empty());.
355 if (search_url.empty())
356 return false;
357 std::string suggest_url =
358 prefs->GetString(prefs::kDefaultSearchProviderSuggestURL);
359 std::string instant_url =
360 prefs->GetString(prefs::kDefaultSearchProviderInstantURL);
361 std::string image_url =
362 prefs->GetString(prefs::kDefaultSearchProviderImageURL);
363 std::string new_tab_url =
364 prefs->GetString(prefs::kDefaultSearchProviderNewTabURL);
365 std::string search_url_post_params =
366 prefs->GetString(prefs::kDefaultSearchProviderSearchURLPostParams);
367 std::string suggest_url_post_params =
368 prefs->GetString(prefs::kDefaultSearchProviderSuggestURLPostParams);
369 std::string instant_url_post_params =
370 prefs->GetString(prefs::kDefaultSearchProviderInstantURLPostParams);
371 std::string image_url_post_params =
372 prefs->GetString(prefs::kDefaultSearchProviderImageURLPostParams);
373 std::string icon_url =
374 prefs->GetString(prefs::kDefaultSearchProviderIconURL);
375 std::string encodings =
376 prefs->GetString(prefs::kDefaultSearchProviderEncodings);
377 std::string id_string = prefs->GetString(prefs::kDefaultSearchProviderID);
378 std::string prepopulate_id =
379 prefs->GetString(prefs::kDefaultSearchProviderPrepopulateID);
380 const base::ListValue* alternate_urls =
381 prefs->GetList(prefs::kDefaultSearchProviderAlternateURLs);
382 std::string search_terms_replacement_key = prefs->GetString(
383 prefs::kDefaultSearchProviderSearchTermsReplacementKey);
384
385 default_provider_data->reset(new TemplateURLData);
386 (*default_provider_data)->short_name = name;
387 (*default_provider_data)->SetKeyword(keyword);
388 (*default_provider_data)->SetURL(search_url);
389 (*default_provider_data)->suggestions_url = suggest_url;
390 (*default_provider_data)->instant_url = instant_url;
391 (*default_provider_data)->image_url = image_url;
392 (*default_provider_data)->new_tab_url = new_tab_url;
393 (*default_provider_data)->search_url_post_params = search_url_post_params;
394 (*default_provider_data)->suggestions_url_post_params =
395 suggest_url_post_params;
396 (*default_provider_data)->instant_url_post_params = instant_url_post_params;
397 (*default_provider_data)->image_url_post_params = image_url_post_params;
398 (*default_provider_data)->favicon_url = GURL(icon_url);
399 (*default_provider_data)->show_in_default_list = true;
400 (*default_provider_data)->alternate_urls.clear();
401 for (size_t i = 0; i < alternate_urls->GetSize(); ++i) {
402 std::string alternate_url;
403 if (alternate_urls->GetString(i, &alternate_url))
404 (*default_provider_data)->alternate_urls.push_back(alternate_url);
405 }
406 (*default_provider_data)->search_terms_replacement_key =
407 search_terms_replacement_key;
408 base::SplitString(encodings, ';', &(*default_provider_data)->input_encodings);
409 if (!id_string.empty() && !*is_managed) {
410 int64 value;
411 base::StringToInt64(id_string, &value);
412 (*default_provider_data)->id = value;
413 }
414 if (!prepopulate_id.empty() && !*is_managed) {
415 int value;
416 base::StringToInt(prepopulate_id, &value);
417 (*default_provider_data)->prepopulate_id = value;
418 }
419 return true;
420 }
421
422 // static
423 base::string16 TemplateURLService::GenerateKeyword(const GURL& url) { 309 base::string16 TemplateURLService::GenerateKeyword(const GURL& url) {
424 DCHECK(url.is_valid()); 310 DCHECK(url.is_valid());
425 // Strip "www." off the front of the keyword; otherwise the keyword won't work 311 // Strip "www." off the front of the keyword; otherwise the keyword won't work
426 // properly. See http://code.google.com/p/chromium/issues/detail?id=6984 . 312 // properly. See http://code.google.com/p/chromium/issues/detail?id=6984 .
427 // Special case: if the host was exactly "www." (not sure this can happen but 313 // Special case: if the host was exactly "www." (not sure this can happen but
428 // perhaps with some weird intranet and custom DNS server?), ensure we at 314 // perhaps with some weird intranet and custom DNS server?), ensure we at
429 // least don't return the empty string. 315 // least don't return the empty string.
430 base::string16 keyword(net::StripWWWFromHost(url)); 316 base::string16 keyword(net::StripWWWFromHost(url));
431 return keyword.empty() ? base::ASCIIToUTF16("www") : keyword; 317 return keyword.empty() ? base::ASCIIToUTF16("www") : keyword;
432 } 318 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 // case the term replaces the URL it's unlikely another keyword would have the 376 // case the term replaces the URL it's unlikely another keyword would have the
491 // same url. 377 // same url.
492 // TODO(jnd): Add additional parameters to get post data when the search URL 378 // TODO(jnd): Add additional parameters to get post data when the search URL
493 // has post parameters. 379 // has post parameters.
494 return GURL(search_ref.ReplaceSearchTermsUsingTermsData( 380 return GURL(search_ref.ReplaceSearchTermsUsingTermsData(
495 TemplateURLRef::SearchTermsArgs( 381 TemplateURLRef::SearchTermsArgs(
496 base::ASCIIToUTF16("blah.blah.blah.blah.blah")), 382 base::ASCIIToUTF16("blah.blah.blah.blah.blah")),
497 search_terms_data, NULL)); 383 search_terms_data, NULL));
498 } 384 }
499 385
500 void TemplateURLService::SaveDefaultSearchProviderToPrefs( 386 // static
501 const TemplateURL* t_url, 387 void TemplateURLService::DisableFallbackSearchEngines() {
502 PrefService* prefs) const { 388 fallback_search_engines_disabled_ = true;
503 if (!prefs || load_failed_)
504 return;
505
506 bool enabled = false;
507 std::string search_url;
508 std::string suggest_url;
509 std::string instant_url;
510 std::string image_url;
511 std::string new_tab_url;
512 std::string search_url_post_params;
513 std::string suggest_url_post_params;
514 std::string instant_url_post_params;
515 std::string image_url_post_params;
516 std::string icon_url;
517 std::string encodings;
518 std::string short_name;
519 std::string keyword;
520 std::string id_string;
521 std::string prepopulate_id;
522 base::ListValue alternate_urls;
523 std::string search_terms_replacement_key;
524 if (t_url) {
525 DCHECK_EQ(TemplateURL::NORMAL, t_url->GetType());
526 enabled = true;
527 search_url = t_url->url();
528 suggest_url = t_url->suggestions_url();
529 instant_url = t_url->instant_url();
530 image_url = t_url->image_url();
531 new_tab_url = t_url->new_tab_url();
532 search_url_post_params = t_url->search_url_post_params();
533 suggest_url_post_params = t_url->suggestions_url_post_params();
534 instant_url_post_params = t_url->instant_url_post_params();
535 image_url_post_params = t_url->image_url_post_params();
536 GURL icon_gurl = t_url->favicon_url();
537 if (!icon_gurl.is_empty())
538 icon_url = icon_gurl.spec();
539 encodings = JoinString(t_url->input_encodings(), ';');
540 short_name = base::UTF16ToUTF8(t_url->short_name());
541 keyword = base::UTF16ToUTF8(t_url->keyword());
542 id_string = base::Int64ToString(t_url->id());
543 prepopulate_id = base::Int64ToString(t_url->prepopulate_id());
544 for (size_t i = 0; i < t_url->alternate_urls().size(); ++i)
545 alternate_urls.AppendString(t_url->alternate_urls()[i]);
546 search_terms_replacement_key = t_url->search_terms_replacement_key();
547 }
548 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, enabled);
549 prefs->SetString(prefs::kDefaultSearchProviderSearchURL, search_url);
550 prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, suggest_url);
551 prefs->SetString(prefs::kDefaultSearchProviderInstantURL, instant_url);
552 prefs->SetString(prefs::kDefaultSearchProviderImageURL, image_url);
553 prefs->SetString(prefs::kDefaultSearchProviderNewTabURL, new_tab_url);
554 prefs->SetString(prefs::kDefaultSearchProviderSearchURLPostParams,
555 search_url_post_params);
556 prefs->SetString(prefs::kDefaultSearchProviderSuggestURLPostParams,
557 suggest_url_post_params);
558 prefs->SetString(prefs::kDefaultSearchProviderInstantURLPostParams,
559 instant_url_post_params);
560 prefs->SetString(prefs::kDefaultSearchProviderImageURLPostParams,
561 image_url_post_params);
562 prefs->SetString(prefs::kDefaultSearchProviderIconURL, icon_url);
563 prefs->SetString(prefs::kDefaultSearchProviderEncodings, encodings);
564 prefs->SetString(prefs::kDefaultSearchProviderName, short_name);
565 prefs->SetString(prefs::kDefaultSearchProviderKeyword, keyword);
566 prefs->SetString(prefs::kDefaultSearchProviderID, id_string);
567 prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID, prepopulate_id);
568 prefs->Set(prefs::kDefaultSearchProviderAlternateURLs, alternate_urls);
569 prefs->SetString(prefs::kDefaultSearchProviderSearchTermsReplacementKey,
570 search_terms_replacement_key);
571 } 389 }
572 390
573 bool TemplateURLService::CanReplaceKeyword( 391 bool TemplateURLService::CanReplaceKeyword(
574 const base::string16& keyword, 392 const base::string16& keyword,
575 const GURL& url, 393 const GURL& url,
576 TemplateURL** template_url_to_replace) { 394 TemplateURL** template_url_to_replace) {
577 DCHECK(!keyword.empty()); // This should only be called for non-empty 395 DCHECK(!keyword.empty()); // This should only be called for non-empty
578 // keywords. If we need to support empty kewords 396 // keywords. If we need to support empty kewords
579 // the code needs to change slightly. 397 // the code needs to change slightly.
580 TemplateURL* existing_url = GetTemplateURLForKeyword(keyword); 398 TemplateURL* existing_url = GetTemplateURLForKeyword(keyword);
(...skipping 10 matching lines...) Expand all
591 // be replaced. We do this to ensure that if the user assigns a different 409 // be replaced. We do this to ensure that if the user assigns a different
592 // keyword to a generated TemplateURL, we won't regenerate another keyword for 410 // keyword to a generated TemplateURL, we won't regenerate another keyword for
593 // the same host. 411 // the same host.
594 return !url.is_valid() || url.host().empty() || 412 return !url.is_valid() || url.host().empty() ||
595 CanReplaceKeywordForHost(url.host(), template_url_to_replace); 413 CanReplaceKeywordForHost(url.host(), template_url_to_replace);
596 } 414 }
597 415
598 void TemplateURLService::FindMatchingKeywords( 416 void TemplateURLService::FindMatchingKeywords(
599 const base::string16& prefix, 417 const base::string16& prefix,
600 bool support_replacement_only, 418 bool support_replacement_only,
601 TemplateURLVector* matches) const { 419 TemplateURLVector* matches) {
602 // Sanity check args. 420 // Sanity check args.
603 if (prefix.empty()) 421 if (prefix.empty())
604 return; 422 return;
605 DCHECK(matches != NULL); 423 DCHECK(matches != NULL);
606 DCHECK(matches->empty()); // The code for exact matches assumes this. 424 DCHECK(matches->empty()); // The code for exact matches assumes this.
607 425
608 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/det ails/520043/error-converting-from-null-to-a-pointer-type-in-std-pair 426 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/det ails/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
609 TemplateURL* const kNullTemplateURL = NULL; 427 TemplateURL* const kNullTemplateURL = NULL;
610 428
611 // Find matching keyword range. Searches the element map for keywords 429 // Find matching keyword range. Searches the element map for keywords
(...skipping 13 matching lines...) Expand all
625 matches->push_back(i->second); 443 matches->push_back(i->second);
626 } 444 }
627 } 445 }
628 446
629 TemplateURL* TemplateURLService::GetTemplateURLForKeyword( 447 TemplateURL* TemplateURLService::GetTemplateURLForKeyword(
630 const base::string16& keyword) { 448 const base::string16& keyword) {
631 KeywordToTemplateMap::const_iterator elem( 449 KeywordToTemplateMap::const_iterator elem(
632 keyword_to_template_map_.find(keyword)); 450 keyword_to_template_map_.find(keyword));
633 if (elem != keyword_to_template_map_.end()) 451 if (elem != keyword_to_template_map_.end())
634 return elem->second; 452 return elem->second;
635 return ((!loaded_ || load_failed_) && 453 return (!loaded_ && initial_default_search_provider_.get() &&
636 initial_default_search_provider_.get() &&
637 (initial_default_search_provider_->keyword() == keyword)) ? 454 (initial_default_search_provider_->keyword() == keyword)) ?
638 initial_default_search_provider_.get() : NULL; 455 initial_default_search_provider_.get() : NULL;
639 } 456 }
640 457
641 TemplateURL* TemplateURLService::GetTemplateURLForGUID( 458 TemplateURL* TemplateURLService::GetTemplateURLForGUID(
642 const std::string& sync_guid) { 459 const std::string& sync_guid) {
643 GUIDToTemplateMap::const_iterator elem(guid_to_template_map_.find(sync_guid)); 460 GUIDToTemplateMap::const_iterator elem(guid_to_template_map_.find(sync_guid));
644 if (elem != guid_to_template_map_.end()) 461 if (elem != guid_to_template_map_.end())
645 return elem->second; 462 return elem->second;
646 return ((!loaded_ || load_failed_) && 463 return (!loaded_ && initial_default_search_provider_.get() &&
647 initial_default_search_provider_.get() &&
648 (initial_default_search_provider_->sync_guid() == sync_guid)) ? 464 (initial_default_search_provider_->sync_guid() == sync_guid)) ?
649 initial_default_search_provider_.get() : NULL; 465 initial_default_search_provider_.get() : NULL;
650 } 466 }
651 467
652 TemplateURL* TemplateURLService::GetTemplateURLForHost( 468 TemplateURL* TemplateURLService::GetTemplateURLForHost(
653 const std::string& host) { 469 const std::string& host) {
654 if (loaded_) { 470 if (loaded_) {
655 TemplateURL* t_url = provider_map_->GetTemplateURLForHost(host); 471 TemplateURL* t_url = provider_map_->GetTemplateURLForHost(host);
656 if (t_url) 472 if (t_url)
657 return t_url; 473 return t_url;
658 } 474 }
659 return ((!loaded_ || load_failed_) && 475 return (!loaded_ && initial_default_search_provider_.get() &&
660 initial_default_search_provider_.get() &&
661 (GenerateSearchURL(initial_default_search_provider_.get()).host() == 476 (GenerateSearchURL(initial_default_search_provider_.get()).host() ==
662 host)) ? initial_default_search_provider_.get() : NULL; 477 host)) ? initial_default_search_provider_.get() : NULL;
663 } 478 }
664 479
665 void TemplateURLService::Add(TemplateURL* template_url) { 480 bool TemplateURLService::Add(TemplateURL* template_url) {
666 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 481 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
667 if (AddNoNotify(template_url, true)) 482 bool result = AddNoNotify(template_url, true);
483 if (result)
668 NotifyObservers(); 484 NotifyObservers();
485 return result;
669 } 486 }
670 487
671 void TemplateURLService::AddAndSetProfile(TemplateURL* template_url, 488 void TemplateURLService::AddAndSetProfile(TemplateURL* template_url,
672 Profile* profile) { 489 Profile* profile) {
673 template_url->profile_ = profile; 490 template_url->profile_ = profile;
674 Add(template_url); 491 Add(template_url);
675 } 492 }
676 493
677 void TemplateURLService::AddWithOverrides(TemplateURL* template_url, 494 void TemplateURLService::AddWithOverrides(TemplateURL* template_url,
678 const base::string16& short_name, 495 const base::string16& short_name,
(...skipping 16 matching lines...) Expand all
695 DCHECK(info); 512 DCHECK(info);
696 DCHECK_EQ(info->wants_to_be_default_engine, 513 DCHECK_EQ(info->wants_to_be_default_engine,
697 template_url->show_in_default_list()); 514 template_url->show_in_default_list());
698 template_url->extension_info_.swap(info); 515 template_url->extension_info_.swap(info);
699 DCHECK(!FindTemplateURLForExtension( 516 DCHECK(!FindTemplateURLForExtension(
700 template_url->GetExtensionId(), 517 template_url->GetExtensionId(),
701 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)); 518 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION));
702 519
703 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 520 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
704 if (AddNoNotify(template_url, true)) { 521 if (AddNoNotify(template_url, true)) {
705 // Note that we can't call CanMakeDefault() here, since it would return 522 if (template_url->extension_info_->wants_to_be_default_engine)
706 // false when another extension is already controlling the default search 523 UpdateExtensionDefaultSearchEngine();
707 // engine, and we want to allow new extensions to take over.
708 if (template_url->extension_info_->wants_to_be_default_engine &&
709 !is_default_search_managed()) {
710 TemplateURL* default_candidate = FindExtensionDefaultSearchEngine();
711 if (default_candidate == template_url) {
712 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
713 &dsp_change_origin_, DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION);
714 SetDefaultSearchProviderNoNotify(template_url);
715 }
716 }
717 NotifyObservers(); 524 NotifyObservers();
718 } 525 }
719 } 526 }
720 527
721 void TemplateURLService::Remove(TemplateURL* template_url) { 528 void TemplateURLService::Remove(TemplateURL* template_url) {
722 RemoveNoNotify(template_url); 529 RemoveNoNotify(template_url);
723 NotifyObservers(); 530 NotifyObservers();
724 } 531 }
725 532
726 void TemplateURLService::RemoveExtensionControlledTURL( 533 void TemplateURLService::RemoveExtensionControlledTURL(
727 const std::string& extension_id) { 534 const std::string& extension_id) {
728 DCHECK(loaded_); 535 DCHECK(loaded_);
729 TemplateURL* url = FindTemplateURLForExtension( 536 TemplateURL* url = FindTemplateURLForExtension(
730 extension_id, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION); 537 extension_id, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);
731 if (!url) 538 if (!url)
732 return; 539 return;
733 bool restore_dse = (url == GetDefaultSearchProvider()); 540 // NULL this out so that we can call RemoveNoNotify. The subsequent
734 if (restore_dse) { 541 // UpdateExtensionDefaultSearchEngine will cause it to be reset.
735 DCHECK(!is_default_search_managed()); 542 if (default_search_provider_ == url)
736 default_search_provider_ = NULL; 543 default_search_provider_ = NULL;
737 }
738 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 544 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
739 RemoveNoNotify(url); 545 RemoveNoNotify(url);
740 if (restore_dse) 546 UpdateExtensionDefaultSearchEngine();
741 SetDefaultSearchProviderAfterRemovingDefaultExtension();
742 NotifyObservers(); 547 NotifyObservers();
743 } 548 }
744 549
745 void TemplateURLService::RemoveAutoGeneratedSince(base::Time created_after) { 550 void TemplateURLService::RemoveAutoGeneratedSince(base::Time created_after) {
746 RemoveAutoGeneratedBetween(created_after, base::Time()); 551 RemoveAutoGeneratedBetween(created_after, base::Time());
747 } 552 }
748 553
749 void TemplateURLService::RemoveAutoGeneratedBetween(base::Time created_after, 554 void TemplateURLService::RemoveAutoGeneratedBetween(base::Time created_after,
750 base::Time created_before) { 555 base::Time created_before) {
751 RemoveAutoGeneratedForOriginBetween(GURL(), created_after, created_before); 556 RemoveAutoGeneratedForOriginBetween(GURL(), created_after, created_before);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 TemplateURLData data(url->data()); 632 TemplateURLData data(url->data());
828 data.short_name = title; 633 data.short_name = title;
829 data.SetKeyword(keyword); 634 data.SetKeyword(keyword);
830 if (search_url != data.url()) { 635 if (search_url != data.url()) {
831 data.SetURL(search_url); 636 data.SetURL(search_url);
832 // The urls have changed, reset the favicon url. 637 // The urls have changed, reset the favicon url.
833 data.favicon_url = GURL(); 638 data.favicon_url = GURL();
834 } 639 }
835 data.safe_for_autoreplace = false; 640 data.safe_for_autoreplace = false;
836 data.last_modified = time_provider_(); 641 data.last_modified = time_provider_();
837 TemplateURL new_url(url->profile(), data); 642
838 UIThreadSearchTermsData search_terms_data(url->profile()); 643 UIThreadSearchTermsData search_terms_data(url->profile());
839 if (UpdateNoNotify(url, new_url, search_terms_data)) 644 if (UpdateNoNotify(url, data, search_terms_data))
840 NotifyObservers(); 645 NotifyObservers();
841 } 646 }
842 647
843 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) { 648 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) {
844 return !is_default_search_managed() && 649 return ((default_search_provider_source_ ==
845 !IsExtensionControlledDefaultSearch() && 650 DefaultSearchManager::FROM_USER) ||
846 (url != GetDefaultSearchProvider()) && 651 (default_search_provider_source_ ==
847 url->url_ref().SupportsReplacement() && 652 DefaultSearchManager::FROM_FALLBACK)) &&
848 (url->GetType() == TemplateURL::NORMAL); 653 (url != GetDefaultSearchProvider()) &&
654 url->url_ref().SupportsReplacement() &&
655 (url->GetType() == TemplateURL::NORMAL);
849 } 656 }
850 657
851 void TemplateURLService::SetUserSelectedDefaultSearchProvider( 658 void TemplateURLService::SetUserSelectedDefaultSearchProvider(
852 TemplateURL* url) { 659 TemplateURL* url) {
853 SetDefaultSearchProvider(url); 660 // Omnibox keywords cannot be made default. Extension-controlled search
854 if (default_search_manager_) { 661 // engines can be made default only by the extension itself because they
855 if (url) 662 // aren't persisted.
856 default_search_manager_->SetUserSelectedDefaultSearchEngine(url->data()); 663 DCHECK(!url || (url->GetType() == TemplateURL::NORMAL));
857 else 664 // We rely on the DefaultSearchManager to push this back to us if, in fact,
858 default_search_manager_->ClearUserSelectedDefaultSearchEngine(); 665 // the effective DSE changes.
859 } 666 if (url)
667 default_search_manager_.SetUserSelectedDefaultSearchEngine(url->data());
668 else
669 default_search_manager_.ClearUserSelectedDefaultSearchEngine();
860 } 670 }
861 671
862 TemplateURL* TemplateURLService::GetDefaultSearchProvider() { 672 TemplateURL* TemplateURLService::GetDefaultSearchProvider() {
863 return (loaded_ && !load_failed_) ? 673 return loaded_ ?
864 default_search_provider_ : initial_default_search_provider_.get(); 674 default_search_provider_ : initial_default_search_provider_.get();
865 } 675 }
866 676
867 bool TemplateURLService::IsSearchResultsPageFromDefaultSearchProvider( 677 bool TemplateURLService::IsSearchResultsPageFromDefaultSearchProvider(
868 const GURL& url) { 678 const GURL& url) {
869 TemplateURL* default_provider = GetDefaultSearchProvider(); 679 TemplateURL* default_provider = GetDefaultSearchProvider();
870 return default_provider && default_provider->IsSearchURL(url); 680 return default_provider && default_provider->IsSearchURL(url);
871 } 681 }
872 682
873 bool TemplateURLService::IsExtensionControlledDefaultSearch() { 683 bool TemplateURLService::IsExtensionControlledDefaultSearch() {
874 const TemplateURL* default_provider = GetDefaultSearchProvider(); 684 return default_search_provider_source_ ==
875 return default_provider && (default_provider->GetType() == 685 DefaultSearchManager::FROM_EXTENSION;
876 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);
877 }
878
879 TemplateURL* TemplateURLService::FindNewDefaultSearchProvider() {
880 // See if the prepopulated default still exists.
881 scoped_ptr<TemplateURLData> prepopulated_default =
882 TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs());
883
884 for (TemplateURLVector::iterator i = template_urls_.begin();
885 i != template_urls_.end(); ++i) {
886 if ((*i)->prepopulate_id() == prepopulated_default->prepopulate_id)
887 return *i;
888 }
889 // If not, use the first non-extension keyword of the templates that supports
890 // search term replacement.
891 if (processing_syncer_changes_) {
892 UMA_HISTOGRAM_ENUMERATION(
893 kFirstPotentialEngineHistogramName,
894 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_PROCESSING_SYNC_CHANGES,
895 FIRST_POTENTIAL_CALLSITE_MAX);
896 } else {
897 if (sync_processor_.get()) {
898 // We're not currently in a sync cycle, but we're syncing.
899 UMA_HISTOGRAM_ENUMERATION(kFirstPotentialEngineHistogramName,
900 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_SYNCING,
901 FIRST_POTENTIAL_CALLSITE_MAX);
902 } else {
903 // We're not syncing at all.
904 UMA_HISTOGRAM_ENUMERATION(
905 kFirstPotentialEngineHistogramName,
906 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_NOT_SYNCING,
907 FIRST_POTENTIAL_CALLSITE_MAX);
908 }
909 }
910 return FirstPotentialDefaultEngine(template_urls_);
911 } 686 }
912 687
913 void TemplateURLService::RepairPrepopulatedSearchEngines() { 688 void TemplateURLService::RepairPrepopulatedSearchEngines() {
914 // Can't clean DB if it hasn't been loaded. 689 // Can't clean DB if it hasn't been loaded.
915 DCHECK(loaded()); 690 DCHECK(loaded());
916 691
692 if (default_search_provider_source_ == DefaultSearchManager::FROM_USER ||
693 default_search_provider_source_ == DefaultSearchManager::FROM_FALLBACK) {
694 // Clear this so that we can remove what it points to (if it's a
695 // prepopulated engine). No matter what we will reset it at the end anyway.
696 default_search_provider_ = NULL;
697 }
698
917 size_t default_search_provider_index = 0; 699 size_t default_search_provider_index = 0;
918 ScopedVector<TemplateURLData> prepopulated_urls = 700 ScopedVector<TemplateURLData> prepopulated_urls =
919 TemplateURLPrepopulateData::GetPrepopulatedEngines( 701 TemplateURLPrepopulateData::GetPrepopulatedEngines(
920 GetPrefs(), &default_search_provider_index); 702 GetPrefs(), &default_search_provider_index);
921 DCHECK(!prepopulated_urls.empty()); 703 DCHECK(!prepopulated_urls.empty());
922 int default_search_engine_id =
923 prepopulated_urls[default_search_provider_index]->prepopulate_id;
924 TemplateURL* current_dse = default_search_provider_;
925 ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData( 704 ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData(
926 &prepopulated_urls, template_urls_, current_dse)); 705 &prepopulated_urls, template_urls_, default_search_provider_));
927 706
928 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 707 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
929 708
930 // Remove items. 709 // Remove items.
931 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin(); 710 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin();
932 i < actions.removed_engines.end(); ++i) 711 i < actions.removed_engines.end(); ++i)
933 RemoveNoNotify(*i); 712 RemoveNoNotify(*i);
934 713
935 // Edit items. 714 // Edit items.
936 for (EditedEngines::iterator i(actions.edited_engines.begin()); 715 for (EditedEngines::iterator i(actions.edited_engines.begin());
937 i < actions.edited_engines.end(); ++i) { 716 i < actions.edited_engines.end(); ++i) {
938 UIThreadSearchTermsData search_terms_data(profile()); 717 UIThreadSearchTermsData search_terms_data(profile());
939 TemplateURL new_values(profile(), i->second); 718 UpdateNoNotify(i->first, i->second, search_terms_data);
940 UpdateNoNotify(i->first, new_values, search_terms_data);
941 } 719 }
942 720
943 // Add items. 721 // Add items.
944 for (std::vector<TemplateURLData>::const_iterator i = 722 for (std::vector<TemplateURLData>::const_iterator i =
945 actions.added_engines.begin(); 723 actions.added_engines.begin();
946 i < actions.added_engines.end(); 724 i < actions.added_engines.end();
947 ++i) { 725 ++i) {
948 AddNoNotify(new TemplateURL(profile_, *i), true); 726 AddNoNotify(new TemplateURL(profile_, *i), true);
949 } 727 }
950 728
951 // Change the DSE. 729 default_search_manager_.ClearUserSelectedDefaultSearchEngine();
952 TemplateURL* new_dse = FindURLByPrepopulateID(template_urls_, 730
953 default_search_engine_id); 731 if (!default_search_provider_) {
954 DCHECK(new_dse); 732 DefaultSearchManager::Source source;
955 if (CanMakeDefault(new_dse)) { 733 const TemplateURLData* new_dse =
956 base::AutoReset<DefaultSearchChangeOrigin> change_origin( 734 default_search_manager_.GetDefaultSearchEngine(&source);
957 &dsp_change_origin_, DSP_CHANGE_PROFILE_RESET); 735 // ApplyDefaultSearchChange will notify observers once it is done.
958 SetDefaultSearchProviderNoNotify(new_dse); 736 ApplyDefaultSearchChange(new_dse, source);
737 } else {
738 NotifyObservers();
959 } 739 }
960 NotifyObservers();
961 } 740 }
962 741
963 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) { 742 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) {
964 model_observers_.AddObserver(observer); 743 model_observers_.AddObserver(observer);
965 } 744 }
966 745
967 void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) { 746 void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) {
968 model_observers_.RemoveObserver(observer); 747 model_observers_.RemoveObserver(observer);
969 } 748 }
970 749
971 void TemplateURLService::Load() { 750 void TemplateURLService::Load() {
972 if (loaded_ || load_handle_) 751 if (loaded_ || load_handle_)
973 return; 752 return;
974 753
975 if (!service_) 754 if (!service_)
976 service_ = WebDataService::FromBrowserContext(profile_); 755 service_ = WebDataService::FromBrowserContext(profile_);
977 756
978 if (service_) { 757 if (service_)
979 load_handle_ = service_->GetKeywords(this); 758 load_handle_ = service_->GetKeywords(this);
980 } else { 759 else
981 ChangeToLoadedState(); 760 OnFailedLoad();
982 on_loaded_callbacks_.Notify();
983 }
984 } 761 }
985 762
986 scoped_ptr<TemplateURLService::Subscription> 763 scoped_ptr<TemplateURLService::Subscription>
987 TemplateURLService::RegisterOnLoadedCallback( 764 TemplateURLService::RegisterOnLoadedCallback(
988 const base::Closure& callback) { 765 const base::Closure& callback) {
989 return loaded_ ? 766 return loaded_ ?
990 scoped_ptr<TemplateURLService::Subscription>() : 767 scoped_ptr<TemplateURLService::Subscription>() :
991 on_loaded_callbacks_.Add(callback); 768 on_loaded_callbacks_.Add(callback);
992 } 769 }
993 770
994 void TemplateURLService::OnWebDataServiceRequestDone( 771 void TemplateURLService::OnWebDataServiceRequestDone(
995 WebDataService::Handle h, 772 WebDataService::Handle h,
996 const WDTypedResult* result) { 773 const WDTypedResult* result) {
997 // Reset the load_handle so that we don't try and cancel the load in 774 // Reset the load_handle so that we don't try and cancel the load in
998 // the destructor. 775 // the destructor.
999 load_handle_ = 0; 776 load_handle_ = 0;
1000 777
1001 if (!result) { 778 if (!result) {
1002 // Results are null if the database went away or (most likely) wasn't 779 // Results are null if the database went away or (most likely) wasn't
1003 // loaded. 780 // loaded.
1004 load_failed_ = true; 781 OnFailedLoad();
1005 service_ = NULL;
1006 ChangeToLoadedState();
1007 on_loaded_callbacks_.Notify();
1008 return; 782 return;
1009 } 783 }
1010 784
1011 // initial_default_search_provider_ is only needed before we've finished
1012 // loading. Now that we've loaded we can nuke it.
1013 initial_default_search_provider_.reset();
1014
1015 TemplateURLVector template_urls; 785 TemplateURLVector template_urls;
1016 TemplateURL* default_search_provider = NULL;
1017 int new_resource_keyword_version = 0; 786 int new_resource_keyword_version = 0;
1018 GetSearchProvidersUsingKeywordResult(*result, service_.get(), profile_, 787 GetSearchProvidersUsingKeywordResult(
1019 &template_urls, &default_search_provider, &new_resource_keyword_version, 788 *result,
789 service_.get(),
790 profile_,
791 &template_urls,
792 (default_search_provider_source_ == DefaultSearchManager::FROM_USER) ?
793 initial_default_search_provider_.get() : NULL,
794 &new_resource_keyword_version,
1020 &pre_sync_deletes_); 795 &pre_sync_deletes_);
1021 796
1022 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 797 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1023 798
1024 AddTemplateURLsAndSetupDefaultEngine(&template_urls, default_search_provider); 799 PatchMissingSyncGUIDs(&template_urls);
800 SetTemplateURLs(&template_urls);
1025 801
1026 // This initializes provider_map_ which should be done before 802 // This initializes provider_map_ which should be done before
1027 // calling UpdateKeywordSearchTermsForURL. 803 // calling UpdateKeywordSearchTermsForURL.
804 // This also calls NotifyObservers.
1028 ChangeToLoadedState(); 805 ChangeToLoadedState();
1029 806
1030 // Index any visits that occurred before we finished loading. 807 // Index any visits that occurred before we finished loading.
1031 for (size_t i = 0; i < visits_to_add_.size(); ++i) 808 for (size_t i = 0; i < visits_to_add_.size(); ++i)
1032 UpdateKeywordSearchTermsForURL(visits_to_add_[i]); 809 UpdateKeywordSearchTermsForURL(visits_to_add_[i]);
1033 visits_to_add_.clear(); 810 visits_to_add_.clear();
1034 811
1035 if (new_resource_keyword_version) 812 if (new_resource_keyword_version)
1036 service_->SetBuiltinKeywordVersion(new_resource_keyword_version); 813 service_->SetBuiltinKeywordVersion(new_resource_keyword_version);
1037
1038 EnsureDefaultSearchProviderExists();
1039
1040 NotifyObservers();
1041 on_loaded_callbacks_.Notify();
1042 } 814 }
1043 815
1044 base::string16 TemplateURLService::GetKeywordShortName( 816 base::string16 TemplateURLService::GetKeywordShortName(
1045 const base::string16& keyword, 817 const base::string16& keyword,
1046 bool* is_omnibox_api_extension_keyword) { 818 bool* is_omnibox_api_extension_keyword) {
1047 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); 819 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword);
1048 820
1049 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService 821 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService
1050 // to track changes to the model, this should become a DCHECK. 822 // to track changes to the model, this should become a DCHECK.
1051 if (template_url) { 823 if (template_url) {
1052 *is_omnibox_api_extension_keyword = 824 *is_omnibox_api_extension_keyword =
1053 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION; 825 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION;
1054 return template_url->AdjustedShortNameForLocaleDirection(); 826 return template_url->AdjustedShortNameForLocaleDirection();
1055 } 827 }
1056 *is_omnibox_api_extension_keyword = false; 828 *is_omnibox_api_extension_keyword = false;
1057 return base::string16(); 829 return base::string16();
1058 } 830 }
1059 831
1060 void TemplateURLService::Observe(int type, 832 void TemplateURLService::Observe(int type,
1061 const content::NotificationSource& source, 833 const content::NotificationSource& source,
1062 const content::NotificationDetails& details) { 834 const content::NotificationDetails& details) {
1063 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) { 835 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) {
1064 content::Details<history::URLVisitedDetails> visit_details(details); 836 content::Details<history::URLVisitedDetails> visit_details(details);
1065 if (!loaded_) 837 if (!loaded_)
1066 visits_to_add_.push_back(*visit_details.ptr()); 838 visits_to_add_.push_back(*visit_details.ptr());
1067 else 839 else
1068 UpdateKeywordSearchTermsForURL(*visit_details.ptr()); 840 UpdateKeywordSearchTermsForURL(*visit_details.ptr());
1069 } else if (type == chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED) {
1070 // Policy has been updated, so the default search prefs may be different.
1071 // Reload the default search provider from them.
1072 // TODO(pkasting): Rather than communicating via prefs, we should eventually
1073 // observe policy changes directly.
1074 UpdateDefaultSearch();
1075 } else { 841 } else {
1076 DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_URL_UPDATED, type); 842 DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_URL_UPDATED, type);
1077 if (loaded_) { 843 if (loaded_) {
1078 GoogleBaseURLChanged( 844 GoogleBaseURLChanged(
1079 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first); 845 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first);
1080 } 846 }
1081 } 847 }
1082 } 848 }
1083 849
1084 void TemplateURLService::Shutdown() { 850 void TemplateURLService::Shutdown() {
1085 // This check has to be done at Shutdown() instead of in the dtor to ensure 851 // This check has to be done at Shutdown() instead of in the dtor to ensure
1086 // that no clients of WebDataService are holding ptrs to it after the first 852 // that no clients of WebDataService are holding ptrs to it after the first
1087 // phase of the KeyedService Shutdown() process. 853 // phase of the KeyedService Shutdown() process.
1088 if (load_handle_) { 854 if (load_handle_) {
1089 DCHECK(service_.get()); 855 DCHECK(service_.get());
1090 service_->CancelRequest(load_handle_); 856 service_->CancelRequest(load_handle_);
1091 } 857 }
1092 service_ = NULL; 858 service_ = NULL;
1093 } 859 }
1094 860
1095 void TemplateURLService::OnSyncedDefaultSearchProviderGUIDChanged() {
1096 // Listen for changes to the default search from Sync.
1097 PrefService* prefs = GetPrefs();
1098 TemplateURL* new_default_search = GetTemplateURLForGUID(
1099 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID));
1100 if (new_default_search && !is_default_search_managed_) {
1101 if (new_default_search != GetDefaultSearchProvider()) {
1102 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
1103 &dsp_change_origin_, DSP_CHANGE_SYNC_PREF);
1104 SetUserSelectedDefaultSearchProvider(new_default_search);
1105 pending_synced_default_search_ = false;
1106 }
1107 } else {
1108 // If it's not there, or if default search is currently managed, set a
1109 // flag to indicate that we waiting on the search engine entry to come
1110 // in through Sync.
1111 pending_synced_default_search_ = true;
1112 }
1113 UpdateDefaultSearch();
1114 }
1115
1116 syncer::SyncDataList TemplateURLService::GetAllSyncData( 861 syncer::SyncDataList TemplateURLService::GetAllSyncData(
1117 syncer::ModelType type) const { 862 syncer::ModelType type) const {
1118 DCHECK_EQ(syncer::SEARCH_ENGINES, type); 863 DCHECK_EQ(syncer::SEARCH_ENGINES, type);
1119 864
1120 syncer::SyncDataList current_data; 865 syncer::SyncDataList current_data;
1121 for (TemplateURLVector::const_iterator iter = template_urls_.begin(); 866 for (TemplateURLVector::const_iterator iter = template_urls_.begin();
1122 iter != template_urls_.end(); ++iter) { 867 iter != template_urls_.end(); ++iter) {
1123 // We don't sync keywords managed by policy. 868 // We don't sync keywords managed by policy.
1124 if ((*iter)->created_by_policy()) 869 if ((*iter)->created_by_policy())
1125 continue; 870 continue;
(...skipping 13 matching lines...) Expand all
1139 syncer::SyncError error(FROM_HERE, 884 syncer::SyncError error(FROM_HERE,
1140 syncer::SyncError::DATATYPE_ERROR, 885 syncer::SyncError::DATATYPE_ERROR,
1141 "Models not yet associated.", 886 "Models not yet associated.",
1142 syncer::SEARCH_ENGINES); 887 syncer::SEARCH_ENGINES);
1143 return error; 888 return error;
1144 } 889 }
1145 DCHECK(loaded_); 890 DCHECK(loaded_);
1146 891
1147 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); 892 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
1148 893
1149 // We've started syncing, so set our origin member to the base Sync value.
1150 // As we move through Sync Code, we may set this to increasingly specific
1151 // origins so we can tell what exactly caused a DSP change.
1152 base::AutoReset<DefaultSearchChangeOrigin> change_origin(&dsp_change_origin_,
1153 DSP_CHANGE_SYNC_UNINTENTIONAL);
1154
1155 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 894 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1156 895
1157 syncer::SyncChangeList new_changes; 896 syncer::SyncChangeList new_changes;
1158 syncer::SyncError error; 897 syncer::SyncError error;
1159 for (syncer::SyncChangeList::const_iterator iter = change_list.begin(); 898 for (syncer::SyncChangeList::const_iterator iter = change_list.begin();
1160 iter != change_list.end(); ++iter) { 899 iter != change_list.end(); ++iter) {
1161 DCHECK_EQ(syncer::SEARCH_ENGINES, iter->sync_data().GetDataType()); 900 DCHECK_EQ(syncer::SEARCH_ENGINES, iter->sync_data().GetDataType());
1162 901
1163 std::string guid = 902 std::string guid =
1164 iter->sync_data().GetSpecifics().search_engine().sync_guid(); 903 iter->sync_data().GetSpecifics().search_engine().sync_guid();
(...skipping 28 matching lines...) Expand all
1193 // not ideal, but it prevents a far more severe bug where the default is 932 // not ideal, but it prevents a far more severe bug where the default is
1194 // unexpectedly swapped to something else. The user can safely delete 933 // unexpectedly swapped to something else. The user can safely delete
1195 // the extra entry again later, if they choose. Most users who do not 934 // the extra entry again later, if they choose. Most users who do not
1196 // look at the search engines UI will not notice this. 935 // look at the search engines UI will not notice this.
1197 // Note that we append a special character to the end of the keyword in 936 // Note that we append a special character to the end of the keyword in
1198 // an attempt to avoid a ping-poinging situation where receiving clients 937 // an attempt to avoid a ping-poinging situation where receiving clients
1199 // may try to continually delete the resurrected entry. 938 // may try to continually delete the resurrected entry.
1200 base::string16 updated_keyword = UniquifyKeyword(*existing_turl, true); 939 base::string16 updated_keyword = UniquifyKeyword(*existing_turl, true);
1201 TemplateURLData data(existing_turl->data()); 940 TemplateURLData data(existing_turl->data());
1202 data.SetKeyword(updated_keyword); 941 data.SetKeyword(updated_keyword);
1203 TemplateURL new_turl(existing_turl->profile(), data);
1204 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); 942 UIThreadSearchTermsData search_terms_data(existing_turl->profile());
1205 if (UpdateNoNotify(existing_turl, new_turl, search_terms_data)) 943 if (UpdateNoNotify(existing_turl, data, search_terms_data))
1206 NotifyObservers(); 944 NotifyObservers();
1207 945
1208 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(new_turl); 946 syncer::SyncData sync_data =
947 CreateSyncDataFromTemplateURL(*existing_turl);
948 // TODO(erikwright): UpdateNoNotify already sent an ACTION_UPDATE for
Nicolas Zea 2014/05/07 20:30:07 We're within a processing_changes bool, so UpdateN
erikwright (departed) 2014/05/07 22:26:47 Done.
949 // this. Is it correct/necessary to send an ACTION_ADD here?
1209 new_changes.push_back(syncer::SyncChange(FROM_HERE, 950 new_changes.push_back(syncer::SyncChange(FROM_HERE,
1210 syncer::SyncChange::ACTION_ADD, 951 syncer::SyncChange::ACTION_ADD,
1211 sync_data)); 952 sync_data));
1212 // Ignore the delete attempt. This means we never end up reseting the 953 // Ignore the delete attempt. This means we never end up resetting the
1213 // default search provider due to an ACTION_DELETE from sync. 954 // default search provider due to an ACTION_DELETE from sync.
1214 continue; 955 continue;
1215 } 956 }
1216 957
1217 Remove(existing_turl); 958 Remove(existing_turl);
1218 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { 959 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) {
1219 if (existing_turl) { 960 if (existing_turl) {
1220 error = sync_error_factory_->CreateAndUploadError( 961 error = sync_error_factory_->CreateAndUploadError(
1221 FROM_HERE, 962 FROM_HERE,
1222 "ProcessSyncChanges failed on ChangeType ACTION_ADD"); 963 "ProcessSyncChanges failed on ChangeType ACTION_ADD");
1223 continue; 964 continue;
1224 } 965 }
1225 const std::string guid = turl->sync_guid(); 966 const std::string guid = turl->sync_guid();
1226 if (existing_keyword_turl) { 967 if (existing_keyword_turl) {
1227 // Resolve any conflicts so we can safely add the new entry. 968 // Resolve any conflicts so we can safely add the new entry.
1228 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 969 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1229 &new_changes); 970 &new_changes);
1230 } 971 }
1231 // Force the local ID to kInvalidTemplateURLID so we can add it. 972 // Force the local ID to kInvalidTemplateURLID so we can add it.
1232 TemplateURLData data(turl->data()); 973 TemplateURLData data(turl->data());
1233 data.id = kInvalidTemplateURLID; 974 data.id = kInvalidTemplateURLID;
1234 Add(new TemplateURL(profile_, data)); 975 TemplateURL* added = new TemplateURL(profile_, data);
1235 976 if (Add(added) && GetPrefs() &&
Nicolas Zea 2014/05/07 20:30:07 nit: This logic seems to be reused in several plac
erikwright (departed) 2014/05/07 22:26:47 Done.
1236 // Possibly set the newly added |turl| as the default search provider. 977 (guid ==
1237 SetDefaultSearchProviderIfNewlySynced(guid); 978 GetPrefs()->GetString(prefs::kSyncedDefaultSearchProviderGUID))) {
979 default_search_manager_.SetUserSelectedDefaultSearchEngine(
980 added->data());
981 }
1238 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) { 982 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) {
1239 if (!existing_turl) { 983 if (!existing_turl) {
1240 error = sync_error_factory_->CreateAndUploadError( 984 error = sync_error_factory_->CreateAndUploadError(
1241 FROM_HERE, 985 FROM_HERE,
1242 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE"); 986 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE");
1243 continue; 987 continue;
1244 } 988 }
1245 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) { 989 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) {
1246 // Resolve any conflicts with other entries so we can safely update the 990 // Resolve any conflicts with other entries so we can safely update the
1247 // keyword. 991 // keyword.
1248 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 992 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1249 &new_changes); 993 &new_changes);
1250 } 994 }
1251 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); 995 UIThreadSearchTermsData search_terms_data(existing_turl->profile());
1252 if (UpdateNoNotify(existing_turl, *turl, search_terms_data)) 996 if (UpdateNoNotify(existing_turl, turl->data(), search_terms_data)) {
1253 NotifyObservers(); 997 NotifyObservers();
998 if (GetPrefs() &&
999 (turl->sync_guid() ==
1000 GetPrefs()->GetString(prefs::kSyncedDefaultSearchProviderGUID))) {
1001 default_search_manager_.SetUserSelectedDefaultSearchEngine(
1002 existing_turl->data());
1003 }
1004 }
1254 } else { 1005 } else {
1255 // We've unexpectedly received an ACTION_INVALID. 1006 // We've unexpectedly received an ACTION_INVALID.
1256 error = sync_error_factory_->CreateAndUploadError( 1007 error = sync_error_factory_->CreateAndUploadError(
1257 FROM_HERE, 1008 FROM_HERE,
1258 "ProcessSyncChanges received an ACTION_INVALID"); 1009 "ProcessSyncChanges received an ACTION_INVALID");
1259 } 1010 }
1260 } 1011 }
1261 1012
1262 // If something went wrong, we want to prematurely exit to avoid pushing 1013 // If something went wrong, we want to prematurely exit to avoid pushing
1263 // inconsistent data to Sync. We return the last error we received. 1014 // inconsistent data to Sync. We return the last error we received.
(...skipping 21 matching lines...) Expand all
1285 if (load_failed_) { 1036 if (load_failed_) {
1286 merge_result.set_error(syncer::SyncError( 1037 merge_result.set_error(syncer::SyncError(
1287 FROM_HERE, syncer::SyncError::DATATYPE_ERROR, 1038 FROM_HERE, syncer::SyncError::DATATYPE_ERROR,
1288 "Local database load failed.", syncer::SEARCH_ENGINES)); 1039 "Local database load failed.", syncer::SEARCH_ENGINES));
1289 return merge_result; 1040 return merge_result;
1290 } 1041 }
1291 1042
1292 sync_processor_ = sync_processor.Pass(); 1043 sync_processor_ = sync_processor.Pass();
1293 sync_error_factory_ = sync_error_factory.Pass(); 1044 sync_error_factory_ = sync_error_factory.Pass();
1294 1045
1295 // We just started syncing, so set our wait-for-default flag if we are
1296 // expecting a default from Sync.
1297 if (GetPrefs()) {
1298 std::string default_guid = GetPrefs()->GetString(
1299 prefs::kSyncedDefaultSearchProviderGUID);
1300 const TemplateURL* current_default = GetDefaultSearchProvider();
1301
1302 if (!default_guid.empty() &&
1303 (!current_default || current_default->sync_guid() != default_guid))
1304 pending_synced_default_search_ = true;
1305 }
1306
1307 // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we 1046 // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we
1308 // don't step on our own toes. 1047 // don't step on our own toes.
1309 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); 1048 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
1310 1049
1311 // We've started syncing, so set our origin member to the base Sync value.
1312 // As we move through Sync Code, we may set this to increasingly specific
1313 // origins so we can tell what exactly caused a DSP change.
1314 base::AutoReset<DefaultSearchChangeOrigin> change_origin(&dsp_change_origin_,
1315 DSP_CHANGE_SYNC_UNINTENTIONAL);
1316
1317 syncer::SyncChangeList new_changes; 1050 syncer::SyncChangeList new_changes;
1318 1051
1319 // Build maps of our sync GUIDs to syncer::SyncData. 1052 // Build maps of our sync GUIDs to syncer::SyncData.
1320 SyncDataMap local_data_map = CreateGUIDToSyncDataMap( 1053 SyncDataMap local_data_map = CreateGUIDToSyncDataMap(
1321 GetAllSyncData(syncer::SEARCH_ENGINES)); 1054 GetAllSyncData(syncer::SEARCH_ENGINES));
1322 SyncDataMap sync_data_map = CreateGUIDToSyncDataMap(initial_sync_data); 1055 SyncDataMap sync_data_map = CreateGUIDToSyncDataMap(initial_sync_data);
1323 1056
1324 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 1057 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1325 1058
1326 merge_result.set_num_items_before_association(local_data_map.size()); 1059 merge_result.set_num_items_before_association(local_data_map.size());
(...skipping 25 matching lines...) Expand all
1352 // This local search engine is already synced. If the timestamp differs 1085 // This local search engine is already synced. If the timestamp differs
1353 // from Sync, we need to update locally or to the cloud. Note that if the 1086 // from Sync, we need to update locally or to the cloud. Note that if the
1354 // timestamps are equal, we touch neither. 1087 // timestamps are equal, we touch neither.
1355 if (sync_turl->last_modified() > local_turl->last_modified()) { 1088 if (sync_turl->last_modified() > local_turl->last_modified()) {
1356 // We've received an update from Sync. We should replace all synced 1089 // We've received an update from Sync. We should replace all synced
1357 // fields in the local TemplateURL. Note that this includes the 1090 // fields in the local TemplateURL. Note that this includes the
1358 // TemplateURLID and the TemplateURL may have to be reparsed. This 1091 // TemplateURLID and the TemplateURL may have to be reparsed. This
1359 // also makes the local data's last_modified timestamp equal to Sync's, 1092 // also makes the local data's last_modified timestamp equal to Sync's,
1360 // avoiding an Update on the next MergeData call. 1093 // avoiding an Update on the next MergeData call.
1361 UIThreadSearchTermsData search_terms_data(local_turl->profile()); 1094 UIThreadSearchTermsData search_terms_data(local_turl->profile());
1362 if (UpdateNoNotify(local_turl, *sync_turl, search_terms_data)) 1095 if (UpdateNoNotify(local_turl, sync_turl->data(), search_terms_data))
1363 NotifyObservers(); 1096 NotifyObservers();
1364 merge_result.set_num_items_modified( 1097 merge_result.set_num_items_modified(
1365 merge_result.num_items_modified() + 1); 1098 merge_result.num_items_modified() + 1);
1366 } else if (sync_turl->last_modified() < local_turl->last_modified()) { 1099 } else if (sync_turl->last_modified() < local_turl->last_modified()) {
1367 // Otherwise, we know we have newer data, so update Sync with our 1100 // Otherwise, we know we have newer data, so update Sync with our
1368 // data fields. 1101 // data fields.
1369 new_changes.push_back( 1102 new_changes.push_back(
1370 syncer::SyncChange(FROM_HERE, 1103 syncer::SyncChange(FROM_HERE,
1371 syncer::SyncChange::ACTION_UPDATE, 1104 syncer::SyncChange::ACTION_UPDATE,
1372 local_data_map[local_turl->sync_guid()])); 1105 local_data_map[local_turl->sync_guid()]));
1373 } 1106 }
1374 local_data_map.erase(iter->first); 1107 local_data_map.erase(iter->first);
1375 } else { 1108 } else {
1376 // The search engine from the cloud has not been synced locally. Merge it 1109 // The search engine from the cloud has not been synced locally. Merge it
1377 // into our local model. This will handle any conflicts with local (and 1110 // into our local model. This will handle any conflicts with local (and
1378 // already-synced) TemplateURLs. It will prefer to keep entries from Sync 1111 // already-synced) TemplateURLs. It will prefer to keep entries from Sync
1379 // over not-yet-synced TemplateURLs. 1112 // over not-yet-synced TemplateURLs.
1380 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes, 1113 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes,
1381 &local_data_map, &merge_result); 1114 &local_data_map, &merge_result);
1382 } 1115 }
1383 } 1116 }
1384 1117
1385 // If there is a pending synced default search provider that was processed
1386 // above, set it now.
1387 TemplateURL* pending_default = GetPendingSyncedDefaultSearchProvider();
1388 if (pending_default) {
1389 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
1390 &dsp_change_origin_, DSP_CHANGE_SYNC_ADD);
1391 SetUserSelectedDefaultSearchProvider(pending_default);
Nicolas Zea 2014/05/07 20:30:07 So I understand, are we removing this because it's
erikwright (departed) 2014/05/07 22:26:47 In ProcessSyncChanges and MergeInSyncTemplateURL w
1392 }
1393
1394 // The remaining SyncData in local_data_map should be everything that needs to 1118 // The remaining SyncData in local_data_map should be everything that needs to
1395 // be pushed as ADDs to sync. 1119 // be pushed as ADDs to sync.
1396 for (SyncDataMap::const_iterator iter = local_data_map.begin(); 1120 for (SyncDataMap::const_iterator iter = local_data_map.begin();
1397 iter != local_data_map.end(); ++iter) { 1121 iter != local_data_map.end(); ++iter) {
1398 new_changes.push_back( 1122 new_changes.push_back(
1399 syncer::SyncChange(FROM_HERE, 1123 syncer::SyncChange(FROM_HERE,
1400 syncer::SyncChange::ACTION_ADD, 1124 syncer::SyncChange::ACTION_ADD,
1401 iter->second)); 1125 iter->second));
1402 } 1126 }
1403 1127
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1617 HistoryServiceFactory::GetForProfile(profile_, 1341 HistoryServiceFactory::GetForProfile(profile_,
1618 Profile::EXPLICIT_ACCESS) : 1342 Profile::EXPLICIT_ACCESS) :
1619 NULL; 1343 NULL;
1620 if (!history) 1344 if (!history)
1621 return; 1345 return;
1622 history->SetKeywordSearchTermsForURL(url, t_url->id(), term); 1346 history->SetKeywordSearchTermsForURL(url, t_url->id(), term);
1623 } 1347 }
1624 1348
1625 void TemplateURLService::Init(const Initializer* initializers, 1349 void TemplateURLService::Init(const Initializer* initializers,
1626 int num_initializers) { 1350 int num_initializers) {
1351 if (GetPrefs()) {
1352 pref_change_registrar_.Init(GetPrefs());
1353 pref_change_registrar_.Add(
1354 prefs::kSyncedDefaultSearchProviderGUID,
1355 base::Bind(&TemplateURLService::OnDSEGUIDPrefChanged,
1356 base::Unretained(this)));
1357 }
1358
1627 // Register for notifications. 1359 // Register for notifications.
1628 if (profile_) { 1360 if (profile_) {
1629 // TODO(sky): bug 1166191. The keywords should be moved into the history 1361 // TODO(sky): bug 1166191. The keywords should be moved into the history
1630 // db, which will mean we no longer need this notification and the history 1362 // db, which will mean we no longer need this notification and the history
1631 // backend can handle automatically adding the search terms as the user 1363 // backend can handle automatically adding the search terms as the user
1632 // navigates. 1364 // navigates.
1633 content::Source<Profile> profile_source(profile_->GetOriginalProfile()); 1365 content::Source<Profile> profile_source(profile_->GetOriginalProfile());
1634 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, 1366 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED,
1635 profile_source); 1367 profile_source);
1636 notification_registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED, 1368 notification_registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED,
1637 profile_source); 1369 profile_source);
1638 pref_change_registrar_.Init(GetPrefs());
1639 pref_change_registrar_.Add(
1640 prefs::kSyncedDefaultSearchProviderGUID,
1641 base::Bind(
1642 &TemplateURLService::OnSyncedDefaultSearchProviderGUIDChanged,
1643 base::Unretained(this)));
1644 } 1370 }
1645 notification_registrar_.Add( 1371
1646 this, chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED, 1372 DefaultSearchManager::Source source = DefaultSearchManager::FROM_USER;
1647 content::NotificationService::AllSources()); 1373 TemplateURLData* dse =
1374 default_search_manager_.GetDefaultSearchEngine(&source);
1375 ApplyDefaultSearchChange(dse, source);
1648 1376
1649 if (num_initializers > 0) { 1377 if (num_initializers > 0) {
1650 // This path is only hit by test code and is used to simulate a loaded 1378 // This path is only hit by test code and is used to simulate a loaded
1651 // TemplateURLService. 1379 // TemplateURLService.
1652 ChangeToLoadedState(); 1380 ChangeToLoadedState();
1653 1381
1654 // Add specific initializers, if any. 1382 // Add specific initializers, if any.
1655 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 1383 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1656 for (int i(0); i < num_initializers; ++i) { 1384 for (int i(0); i < num_initializers; ++i) {
1657 DCHECK(initializers[i].keyword); 1385 DCHECK(initializers[i].keyword);
1658 DCHECK(initializers[i].url); 1386 DCHECK(initializers[i].url);
1659 DCHECK(initializers[i].content); 1387 DCHECK(initializers[i].content);
1660 1388
1661 // TemplateURLService ends up owning the TemplateURL, don't try and free 1389 // TemplateURLService ends up owning the TemplateURL, don't try and free
1662 // it. 1390 // it.
1663 TemplateURLData data; 1391 TemplateURLData data;
1664 data.short_name = base::UTF8ToUTF16(initializers[i].content); 1392 data.short_name = base::UTF8ToUTF16(initializers[i].content);
1665 data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword)); 1393 data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword));
1666 data.SetURL(initializers[i].url); 1394 data.SetURL(initializers[i].url);
1667 TemplateURL* template_url = new TemplateURL(profile_, data); 1395 TemplateURL* template_url = new TemplateURL(profile_, data);
1668 AddNoNotify(template_url, true); 1396 AddNoNotify(template_url, true);
1669 1397
1670 // Set the first provided identifier to be the default. 1398 // Set the first provided identifier to be the default.
1671 if (i == 0) 1399 if (i == 0)
1672 SetDefaultSearchProviderNoNotify(template_url); 1400 default_search_manager_.SetUserSelectedDefaultSearchEngine(data);
1673 } 1401 }
1674 } 1402 }
1675 1403
1676 // Initialize default search.
1677 UpdateDefaultSearch();
1678
1679 // Request a server check for the correct Google URL if Google is the 1404 // Request a server check for the correct Google URL if Google is the
1680 // default search engine and not in headless mode. 1405 // default search engine and not in headless mode.
1681 if (profile_ && initial_default_search_provider_.get() && 1406 TemplateURL* default_search_provider = GetDefaultSearchProvider();
1682 initial_default_search_provider_->url_ref().HasGoogleBaseURLs()) { 1407 if (profile_ && default_search_provider &&
1408 default_search_provider->url_ref().HasGoogleBaseURLs()) {
1683 scoped_ptr<base::Environment> env(base::Environment::Create()); 1409 scoped_ptr<base::Environment> env(base::Environment::Create());
1684 if (!env->HasVar(env_vars::kHeadless)) 1410 if (!env->HasVar(env_vars::kHeadless))
1685 GoogleURLTracker::RequestServerCheck(profile_, false); 1411 GoogleURLTracker::RequestServerCheck(profile_, false);
1686 } 1412 }
1687 } 1413 }
1688 1414
1689 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) { 1415 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) {
1690 const base::string16& keyword = template_url->keyword(); 1416 const base::string16& keyword = template_url->keyword();
1691 DCHECK_NE(0U, keyword_to_template_map_.count(keyword)); 1417 DCHECK_NE(0U, keyword_to_template_map_.count(keyword));
1692 if (keyword_to_template_map_[keyword] == template_url) { 1418 if (keyword_to_template_map_[keyword] == template_url) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1785 // (possibly deleted) entry. 1511 // (possibly deleted) entry.
1786 urls->clear(); 1512 urls->clear();
1787 } 1513 }
1788 1514
1789 void TemplateURLService::ChangeToLoadedState() { 1515 void TemplateURLService::ChangeToLoadedState() {
1790 DCHECK(!loaded_); 1516 DCHECK(!loaded_);
1791 1517
1792 UIThreadSearchTermsData search_terms_data(profile_); 1518 UIThreadSearchTermsData search_terms_data(profile_);
1793 provider_map_->Init(template_urls_, search_terms_data); 1519 provider_map_->Init(template_urls_, search_terms_data);
1794 loaded_ = true; 1520 loaded_ = true;
1521
1522 // This will cause a call to NotifyObservers().
1523 ApplyDefaultSearchChange(initial_default_search_provider_
1524 ? &initial_default_search_provider_->data()
1525 : NULL,
1526 default_search_provider_source_);
1527 initial_default_search_provider_.reset();
1528 on_loaded_callbacks_.Notify();
1795 } 1529 }
1796 1530
1797 void TemplateURLService::ClearDefaultProviderFromPrefs() { 1531 void TemplateURLService::OnFailedLoad() {
1798 // We overwrite user preferences. If the default search engine is managed, 1532 load_failed_ = true;
1799 // there is no effect. 1533 service_ = NULL;
1800 SaveDefaultSearchProviderToPrefs(NULL, GetPrefs()); 1534 // Have to call this before GetDefaultSearchProvider(), or that function will
1801 // Default value for kDefaultSearchProviderEnabled is true. 1535 // just return |initial_default_search_provider_|.
1802 PrefService* prefs = GetPrefs(); 1536 ChangeToLoadedState();
1803 if (prefs)
1804 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, true);
1805 } 1537 }
1806 1538
1807 bool TemplateURLService::CanReplaceKeywordForHost( 1539 bool TemplateURLService::CanReplaceKeywordForHost(
1808 const std::string& host, 1540 const std::string& host,
1809 TemplateURL** to_replace) { 1541 TemplateURL** to_replace) {
1810 DCHECK(!to_replace || !*to_replace); 1542 DCHECK(!to_replace || !*to_replace);
1811 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host); 1543 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host);
1812 if (!urls) 1544 if (!urls)
1813 return true; 1545 return true;
1814 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) { 1546 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) {
(...skipping 22 matching lines...) Expand all
1837 i != template_urls_.end(); ++i) { 1569 i != template_urls_.end(); ++i) {
1838 if (((*i)->GetType() == TemplateURL::NORMAL) && 1570 if (((*i)->GetType() == TemplateURL::NORMAL) &&
1839 ((*i)->keyword() == keyword)) 1571 ((*i)->keyword() == keyword))
1840 return *i; 1572 return *i;
1841 } 1573 }
1842 return NULL; 1574 return NULL;
1843 } 1575 }
1844 1576
1845 bool TemplateURLService::UpdateNoNotify( 1577 bool TemplateURLService::UpdateNoNotify(
1846 TemplateURL* existing_turl, 1578 TemplateURL* existing_turl,
1847 const TemplateURL& new_values, 1579 const TemplateURLData& new_values,
1848 const SearchTermsData& old_search_terms_data) { 1580 const SearchTermsData& old_search_terms_data) {
1849 DCHECK(loaded_); 1581 DCHECK(loaded_);
1850 DCHECK(existing_turl); 1582 DCHECK(existing_turl);
1851 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == 1583 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) ==
1852 template_urls_.end()) 1584 template_urls_.end())
1853 return false; 1585 return false;
1854 1586
1855 base::string16 old_keyword(existing_turl->keyword()); 1587 base::string16 old_keyword(existing_turl->keyword());
1856 keyword_to_template_map_.erase(old_keyword); 1588 keyword_to_template_map_.erase(old_keyword);
1857 if (!existing_turl->sync_guid().empty()) 1589 if (!existing_turl->sync_guid().empty())
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 } 1623 }
1892 } 1624 }
1893 } 1625 }
1894 if (!existing_turl->sync_guid().empty()) 1626 if (!existing_turl->sync_guid().empty())
1895 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl; 1627 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl;
1896 1628
1897 if (service_) 1629 if (service_)
1898 service_->UpdateKeyword(existing_turl->data()); 1630 service_->UpdateKeyword(existing_turl->data());
1899 1631
1900 // Inform sync of the update. 1632 // Inform sync of the update.
1901 ProcessTemplateURLChange(FROM_HERE, 1633 ProcessTemplateURLChange(
1902 existing_turl, 1634 FROM_HERE, existing_turl, syncer::SyncChange::ACTION_UPDATE);
1903 syncer::SyncChange::ACTION_UPDATE);
1904 1635
1905 if (default_search_provider_ == existing_turl) { 1636 if (default_search_provider_ == existing_turl &&
1906 bool success = SetDefaultSearchProviderNoNotify(existing_turl); 1637 default_search_provider_source_ ==
1907 DCHECK(success); 1638 DefaultSearchManager::FROM_USER) {
1639 default_search_manager_.SetUserSelectedDefaultSearchEngine(
1640 default_search_provider_->data());
1908 } 1641 }
1909 return true; 1642 return true;
1910 } 1643 }
1911 1644
1912 // static 1645 // static
1913 void TemplateURLService::UpdateTemplateURLIfPrepopulated( 1646 void TemplateURLService::UpdateTemplateURLIfPrepopulated(
1914 TemplateURL* template_url, 1647 TemplateURL* template_url,
1915 Profile* profile) { 1648 Profile* profile) {
1916 int prepopulate_id = template_url->prepopulate_id(); 1649 int prepopulate_id = template_url->prepopulate_id();
1917 if (template_url->prepopulate_id() == 0) 1650 if (template_url->prepopulate_id() == 0)
1918 return; 1651 return;
1919 1652
1920 size_t default_search_index; 1653 size_t default_search_index;
1921 ScopedVector<TemplateURLData> prepopulated_urls = 1654 ScopedVector<TemplateURLData> prepopulated_urls =
1922 TemplateURLPrepopulateData::GetPrepopulatedEngines( 1655 TemplateURLPrepopulateData::GetPrepopulatedEngines(
1923 profile ? profile->GetPrefs() : NULL, &default_search_index); 1656 profile ? profile->GetPrefs() : NULL, &default_search_index);
1924 1657
1925 for (size_t i = 0; i < prepopulated_urls.size(); ++i) { 1658 for (size_t i = 0; i < prepopulated_urls.size(); ++i) {
1926 if (prepopulated_urls[i]->prepopulate_id == prepopulate_id) { 1659 if (prepopulated_urls[i]->prepopulate_id == prepopulate_id) {
1927 MergeIntoPrepopulatedEngineData(template_url, prepopulated_urls[i]); 1660 MergeIntoPrepopulatedEngineData(template_url, prepopulated_urls[i]);
1928 template_url->CopyFrom(TemplateURL(profile, *prepopulated_urls[i])); 1661 template_url->CopyFrom(*prepopulated_urls[i]);
1929 } 1662 }
1930 } 1663 }
1931 } 1664 }
1932 1665
1933 PrefService* TemplateURLService::GetPrefs() { 1666 PrefService* TemplateURLService::GetPrefs() {
1934 return profile_ ? profile_->GetPrefs() : NULL; 1667 return profile_ ? profile_->GetPrefs() : NULL;
1935 } 1668 }
1936 1669
1937 void TemplateURLService::UpdateKeywordSearchTermsForURL( 1670 void TemplateURLService::UpdateKeywordSearchTermsForURL(
1938 const history::URLVisitedDetails& details) { 1671 const history::URLVisitedDetails& details) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 // |provider_map_| will not be updated correctly. 1746 // |provider_map_| will not be updated correctly.
2014 if (CanReplace(existing_entry->second)) 1747 if (CanReplace(existing_entry->second))
2015 RemoveNoNotify(existing_entry->second); 1748 RemoveNoNotify(existing_entry->second);
2016 else 1749 else
2017 updated_turl.data_.SetKeyword(t_url->keyword()); 1750 updated_turl.data_.SetKeyword(t_url->keyword());
2018 } 1751 }
2019 something_changed = true; 1752 something_changed = true;
2020 // This will send the keyword change to sync. Note that other clients 1753 // This will send the keyword change to sync. Note that other clients
2021 // need to reset the keyword to an appropriate local value when this 1754 // need to reset the keyword to an appropriate local value when this
2022 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData(). 1755 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData().
2023 UpdateNoNotify(t_url, updated_turl, 1756 UpdateNoNotify(t_url, updated_turl.data(),
2024 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec())); 1757 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec()));
2025 } 1758 }
2026 } 1759 }
2027 if (something_changed) 1760 if (something_changed)
2028 NotifyObservers(); 1761 NotifyObservers();
2029 } 1762 }
2030 1763
2031 void TemplateURLService::UpdateDefaultSearch() { 1764 void TemplateURLService::OnDSEGUIDPrefChanged() {
1765 std::string new_guid =
1766 GetPrefs()->GetString(prefs::kSyncedDefaultSearchProviderGUID);
1767 if (new_guid.empty()) {
1768 default_search_manager_.ClearUserSelectedDefaultSearchEngine();
1769 return;
1770 }
1771
1772 TemplateURL* turl = GetTemplateURLForGUID(new_guid);
1773 if (turl)
1774 default_search_manager_.SetUserSelectedDefaultSearchEngine(turl->data());
1775 }
1776
1777 void TemplateURLService::OnDefaultSearchChange(
1778 const TemplateURLData* data,
1779 DefaultSearchManager::Source source) {
1780 if ((source == DefaultSearchManager::FROM_USER) &&
1781 ((source != default_search_provider_source_) ||
1782 !IdenticalSyncGUIDs(data, GetDefaultSearchProvider()))) {
1783 GetPrefs()->SetString(prefs::kSyncedDefaultSearchProviderGUID,
1784 data->sync_guid);
1785 }
1786 ApplyDefaultSearchChange(data, source);
1787 }
1788
1789 void TemplateURLService::ApplyDefaultSearchChange(
1790 const TemplateURLData* data,
1791 DefaultSearchManager::Source source) {
2032 if (!loaded_) { 1792 if (!loaded_) {
2033 // Set |initial_default_search_provider_| from the preferences. We use this 1793 // Set |initial_default_search_provider_| from the preferences. This is
2034 // value for default search provider until the database has been loaded. 1794 // mainly so we can hold ownership until we get to the point where the list
2035 scoped_ptr<TemplateURLData> data; 1795 // of keywords from Web Data is the owner of everything including the
2036 if (!LoadDefaultSearchProviderFromPrefs( 1796 // default.
2037 GetPrefs(), &data, &is_default_search_managed_)) { 1797 initial_default_search_provider_.reset(
2038 // Prefs does not specify, so rely on the prepopulated engines. This 1798 data ? new TemplateURL(profile_, *data) : NULL);
2039 // should happen only the first time Chrome is started. 1799 default_search_provider_source_ = source;
2040 data = 1800 return;
2041 TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs()); 1801 }
2042 is_default_search_managed_ = false; 1802
1803 // Prevent recursion if we update the value stored in default_search_manager_.
1804 // Note that we exclude if data == NULL because that could cause a false
1805 // positive for recursion when the initial_default_search_provider_ is NULL
1806 // due to policy. No recursion case could lead to recursion with NULL.
1807 if (source == default_search_provider_source_ && data != NULL &&
1808 TemplateURLMatchesData(default_search_provider_, data))
1809 return;
1810
1811 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1812 if (default_search_provider_source_ == DefaultSearchManager::FROM_POLICY ||
1813 source == DefaultSearchManager::FROM_POLICY) {
1814 // We do this both to clear up removed policy-defined DSE as well as to add
1815 // the new one, if appropriate.
1816 UpdateProvidersCreatedByPolicy(
1817 &template_urls_,
1818 source == DefaultSearchManager::FROM_POLICY ? data : NULL);
1819 }
1820
1821 if (!data) {
1822 default_search_provider_ = NULL;
1823 default_search_provider_source_ = source;
1824 NotifyObservers();
1825 return;
1826 }
1827
1828 if (source == DefaultSearchManager::FROM_EXTENSION) {
1829 default_search_provider_ = FindMatchingExtensionTemplateURL(
1830 *data, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);
1831 }
1832
1833 if (source == DefaultSearchManager::FROM_FALLBACK) {
1834 default_search_provider_ =
1835 FindPrepopulatedTemplateURL(data->prepopulate_id);
1836 if (default_search_provider_) {
1837 TemplateURLData update_data(*data);
1838 update_data.sync_guid = default_search_provider_->sync_guid();
1839 if (!default_search_provider_->safe_for_autoreplace()) {
1840 update_data.safe_for_autoreplace = false;
1841 update_data.SetKeyword(default_search_provider_->keyword());
1842 update_data.short_name = default_search_provider_->short_name();
1843 }
1844 UIThreadSearchTermsData search_terms_data(
1845 default_search_provider_->profile());
1846 UpdateNoNotify(default_search_provider_, update_data, search_terms_data);
1847 } else {
1848 // Normally the prepopulated fallback should be present in
1849 // |template_urls_|, but in a few cases it might not be:
1850 // (1) Tests that initialize the TemplateURLService in peculiar ways.
1851 // (2) If the user deleted the pre-populated default and we subsequently
1852 // lost their user-selected value.
1853 TemplateURL* new_dse = new TemplateURL(profile_, *data);
1854 if (AddNoNotify(new_dse, true))
1855 default_search_provider_ = new_dse;
1856 else
1857 delete new_dse;
1858 }
1859 }
1860 if (source == DefaultSearchManager::FROM_USER) {
1861 default_search_provider_ = GetTemplateURLForGUID(data->sync_guid);
1862 if (!default_search_provider_ && data->prepopulate_id) {
1863 default_search_provider_ =
1864 FindPrepopulatedTemplateURL(data->prepopulate_id);
1865 }
1866 if (default_search_provider_) {
1867 TemplateURLData new_data(*data);
1868 new_data.show_in_default_list = true;
1869 UIThreadSearchTermsData search_terms_data(
1870 default_search_provider_->profile());
1871 UpdateNoNotify(default_search_provider_, new_data, search_terms_data);
1872 } else {
1873 TemplateURL* new_dse = new TemplateURL(profile_, *data);
1874 new_dse->data_.show_in_default_list = true;
1875 new_dse->data_.id = kInvalidTemplateURLID;
1876 if (!AddNoNotify(new_dse, true))
1877 delete new_dse;
1878 else
1879 default_search_provider_ = new_dse;
1880 }
1881 if (default_search_provider_ && GetPrefs()) {
1882 GetPrefs()->SetString(
1883 prefs::kSyncedDefaultSearchProviderGUID,
1884 default_search_provider_->sync_guid());
2043 } 1885 }
2044 1886
2045 initial_default_search_provider_.reset( 1887 }
2046 data ? new TemplateURL(profile_, *data) : NULL);
2047 1888
2048 return; 1889 default_search_provider_source_ = source;
1890
1891 if (default_search_provider_ &&
1892 default_search_provider_->url_ref().HasGoogleBaseURLs()) {
1893 if (profile_)
1894 GoogleURLTracker::RequestServerCheck(profile_, false);
1895 #if defined(ENABLE_RLZ)
1896 // TODO(erikwright): should this only be if user-selected?
1897 RLZTracker::RecordProductEvent(rlz_lib::CHROME,
1898 RLZTracker::CHROME_OMNIBOX,
1899 rlz_lib::SET_TO_GOOGLE);
1900 #endif
2049 } 1901 }
2050 // Load the default search specified in prefs.
2051 scoped_ptr<TemplateURLData> new_default_from_prefs;
2052 bool new_is_default_managed = false;
2053 // Load the default from prefs. It's possible that it won't succeed
2054 // because we are in the middle of doing SaveDefaultSearchProviderToPrefs()
2055 // and all the preference items have not been saved. In that case, we
2056 // don't have yet a default. It would be much better if we could save
2057 // preferences in batches and trigger notifications at the end.
2058 LoadDefaultSearchProviderFromPrefs(
2059 GetPrefs(), &new_default_from_prefs, &new_is_default_managed);
2060 if (!is_default_search_managed_ && !new_is_default_managed) {
2061 // We're not interested in cases where the default was and remains
2062 // unmanaged. In that case, preferences have no impact on the default.
2063 return;
2064 }
2065 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
2066 if (is_default_search_managed_ && new_is_default_managed) {
2067 // The default was managed and remains managed. Update the default only
2068 // if it has changed; we don't want to respond to changes triggered by
2069 // SaveDefaultSearchProviderToPrefs.
2070 if (TemplateURLMatchesData(default_search_provider_,
2071 new_default_from_prefs.get()))
2072 return;
2073 if (!new_default_from_prefs) {
2074 // default_search_provider_ can't be NULL otherwise
2075 // TemplateURLMatchesData would have returned true. Remove this now
2076 // invalid value.
2077 TemplateURL* old_default = default_search_provider_;
2078 bool success = SetDefaultSearchProviderNoNotify(NULL);
2079 DCHECK(success);
2080 RemoveNoNotify(old_default);
2081 } else if (default_search_provider_) {
2082 new_default_from_prefs->created_by_policy = true;
2083 TemplateURL new_values(profile_, *new_default_from_prefs);
2084 UIThreadSearchTermsData search_terms_data(
2085 default_search_provider_->profile());
2086 UpdateNoNotify(default_search_provider_, new_values, search_terms_data);
2087 } else {
2088 TemplateURL* new_template = NULL;
2089 if (new_default_from_prefs) {
2090 new_default_from_prefs->created_by_policy = true;
2091 new_template = new TemplateURL(profile_, *new_default_from_prefs);
2092 if (!AddNoNotify(new_template, true))
2093 return;
2094 }
2095 bool success = SetDefaultSearchProviderNoNotify(new_template);
2096 DCHECK(success);
2097 }
2098 } else if (!is_default_search_managed_ && new_is_default_managed) {
2099 // The default used to be unmanaged and is now managed. Add the new
2100 // managed default to the list of URLs and set it as default.
2101 is_default_search_managed_ = new_is_default_managed;
2102 TemplateURL* new_template = NULL;
2103 if (new_default_from_prefs) {
2104 new_default_from_prefs->created_by_policy = true;
2105 new_template = new TemplateURL(profile_, *new_default_from_prefs);
2106 if (!AddNoNotify(new_template, true))
2107 return;
2108 }
2109 bool success = SetDefaultSearchProviderNoNotify(new_template);
2110 DCHECK(success);
2111 } else {
2112 // The default was managed and is no longer.
2113 DCHECK(is_default_search_managed_ && !new_is_default_managed);
2114 is_default_search_managed_ = new_is_default_managed;
2115 // If we had a default, delete the previous default if created by policy
2116 // and set a likely default.
2117 if ((default_search_provider_ != NULL) &&
2118 default_search_provider_->created_by_policy()) {
2119 TemplateURL* old_default = default_search_provider_;
2120 default_search_provider_ = NULL;
2121 RemoveNoNotify(old_default);
2122 }
2123 1902
2124 // The likely default should be from Sync if we were waiting on Sync.
2125 // Otherwise, it should be FindNewDefaultSearchProvider.
2126 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider();
2127 if (synced_default) {
2128 pending_synced_default_search_ = false;
2129
2130 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2131 &dsp_change_origin_, DSP_CHANGE_SYNC_NOT_MANAGED);
2132 SetDefaultSearchProviderNoNotify(synced_default);
2133 } else {
2134 SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider());
2135 }
2136 }
2137 NotifyObservers(); 1903 NotifyObservers();
2138 } 1904 }
2139 1905
2140 void TemplateURLService::SetDefaultSearchProvider(
2141 TemplateURL* url) {
2142 DCHECK(!is_default_search_managed_);
2143 // Omnibox keywords cannot be made default. Extension-controlled search
2144 // engines can be made default only by the extension itself because they
2145 // aren't persisted.
2146 DCHECK(!url || (url->GetType() == TemplateURL::NORMAL));
2147
2148 // Always persist the setting in the database, that way if the backup
2149 // signature has changed out from under us it gets reset correctly.
2150 if (SetDefaultSearchProviderNoNotify(url))
2151 NotifyObservers();
2152 }
2153
2154 bool TemplateURLService::SetDefaultSearchProviderNoNotify(TemplateURL* url) {
2155 if (url) {
2156 if (std::find(template_urls_.begin(), template_urls_.end(), url) ==
2157 template_urls_.end())
2158 return false;
2159 // Omnibox keywords cannot be made default.
2160 DCHECK_NE(TemplateURL::OMNIBOX_API_EXTENSION, url->GetType());
2161 }
2162
2163 // Only bother reassigning |url| if it has changed. Notice that we don't just
2164 // early exit if they are equal, because |url| may have had its fields
2165 // changed, and needs to be persisted below (for example, when this is called
2166 // from UpdateNoNotify).
2167 if (default_search_provider_ != url) {
2168 // Engines set by policy override extension-controlled engines, which
2169 // override other engines.
2170 DCHECK(!is_default_search_managed() || !url ||
2171 (url->GetType() == TemplateURL::NORMAL));
2172 if (is_default_search_managed() || !default_search_provider_ ||
2173 (default_search_provider_->GetType() == TemplateURL::NORMAL) ||
2174 (url &&
2175 (url->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION))){
2176 UMA_HISTOGRAM_ENUMERATION("Search.DefaultSearchChangeOrigin",
gab 2014/05/07 20:25:09 You'll need to mark this histogram as obsolete in
2177 dsp_change_origin_, DSP_CHANGE_MAX);
2178 default_search_provider_ = url;
2179 }
2180 }
2181
2182 if (url) {
2183 // Don't mark the url as edited, otherwise we won't be able to rev the
2184 // template urls we ship with.
2185 url->data_.show_in_default_list = true;
2186 if (service_ && (url->GetType() == TemplateURL::NORMAL))
2187 service_->UpdateKeyword(url->data());
2188
2189 if (url->url_ref().HasGoogleBaseURLs()) {
2190 GoogleURLTracker::RequestServerCheck(profile_, false);
2191 #if defined(ENABLE_RLZ)
2192 RLZTracker::RecordProductEvent(rlz_lib::CHROME,
2193 RLZTracker::CHROME_OMNIBOX,
2194 rlz_lib::SET_TO_GOOGLE);
2195 #endif
2196 }
2197 }
2198
2199 // Extension-controlled search engines shouldn't be persisted anywhere.
2200 if (url && (url->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION))
2201 return true;
2202
2203 if (!is_default_search_managed_) {
2204 SaveDefaultSearchProviderToPrefs(url, GetPrefs());
2205
2206 // If we are syncing, we want to set the synced pref that will notify other
2207 // instances to change their default to this new search provider.
2208 // Note: we don't update the pref if we're currently in the middle of
2209 // handling a sync operation. Sync operations from other clients are not
2210 // guaranteed to arrive together, and any client that deletes the default
2211 // needs to set a new default as well. If we update the default here, we're
2212 // likely to race with the update from the other client, resulting in
2213 // a possibly random default search provider.
2214 if (sync_processor_.get() && url && !url->sync_guid().empty() &&
2215 GetPrefs() && !processing_syncer_changes_) {
2216 GetPrefs()->SetString(prefs::kSyncedDefaultSearchProviderGUID,
2217 url->sync_guid());
2218 }
2219 }
2220
2221 if (service_)
2222 service_->SetDefaultSearchProviderID(url ? url->id() : 0);
2223
2224 // Inform sync the change to the show_in_default_list flag.
2225 if (url)
2226 ProcessTemplateURLChange(FROM_HERE,
2227 url,
2228 syncer::SyncChange::ACTION_UPDATE);
2229 return true;
2230 }
2231
2232 bool TemplateURLService::AddNoNotify(TemplateURL* template_url, 1906 bool TemplateURLService::AddNoNotify(TemplateURL* template_url,
2233 bool newly_adding) { 1907 bool newly_adding) {
2234 DCHECK(template_url); 1908 DCHECK(template_url);
2235 1909
2236 if (newly_adding) { 1910 if (newly_adding) {
2237 DCHECK_EQ(kInvalidTemplateURLID, template_url->id()); 1911 DCHECK_EQ(kInvalidTemplateURLID, template_url->id());
2238 DCHECK(std::find(template_urls_.begin(), template_urls_.end(), 1912 DCHECK(std::find(template_urls_.begin(), template_urls_.end(),
2239 template_url) == template_urls_.end()); 1913 template_url) == template_urls_.end());
2240 template_url->data_.id = ++next_id_; 1914 template_url->data_.id = ++next_id_;
2241 } 1915 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2324 1998
2325 void TemplateURLService::NotifyObservers() { 1999 void TemplateURLService::NotifyObservers() {
2326 if (!loaded_) 2000 if (!loaded_)
2327 return; 2001 return;
2328 2002
2329 FOR_EACH_OBSERVER(TemplateURLServiceObserver, model_observers_, 2003 FOR_EACH_OBSERVER(TemplateURLServiceObserver, model_observers_,
2330 OnTemplateURLServiceChanged()); 2004 OnTemplateURLServiceChanged());
2331 } 2005 }
2332 2006
2333 // |template_urls| are the TemplateURLs loaded from the database. 2007 // |template_urls| are the TemplateURLs loaded from the database.
2334 // |default_search_provider| points to one of them, if it was set in the db. 2008 // |default_from_prefs| is the default search provider from the preferences, or
2335 // |default_from_prefs| is the default search provider from the preferences. 2009 // NULL if the DSE is not policy-defined.
2336 // Check |is_default_search_managed_| to determine if it was set by policy.
2337 // 2010 //
2338 // This function removes from the vector and the database all the TemplateURLs 2011 // This function removes from the vector and the database all the TemplateURLs
2339 // that were set by policy, unless it is the current default search provider 2012 // that were set by policy, unless it is the current default search provider, in
2340 // and matches what is set by a managed preference. 2013 // which case it is updated with the data from prefs.
2341 void TemplateURLService::RemoveProvidersCreatedByPolicy( 2014 void TemplateURLService::UpdateProvidersCreatedByPolicy(
2342 TemplateURLVector* template_urls, 2015 TemplateURLVector* template_urls,
2343 TemplateURL** default_search_provider, 2016 const TemplateURLData* default_from_prefs) {
2344 TemplateURLData* default_from_prefs) {
2345 DCHECK(template_urls); 2017 DCHECK(template_urls);
2346 DCHECK(default_search_provider); 2018
2347 for (TemplateURLVector::iterator i = template_urls->begin(); 2019 for (TemplateURLVector::iterator i = template_urls->begin();
2348 i != template_urls->end(); ) { 2020 i != template_urls->end(); ) {
2349 TemplateURL* template_url = *i; 2021 TemplateURL* template_url = *i;
2350 if (template_url->created_by_policy()) { 2022 if (template_url->created_by_policy()) {
2351 if (template_url == *default_search_provider && 2023 if (default_from_prefs &&
2352 is_default_search_managed_ &&
2353 TemplateURLMatchesData(template_url, default_from_prefs)) { 2024 TemplateURLMatchesData(template_url, default_from_prefs)) {
2354 // If the database specified a default search provider that was set 2025 // If the database specified a default search provider that was set
2355 // by policy, and the default search provider from the preferences 2026 // by policy, and the default search provider from the preferences
2356 // is also set by policy and they are the same, keep the entry in the 2027 // is also set by policy and they are the same, keep the entry in the
2357 // database and the |default_search_provider|. 2028 // database and the |default_search_provider|.
2029 default_search_provider_ = template_url;
2030 // Prevent us from saving any other entries, or creating a new one.
2031 default_from_prefs = NULL;
2358 ++i; 2032 ++i;
2359 continue; 2033 continue;
2360 } 2034 }
2361 2035
2362 // The database loaded a managed |default_search_provider|, but it has 2036 RemoveFromMaps(template_url);
2363 // been updated in the prefs. Remove it from the database, and update the
2364 // |default_search_provider| pointer here.
2365 if (*default_search_provider &&
2366 (*default_search_provider)->id() == template_url->id())
2367 *default_search_provider = NULL;
2368
2369 i = template_urls->erase(i); 2037 i = template_urls->erase(i);
2370 if (service_) 2038 if (service_)
2371 service_->RemoveKeyword(template_url->id()); 2039 service_->RemoveKeyword(template_url->id());
2372 delete template_url; 2040 delete template_url;
2373 } else { 2041 } else {
2374 ++i; 2042 ++i;
2375 } 2043 }
2376 } 2044 }
2045
2046 if (default_from_prefs) {
2047 default_search_provider_ = NULL;
2048 default_search_provider_source_ = DefaultSearchManager::FROM_POLICY;
2049 TemplateURLData new_data(*default_from_prefs);
2050 new_data.created_by_policy = true;
2051 TemplateURL* new_dse = new TemplateURL(profile_, new_data);
2052 if (!AddNoNotify(new_dse, true))
2053 delete new_dse;
2054 else
2055 default_search_provider_ = new_dse;
2056 }
2377 } 2057 }
2378 2058
2379 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url, 2059 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url,
2380 const std::string& guid) { 2060 const std::string& guid) {
2381 DCHECK(loaded_); 2061 DCHECK(loaded_);
2382 DCHECK(!guid.empty()); 2062 DCHECK(!guid.empty());
2383 2063
2384 TemplateURLData data(url->data()); 2064 TemplateURLData data(url->data());
2385 data.sync_guid = guid; 2065 data.sync_guid = guid;
2386 TemplateURL new_url(url->profile(), data);
2387 UIThreadSearchTermsData search_terms_data(url->profile()); 2066 UIThreadSearchTermsData search_terms_data(url->profile());
2388 UpdateNoNotify(url, new_url, search_terms_data); 2067 UpdateNoNotify(url, data, search_terms_data);
2389 } 2068 }
2390 2069
2391 base::string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl, 2070 base::string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl,
2392 bool force) { 2071 bool force) {
2393 if (!force) { 2072 if (!force) {
2394 // Already unique. 2073 // Already unique.
2395 if (!GetTemplateURLForKeyword(turl.keyword())) 2074 if (!GetTemplateURLForKeyword(turl.keyword()))
2396 return turl.keyword(); 2075 return turl.keyword();
2397 2076
2398 // First, try to return the generated keyword for the TemplateURL (except 2077 // First, try to return the generated keyword for the TemplateURL (except
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2449 base::string16 new_keyword = UniquifyKeyword(*loser, false); 2128 base::string16 new_keyword = UniquifyKeyword(*loser, false);
2450 DCHECK(!GetTemplateURLForKeyword(new_keyword)); 2129 DCHECK(!GetTemplateURLForKeyword(new_keyword));
2451 if (applied_turl_is_better) { 2130 if (applied_turl_is_better) {
2452 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible 2131 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible
2453 // for adding or updating unapplied_sync_turl in the local model. 2132 // for adding or updating unapplied_sync_turl in the local model.
2454 unapplied_sync_turl->data_.SetKeyword(new_keyword); 2133 unapplied_sync_turl->data_.SetKeyword(new_keyword);
2455 } else { 2134 } else {
2456 // Update |applied_sync_turl| in the local model with the new keyword. 2135 // Update |applied_sync_turl| in the local model with the new keyword.
2457 TemplateURLData data(applied_sync_turl->data()); 2136 TemplateURLData data(applied_sync_turl->data());
2458 data.SetKeyword(new_keyword); 2137 data.SetKeyword(new_keyword);
2459 TemplateURL new_turl(applied_sync_turl->profile(), data);
2460 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile()); 2138 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile());
2461 if (UpdateNoNotify(applied_sync_turl, new_turl, search_terms_data)) 2139 if (UpdateNoNotify(applied_sync_turl, data, search_terms_data))
2462 NotifyObservers(); 2140 NotifyObservers();
2463 } 2141 }
2464 // The losing TemplateURL should have their keyword updated. Send a change to 2142 // The losing TemplateURL should have their keyword updated. Send a change to
2465 // the server to reflect this change. 2143 // the server to reflect this change.
2466 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser); 2144 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser);
2467 change_list->push_back(syncer::SyncChange(FROM_HERE, 2145 change_list->push_back(syncer::SyncChange(FROM_HERE,
2468 syncer::SyncChange::ACTION_UPDATE, 2146 syncer::SyncChange::ACTION_UPDATE,
2469 sync_data)); 2147 sync_data));
2470 } 2148 }
2471 2149
(...skipping 28 matching lines...) Expand all
2500 // |conflicting_turl| is not yet known to Sync. If it is better, then we 2178 // |conflicting_turl| is not yet known to Sync. If it is better, then we
2501 // want to transfer its values up to sync. Otherwise, we remove it and 2179 // want to transfer its values up to sync. Otherwise, we remove it and
2502 // allow the entry from Sync to overtake it in the model. 2180 // allow the entry from Sync to overtake it in the model.
2503 const std::string guid = conflicting_turl->sync_guid(); 2181 const std::string guid = conflicting_turl->sync_guid();
2504 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) { 2182 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) {
2505 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid()); 2183 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid());
2506 syncer::SyncData sync_data = 2184 syncer::SyncData sync_data =
2507 CreateSyncDataFromTemplateURL(*conflicting_turl); 2185 CreateSyncDataFromTemplateURL(*conflicting_turl);
2508 change_list->push_back(syncer::SyncChange( 2186 change_list->push_back(syncer::SyncChange(
2509 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data)); 2187 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data));
2510 if (conflicting_turl == GetDefaultSearchProvider() &&
2511 !pending_synced_default_search_) {
2512 // If we're not waiting for the Synced default to come in, we should
2513 // override the pref with our new GUID. If we are waiting for the
2514 // arrival of a synced default, setting the pref here would cause us
2515 // to lose the GUID we are waiting on.
2516 PrefService* prefs = GetPrefs();
2517 if (prefs) {
2518 prefs->SetString(prefs::kSyncedDefaultSearchProviderGUID,
2519 conflicting_turl->sync_guid());
2520 }
2521 }
2522 // Note that in this case we do not add the Sync TemplateURL to the 2188 // Note that in this case we do not add the Sync TemplateURL to the
2523 // local model, since we've effectively "merged" it in by updating the 2189 // local model, since we've effectively "merged" it in by updating the
2524 // local conflicting entry with its sync_guid. 2190 // local conflicting entry with its sync_guid.
2525 should_add_sync_turl = false; 2191 should_add_sync_turl = false;
2526 merge_result->set_num_items_modified( 2192 merge_result->set_num_items_modified(
2527 merge_result->num_items_modified() + 1); 2193 merge_result->num_items_modified() + 1);
2528 } else { 2194 } else {
2529 // We guarantee that this isn't the local search provider. Otherwise, 2195 // We guarantee that this isn't the local search provider. Otherwise,
2530 // local would have won. 2196 // local would have won.
2531 DCHECK(conflicting_turl != GetDefaultSearchProvider()); 2197 DCHECK(conflicting_turl != GetDefaultSearchProvider());
2532 Remove(conflicting_turl); 2198 Remove(conflicting_turl);
2533 merge_result->set_num_items_deleted( 2199 merge_result->set_num_items_deleted(
2534 merge_result->num_items_deleted() + 1); 2200 merge_result->num_items_deleted() + 1);
2535 } 2201 }
2536 // This TemplateURL was either removed or overwritten in the local model. 2202 // This TemplateURL was either removed or overwritten in the local model.
2537 // Remove the entry from the local data so it isn't pushed up to Sync. 2203 // Remove the entry from the local data so it isn't pushed up to Sync.
2538 local_data->erase(guid); 2204 local_data->erase(guid);
2539 } 2205 }
2540 } 2206 }
2541 2207
2542 if (should_add_sync_turl) { 2208 if (should_add_sync_turl) {
2543 // Force the local ID to kInvalidTemplateURLID so we can add it. 2209 // Force the local ID to kInvalidTemplateURLID so we can add it.
2544 TemplateURLData data(sync_turl->data()); 2210 TemplateURLData data(sync_turl->data());
2545 data.id = kInvalidTemplateURLID; 2211 data.id = kInvalidTemplateURLID;
2546 Add(new TemplateURL(profile_, data)); 2212 TemplateURL* added = new TemplateURL(profile_, data);
2213 if (Add(added) && GetPrefs() &&
2214 (added->sync_guid() ==
2215 GetPrefs()->GetString(prefs::kSyncedDefaultSearchProviderGUID))) {
2216 default_search_manager_.SetUserSelectedDefaultSearchEngine(
2217 added->data());
2218 }
2547 merge_result->set_num_items_added( 2219 merge_result->set_num_items_added(
2548 merge_result->num_items_added() + 1); 2220 merge_result->num_items_added() + 1);
2549 } 2221 }
2550 } 2222 }
2551 2223
2552 void TemplateURLService::SetDefaultSearchProviderIfNewlySynced(
2553 const std::string& guid) {
2554 // If we're not syncing or if default search is managed by policy, ignore.
2555 if (!sync_processor_.get() || is_default_search_managed_)
2556 return;
2557
2558 PrefService* prefs = GetPrefs();
2559 if (prefs && pending_synced_default_search_ &&
2560 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID) == guid) {
2561 // Make sure this actually exists. We should not be calling this unless we
2562 // really just added this TemplateURL.
2563 TemplateURL* turl_from_sync = GetTemplateURLForGUID(guid);
2564 if (turl_from_sync && turl_from_sync->SupportsReplacement()) {
2565 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2566 &dsp_change_origin_, DSP_CHANGE_SYNC_ADD);
2567 SetDefaultSearchProvider(turl_from_sync);
2568 }
2569 pending_synced_default_search_ = false;
2570 }
2571 }
2572
2573 TemplateURL* TemplateURLService::GetPendingSyncedDefaultSearchProvider() {
2574 PrefService* prefs = GetPrefs();
2575 if (!prefs || !pending_synced_default_search_)
2576 return NULL;
2577
2578 // Could be NULL if no such thing exists.
2579 return GetTemplateURLForGUID(
2580 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID));
2581 }
2582
2583 void TemplateURLService::PatchMissingSyncGUIDs( 2224 void TemplateURLService::PatchMissingSyncGUIDs(
2584 TemplateURLVector* template_urls) { 2225 TemplateURLVector* template_urls) {
2585 DCHECK(template_urls); 2226 DCHECK(template_urls);
2586 for (TemplateURLVector::iterator i = template_urls->begin(); 2227 for (TemplateURLVector::iterator i = template_urls->begin();
2587 i != template_urls->end(); ++i) { 2228 i != template_urls->end(); ++i) {
2588 TemplateURL* template_url = *i; 2229 TemplateURL* template_url = *i;
2589 DCHECK(template_url); 2230 DCHECK(template_url);
2590 if (template_url->sync_guid().empty() && 2231 if (template_url->sync_guid().empty() &&
2591 (template_url->GetType() != 2232 (template_url->GetType() !=
2592 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) { 2233 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) {
2593 template_url->data_.sync_guid = base::GenerateGUID(); 2234 template_url->data_.sync_guid = base::GenerateGUID();
2594 if (service_) 2235 if (service_)
2595 service_->UpdateKeyword(template_url->data()); 2236 service_->UpdateKeyword(template_url->data());
2596 } 2237 }
2597 } 2238 }
2598 } 2239 }
2599 2240
2600 void TemplateURLService::AddTemplateURLsAndSetupDefaultEngine( 2241 TemplateURL* TemplateURLService::FindPrepopulatedTemplateURL(
2601 TemplateURLVector* template_urls, 2242 int prepopulated_id) {
2602 TemplateURL* default_search_provider) { 2243 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2603 DCHECK(template_urls); 2244 i != template_urls_.end(); ++i) {
2604 is_default_search_managed_ = false; 2245 if ((*i)->prepopulate_id() == prepopulated_id)
2605 bool database_specified_a_default = (default_search_provider != NULL); 2246 return *i;
2247 }
2606 2248
2607 // Check if default search provider is now managed. 2249 return NULL;
2608 scoped_ptr<TemplateURLData> default_from_prefs;
2609 LoadDefaultSearchProviderFromPrefs(
2610 GetPrefs(), &default_from_prefs, &is_default_search_managed_);
2611
2612 // Remove entries that were created because of policy as they may have
2613 // changed since the database was saved.
2614 RemoveProvidersCreatedByPolicy(template_urls,
2615 &default_search_provider,
2616 default_from_prefs.get());
2617
2618 PatchMissingSyncGUIDs(template_urls);
2619
2620 if (is_default_search_managed_) {
2621 SetTemplateURLs(template_urls);
2622
2623 if (TemplateURLMatchesData(default_search_provider,
2624 default_from_prefs.get())) {
2625 // The value from the preferences was previously stored in the database.
2626 // Reuse it.
2627 } else {
2628 // The value from the preferences takes over.
2629 default_search_provider = NULL;
2630 if (default_from_prefs) {
2631 default_from_prefs->created_by_policy = true;
2632 default_from_prefs->id = kInvalidTemplateURLID;
2633 default_search_provider =
2634 new TemplateURL(profile_, *default_from_prefs);
2635 if (!AddNoNotify(default_search_provider, true))
2636 default_search_provider = NULL;
2637 }
2638 }
2639 // Note that this saves the default search provider to prefs.
2640 if (!default_search_provider ||
2641 ((default_search_provider->GetType() !=
2642 TemplateURL::OMNIBOX_API_EXTENSION) &&
2643 default_search_provider->SupportsReplacement())) {
2644 bool success = SetDefaultSearchProviderNoNotify(default_search_provider);
2645 DCHECK(success);
2646 }
2647 } else {
2648 // If we had a managed default, replace it with the synced default if
2649 // applicable, or the first provider of the list.
2650 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider();
2651 if (synced_default) {
2652 default_search_provider = synced_default;
2653 pending_synced_default_search_ = false;
2654 } else if (database_specified_a_default &&
2655 default_search_provider == NULL) {
2656 UMA_HISTOGRAM_ENUMERATION(kFirstPotentialEngineHistogramName,
2657 FIRST_POTENTIAL_CALLSITE_ON_LOAD,
2658 FIRST_POTENTIAL_CALLSITE_MAX);
2659 default_search_provider = FirstPotentialDefaultEngine(*template_urls);
2660 }
2661
2662 // If the default search provider existed previously, then just
2663 // set the member variable. Otherwise, we'll set it using the method
2664 // to ensure that it is saved properly after its id is set.
2665 if (default_search_provider &&
2666 (default_search_provider->id() != kInvalidTemplateURLID)) {
2667 default_search_provider_ = default_search_provider;
2668 default_search_provider = NULL;
2669 }
2670 SetTemplateURLs(template_urls);
2671
2672 if (default_search_provider) {
2673 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2674 &dsp_change_origin_, default_from_prefs ?
2675 dsp_change_origin_ : DSP_CHANGE_NEW_ENGINE_NO_PREFS);
2676 // Note that this saves the default search provider to prefs.
2677 SetDefaultSearchProvider(default_search_provider);
2678 } else {
2679 // Always save the default search provider to prefs. That way we don't
2680 // have to worry about it being out of sync.
2681 if (default_search_provider_)
2682 SaveDefaultSearchProviderToPrefs(default_search_provider_, GetPrefs());
2683 }
2684 }
2685 }
2686
2687 void TemplateURLService::EnsureDefaultSearchProviderExists() {
2688 if (!is_default_search_managed()) {
2689 bool has_default_search_provider = default_search_provider_ &&
2690 default_search_provider_->SupportsReplacement();
2691 UMA_HISTOGRAM_BOOLEAN("Search.HasDefaultSearchProvider",
2692 has_default_search_provider);
2693 // Ensure that default search provider exists. See http://crbug.com/116952.
2694 if (!has_default_search_provider) {
2695 bool success =
2696 SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider());
2697 DCHECK(success);
2698 }
2699 // Don't log anything if the user has a NULL default search provider.
2700 if (default_search_provider_) {
2701 UMA_HISTOGRAM_ENUMERATION("Search.DefaultSearchProviderType",
2702 TemplateURLPrepopulateData::GetEngineType(*default_search_provider_),
2703 SEARCH_ENGINE_MAX);
2704 }
2705 }
2706 } 2250 }
2707 2251
2708 TemplateURL* TemplateURLService::CreateTemplateURLForExtension( 2252 TemplateURL* TemplateURLService::CreateTemplateURLForExtension(
2709 const ExtensionKeyword& extension_keyword) const { 2253 const ExtensionKeyword& extension_keyword) {
2710 TemplateURLData data; 2254 TemplateURLData data;
2711 data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name); 2255 data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name);
2712 data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword)); 2256 data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword));
2713 // This URL is not actually used for navigation. It holds the extension's 2257 // This URL is not actually used for navigation. It holds the extension's
2714 // ID, as well as forcing the TemplateURL to be treated as a search keyword. 2258 // ID, as well as forcing the TemplateURL to be treated as a search keyword.
2715 data.SetURL(std::string(extensions::kExtensionScheme) + "://" + 2259 data.SetURL(std::string(extensions::kExtensionScheme) + "://" +
2716 extension_keyword.extension_id + "/?q={searchTerms}"); 2260 extension_keyword.extension_id + "/?q={searchTerms}");
2717 return new TemplateURL(profile_, data); 2261 return new TemplateURL(profile_, data);
2718 } 2262 }
2719 2263
2720 TemplateURL* TemplateURLService::FindTemplateURLForExtension( 2264 TemplateURL* TemplateURLService::FindTemplateURLForExtension(
2721 const std::string& extension_id, 2265 const std::string& extension_id,
2722 TemplateURL::Type type) const { 2266 TemplateURL::Type type) {
2723 DCHECK_NE(TemplateURL::NORMAL, type); 2267 DCHECK_NE(TemplateURL::NORMAL, type);
2724 for (TemplateURLVector::const_iterator i = template_urls_.begin(); 2268 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2725 i != template_urls_.end(); ++i) { 2269 i != template_urls_.end(); ++i) {
2726 if ((*i)->GetType() == type && 2270 if ((*i)->GetType() == type &&
2727 (*i)->GetExtensionId() == extension_id) 2271 (*i)->GetExtensionId() == extension_id)
2728 return *i; 2272 return *i;
2729 } 2273 }
2730 2274
2731 return NULL; 2275 return NULL;
2732 } 2276 }
2733 2277
2734 TemplateURL* TemplateURLService::FindExtensionDefaultSearchEngine() const { 2278 TemplateURL* TemplateURLService::FindMatchingExtensionTemplateURL(
2279 const TemplateURLData& data,
2280 TemplateURL::Type type) {
2281 DCHECK_NE(TemplateURL::NORMAL, type);
2282 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2283 i != template_urls_.end(); ++i) {
2284 if ((*i)->GetType() == type && TemplateURLMatchesData(*i, &data))
2285 return *i;
2286 }
2287
2288 return NULL;
2289 }
2290
2291 void TemplateURLService::UpdateExtensionDefaultSearchEngine() {
2735 TemplateURL* most_recently_intalled_default = NULL; 2292 TemplateURL* most_recently_intalled_default = NULL;
2736 for (TemplateURLVector::const_iterator i = template_urls_.begin(); 2293 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2737 i != template_urls_.end(); ++i) { 2294 i != template_urls_.end(); ++i) {
2738 if (((*i)->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) && 2295 if (((*i)->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) &&
2739 (*i)->extension_info_->wants_to_be_default_engine && 2296 (*i)->extension_info_->wants_to_be_default_engine &&
2740 (*i)->SupportsReplacement() && 2297 (*i)->SupportsReplacement() &&
2741 (!most_recently_intalled_default || 2298 (!most_recently_intalled_default ||
2742 (most_recently_intalled_default->extension_info_->install_time < 2299 (most_recently_intalled_default->extension_info_->install_time <
2743 (*i)->extension_info_->install_time))) 2300 (*i)->extension_info_->install_time)))
2744 most_recently_intalled_default = *i; 2301 most_recently_intalled_default = *i;
2745 } 2302 }
2746 2303
2747 return most_recently_intalled_default; 2304 if (most_recently_intalled_default) {
2305 default_search_manager_.SetExtensionControlledDefaultSearchEngine(
2306 most_recently_intalled_default->data());
2307 } else {
2308 default_search_manager_.ClearExtensionControlledDefaultSearchEngine();
2309 }
2748 } 2310 }
2749
2750 void TemplateURLService::
2751 SetDefaultSearchProviderAfterRemovingDefaultExtension() {
2752 DCHECK(!is_default_search_managed());
2753 TemplateURL* new_dse = FindExtensionDefaultSearchEngine();
2754 if (!new_dse) {
2755 scoped_ptr<TemplateURLData> default_provider;
2756 bool is_managed;
2757 if (LoadDefaultSearchProviderFromPrefs(
2758 GetPrefs(), &default_provider, &is_managed) &&
2759 default_provider) {
2760 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2761 i != template_urls_.end(); ++i) {
2762 if ((*i)->id() == default_provider->id) {
2763 new_dse = *i;
2764 break;
2765 }
2766 }
2767 }
2768 }
2769 if (!new_dse)
2770 new_dse = FindNewDefaultSearchProvider();
2771 SetDefaultSearchProviderNoNotify(new_dse);
2772 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698