OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } | |
OLD | NEW |