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 TemplateURLMatchesData(const TemplateURL* url1, | 60 bool TemplateURLMatchesData(const TemplateURL* url1, |
61 const TemplateURLData* url2) { | 61 const TemplateURLData* url2) { |
62 if (!url1 || !url2) | 62 if (!url1 || !url2) |
63 return !url1 && !url2; | 63 return !url1 && !url2; |
(...skipping 12 matching lines...) Expand all Loading... |
76 (url1->image_url_post_params() == url2->image_url_post_params) && | 76 (url1->image_url_post_params() == url2->image_url_post_params) && |
77 (url1->favicon_url() == url2->favicon_url) && | 77 (url1->favicon_url() == url2->favicon_url) && |
78 (url1->safe_for_autoreplace() == url2->safe_for_autoreplace) && | 78 (url1->safe_for_autoreplace() == url2->safe_for_autoreplace) && |
79 (url1->show_in_default_list() == url2->show_in_default_list) && | 79 (url1->show_in_default_list() == url2->show_in_default_list) && |
80 (url1->input_encodings() == url2->input_encodings) && | 80 (url1->input_encodings() == url2->input_encodings) && |
81 (url1->alternate_urls() == url2->alternate_urls) && | 81 (url1->alternate_urls() == url2->alternate_urls) && |
82 (url1->search_terms_replacement_key() == | 82 (url1->search_terms_replacement_key() == |
83 url2->search_terms_replacement_key); | 83 url2->search_terms_replacement_key); |
84 } | 84 } |
85 | 85 |
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[] = | 86 const char kDeleteSyncedEngineHistogramName[] = |
101 "Search.DeleteSyncedSearchEngine"; | 87 "Search.DeleteSyncedSearchEngine"; |
102 | 88 |
103 // Values for an enumerated histogram used to track whenever an ACTION_DELETE is | 89 // Values for an enumerated histogram used to track whenever an ACTION_DELETE is |
104 // sent to the server for search engines. | 90 // sent to the server for search engines. |
105 enum DeleteSyncedSearchEngineEvent { | 91 enum DeleteSyncedSearchEngineEvent { |
106 DELETE_ENGINE_USER_ACTION, | 92 DELETE_ENGINE_USER_ACTION, |
107 DELETE_ENGINE_PRE_SYNC, | 93 DELETE_ENGINE_PRE_SYNC, |
108 DELETE_ENGINE_EMPTY_FIELD, | 94 DELETE_ENGINE_EMPTY_FIELD, |
109 DELETE_ENGINE_MAX, | 95 DELETE_ENGINE_MAX, |
110 }; | 96 }; |
111 | 97 |
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 | 98 // 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 | 99 // up to the server based on its GUIDs presence in |sync_data| or when compared |
125 // to changes after it in |change_list|. | 100 // to changes after it in |change_list|. |
126 // The criteria is: | 101 // The criteria is: |
127 // 1) It is an ACTION_UPDATE or ACTION_DELETE and the sync_guid associated | 102 // 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 | 103 // with it is NOT found in |sync_data|. We can only update and remove |
129 // entries that were originally from the Sync server. | 104 // 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 | 105 // 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. | 106 // |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 | 107 // 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 | 241 // rather "two elements", so we pass the prefix as a fake "element" which has |
267 // a NULL KeywordDataElement pointer. | 242 // a NULL KeywordDataElement pointer. |
268 bool operator()(const KeywordToTemplateMap::value_type& elem1, | 243 bool operator()(const KeywordToTemplateMap::value_type& elem1, |
269 const KeywordToTemplateMap::value_type& elem2) const { | 244 const KeywordToTemplateMap::value_type& elem2) const { |
270 return (elem1.second == NULL) ? | 245 return (elem1.second == NULL) ? |
271 (elem2.first.compare(0, elem1.first.length(), elem1.first) > 0) : | 246 (elem2.first.compare(0, elem1.first.length(), elem1.first) > 0) : |
272 (elem1.first < elem2.first); | 247 (elem1.first < elem2.first); |
273 } | 248 } |
274 }; | 249 }; |
275 | 250 |
| 251 // static |
| 252 bool TemplateURLService::fallback_search_engines_disabled_ = false; |
276 | 253 |
277 // TemplateURLService --------------------------------------------------------- | 254 // TemplateURLService --------------------------------------------------------- |
278 | 255 |
279 TemplateURLService::TemplateURLService(Profile* profile) | 256 TemplateURLService::TemplateURLService(Profile* profile) |
280 : provider_map_(new SearchHostToURLsMap), | 257 : provider_map_(new SearchHostToURLsMap), |
281 profile_(profile), | 258 profile_(profile), |
282 loaded_(false), | 259 loaded_(false), |
283 load_failed_(false), | |
284 load_handle_(0), | 260 load_handle_(0), |
285 default_search_provider_(NULL), | 261 default_search_provider_(NULL), |
286 is_default_search_managed_(false), | |
287 next_id_(kInvalidTemplateURLID + 1), | 262 next_id_(kInvalidTemplateURLID + 1), |
288 time_provider_(&base::Time::Now), | 263 time_provider_(&base::Time::Now), |
289 models_associated_(false), | 264 models_associated_(false), |
290 processing_syncer_changes_(false), | 265 processing_syncer_changes_(false), |
291 pending_synced_default_search_(false), | 266 default_search_manager_( |
292 dsp_change_origin_(DSP_CHANGE_OTHER), | 267 GetPrefs(), |
293 default_search_manager_(new DefaultSearchManager(GetPrefs())) { | 268 base::Bind(&TemplateURLService::OnDefaultSearchChange, |
| 269 base::Unretained(this))) { |
294 DCHECK(profile_); | 270 DCHECK(profile_); |
295 Init(NULL, 0); | 271 Init(NULL, 0); |
296 } | 272 } |
297 | 273 |
298 TemplateURLService::TemplateURLService(const Initializer* initializers, | 274 TemplateURLService::TemplateURLService(const Initializer* initializers, |
299 const int count) | 275 const int count) |
300 : provider_map_(new SearchHostToURLsMap), | 276 : provider_map_(new SearchHostToURLsMap), |
301 profile_(NULL), | 277 profile_(NULL), |
302 loaded_(false), | 278 loaded_(false), |
303 load_failed_(false), | |
304 load_handle_(0), | 279 load_handle_(0), |
305 service_(NULL), | 280 service_(NULL), |
306 default_search_provider_(NULL), | 281 default_search_provider_(NULL), |
307 is_default_search_managed_(false), | |
308 next_id_(kInvalidTemplateURLID + 1), | 282 next_id_(kInvalidTemplateURLID + 1), |
309 time_provider_(&base::Time::Now), | 283 time_provider_(&base::Time::Now), |
310 models_associated_(false), | 284 models_associated_(false), |
311 processing_syncer_changes_(false), | 285 processing_syncer_changes_(false), |
312 pending_synced_default_search_(false), | 286 default_search_manager_( |
313 dsp_change_origin_(DSP_CHANGE_OTHER) { | 287 GetPrefs(), |
| 288 base::Bind(&TemplateURLService::OnDefaultSearchChange, |
| 289 base::Unretained(this))) { |
314 Init(initializers, count); | 290 Init(initializers, count); |
315 } | 291 } |
316 | 292 |
317 TemplateURLService::~TemplateURLService() { | 293 TemplateURLService::~TemplateURLService() { |
318 // |service_| should be deleted during Shutdown(). | 294 // |service_| should be deleted during Shutdown(). |
319 DCHECK(!service_); | 295 DCHECK(!service_); |
320 STLDeleteElements(&template_urls_); | 296 STLDeleteElements(&template_urls_); |
321 } | 297 } |
322 | 298 |
323 // static | 299 // static |
324 bool TemplateURLService::LoadDefaultSearchProviderFromPrefs( | |
325 PrefService* prefs, | |
326 scoped_ptr<TemplateURLData>* default_provider_data, | |
327 bool* is_managed) { | |
328 if (!prefs || !prefs->HasPrefPath(prefs::kDefaultSearchProviderSearchURL) || | |
329 !prefs->HasPrefPath(prefs::kDefaultSearchProviderKeyword)) | |
330 return false; | |
331 | |
332 const PrefService::Preference* pref = | |
333 prefs->FindPreference(prefs::kDefaultSearchProviderSearchURL); | |
334 *is_managed = pref && pref->IsManaged(); | |
335 | |
336 if (!prefs->GetBoolean(prefs::kDefaultSearchProviderEnabled)) { | |
337 // The user doesn't want a default search provider. | |
338 default_provider_data->reset(NULL); | |
339 return true; | |
340 } | |
341 | |
342 base::string16 name = | |
343 base::UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderName)); | |
344 base::string16 keyword = | |
345 base::UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderKeyword)); | |
346 if (keyword.empty()) | |
347 return false; | |
348 std::string search_url = | |
349 prefs->GetString(prefs::kDefaultSearchProviderSearchURL); | |
350 // Force URL to be non-empty. We've never supported this case, but past bugs | |
351 // might have resulted in it slipping through; eventually this code can be | |
352 // replaced with a DCHECK(!search_url.empty());. | |
353 if (search_url.empty()) | |
354 return false; | |
355 std::string suggest_url = | |
356 prefs->GetString(prefs::kDefaultSearchProviderSuggestURL); | |
357 std::string instant_url = | |
358 prefs->GetString(prefs::kDefaultSearchProviderInstantURL); | |
359 std::string image_url = | |
360 prefs->GetString(prefs::kDefaultSearchProviderImageURL); | |
361 std::string new_tab_url = | |
362 prefs->GetString(prefs::kDefaultSearchProviderNewTabURL); | |
363 std::string search_url_post_params = | |
364 prefs->GetString(prefs::kDefaultSearchProviderSearchURLPostParams); | |
365 std::string suggest_url_post_params = | |
366 prefs->GetString(prefs::kDefaultSearchProviderSuggestURLPostParams); | |
367 std::string instant_url_post_params = | |
368 prefs->GetString(prefs::kDefaultSearchProviderInstantURLPostParams); | |
369 std::string image_url_post_params = | |
370 prefs->GetString(prefs::kDefaultSearchProviderImageURLPostParams); | |
371 std::string icon_url = | |
372 prefs->GetString(prefs::kDefaultSearchProviderIconURL); | |
373 std::string encodings = | |
374 prefs->GetString(prefs::kDefaultSearchProviderEncodings); | |
375 std::string id_string = prefs->GetString(prefs::kDefaultSearchProviderID); | |
376 std::string prepopulate_id = | |
377 prefs->GetString(prefs::kDefaultSearchProviderPrepopulateID); | |
378 const base::ListValue* alternate_urls = | |
379 prefs->GetList(prefs::kDefaultSearchProviderAlternateURLs); | |
380 std::string search_terms_replacement_key = prefs->GetString( | |
381 prefs::kDefaultSearchProviderSearchTermsReplacementKey); | |
382 | |
383 default_provider_data->reset(new TemplateURLData); | |
384 (*default_provider_data)->short_name = name; | |
385 (*default_provider_data)->SetKeyword(keyword); | |
386 (*default_provider_data)->SetURL(search_url); | |
387 (*default_provider_data)->suggestions_url = suggest_url; | |
388 (*default_provider_data)->instant_url = instant_url; | |
389 (*default_provider_data)->image_url = image_url; | |
390 (*default_provider_data)->new_tab_url = new_tab_url; | |
391 (*default_provider_data)->search_url_post_params = search_url_post_params; | |
392 (*default_provider_data)->suggestions_url_post_params = | |
393 suggest_url_post_params; | |
394 (*default_provider_data)->instant_url_post_params = instant_url_post_params; | |
395 (*default_provider_data)->image_url_post_params = image_url_post_params; | |
396 (*default_provider_data)->favicon_url = GURL(icon_url); | |
397 (*default_provider_data)->show_in_default_list = true; | |
398 (*default_provider_data)->alternate_urls.clear(); | |
399 for (size_t i = 0; i < alternate_urls->GetSize(); ++i) { | |
400 std::string alternate_url; | |
401 if (alternate_urls->GetString(i, &alternate_url)) | |
402 (*default_provider_data)->alternate_urls.push_back(alternate_url); | |
403 } | |
404 (*default_provider_data)->search_terms_replacement_key = | |
405 search_terms_replacement_key; | |
406 base::SplitString(encodings, ';', &(*default_provider_data)->input_encodings); | |
407 if (!id_string.empty() && !*is_managed) { | |
408 int64 value; | |
409 base::StringToInt64(id_string, &value); | |
410 (*default_provider_data)->id = value; | |
411 } | |
412 if (!prepopulate_id.empty() && !*is_managed) { | |
413 int value; | |
414 base::StringToInt(prepopulate_id, &value); | |
415 (*default_provider_data)->prepopulate_id = value; | |
416 } | |
417 return true; | |
418 } | |
419 | |
420 // static | |
421 void TemplateURLService::SaveDefaultSearchProviderToPrefs( | |
422 const TemplateURL* t_url, PrefService* prefs) { | |
423 if (!prefs) | |
424 return; | |
425 | |
426 bool enabled = false; | |
427 std::string search_url; | |
428 std::string suggest_url; | |
429 std::string instant_url; | |
430 std::string image_url; | |
431 std::string new_tab_url; | |
432 std::string search_url_post_params; | |
433 std::string suggest_url_post_params; | |
434 std::string instant_url_post_params; | |
435 std::string image_url_post_params; | |
436 std::string icon_url; | |
437 std::string encodings; | |
438 std::string short_name; | |
439 std::string keyword; | |
440 std::string id_string; | |
441 std::string prepopulate_id; | |
442 base::ListValue alternate_urls; | |
443 std::string search_terms_replacement_key; | |
444 if (t_url) { | |
445 DCHECK_EQ(TemplateURL::NORMAL, t_url->GetType()); | |
446 enabled = true; | |
447 search_url = t_url->url(); | |
448 suggest_url = t_url->suggestions_url(); | |
449 instant_url = t_url->instant_url(); | |
450 image_url = t_url->image_url(); | |
451 new_tab_url = t_url->new_tab_url(); | |
452 search_url_post_params = t_url->search_url_post_params(); | |
453 suggest_url_post_params = t_url->suggestions_url_post_params(); | |
454 instant_url_post_params = t_url->instant_url_post_params(); | |
455 image_url_post_params = t_url->image_url_post_params(); | |
456 GURL icon_gurl = t_url->favicon_url(); | |
457 if (!icon_gurl.is_empty()) | |
458 icon_url = icon_gurl.spec(); | |
459 encodings = JoinString(t_url->input_encodings(), ';'); | |
460 short_name = base::UTF16ToUTF8(t_url->short_name()); | |
461 keyword = base::UTF16ToUTF8(t_url->keyword()); | |
462 id_string = base::Int64ToString(t_url->id()); | |
463 prepopulate_id = base::Int64ToString(t_url->prepopulate_id()); | |
464 for (size_t i = 0; i < t_url->alternate_urls().size(); ++i) | |
465 alternate_urls.AppendString(t_url->alternate_urls()[i]); | |
466 search_terms_replacement_key = t_url->search_terms_replacement_key(); | |
467 } | |
468 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, enabled); | |
469 prefs->SetString(prefs::kDefaultSearchProviderSearchURL, search_url); | |
470 prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, suggest_url); | |
471 prefs->SetString(prefs::kDefaultSearchProviderInstantURL, instant_url); | |
472 prefs->SetString(prefs::kDefaultSearchProviderImageURL, image_url); | |
473 prefs->SetString(prefs::kDefaultSearchProviderNewTabURL, new_tab_url); | |
474 prefs->SetString(prefs::kDefaultSearchProviderSearchURLPostParams, | |
475 search_url_post_params); | |
476 prefs->SetString(prefs::kDefaultSearchProviderSuggestURLPostParams, | |
477 suggest_url_post_params); | |
478 prefs->SetString(prefs::kDefaultSearchProviderInstantURLPostParams, | |
479 instant_url_post_params); | |
480 prefs->SetString(prefs::kDefaultSearchProviderImageURLPostParams, | |
481 image_url_post_params); | |
482 prefs->SetString(prefs::kDefaultSearchProviderIconURL, icon_url); | |
483 prefs->SetString(prefs::kDefaultSearchProviderEncodings, encodings); | |
484 prefs->SetString(prefs::kDefaultSearchProviderName, short_name); | |
485 prefs->SetString(prefs::kDefaultSearchProviderKeyword, keyword); | |
486 prefs->SetString(prefs::kDefaultSearchProviderID, id_string); | |
487 prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID, prepopulate_id); | |
488 prefs->Set(prefs::kDefaultSearchProviderAlternateURLs, alternate_urls); | |
489 prefs->SetString(prefs::kDefaultSearchProviderSearchTermsReplacementKey, | |
490 search_terms_replacement_key); | |
491 } | |
492 | |
493 // static | |
494 base::string16 TemplateURLService::GenerateKeyword(const GURL& url) { | 300 base::string16 TemplateURLService::GenerateKeyword(const GURL& url) { |
495 DCHECK(url.is_valid()); | 301 DCHECK(url.is_valid()); |
496 // Strip "www." off the front of the keyword; otherwise the keyword won't work | 302 // Strip "www." off the front of the keyword; otherwise the keyword won't work |
497 // properly. See http://code.google.com/p/chromium/issues/detail?id=6984 . | 303 // properly. See http://code.google.com/p/chromium/issues/detail?id=6984 . |
498 // Special case: if the host was exactly "www." (not sure this can happen but | 304 // Special case: if the host was exactly "www." (not sure this can happen but |
499 // perhaps with some weird intranet and custom DNS server?), ensure we at | 305 // perhaps with some weird intranet and custom DNS server?), ensure we at |
500 // least don't return the empty string. | 306 // least don't return the empty string. |
501 base::string16 keyword(net::StripWWWFromHost(url)); | 307 base::string16 keyword(net::StripWWWFromHost(url)); |
502 return keyword.empty() ? base::ASCIIToUTF16("www") : keyword; | 308 return keyword.empty() ? base::ASCIIToUTF16("www") : keyword; |
503 } | 309 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 // case the term replaces the URL it's unlikely another keyword would have the | 367 // case the term replaces the URL it's unlikely another keyword would have the |
562 // same url. | 368 // same url. |
563 // TODO(jnd): Add additional parameters to get post data when the search URL | 369 // TODO(jnd): Add additional parameters to get post data when the search URL |
564 // has post parameters. | 370 // has post parameters. |
565 return GURL(search_ref.ReplaceSearchTermsUsingTermsData( | 371 return GURL(search_ref.ReplaceSearchTermsUsingTermsData( |
566 TemplateURLRef::SearchTermsArgs( | 372 TemplateURLRef::SearchTermsArgs( |
567 base::ASCIIToUTF16("blah.blah.blah.blah.blah")), | 373 base::ASCIIToUTF16("blah.blah.blah.blah.blah")), |
568 search_terms_data, NULL)); | 374 search_terms_data, NULL)); |
569 } | 375 } |
570 | 376 |
| 377 // static |
| 378 void TemplateURLService::DisableFallbackSearchEngines() { |
| 379 fallback_search_engines_disabled_ = true; |
| 380 } |
| 381 |
571 bool TemplateURLService::CanReplaceKeyword( | 382 bool TemplateURLService::CanReplaceKeyword( |
572 const base::string16& keyword, | 383 const base::string16& keyword, |
573 const GURL& url, | 384 const GURL& url, |
574 TemplateURL** template_url_to_replace) { | 385 TemplateURL** template_url_to_replace) { |
575 DCHECK(!keyword.empty()); // This should only be called for non-empty | 386 DCHECK(!keyword.empty()); // This should only be called for non-empty |
576 // keywords. If we need to support empty kewords | 387 // keywords. If we need to support empty kewords |
577 // the code needs to change slightly. | 388 // the code needs to change slightly. |
578 TemplateURL* existing_url = GetTemplateURLForKeyword(keyword); | 389 TemplateURL* existing_url = GetTemplateURLForKeyword(keyword); |
579 if (template_url_to_replace) | 390 if (template_url_to_replace) |
580 *template_url_to_replace = existing_url; | 391 *template_url_to_replace = existing_url; |
581 if (existing_url) { | 392 if (existing_url) { |
582 // We already have a TemplateURL for this keyword. Only allow it to be | 393 // We already have a TemplateURL for this keyword. Only allow it to be |
583 // replaced if the TemplateURL can be replaced. | 394 // replaced if the TemplateURL can be replaced. |
584 return CanReplace(existing_url); | 395 return CanReplace(existing_url); |
585 } | 396 } |
586 | 397 |
587 // We don't have a TemplateURL with keyword. Only allow a new one if there | 398 // We don't have a TemplateURL with keyword. Only allow a new one if there |
588 // isn't a TemplateURL for the specified host, or there is one but it can | 399 // isn't a TemplateURL for the specified host, or there is one but it can |
589 // be replaced. We do this to ensure that if the user assigns a different | 400 // be replaced. We do this to ensure that if the user assigns a different |
590 // keyword to a generated TemplateURL, we won't regenerate another keyword for | 401 // keyword to a generated TemplateURL, we won't regenerate another keyword for |
591 // the same host. | 402 // the same host. |
592 return !url.is_valid() || url.host().empty() || | 403 return !url.is_valid() || url.host().empty() || |
593 CanReplaceKeywordForHost(url.host(), template_url_to_replace); | 404 CanReplaceKeywordForHost(url.host(), template_url_to_replace); |
594 } | 405 } |
595 | 406 |
596 void TemplateURLService::FindMatchingKeywords( | 407 void TemplateURLService::FindMatchingKeywords( |
597 const base::string16& prefix, | 408 const base::string16& prefix, |
598 bool support_replacement_only, | 409 bool support_replacement_only, |
599 TemplateURLVector* matches) const { | 410 TemplateURLVector* matches) { |
600 // Sanity check args. | 411 // Sanity check args. |
601 if (prefix.empty()) | 412 if (prefix.empty()) |
602 return; | 413 return; |
603 DCHECK(matches != NULL); | 414 DCHECK(matches != NULL); |
604 DCHECK(matches->empty()); // The code for exact matches assumes this. | 415 DCHECK(matches->empty()); // The code for exact matches assumes this. |
605 | 416 |
606 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/det
ails/520043/error-converting-from-null-to-a-pointer-type-in-std-pair | 417 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/det
ails/520043/error-converting-from-null-to-a-pointer-type-in-std-pair |
607 TemplateURL* const kNullTemplateURL = NULL; | 418 TemplateURL* const kNullTemplateURL = NULL; |
608 | 419 |
609 // Find matching keyword range. Searches the element map for keywords | 420 // Find matching keyword range. Searches the element map for keywords |
(...skipping 13 matching lines...) Expand all Loading... |
623 matches->push_back(i->second); | 434 matches->push_back(i->second); |
624 } | 435 } |
625 } | 436 } |
626 | 437 |
627 TemplateURL* TemplateURLService::GetTemplateURLForKeyword( | 438 TemplateURL* TemplateURLService::GetTemplateURLForKeyword( |
628 const base::string16& keyword) { | 439 const base::string16& keyword) { |
629 KeywordToTemplateMap::const_iterator elem( | 440 KeywordToTemplateMap::const_iterator elem( |
630 keyword_to_template_map_.find(keyword)); | 441 keyword_to_template_map_.find(keyword)); |
631 if (elem != keyword_to_template_map_.end()) | 442 if (elem != keyword_to_template_map_.end()) |
632 return elem->second; | 443 return elem->second; |
633 return ((!loaded_ || load_failed_) && | 444 return (!loaded_ && |
634 initial_default_search_provider_.get() && | 445 initial_default_search_provider_.get() && |
635 (initial_default_search_provider_->keyword() == keyword)) ? | 446 (initial_default_search_provider_->keyword() == keyword)) ? |
636 initial_default_search_provider_.get() : NULL; | 447 initial_default_search_provider_.get() : NULL; |
637 } | 448 } |
638 | 449 |
639 TemplateURL* TemplateURLService::GetTemplateURLForGUID( | 450 TemplateURL* TemplateURLService::GetTemplateURLForGUID( |
640 const std::string& sync_guid) { | 451 const std::string& sync_guid) { |
641 GUIDToTemplateMap::const_iterator elem(guid_to_template_map_.find(sync_guid)); | 452 GUIDToTemplateMap::const_iterator elem(guid_to_template_map_.find(sync_guid)); |
642 if (elem != guid_to_template_map_.end()) | 453 if (elem != guid_to_template_map_.end()) |
643 return elem->second; | 454 return elem->second; |
644 return ((!loaded_ || load_failed_) && | 455 return (!loaded_ && |
645 initial_default_search_provider_.get() && | 456 initial_default_search_provider_.get() && |
646 (initial_default_search_provider_->sync_guid() == sync_guid)) ? | 457 (initial_default_search_provider_->sync_guid() == sync_guid)) ? |
647 initial_default_search_provider_.get() : NULL; | 458 initial_default_search_provider_.get() : NULL; |
648 } | 459 } |
649 | 460 |
650 TemplateURL* TemplateURLService::GetTemplateURLForHost( | 461 TemplateURL* TemplateURLService::GetTemplateURLForHost( |
651 const std::string& host) { | 462 const std::string& host) { |
652 if (loaded_) { | 463 if (loaded_) { |
653 TemplateURL* t_url = provider_map_->GetTemplateURLForHost(host); | 464 TemplateURL* t_url = provider_map_->GetTemplateURLForHost(host); |
654 if (t_url) | 465 if (t_url) |
655 return t_url; | 466 return t_url; |
656 } | 467 } |
657 return ((!loaded_ || load_failed_) && | 468 return (!loaded_ && |
658 initial_default_search_provider_.get() && | 469 initial_default_search_provider_.get() && |
659 (GenerateSearchURL(initial_default_search_provider_.get()).host() == | 470 (GenerateSearchURL(initial_default_search_provider_.get()).host() == |
660 host)) ? initial_default_search_provider_.get() : NULL; | 471 host)) ? initial_default_search_provider_.get() : NULL; |
661 } | 472 } |
662 | 473 |
663 void TemplateURLService::Add(TemplateURL* template_url) { | 474 void TemplateURLService::Add(TemplateURL* template_url) { |
664 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); | 475 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); |
665 if (AddNoNotify(template_url, true)) | 476 if (AddNoNotify(template_url, true)) |
666 NotifyObservers(); | 477 NotifyObservers(); |
667 } | 478 } |
(...skipping 25 matching lines...) Expand all Loading... |
693 DCHECK(info); | 504 DCHECK(info); |
694 DCHECK_EQ(info->wants_to_be_default_engine, | 505 DCHECK_EQ(info->wants_to_be_default_engine, |
695 template_url->show_in_default_list()); | 506 template_url->show_in_default_list()); |
696 template_url->extension_info_.swap(info); | 507 template_url->extension_info_.swap(info); |
697 DCHECK(!FindTemplateURLForExtension( | 508 DCHECK(!FindTemplateURLForExtension( |
698 template_url->GetExtensionId(), | 509 template_url->GetExtensionId(), |
699 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)); | 510 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)); |
700 | 511 |
701 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); | 512 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); |
702 if (AddNoNotify(template_url, true)) { | 513 if (AddNoNotify(template_url, true)) { |
703 // Note that we can't call CanMakeDefault() here, since it would return | 514 if (template_url->extension_info_->wants_to_be_default_engine) |
704 // false when another extension is already controlling the default search | 515 UpdateExtensionDefaultSearchEngine(); |
705 // engine, and we want to allow new extensions to take over. | |
706 if (template_url->extension_info_->wants_to_be_default_engine && | |
707 !is_default_search_managed()) { | |
708 TemplateURL* default_candidate = FindExtensionDefaultSearchEngine(); | |
709 if (default_candidate == template_url) { | |
710 base::AutoReset<DefaultSearchChangeOrigin> change_origin( | |
711 &dsp_change_origin_, DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION); | |
712 SetDefaultSearchProviderNoNotify(template_url); | |
713 } | |
714 } | |
715 NotifyObservers(); | 516 NotifyObservers(); |
716 } | 517 } |
717 } | 518 } |
718 | 519 |
719 void TemplateURLService::Remove(TemplateURL* template_url) { | 520 void TemplateURLService::Remove(TemplateURL* template_url) { |
720 RemoveNoNotify(template_url); | 521 RemoveNoNotify(template_url); |
721 NotifyObservers(); | 522 NotifyObservers(); |
722 } | 523 } |
723 | 524 |
724 void TemplateURLService::RemoveExtensionControlledTURL( | 525 void TemplateURLService::RemoveExtensionControlledTURL( |
725 const std::string& extension_id) { | 526 const std::string& extension_id) { |
726 DCHECK(loaded_); | 527 DCHECK(loaded_); |
727 TemplateURL* url = FindTemplateURLForExtension( | 528 TemplateURL* url = FindTemplateURLForExtension( |
728 extension_id, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION); | 529 extension_id, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION); |
729 if (!url) | 530 if (!url) |
730 return; | 531 return; |
731 bool restore_dse = (url == GetDefaultSearchProvider()); | 532 // NULL this out so that we can call RemoveNoNotify. The subsequent |
732 if (restore_dse) { | 533 // UpdateExtensionDefaultSearchEngine will cause it to be reset. |
733 DCHECK(!is_default_search_managed()); | 534 if (default_search_provider_ == url) |
734 default_search_provider_ = NULL; | 535 default_search_provider_ = NULL; |
735 } | |
736 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); | 536 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); |
737 RemoveNoNotify(url); | 537 RemoveNoNotify(url); |
738 if (restore_dse) | 538 UpdateExtensionDefaultSearchEngine(); |
739 SetDefaultSearchProviderAfterRemovingDefaultExtension(); | |
740 NotifyObservers(); | 539 NotifyObservers(); |
741 } | 540 } |
742 | 541 |
743 void TemplateURLService::RemoveAutoGeneratedSince(base::Time created_after) { | 542 void TemplateURLService::RemoveAutoGeneratedSince(base::Time created_after) { |
744 RemoveAutoGeneratedBetween(created_after, base::Time()); | 543 RemoveAutoGeneratedBetween(created_after, base::Time()); |
745 } | 544 } |
746 | 545 |
747 void TemplateURLService::RemoveAutoGeneratedBetween(base::Time created_after, | 546 void TemplateURLService::RemoveAutoGeneratedBetween(base::Time created_after, |
748 base::Time created_before) { | 547 base::Time created_before) { |
749 RemoveAutoGeneratedForOriginBetween(GURL(), created_after, created_before); | 548 RemoveAutoGeneratedForOriginBetween(GURL(), created_after, created_before); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 TemplateURLData data(url->data()); | 624 TemplateURLData data(url->data()); |
826 data.short_name = title; | 625 data.short_name = title; |
827 data.SetKeyword(keyword); | 626 data.SetKeyword(keyword); |
828 if (search_url != data.url()) { | 627 if (search_url != data.url()) { |
829 data.SetURL(search_url); | 628 data.SetURL(search_url); |
830 // The urls have changed, reset the favicon url. | 629 // The urls have changed, reset the favicon url. |
831 data.favicon_url = GURL(); | 630 data.favicon_url = GURL(); |
832 } | 631 } |
833 data.safe_for_autoreplace = false; | 632 data.safe_for_autoreplace = false; |
834 data.last_modified = time_provider_(); | 633 data.last_modified = time_provider_(); |
835 TemplateURL new_url(url->profile(), data); | 634 |
836 UIThreadSearchTermsData search_terms_data(url->profile()); | 635 UIThreadSearchTermsData search_terms_data(url->profile()); |
837 if (UpdateNoNotify(url, new_url, search_terms_data)) | 636 if (UpdateNoNotify(url, data, search_terms_data)) |
838 NotifyObservers(); | 637 NotifyObservers(); |
839 } | 638 } |
840 | 639 |
841 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) { | 640 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) { |
842 return !is_default_search_managed() && | 641 return ((default_search_provider_source_ == |
843 !IsExtensionControlledDefaultSearch() && | 642 DefaultSearchManager::FROM_USER) || |
844 (url != GetDefaultSearchProvider()) && | 643 (default_search_provider_source_ == |
845 url->url_ref().SupportsReplacement() && | 644 DefaultSearchManager::FROM_FALLBACK)) && |
846 (url->GetType() == TemplateURL::NORMAL); | 645 (url != GetDefaultSearchProvider()) && |
| 646 url->url_ref().SupportsReplacement() && |
| 647 (url->GetType() == TemplateURL::NORMAL); |
847 } | 648 } |
848 | 649 |
849 void TemplateURLService::SetUserSelectedDefaultSearchProvider( | 650 void TemplateURLService::SetUserSelectedDefaultSearchProvider( |
850 TemplateURL* url) { | 651 TemplateURL* url) { |
851 SetDefaultSearchProvider(url); | 652 // Omnibox keywords cannot be made default. Extension-controlled search |
852 if (default_search_manager_) { | 653 // engines can be made default only by the extension itself because they |
853 if (url) | 654 // aren't persisted. |
854 default_search_manager_->SetUserSelectedDefaultSearchEngine(url->data()); | 655 DCHECK(!url || (url->GetType() == TemplateURL::NORMAL)); |
855 else | 656 // We rely on the DefaultSearchManager to push this back to us if, in fact, |
856 default_search_manager_->ClearUserSelectedDefaultSearchEngine(); | 657 // the effective DSE changes. |
857 } | 658 if (url) |
| 659 default_search_manager_.SetUserSelectedDefaultSearchEngine(url->data()); |
| 660 else |
| 661 default_search_manager_.ClearUserSelectedDefaultSearchEngine(); |
858 } | 662 } |
859 | 663 |
860 TemplateURL* TemplateURLService::GetDefaultSearchProvider() { | 664 TemplateURL* TemplateURLService::GetDefaultSearchProvider() { |
861 if (loaded_ && !load_failed_) | 665 if (loaded_) |
862 return default_search_provider_; | 666 return default_search_provider_; |
863 // We're not loaded, rely on the default search provider stored in prefs. | 667 // We're not loaded, rely on the default search provider stored in prefs. |
864 return initial_default_search_provider_.get(); | 668 return initial_default_search_provider_.get(); |
865 } | 669 } |
866 | 670 |
867 bool TemplateURLService::IsSearchResultsPageFromDefaultSearchProvider( | 671 bool TemplateURLService::IsSearchResultsPageFromDefaultSearchProvider( |
868 const GURL& url) { | 672 const GURL& url) { |
869 TemplateURL* default_provider = GetDefaultSearchProvider(); | 673 TemplateURL* default_provider = GetDefaultSearchProvider(); |
870 return default_provider && default_provider->IsSearchURL(url); | 674 return default_provider && default_provider->IsSearchURL(url); |
871 } | 675 } |
872 | 676 |
873 bool TemplateURLService::IsExtensionControlledDefaultSearch() { | 677 bool TemplateURLService::IsExtensionControlledDefaultSearch() { |
874 const TemplateURL* default_provider = GetDefaultSearchProvider(); | 678 return default_search_provider_source_ == |
875 return default_provider && (default_provider->GetType() == | 679 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 } | 680 } |
912 | 681 |
913 void TemplateURLService::RepairPrepopulatedSearchEngines() { | 682 void TemplateURLService::RepairPrepopulatedSearchEngines() { |
914 // Can't clean DB if it hasn't been loaded. | 683 // Can't clean DB if it hasn't been loaded. |
915 DCHECK(loaded()); | 684 DCHECK(loaded()); |
916 | 685 |
| 686 if (default_search_provider_source_ == DefaultSearchManager::FROM_USER || |
| 687 default_search_provider_source_ == DefaultSearchManager::FROM_FALLBACK) { |
| 688 // Clear this so that we can remove what it points to (if it's a |
| 689 // prepopulated engine). No matter what we will reset it at the end anyway. |
| 690 default_search_provider_ = NULL; |
| 691 } |
| 692 |
917 size_t default_search_provider_index = 0; | 693 size_t default_search_provider_index = 0; |
918 ScopedVector<TemplateURLData> prepopulated_urls = | 694 ScopedVector<TemplateURLData> prepopulated_urls = |
919 TemplateURLPrepopulateData::GetPrepopulatedEngines( | 695 TemplateURLPrepopulateData::GetPrepopulatedEngines( |
920 GetPrefs(), &default_search_provider_index); | 696 GetPrefs(), &default_search_provider_index); |
921 DCHECK(!prepopulated_urls.empty()); | 697 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( | 698 ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData( |
926 &prepopulated_urls, template_urls_, current_dse)); | 699 &prepopulated_urls, template_urls_, default_search_provider_)); |
927 | 700 |
928 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); | 701 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); |
929 | 702 |
930 // Remove items. | 703 // Remove items. |
931 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin(); | 704 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin(); |
932 i < actions.removed_engines.end(); ++i) | 705 i < actions.removed_engines.end(); ++i) |
933 RemoveNoNotify(*i); | 706 RemoveNoNotify(*i); |
934 | 707 |
935 // Edit items. | 708 // Edit items. |
936 for (EditedEngines::iterator i(actions.edited_engines.begin()); | 709 for (EditedEngines::iterator i(actions.edited_engines.begin()); |
937 i < actions.edited_engines.end(); ++i) { | 710 i < actions.edited_engines.end(); ++i) { |
938 UIThreadSearchTermsData search_terms_data(profile()); | 711 UIThreadSearchTermsData search_terms_data(profile()); |
939 TemplateURL new_values(profile(), i->second); | 712 UpdateNoNotify(i->first, i->second, search_terms_data); |
940 UpdateNoNotify(i->first, new_values, search_terms_data); | |
941 } | 713 } |
942 | 714 |
943 // Add items. | 715 // Add items. |
944 for (std::vector<TemplateURLData>::const_iterator i = | 716 for (std::vector<TemplateURLData>::const_iterator i = |
945 actions.added_engines.begin(); | 717 actions.added_engines.begin(); |
946 i < actions.added_engines.end(); | 718 i < actions.added_engines.end(); |
947 ++i) { | 719 ++i) { |
948 AddNoNotify(new TemplateURL(profile_, *i), true); | 720 AddNoNotify(new TemplateURL(profile_, *i), true); |
949 } | 721 } |
950 | 722 |
951 // Change the DSE. | 723 default_search_manager_.ClearUserSelectedDefaultSearchEngine(); |
952 TemplateURL* new_dse = FindURLByPrepopulateID(template_urls_, | 724 |
953 default_search_engine_id); | 725 if (!default_search_provider_) { |
954 DCHECK(new_dse); | 726 DefaultSearchManager::Source source; |
955 if (CanMakeDefault(new_dse)) { | 727 const TemplateURLData* new_dse = |
956 base::AutoReset<DefaultSearchChangeOrigin> change_origin( | 728 default_search_manager_.GetDefaultSearchEngine(&source); |
957 &dsp_change_origin_, DSP_CHANGE_PROFILE_RESET); | 729 // OnDefaultSearchChange will notify observers once it is done. |
958 SetDefaultSearchProviderNoNotify(new_dse); | 730 OnDefaultSearchChange(new_dse, source); |
| 731 } else { |
| 732 NotifyObservers(); |
959 } | 733 } |
960 NotifyObservers(); | |
961 } | 734 } |
962 | 735 |
963 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) { | 736 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) { |
964 model_observers_.AddObserver(observer); | 737 model_observers_.AddObserver(observer); |
965 } | 738 } |
966 | 739 |
967 void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) { | 740 void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) { |
968 model_observers_.RemoveObserver(observer); | 741 model_observers_.RemoveObserver(observer); |
969 } | 742 } |
970 | 743 |
(...skipping 24 matching lines...) Expand all Loading... |
995 void TemplateURLService::OnWebDataServiceRequestDone( | 768 void TemplateURLService::OnWebDataServiceRequestDone( |
996 WebDataService::Handle h, | 769 WebDataService::Handle h, |
997 const WDTypedResult* result) { | 770 const WDTypedResult* result) { |
998 // Reset the load_handle so that we don't try and cancel the load in | 771 // Reset the load_handle so that we don't try and cancel the load in |
999 // the destructor. | 772 // the destructor. |
1000 load_handle_ = 0; | 773 load_handle_ = 0; |
1001 | 774 |
1002 if (!result) { | 775 if (!result) { |
1003 // Results are null if the database went away or (most likely) wasn't | 776 // Results are null if the database went away or (most likely) wasn't |
1004 // loaded. | 777 // loaded. |
1005 load_failed_ = true; | |
1006 ChangeToLoadedState(); | 778 ChangeToLoadedState(); |
1007 on_loaded_callbacks_.Notify(); | 779 on_loaded_callbacks_.Notify(); |
1008 return; | 780 return; |
1009 } | 781 } |
1010 | 782 |
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; | 783 TemplateURLVector template_urls; |
1016 TemplateURL* default_search_provider = NULL; | |
1017 int new_resource_keyword_version = 0; | 784 int new_resource_keyword_version = 0; |
1018 GetSearchProvidersUsingKeywordResult(*result, service_.get(), profile_, | 785 GetSearchProvidersUsingKeywordResult( |
1019 &template_urls, &default_search_provider, &new_resource_keyword_version, | 786 *result, |
| 787 service_.get(), |
| 788 profile_, |
| 789 &template_urls, |
| 790 (default_search_provider_source_ == DefaultSearchManager::FROM_USER) ? |
| 791 initial_default_search_provider_.get() : NULL, |
| 792 &new_resource_keyword_version, |
1020 &pre_sync_deletes_); | 793 &pre_sync_deletes_); |
1021 | 794 |
1022 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); | 795 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); |
1023 | 796 |
1024 AddTemplateURLsAndSetupDefaultEngine(&template_urls, default_search_provider); | 797 PatchMissingSyncGUIDs(&template_urls); |
| 798 SetTemplateURLs(&template_urls); |
1025 | 799 |
1026 // This initializes provider_map_ which should be done before | 800 // This initializes provider_map_ which should be done before |
1027 // calling UpdateKeywordSearchTermsForURL. | 801 // calling UpdateKeywordSearchTermsForURL. |
| 802 // This also calls NotifyObservers. |
1028 ChangeToLoadedState(); | 803 ChangeToLoadedState(); |
| 804 on_loaded_callbacks_.Notify(); |
1029 | 805 |
1030 // Index any visits that occurred before we finished loading. | 806 // Index any visits that occurred before we finished loading. |
1031 for (size_t i = 0; i < visits_to_add_.size(); ++i) | 807 for (size_t i = 0; i < visits_to_add_.size(); ++i) |
1032 UpdateKeywordSearchTermsForURL(visits_to_add_[i]); | 808 UpdateKeywordSearchTermsForURL(visits_to_add_[i]); |
1033 visits_to_add_.clear(); | 809 visits_to_add_.clear(); |
1034 | 810 |
1035 if (new_resource_keyword_version) | 811 if (new_resource_keyword_version) |
1036 service_->SetBuiltinKeywordVersion(new_resource_keyword_version); | 812 service_->SetBuiltinKeywordVersion(new_resource_keyword_version); |
1037 | |
1038 EnsureDefaultSearchProviderExists(); | |
1039 | |
1040 NotifyObservers(); | |
1041 on_loaded_callbacks_.Notify(); | |
1042 } | 813 } |
1043 | 814 |
1044 base::string16 TemplateURLService::GetKeywordShortName( | 815 base::string16 TemplateURLService::GetKeywordShortName( |
1045 const base::string16& keyword, | 816 const base::string16& keyword, |
1046 bool* is_omnibox_api_extension_keyword) { | 817 bool* is_omnibox_api_extension_keyword) { |
1047 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); | 818 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); |
1048 | 819 |
1049 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService | 820 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService |
1050 // to track changes to the model, this should become a DCHECK. | 821 // to track changes to the model, this should become a DCHECK. |
1051 if (template_url) { | 822 if (template_url) { |
1052 *is_omnibox_api_extension_keyword = | 823 *is_omnibox_api_extension_keyword = |
1053 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION; | 824 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION; |
1054 return template_url->AdjustedShortNameForLocaleDirection(); | 825 return template_url->AdjustedShortNameForLocaleDirection(); |
1055 } | 826 } |
1056 *is_omnibox_api_extension_keyword = false; | 827 *is_omnibox_api_extension_keyword = false; |
1057 return base::string16(); | 828 return base::string16(); |
1058 } | 829 } |
1059 | 830 |
1060 void TemplateURLService::Observe(int type, | 831 void TemplateURLService::Observe(int type, |
1061 const content::NotificationSource& source, | 832 const content::NotificationSource& source, |
1062 const content::NotificationDetails& details) { | 833 const content::NotificationDetails& details) { |
1063 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) { | 834 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) { |
1064 content::Details<history::URLVisitedDetails> visit_details(details); | 835 content::Details<history::URLVisitedDetails> visit_details(details); |
1065 if (!loaded_) | 836 if (!loaded_) |
1066 visits_to_add_.push_back(*visit_details.ptr()); | 837 visits_to_add_.push_back(*visit_details.ptr()); |
1067 else | 838 else |
1068 UpdateKeywordSearchTermsForURL(*visit_details.ptr()); | 839 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 { | 840 } else { |
1076 DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_URL_UPDATED, type); | 841 DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_URL_UPDATED, type); |
1077 if (loaded_) { | 842 if (loaded_) { |
1078 GoogleBaseURLChanged( | 843 GoogleBaseURLChanged( |
1079 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first); | 844 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first); |
1080 } | 845 } |
1081 } | 846 } |
1082 } | 847 } |
1083 | 848 |
1084 void TemplateURLService::Shutdown() { | 849 void TemplateURLService::Shutdown() { |
1085 // This check has to be done at Shutdown() instead of in the dtor to ensure | 850 // 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 | 851 // that no clients of WebDataService are holding ptrs to it after the first |
1087 // phase of the KeyedService Shutdown() process. | 852 // phase of the KeyedService Shutdown() process. |
1088 if (load_handle_) { | 853 if (load_handle_) { |
1089 DCHECK(service_.get()); | 854 DCHECK(service_.get()); |
1090 service_->CancelRequest(load_handle_); | 855 service_->CancelRequest(load_handle_); |
1091 } | 856 } |
1092 service_ = NULL; | 857 service_ = NULL; |
1093 } | 858 } |
1094 | 859 |
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( | 860 syncer::SyncDataList TemplateURLService::GetAllSyncData( |
1117 syncer::ModelType type) const { | 861 syncer::ModelType type) const { |
1118 DCHECK_EQ(syncer::SEARCH_ENGINES, type); | 862 DCHECK_EQ(syncer::SEARCH_ENGINES, type); |
1119 | 863 |
1120 syncer::SyncDataList current_data; | 864 syncer::SyncDataList current_data; |
1121 for (TemplateURLVector::const_iterator iter = template_urls_.begin(); | 865 for (TemplateURLVector::const_iterator iter = template_urls_.begin(); |
1122 iter != template_urls_.end(); ++iter) { | 866 iter != template_urls_.end(); ++iter) { |
1123 // We don't sync keywords managed by policy. | 867 // We don't sync keywords managed by policy. |
1124 if ((*iter)->created_by_policy()) | 868 if ((*iter)->created_by_policy()) |
1125 continue; | 869 continue; |
(...skipping 13 matching lines...) Expand all Loading... |
1139 syncer::SyncError error(FROM_HERE, | 883 syncer::SyncError error(FROM_HERE, |
1140 syncer::SyncError::DATATYPE_ERROR, | 884 syncer::SyncError::DATATYPE_ERROR, |
1141 "Models not yet associated.", | 885 "Models not yet associated.", |
1142 syncer::SEARCH_ENGINES); | 886 syncer::SEARCH_ENGINES); |
1143 return error; | 887 return error; |
1144 } | 888 } |
1145 DCHECK(loaded_); | 889 DCHECK(loaded_); |
1146 | 890 |
1147 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 891 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); |
1148 | 892 |
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()); | 893 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); |
1156 | 894 |
1157 syncer::SyncChangeList new_changes; | 895 syncer::SyncChangeList new_changes; |
1158 syncer::SyncError error; | 896 syncer::SyncError error; |
1159 for (syncer::SyncChangeList::const_iterator iter = change_list.begin(); | 897 for (syncer::SyncChangeList::const_iterator iter = change_list.begin(); |
1160 iter != change_list.end(); ++iter) { | 898 iter != change_list.end(); ++iter) { |
1161 DCHECK_EQ(syncer::SEARCH_ENGINES, iter->sync_data().GetDataType()); | 899 DCHECK_EQ(syncer::SEARCH_ENGINES, iter->sync_data().GetDataType()); |
1162 | 900 |
1163 std::string guid = | 901 std::string guid = |
1164 iter->sync_data().GetSpecifics().search_engine().sync_guid(); | 902 iter->sync_data().GetSpecifics().search_engine().sync_guid(); |
(...skipping 11 matching lines...) Expand all Loading... |
1176 TemplateURL* existing_keyword_turl = | 914 TemplateURL* existing_keyword_turl = |
1177 FindNonExtensionTemplateURLForKeyword(turl->keyword()); | 915 FindNonExtensionTemplateURLForKeyword(turl->keyword()); |
1178 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { | 916 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { |
1179 if (!existing_turl) { | 917 if (!existing_turl) { |
1180 error = sync_error_factory_->CreateAndUploadError( | 918 error = sync_error_factory_->CreateAndUploadError( |
1181 FROM_HERE, | 919 FROM_HERE, |
1182 "ProcessSyncChanges failed on ChangeType ACTION_DELETE"); | 920 "ProcessSyncChanges failed on ChangeType ACTION_DELETE"); |
1183 continue; | 921 continue; |
1184 } | 922 } |
1185 if (existing_turl == GetDefaultSearchProvider()) { | 923 if (existing_turl == GetDefaultSearchProvider()) { |
1186 // The only way Sync can attempt to delete the default search provider | 924 // TODO(erikwright): This could happen if the user changes the default |
1187 // is if we had changed the kSyncedDefaultSearchProviderGUID | 925 // and then deletes the former default. If we receive the keyword sync |
1188 // preference, but perhaps it has not yet been received. To avoid | 926 // before the pref sync we end up here. For now we will just fail to |
1189 // situations where this has come in erroneously, we will un-delete | 927 // delete the local record. The user can always correct it later if they |
1190 // the current default search from the Sync data. If the pref really | 928 // so choose. |
1191 // does arrive later, then default search will change to the correct | |
1192 // entry, but we'll have this extra entry sitting around. The result is | |
1193 // 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 | |
1195 // the extra entry again later, if they choose. Most users who do not | |
1196 // 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 | |
1198 // an attempt to avoid a ping-poinging situation where receiving clients | |
1199 // may try to continually delete the resurrected entry. | |
1200 base::string16 updated_keyword = UniquifyKeyword(*existing_turl, true); | |
1201 TemplateURLData data(existing_turl->data()); | |
1202 data.SetKeyword(updated_keyword); | |
1203 TemplateURL new_turl(existing_turl->profile(), data); | |
1204 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); | |
1205 if (UpdateNoNotify(existing_turl, new_turl, search_terms_data)) | |
1206 NotifyObservers(); | |
1207 | |
1208 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(new_turl); | |
1209 new_changes.push_back(syncer::SyncChange(FROM_HERE, | |
1210 syncer::SyncChange::ACTION_ADD, | |
1211 sync_data)); | |
1212 // Ignore the delete attempt. This means we never end up reseting the | |
1213 // default search provider due to an ACTION_DELETE from sync. | |
1214 continue; | 929 continue; |
1215 } | 930 } |
1216 | 931 |
1217 Remove(existing_turl); | 932 Remove(existing_turl); |
1218 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { | 933 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { |
1219 if (existing_turl) { | 934 if (existing_turl) { |
1220 error = sync_error_factory_->CreateAndUploadError( | 935 error = sync_error_factory_->CreateAndUploadError( |
1221 FROM_HERE, | 936 FROM_HERE, |
1222 "ProcessSyncChanges failed on ChangeType ACTION_ADD"); | 937 "ProcessSyncChanges failed on ChangeType ACTION_ADD"); |
1223 continue; | 938 continue; |
1224 } | 939 } |
1225 const std::string guid = turl->sync_guid(); | 940 const std::string guid = turl->sync_guid(); |
1226 if (existing_keyword_turl) { | 941 if (existing_keyword_turl) { |
1227 // Resolve any conflicts so we can safely add the new entry. | 942 // Resolve any conflicts so we can safely add the new entry. |
1228 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, | 943 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, |
1229 &new_changes); | 944 &new_changes); |
1230 } | 945 } |
1231 // Force the local ID to kInvalidTemplateURLID so we can add it. | 946 // Force the local ID to kInvalidTemplateURLID so we can add it. |
1232 TemplateURLData data(turl->data()); | 947 TemplateURLData data(turl->data()); |
1233 data.id = kInvalidTemplateURLID; | 948 data.id = kInvalidTemplateURLID; |
1234 Add(new TemplateURL(profile_, data)); | 949 Add(new TemplateURL(profile_, data)); |
1235 | |
1236 // Possibly set the newly added |turl| as the default search provider. | |
1237 SetDefaultSearchProviderIfNewlySynced(guid); | |
1238 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) { | 950 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) { |
1239 if (!existing_turl) { | 951 if (!existing_turl) { |
1240 error = sync_error_factory_->CreateAndUploadError( | 952 error = sync_error_factory_->CreateAndUploadError( |
1241 FROM_HERE, | 953 FROM_HERE, |
1242 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE"); | 954 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE"); |
1243 continue; | 955 continue; |
1244 } | 956 } |
1245 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) { | 957 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) { |
1246 // Resolve any conflicts with other entries so we can safely update the | 958 // Resolve any conflicts with other entries so we can safely update the |
1247 // keyword. | 959 // keyword. |
1248 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, | 960 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, |
1249 &new_changes); | 961 &new_changes); |
1250 } | 962 } |
1251 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); | 963 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); |
1252 if (UpdateNoNotify(existing_turl, *turl, search_terms_data)) | 964 if (UpdateNoNotify(existing_turl, turl->data(), search_terms_data)) |
1253 NotifyObservers(); | 965 NotifyObservers(); |
1254 } else { | 966 } else { |
1255 // We've unexpectedly received an ACTION_INVALID. | 967 // We've unexpectedly received an ACTION_INVALID. |
1256 error = sync_error_factory_->CreateAndUploadError( | 968 error = sync_error_factory_->CreateAndUploadError( |
1257 FROM_HERE, | 969 FROM_HERE, |
1258 "ProcessSyncChanges received an ACTION_INVALID"); | 970 "ProcessSyncChanges received an ACTION_INVALID"); |
1259 } | 971 } |
1260 } | 972 } |
1261 | 973 |
1262 // If something went wrong, we want to prematurely exit to avoid pushing | 974 // If something went wrong, we want to prematurely exit to avoid pushing |
(...skipping 13 matching lines...) Expand all Loading... |
1276 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { | 988 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { |
1277 DCHECK(loaded_); | 989 DCHECK(loaded_); |
1278 DCHECK_EQ(type, syncer::SEARCH_ENGINES); | 990 DCHECK_EQ(type, syncer::SEARCH_ENGINES); |
1279 DCHECK(!sync_processor_.get()); | 991 DCHECK(!sync_processor_.get()); |
1280 DCHECK(sync_processor.get()); | 992 DCHECK(sync_processor.get()); |
1281 DCHECK(sync_error_factory.get()); | 993 DCHECK(sync_error_factory.get()); |
1282 syncer::SyncMergeResult merge_result(type); | 994 syncer::SyncMergeResult merge_result(type); |
1283 sync_processor_ = sync_processor.Pass(); | 995 sync_processor_ = sync_processor.Pass(); |
1284 sync_error_factory_ = sync_error_factory.Pass(); | 996 sync_error_factory_ = sync_error_factory.Pass(); |
1285 | 997 |
1286 // We just started syncing, so set our wait-for-default flag if we are | |
1287 // expecting a default from Sync. | |
1288 if (GetPrefs()) { | |
1289 std::string default_guid = GetPrefs()->GetString( | |
1290 prefs::kSyncedDefaultSearchProviderGUID); | |
1291 const TemplateURL* current_default = GetDefaultSearchProvider(); | |
1292 | |
1293 if (!default_guid.empty() && | |
1294 (!current_default || current_default->sync_guid() != default_guid)) | |
1295 pending_synced_default_search_ = true; | |
1296 } | |
1297 | |
1298 // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we | 998 // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we |
1299 // don't step on our own toes. | 999 // don't step on our own toes. |
1300 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 1000 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); |
1301 | 1001 |
1302 // We've started syncing, so set our origin member to the base Sync value. | |
1303 // As we move through Sync Code, we may set this to increasingly specific | |
1304 // origins so we can tell what exactly caused a DSP change. | |
1305 base::AutoReset<DefaultSearchChangeOrigin> change_origin(&dsp_change_origin_, | |
1306 DSP_CHANGE_SYNC_UNINTENTIONAL); | |
1307 | |
1308 syncer::SyncChangeList new_changes; | 1002 syncer::SyncChangeList new_changes; |
1309 | 1003 |
1310 // Build maps of our sync GUIDs to syncer::SyncData. | 1004 // Build maps of our sync GUIDs to syncer::SyncData. |
1311 SyncDataMap local_data_map = CreateGUIDToSyncDataMap( | 1005 SyncDataMap local_data_map = CreateGUIDToSyncDataMap( |
1312 GetAllSyncData(syncer::SEARCH_ENGINES)); | 1006 GetAllSyncData(syncer::SEARCH_ENGINES)); |
1313 SyncDataMap sync_data_map = CreateGUIDToSyncDataMap(initial_sync_data); | 1007 SyncDataMap sync_data_map = CreateGUIDToSyncDataMap(initial_sync_data); |
1314 | 1008 |
1315 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); | 1009 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); |
1316 | 1010 |
1317 merge_result.set_num_items_before_association(local_data_map.size()); | 1011 merge_result.set_num_items_before_association(local_data_map.size()); |
(...skipping 25 matching lines...) Expand all Loading... |
1343 // This local search engine is already synced. If the timestamp differs | 1037 // This local search engine is already synced. If the timestamp differs |
1344 // from Sync, we need to update locally or to the cloud. Note that if the | 1038 // from Sync, we need to update locally or to the cloud. Note that if the |
1345 // timestamps are equal, we touch neither. | 1039 // timestamps are equal, we touch neither. |
1346 if (sync_turl->last_modified() > local_turl->last_modified()) { | 1040 if (sync_turl->last_modified() > local_turl->last_modified()) { |
1347 // We've received an update from Sync. We should replace all synced | 1041 // We've received an update from Sync. We should replace all synced |
1348 // fields in the local TemplateURL. Note that this includes the | 1042 // fields in the local TemplateURL. Note that this includes the |
1349 // TemplateURLID and the TemplateURL may have to be reparsed. This | 1043 // TemplateURLID and the TemplateURL may have to be reparsed. This |
1350 // also makes the local data's last_modified timestamp equal to Sync's, | 1044 // also makes the local data's last_modified timestamp equal to Sync's, |
1351 // avoiding an Update on the next MergeData call. | 1045 // avoiding an Update on the next MergeData call. |
1352 UIThreadSearchTermsData search_terms_data(local_turl->profile()); | 1046 UIThreadSearchTermsData search_terms_data(local_turl->profile()); |
1353 if (UpdateNoNotify(local_turl, *sync_turl, search_terms_data)) | 1047 if (UpdateNoNotify(local_turl, sync_turl->data(), search_terms_data)) |
1354 NotifyObservers(); | 1048 NotifyObservers(); |
1355 merge_result.set_num_items_modified( | 1049 merge_result.set_num_items_modified( |
1356 merge_result.num_items_modified() + 1); | 1050 merge_result.num_items_modified() + 1); |
1357 } else if (sync_turl->last_modified() < local_turl->last_modified()) { | 1051 } else if (sync_turl->last_modified() < local_turl->last_modified()) { |
1358 // Otherwise, we know we have newer data, so update Sync with our | 1052 // Otherwise, we know we have newer data, so update Sync with our |
1359 // data fields. | 1053 // data fields. |
1360 new_changes.push_back( | 1054 new_changes.push_back( |
1361 syncer::SyncChange(FROM_HERE, | 1055 syncer::SyncChange(FROM_HERE, |
1362 syncer::SyncChange::ACTION_UPDATE, | 1056 syncer::SyncChange::ACTION_UPDATE, |
1363 local_data_map[local_turl->sync_guid()])); | 1057 local_data_map[local_turl->sync_guid()])); |
1364 } | 1058 } |
1365 local_data_map.erase(iter->first); | 1059 local_data_map.erase(iter->first); |
1366 } else { | 1060 } else { |
1367 // The search engine from the cloud has not been synced locally. Merge it | 1061 // The search engine from the cloud has not been synced locally. Merge it |
1368 // into our local model. This will handle any conflicts with local (and | 1062 // into our local model. This will handle any conflicts with local (and |
1369 // already-synced) TemplateURLs. It will prefer to keep entries from Sync | 1063 // already-synced) TemplateURLs. It will prefer to keep entries from Sync |
1370 // over not-yet-synced TemplateURLs. | 1064 // over not-yet-synced TemplateURLs. |
1371 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes, | 1065 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes, |
1372 &local_data_map, &merge_result); | 1066 &local_data_map, &merge_result); |
1373 } | 1067 } |
1374 } | 1068 } |
1375 | 1069 |
1376 // If there is a pending synced default search provider that was processed | |
1377 // above, set it now. | |
1378 TemplateURL* pending_default = GetPendingSyncedDefaultSearchProvider(); | |
1379 if (pending_default) { | |
1380 base::AutoReset<DefaultSearchChangeOrigin> change_origin( | |
1381 &dsp_change_origin_, DSP_CHANGE_SYNC_ADD); | |
1382 SetUserSelectedDefaultSearchProvider(pending_default); | |
1383 } | |
1384 | |
1385 // The remaining SyncData in local_data_map should be everything that needs to | 1070 // The remaining SyncData in local_data_map should be everything that needs to |
1386 // be pushed as ADDs to sync. | 1071 // be pushed as ADDs to sync. |
1387 for (SyncDataMap::const_iterator iter = local_data_map.begin(); | 1072 for (SyncDataMap::const_iterator iter = local_data_map.begin(); |
1388 iter != local_data_map.end(); ++iter) { | 1073 iter != local_data_map.end(); ++iter) { |
1389 new_changes.push_back( | 1074 new_changes.push_back( |
1390 syncer::SyncChange(FROM_HERE, | 1075 syncer::SyncChange(FROM_HERE, |
1391 syncer::SyncChange::ACTION_ADD, | 1076 syncer::SyncChange::ACTION_ADD, |
1392 iter->second)); | 1077 iter->second)); |
1393 } | 1078 } |
1394 | 1079 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1619 if (profile_) { | 1304 if (profile_) { |
1620 // TODO(sky): bug 1166191. The keywords should be moved into the history | 1305 // TODO(sky): bug 1166191. The keywords should be moved into the history |
1621 // db, which will mean we no longer need this notification and the history | 1306 // db, which will mean we no longer need this notification and the history |
1622 // backend can handle automatically adding the search terms as the user | 1307 // backend can handle automatically adding the search terms as the user |
1623 // navigates. | 1308 // navigates. |
1624 content::Source<Profile> profile_source(profile_->GetOriginalProfile()); | 1309 content::Source<Profile> profile_source(profile_->GetOriginalProfile()); |
1625 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, | 1310 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, |
1626 profile_source); | 1311 profile_source); |
1627 notification_registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED, | 1312 notification_registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED, |
1628 profile_source); | 1313 profile_source); |
1629 pref_change_registrar_.Init(GetPrefs()); | |
1630 pref_change_registrar_.Add( | |
1631 prefs::kSyncedDefaultSearchProviderGUID, | |
1632 base::Bind( | |
1633 &TemplateURLService::OnSyncedDefaultSearchProviderGUIDChanged, | |
1634 base::Unretained(this))); | |
1635 } | 1314 } |
1636 notification_registrar_.Add( | 1315 |
1637 this, chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED, | 1316 DefaultSearchManager::Source source = DefaultSearchManager::FROM_USER; |
1638 content::NotificationService::AllSources()); | 1317 TemplateURLData* dse = |
| 1318 default_search_manager_.GetDefaultSearchEngine(&source); |
| 1319 OnDefaultSearchChange(dse, source); |
1639 | 1320 |
1640 if (num_initializers > 0) { | 1321 if (num_initializers > 0) { |
1641 // This path is only hit by test code and is used to simulate a loaded | 1322 // This path is only hit by test code and is used to simulate a loaded |
1642 // TemplateURLService. | 1323 // TemplateURLService. |
1643 ChangeToLoadedState(); | 1324 ChangeToLoadedState(); |
1644 | 1325 |
1645 // Add specific initializers, if any. | 1326 // Add specific initializers, if any. |
1646 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); | 1327 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); |
1647 for (int i(0); i < num_initializers; ++i) { | 1328 for (int i(0); i < num_initializers; ++i) { |
1648 DCHECK(initializers[i].keyword); | 1329 DCHECK(initializers[i].keyword); |
1649 DCHECK(initializers[i].url); | 1330 DCHECK(initializers[i].url); |
1650 DCHECK(initializers[i].content); | 1331 DCHECK(initializers[i].content); |
1651 | 1332 |
1652 // TemplateURLService ends up owning the TemplateURL, don't try and free | 1333 // TemplateURLService ends up owning the TemplateURL, don't try and free |
1653 // it. | 1334 // it. |
1654 TemplateURLData data; | 1335 TemplateURLData data; |
1655 data.short_name = base::UTF8ToUTF16(initializers[i].content); | 1336 data.short_name = base::UTF8ToUTF16(initializers[i].content); |
1656 data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword)); | 1337 data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword)); |
1657 data.SetURL(initializers[i].url); | 1338 data.SetURL(initializers[i].url); |
1658 TemplateURL* template_url = new TemplateURL(profile_, data); | 1339 TemplateURL* template_url = new TemplateURL(profile_, data); |
1659 AddNoNotify(template_url, true); | 1340 AddNoNotify(template_url, true); |
1660 | 1341 |
1661 // Set the first provided identifier to be the default. | 1342 // Set the first provided identifier to be the default. |
1662 if (i == 0) | 1343 if (i == 0) |
1663 SetDefaultSearchProviderNoNotify(template_url); | 1344 default_search_manager_.SetUserSelectedDefaultSearchEngine(data); |
1664 } | 1345 } |
1665 } | 1346 } |
1666 | 1347 |
1667 // Initialize default search. | |
1668 UpdateDefaultSearch(); | |
1669 | |
1670 // Request a server check for the correct Google URL if Google is the | 1348 // Request a server check for the correct Google URL if Google is the |
1671 // default search engine and not in headless mode. | 1349 // default search engine and not in headless mode. |
1672 if (profile_ && initial_default_search_provider_.get() && | 1350 TemplateURL* default_search_provider = GetDefaultSearchProvider(); |
1673 initial_default_search_provider_->url_ref().HasGoogleBaseURLs()) { | 1351 if (profile_ && default_search_provider && |
| 1352 default_search_provider->url_ref().HasGoogleBaseURLs()) { |
1674 scoped_ptr<base::Environment> env(base::Environment::Create()); | 1353 scoped_ptr<base::Environment> env(base::Environment::Create()); |
1675 if (!env->HasVar(env_vars::kHeadless)) | 1354 if (!env->HasVar(env_vars::kHeadless)) |
1676 GoogleURLTracker::RequestServerCheck(profile_, false); | 1355 GoogleURLTracker::RequestServerCheck(profile_, false); |
1677 } | 1356 } |
1678 } | 1357 } |
1679 | 1358 |
1680 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) { | 1359 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) { |
1681 const base::string16& keyword = template_url->keyword(); | 1360 const base::string16& keyword = template_url->keyword(); |
1682 DCHECK_NE(0U, keyword_to_template_map_.count(keyword)); | 1361 DCHECK_NE(0U, keyword_to_template_map_.count(keyword)); |
1683 if (keyword_to_template_map_[keyword] == template_url) { | 1362 if (keyword_to_template_map_[keyword] == template_url) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1776 // (possibly deleted) entry. | 1455 // (possibly deleted) entry. |
1777 urls->clear(); | 1456 urls->clear(); |
1778 } | 1457 } |
1779 | 1458 |
1780 void TemplateURLService::ChangeToLoadedState() { | 1459 void TemplateURLService::ChangeToLoadedState() { |
1781 DCHECK(!loaded_); | 1460 DCHECK(!loaded_); |
1782 | 1461 |
1783 UIThreadSearchTermsData search_terms_data(profile_); | 1462 UIThreadSearchTermsData search_terms_data(profile_); |
1784 provider_map_->Init(template_urls_, search_terms_data); | 1463 provider_map_->Init(template_urls_, search_terms_data); |
1785 loaded_ = true; | 1464 loaded_ = true; |
1786 } | |
1787 | 1465 |
1788 void TemplateURLService::ClearDefaultProviderFromPrefs() { | 1466 // This will cause a call to NotifyObservers(). |
1789 // We overwrite user preferences. If the default search engine is managed, | 1467 OnDefaultSearchChange(initial_default_search_provider_ |
1790 // there is no effect. | 1468 ? &initial_default_search_provider_->data() : NULL, |
1791 SaveDefaultSearchProviderToPrefs(NULL, GetPrefs()); | 1469 default_search_provider_source_); |
1792 // Default value for kDefaultSearchProviderEnabled is true. | 1470 initial_default_search_provider_.reset(); |
1793 PrefService* prefs = GetPrefs(); | |
1794 if (prefs) | |
1795 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, true); | |
1796 } | 1471 } |
1797 | 1472 |
1798 bool TemplateURLService::CanReplaceKeywordForHost( | 1473 bool TemplateURLService::CanReplaceKeywordForHost( |
1799 const std::string& host, | 1474 const std::string& host, |
1800 TemplateURL** to_replace) { | 1475 TemplateURL** to_replace) { |
1801 DCHECK(!to_replace || !*to_replace); | 1476 DCHECK(!to_replace || !*to_replace); |
1802 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host); | 1477 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host); |
1803 if (!urls) | 1478 if (!urls) |
1804 return true; | 1479 return true; |
1805 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) { | 1480 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) { |
(...skipping 22 matching lines...) Expand all Loading... |
1828 i != template_urls_.end(); ++i) { | 1503 i != template_urls_.end(); ++i) { |
1829 if (((*i)->GetType() == TemplateURL::NORMAL) && | 1504 if (((*i)->GetType() == TemplateURL::NORMAL) && |
1830 ((*i)->keyword() == keyword)) | 1505 ((*i)->keyword() == keyword)) |
1831 return *i; | 1506 return *i; |
1832 } | 1507 } |
1833 return NULL; | 1508 return NULL; |
1834 } | 1509 } |
1835 | 1510 |
1836 bool TemplateURLService::UpdateNoNotify( | 1511 bool TemplateURLService::UpdateNoNotify( |
1837 TemplateURL* existing_turl, | 1512 TemplateURL* existing_turl, |
1838 const TemplateURL& new_values, | 1513 const TemplateURLData& new_values, |
1839 const SearchTermsData& old_search_terms_data) { | 1514 const SearchTermsData& old_search_terms_data) { |
1840 DCHECK(loaded_); | 1515 DCHECK(loaded_); |
1841 DCHECK(existing_turl); | 1516 DCHECK(existing_turl); |
1842 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == | 1517 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == |
1843 template_urls_.end()) | 1518 template_urls_.end()) |
1844 return false; | 1519 return false; |
1845 | 1520 |
1846 base::string16 old_keyword(existing_turl->keyword()); | 1521 base::string16 old_keyword(existing_turl->keyword()); |
1847 keyword_to_template_map_.erase(old_keyword); | 1522 keyword_to_template_map_.erase(old_keyword); |
1848 if (!existing_turl->sync_guid().empty()) | 1523 if (!existing_turl->sync_guid().empty()) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1886 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl; | 1561 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl; |
1887 | 1562 |
1888 if (service_.get()) | 1563 if (service_.get()) |
1889 service_->UpdateKeyword(existing_turl->data()); | 1564 service_->UpdateKeyword(existing_turl->data()); |
1890 | 1565 |
1891 // Inform sync of the update. | 1566 // Inform sync of the update. |
1892 ProcessTemplateURLChange(FROM_HERE, | 1567 ProcessTemplateURLChange(FROM_HERE, |
1893 existing_turl, | 1568 existing_turl, |
1894 syncer::SyncChange::ACTION_UPDATE); | 1569 syncer::SyncChange::ACTION_UPDATE); |
1895 | 1570 |
1896 if (default_search_provider_ == existing_turl) { | 1571 if (default_search_provider_ == existing_turl && |
1897 bool success = SetDefaultSearchProviderNoNotify(existing_turl); | 1572 default_search_provider_source_ == DefaultSearchManager::FROM_USER) { |
1898 DCHECK(success); | 1573 default_search_manager_.SetUserSelectedDefaultSearchEngine( |
| 1574 default_search_provider_->data()); |
1899 } | 1575 } |
1900 return true; | 1576 return true; |
1901 } | 1577 } |
1902 | 1578 |
1903 // static | 1579 // static |
1904 void TemplateURLService::UpdateTemplateURLIfPrepopulated( | 1580 void TemplateURLService::UpdateTemplateURLIfPrepopulated( |
1905 TemplateURL* template_url, | 1581 TemplateURL* template_url, |
1906 Profile* profile) { | 1582 Profile* profile) { |
1907 int prepopulate_id = template_url->prepopulate_id(); | 1583 int prepopulate_id = template_url->prepopulate_id(); |
1908 if (template_url->prepopulate_id() == 0) | 1584 if (template_url->prepopulate_id() == 0) |
1909 return; | 1585 return; |
1910 | 1586 |
1911 size_t default_search_index; | 1587 size_t default_search_index; |
1912 ScopedVector<TemplateURLData> prepopulated_urls = | 1588 ScopedVector<TemplateURLData> prepopulated_urls = |
1913 TemplateURLPrepopulateData::GetPrepopulatedEngines( | 1589 TemplateURLPrepopulateData::GetPrepopulatedEngines( |
1914 profile ? profile->GetPrefs() : NULL, &default_search_index); | 1590 profile ? profile->GetPrefs() : NULL, &default_search_index); |
1915 | 1591 |
1916 for (size_t i = 0; i < prepopulated_urls.size(); ++i) { | 1592 for (size_t i = 0; i < prepopulated_urls.size(); ++i) { |
1917 if (prepopulated_urls[i]->prepopulate_id == prepopulate_id) { | 1593 if (prepopulated_urls[i]->prepopulate_id == prepopulate_id) { |
1918 MergeIntoPrepopulatedEngineData(template_url, prepopulated_urls[i]); | 1594 MergeIntoPrepopulatedEngineData(template_url, prepopulated_urls[i]); |
1919 template_url->CopyFrom(TemplateURL(profile, *prepopulated_urls[i])); | 1595 template_url->CopyFrom(*prepopulated_urls[i]); |
1920 } | 1596 } |
1921 } | 1597 } |
1922 } | 1598 } |
1923 | 1599 |
1924 PrefService* TemplateURLService::GetPrefs() { | 1600 PrefService* TemplateURLService::GetPrefs() { |
1925 return profile_ ? profile_->GetPrefs() : NULL; | 1601 return profile_ ? profile_->GetPrefs() : NULL; |
1926 } | 1602 } |
1927 | 1603 |
1928 void TemplateURLService::UpdateKeywordSearchTermsForURL( | 1604 void TemplateURLService::UpdateKeywordSearchTermsForURL( |
1929 const history::URLVisitedDetails& details) { | 1605 const history::URLVisitedDetails& details) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2004 // |provider_map_| will not be updated correctly. | 1680 // |provider_map_| will not be updated correctly. |
2005 if (CanReplace(existing_entry->second)) | 1681 if (CanReplace(existing_entry->second)) |
2006 RemoveNoNotify(existing_entry->second); | 1682 RemoveNoNotify(existing_entry->second); |
2007 else | 1683 else |
2008 updated_turl.data_.SetKeyword(t_url->keyword()); | 1684 updated_turl.data_.SetKeyword(t_url->keyword()); |
2009 } | 1685 } |
2010 something_changed = true; | 1686 something_changed = true; |
2011 // This will send the keyword change to sync. Note that other clients | 1687 // This will send the keyword change to sync. Note that other clients |
2012 // need to reset the keyword to an appropriate local value when this | 1688 // need to reset the keyword to an appropriate local value when this |
2013 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData(). | 1689 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData(). |
2014 UpdateNoNotify(t_url, updated_turl, | 1690 UpdateNoNotify(t_url, updated_turl.data(), |
2015 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec())); | 1691 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec())); |
2016 } | 1692 } |
2017 } | 1693 } |
2018 if (something_changed) | 1694 if (something_changed) |
2019 NotifyObservers(); | 1695 NotifyObservers(); |
2020 } | 1696 } |
2021 | 1697 |
2022 void TemplateURLService::UpdateDefaultSearch() { | 1698 void TemplateURLService::OnDefaultSearchChange( |
| 1699 const TemplateURLData* data, |
| 1700 DefaultSearchManager::Source source) { |
2023 if (!loaded_) { | 1701 if (!loaded_) { |
2024 // Set |initial_default_search_provider_| from the preferences. We use this | 1702 // Set |initial_default_search_provider_| from the preferences. This is |
2025 // value for default search provider until the database has been loaded. | 1703 // mainly so we can hold ownership until we get to the point where the list |
2026 scoped_ptr<TemplateURLData> data; | 1704 // of keywords from Web Data is the owner of everything including the |
2027 if (!LoadDefaultSearchProviderFromPrefs( | 1705 // default. |
2028 GetPrefs(), &data, &is_default_search_managed_)) { | 1706 initial_default_search_provider_.reset( |
2029 // Prefs does not specify, so rely on the prepopulated engines. This | 1707 data ? new TemplateURL(profile_, *data) : NULL); |
2030 // should happen only the first time Chrome is started. | 1708 default_search_provider_source_ = source; |
2031 data = | 1709 return; |
2032 TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs()); | 1710 } |
2033 is_default_search_managed_ = false; | 1711 |
| 1712 // Prevent recursion if we update the value stored in default_search_manager_. |
| 1713 // Note that we exclude if data == NULL because that could cause a false |
| 1714 // positive for recursion when the initial_default_search_provider_ is NULL |
| 1715 // due to policy. No recursion case could lead to recursion with NULL. |
| 1716 if (source == default_search_provider_source_ && data != NULL && |
| 1717 TemplateURLMatchesData(default_search_provider_, data)) |
| 1718 return; |
| 1719 |
| 1720 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); |
| 1721 if (default_search_provider_source_ == DefaultSearchManager::FROM_POLICY || |
| 1722 source == DefaultSearchManager::FROM_POLICY) { |
| 1723 // We do this both to clear up removed policy-defined DSE as well as to add |
| 1724 // the new one, if appropriate. |
| 1725 UpdateProvidersCreatedByPolicy( |
| 1726 &template_urls_, |
| 1727 source == DefaultSearchManager::FROM_POLICY ? data : NULL); |
| 1728 } |
| 1729 |
| 1730 if (!data) { |
| 1731 default_search_provider_ = NULL; |
| 1732 default_search_provider_source_ = source; |
| 1733 NotifyObservers(); |
| 1734 return; |
| 1735 } |
| 1736 |
| 1737 if (source == DefaultSearchManager::FROM_EXTENSION) { |
| 1738 default_search_provider_ = FindMatchingExtensionTemplateURL( |
| 1739 *data, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION); |
| 1740 } |
| 1741 |
| 1742 if (source == DefaultSearchManager::FROM_FALLBACK) { |
| 1743 default_search_provider_ = |
| 1744 FindPrepopulatedTemplateURL(data->prepopulate_id); |
| 1745 if (default_search_provider_) { |
| 1746 TemplateURLData update_data(*data); |
| 1747 update_data.sync_guid = default_search_provider_->sync_guid(); |
| 1748 if (!default_search_provider_->safe_for_autoreplace()) { |
| 1749 update_data.safe_for_autoreplace = false; |
| 1750 update_data.SetKeyword(default_search_provider_->keyword()); |
| 1751 update_data.short_name = default_search_provider_->short_name(); |
| 1752 } |
| 1753 UIThreadSearchTermsData search_terms_data( |
| 1754 default_search_provider_->profile()); |
| 1755 UpdateNoNotify(default_search_provider_, update_data, search_terms_data); |
| 1756 } else { |
| 1757 // Normally the prepopulated fallback should be present in |
| 1758 // |template_urls_|, but in a few cases it might not be: |
| 1759 // (1) Tests that initialize the TemplateURLService in peculiar ways. |
| 1760 // (2) If the user deleted the pre-populated default and we subsequently |
| 1761 // lost their user-selected value. |
| 1762 TemplateURL* new_dse = new TemplateURL(profile_, *data); |
| 1763 if (AddNoNotify(new_dse, true)) |
| 1764 default_search_provider_ = new_dse; |
| 1765 else |
| 1766 delete new_dse; |
| 1767 } |
| 1768 } |
| 1769 if (source == DefaultSearchManager::FROM_USER) { |
| 1770 default_search_provider_ = GetTemplateURLForGUID(data->sync_guid); |
| 1771 if (!default_search_provider_ && data->prepopulate_id) { |
| 1772 default_search_provider_ = |
| 1773 FindPrepopulatedTemplateURL(data->prepopulate_id); |
| 1774 } |
| 1775 if (default_search_provider_) { |
| 1776 TemplateURLData new_data(*data); |
| 1777 new_data.show_in_default_list = true; |
| 1778 UIThreadSearchTermsData search_terms_data( |
| 1779 default_search_provider_->profile()); |
| 1780 UpdateNoNotify(default_search_provider_, new_data, search_terms_data); |
| 1781 } else { |
| 1782 TemplateURL* new_dse = new TemplateURL(profile_, *data); |
| 1783 new_dse->data_.show_in_default_list = true; |
| 1784 new_dse->data_.id = kInvalidTemplateURLID; |
| 1785 if (!AddNoNotify(new_dse, true)) |
| 1786 delete new_dse; |
| 1787 else |
| 1788 default_search_provider_ = new_dse; |
| 1789 } |
| 1790 if (default_search_provider_ && GetPrefs()) { |
| 1791 GetPrefs()->SetString( |
| 1792 prefs::kSyncedDefaultSearchProviderGUID, |
| 1793 default_search_provider_->sync_guid()); |
2034 } | 1794 } |
2035 | 1795 |
2036 initial_default_search_provider_.reset( | 1796 } |
2037 data ? new TemplateURL(profile_, *data) : NULL); | |
2038 | 1797 |
2039 return; | 1798 default_search_provider_source_ = source; |
| 1799 |
| 1800 if (default_search_provider_ && |
| 1801 default_search_provider_->url_ref().HasGoogleBaseURLs()) { |
| 1802 if (profile_) |
| 1803 GoogleURLTracker::RequestServerCheck(profile_, false); |
| 1804 #if defined(ENABLE_RLZ) |
| 1805 // TODO(erikwright): should this only be if user-selected? |
| 1806 RLZTracker::RecordProductEvent( |
| 1807 rlz_lib::CHROME, RLZTracker::CHROME_OMNIBOX, rlz_lib::SET_TO_GOOGLE); |
| 1808 #endif |
2040 } | 1809 } |
2041 // Load the default search specified in prefs. | |
2042 scoped_ptr<TemplateURLData> new_default_from_prefs; | |
2043 bool new_is_default_managed = false; | |
2044 // Load the default from prefs. It's possible that it won't succeed | |
2045 // because we are in the middle of doing SaveDefaultSearchProviderToPrefs() | |
2046 // and all the preference items have not been saved. In that case, we | |
2047 // don't have yet a default. It would be much better if we could save | |
2048 // preferences in batches and trigger notifications at the end. | |
2049 LoadDefaultSearchProviderFromPrefs( | |
2050 GetPrefs(), &new_default_from_prefs, &new_is_default_managed); | |
2051 if (!is_default_search_managed_ && !new_is_default_managed) { | |
2052 // We're not interested in cases where the default was and remains | |
2053 // unmanaged. In that case, preferences have no impact on the default. | |
2054 return; | |
2055 } | |
2056 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); | |
2057 if (is_default_search_managed_ && new_is_default_managed) { | |
2058 // The default was managed and remains managed. Update the default only | |
2059 // if it has changed; we don't want to respond to changes triggered by | |
2060 // SaveDefaultSearchProviderToPrefs. | |
2061 if (TemplateURLMatchesData(default_search_provider_, | |
2062 new_default_from_prefs.get())) | |
2063 return; | |
2064 if (!new_default_from_prefs) { | |
2065 // default_search_provider_ can't be NULL otherwise | |
2066 // TemplateURLMatchesData would have returned true. Remove this now | |
2067 // invalid value. | |
2068 TemplateURL* old_default = default_search_provider_; | |
2069 bool success = SetDefaultSearchProviderNoNotify(NULL); | |
2070 DCHECK(success); | |
2071 RemoveNoNotify(old_default); | |
2072 } else if (default_search_provider_) { | |
2073 new_default_from_prefs->created_by_policy = true; | |
2074 TemplateURL new_values(profile_, *new_default_from_prefs); | |
2075 UIThreadSearchTermsData search_terms_data( | |
2076 default_search_provider_->profile()); | |
2077 UpdateNoNotify(default_search_provider_, new_values, search_terms_data); | |
2078 } else { | |
2079 TemplateURL* new_template = NULL; | |
2080 if (new_default_from_prefs) { | |
2081 new_default_from_prefs->created_by_policy = true; | |
2082 new_template = new TemplateURL(profile_, *new_default_from_prefs); | |
2083 if (!AddNoNotify(new_template, true)) | |
2084 return; | |
2085 } | |
2086 bool success = SetDefaultSearchProviderNoNotify(new_template); | |
2087 DCHECK(success); | |
2088 } | |
2089 } else if (!is_default_search_managed_ && new_is_default_managed) { | |
2090 // The default used to be unmanaged and is now managed. Add the new | |
2091 // managed default to the list of URLs and set it as default. | |
2092 is_default_search_managed_ = new_is_default_managed; | |
2093 TemplateURL* new_template = NULL; | |
2094 if (new_default_from_prefs) { | |
2095 new_default_from_prefs->created_by_policy = true; | |
2096 new_template = new TemplateURL(profile_, *new_default_from_prefs); | |
2097 if (!AddNoNotify(new_template, true)) | |
2098 return; | |
2099 } | |
2100 bool success = SetDefaultSearchProviderNoNotify(new_template); | |
2101 DCHECK(success); | |
2102 } else { | |
2103 // The default was managed and is no longer. | |
2104 DCHECK(is_default_search_managed_ && !new_is_default_managed); | |
2105 is_default_search_managed_ = new_is_default_managed; | |
2106 // If we had a default, delete the previous default if created by policy | |
2107 // and set a likely default. | |
2108 if ((default_search_provider_ != NULL) && | |
2109 default_search_provider_->created_by_policy()) { | |
2110 TemplateURL* old_default = default_search_provider_; | |
2111 default_search_provider_ = NULL; | |
2112 RemoveNoNotify(old_default); | |
2113 } | |
2114 | 1810 |
2115 // The likely default should be from Sync if we were waiting on Sync. | |
2116 // Otherwise, it should be FindNewDefaultSearchProvider. | |
2117 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider(); | |
2118 if (synced_default) { | |
2119 pending_synced_default_search_ = false; | |
2120 | |
2121 base::AutoReset<DefaultSearchChangeOrigin> change_origin( | |
2122 &dsp_change_origin_, DSP_CHANGE_SYNC_NOT_MANAGED); | |
2123 SetDefaultSearchProviderNoNotify(synced_default); | |
2124 } else { | |
2125 SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider()); | |
2126 } | |
2127 } | |
2128 NotifyObservers(); | 1811 NotifyObservers(); |
2129 } | 1812 } |
2130 | 1813 |
2131 void TemplateURLService::SetDefaultSearchProvider( | |
2132 TemplateURL* url) { | |
2133 DCHECK(!is_default_search_managed_); | |
2134 // Omnibox keywords cannot be made default. Extension-controlled search | |
2135 // engines can be made default only by the extension itself because they | |
2136 // aren't persisted. | |
2137 DCHECK(!url || (url->GetType() == TemplateURL::NORMAL)); | |
2138 | |
2139 // Always persist the setting in the database, that way if the backup | |
2140 // signature has changed out from under us it gets reset correctly. | |
2141 if (SetDefaultSearchProviderNoNotify(url)) | |
2142 NotifyObservers(); | |
2143 } | |
2144 | |
2145 bool TemplateURLService::SetDefaultSearchProviderNoNotify(TemplateURL* url) { | |
2146 if (url) { | |
2147 if (std::find(template_urls_.begin(), template_urls_.end(), url) == | |
2148 template_urls_.end()) | |
2149 return false; | |
2150 // Omnibox keywords cannot be made default. | |
2151 DCHECK_NE(TemplateURL::OMNIBOX_API_EXTENSION, url->GetType()); | |
2152 } | |
2153 | |
2154 // Only bother reassigning |url| if it has changed. Notice that we don't just | |
2155 // early exit if they are equal, because |url| may have had its fields | |
2156 // changed, and needs to be persisted below (for example, when this is called | |
2157 // from UpdateNoNotify). | |
2158 if (default_search_provider_ != url) { | |
2159 // Engines set by policy override extension-controlled engines, which | |
2160 // override other engines. | |
2161 DCHECK(!is_default_search_managed() || !url || | |
2162 (url->GetType() == TemplateURL::NORMAL)); | |
2163 if (is_default_search_managed() || !default_search_provider_ || | |
2164 (default_search_provider_->GetType() == TemplateURL::NORMAL) || | |
2165 (url && | |
2166 (url->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION))){ | |
2167 UMA_HISTOGRAM_ENUMERATION("Search.DefaultSearchChangeOrigin", | |
2168 dsp_change_origin_, DSP_CHANGE_MAX); | |
2169 default_search_provider_ = url; | |
2170 } | |
2171 } | |
2172 | |
2173 if (url) { | |
2174 // Don't mark the url as edited, otherwise we won't be able to rev the | |
2175 // template urls we ship with. | |
2176 url->data_.show_in_default_list = true; | |
2177 if (service_.get() && (url->GetType() == TemplateURL::NORMAL)) | |
2178 service_->UpdateKeyword(url->data()); | |
2179 | |
2180 if (url->url_ref().HasGoogleBaseURLs()) { | |
2181 GoogleURLTracker::RequestServerCheck(profile_, false); | |
2182 #if defined(ENABLE_RLZ) | |
2183 RLZTracker::RecordProductEvent(rlz_lib::CHROME, | |
2184 RLZTracker::CHROME_OMNIBOX, | |
2185 rlz_lib::SET_TO_GOOGLE); | |
2186 #endif | |
2187 } | |
2188 } | |
2189 | |
2190 // Extension-controlled search engines shouldn't be persisted anywhere. | |
2191 if (url && (url->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) | |
2192 return true; | |
2193 | |
2194 if (!is_default_search_managed_) { | |
2195 SaveDefaultSearchProviderToPrefs(url, GetPrefs()); | |
2196 | |
2197 // If we are syncing, we want to set the synced pref that will notify other | |
2198 // instances to change their default to this new search provider. | |
2199 // Note: we don't update the pref if we're currently in the middle of | |
2200 // handling a sync operation. Sync operations from other clients are not | |
2201 // guaranteed to arrive together, and any client that deletes the default | |
2202 // needs to set a new default as well. If we update the default here, we're | |
2203 // likely to race with the update from the other client, resulting in | |
2204 // a possibly random default search provider. | |
2205 if (sync_processor_.get() && url && !url->sync_guid().empty() && | |
2206 GetPrefs() && !processing_syncer_changes_) { | |
2207 GetPrefs()->SetString(prefs::kSyncedDefaultSearchProviderGUID, | |
2208 url->sync_guid()); | |
2209 } | |
2210 } | |
2211 | |
2212 if (service_.get()) | |
2213 service_->SetDefaultSearchProviderID(url ? url->id() : 0); | |
2214 | |
2215 // Inform sync the change to the show_in_default_list flag. | |
2216 if (url) | |
2217 ProcessTemplateURLChange(FROM_HERE, | |
2218 url, | |
2219 syncer::SyncChange::ACTION_UPDATE); | |
2220 return true; | |
2221 } | |
2222 | |
2223 bool TemplateURLService::AddNoNotify(TemplateURL* template_url, | 1814 bool TemplateURLService::AddNoNotify(TemplateURL* template_url, |
2224 bool newly_adding) { | 1815 bool newly_adding) { |
2225 DCHECK(template_url); | 1816 DCHECK(template_url); |
2226 | 1817 |
2227 if (newly_adding) { | 1818 if (newly_adding) { |
2228 DCHECK_EQ(kInvalidTemplateURLID, template_url->id()); | 1819 DCHECK_EQ(kInvalidTemplateURLID, template_url->id()); |
2229 DCHECK(std::find(template_urls_.begin(), template_urls_.end(), | 1820 DCHECK(std::find(template_urls_.begin(), template_urls_.end(), |
2230 template_url) == template_urls_.end()); | 1821 template_url) == template_urls_.end()); |
2231 template_url->data_.id = ++next_id_; | 1822 template_url->data_.id = ++next_id_; |
2232 } | 1823 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2315 | 1906 |
2316 void TemplateURLService::NotifyObservers() { | 1907 void TemplateURLService::NotifyObservers() { |
2317 if (!loaded_) | 1908 if (!loaded_) |
2318 return; | 1909 return; |
2319 | 1910 |
2320 FOR_EACH_OBSERVER(TemplateURLServiceObserver, model_observers_, | 1911 FOR_EACH_OBSERVER(TemplateURLServiceObserver, model_observers_, |
2321 OnTemplateURLServiceChanged()); | 1912 OnTemplateURLServiceChanged()); |
2322 } | 1913 } |
2323 | 1914 |
2324 // |template_urls| are the TemplateURLs loaded from the database. | 1915 // |template_urls| are the TemplateURLs loaded from the database. |
2325 // |default_search_provider| points to one of them, if it was set in the db. | 1916 // |default_from_prefs| is the default search provider from the preferences, or |
2326 // |default_from_prefs| is the default search provider from the preferences. | 1917 // NULL if the DSE is not policy-defined. |
2327 // Check |is_default_search_managed_| to determine if it was set by policy. | |
2328 // | 1918 // |
2329 // This function removes from the vector and the database all the TemplateURLs | 1919 // This function removes from the vector and the database all the TemplateURLs |
2330 // that were set by policy, unless it is the current default search provider | 1920 // that were set by policy, unless it is the current default search provider, in |
2331 // and matches what is set by a managed preference. | 1921 // which case it is updated with the data from prefs. |
2332 void TemplateURLService::RemoveProvidersCreatedByPolicy( | 1922 void TemplateURLService::UpdateProvidersCreatedByPolicy( |
2333 TemplateURLVector* template_urls, | 1923 TemplateURLVector* template_urls, |
2334 TemplateURL** default_search_provider, | 1924 const TemplateURLData* default_from_prefs) { |
2335 TemplateURLData* default_from_prefs) { | |
2336 DCHECK(template_urls); | 1925 DCHECK(template_urls); |
2337 DCHECK(default_search_provider); | 1926 |
2338 for (TemplateURLVector::iterator i = template_urls->begin(); | 1927 for (TemplateURLVector::iterator i = template_urls->begin(); |
2339 i != template_urls->end(); ) { | 1928 i != template_urls->end(); ) { |
2340 TemplateURL* template_url = *i; | 1929 TemplateURL* template_url = *i; |
2341 if (template_url->created_by_policy()) { | 1930 if (template_url->created_by_policy()) { |
2342 if (template_url == *default_search_provider && | 1931 if (default_from_prefs && |
2343 is_default_search_managed_ && | |
2344 TemplateURLMatchesData(template_url, default_from_prefs)) { | 1932 TemplateURLMatchesData(template_url, default_from_prefs)) { |
2345 // If the database specified a default search provider that was set | 1933 // If the database specified a default search provider that was set |
2346 // by policy, and the default search provider from the preferences | 1934 // by policy, and the default search provider from the preferences |
2347 // is also set by policy and they are the same, keep the entry in the | 1935 // is also set by policy and they are the same, keep the entry in the |
2348 // database and the |default_search_provider|. | 1936 // database and the |default_search_provider|. |
| 1937 default_search_provider_ = template_url; |
| 1938 // Prevent us from saving any other entries, or creating a new one. |
| 1939 default_from_prefs = NULL; |
2349 ++i; | 1940 ++i; |
2350 continue; | 1941 continue; |
2351 } | 1942 } |
2352 | 1943 |
2353 // The database loaded a managed |default_search_provider|, but it has | 1944 RemoveFromMaps(template_url); |
2354 // been updated in the prefs. Remove it from the database, and update the | |
2355 // |default_search_provider| pointer here. | |
2356 if (*default_search_provider && | |
2357 (*default_search_provider)->id() == template_url->id()) | |
2358 *default_search_provider = NULL; | |
2359 | |
2360 i = template_urls->erase(i); | 1945 i = template_urls->erase(i); |
2361 if (service_.get()) | 1946 if (service_.get()) |
2362 service_->RemoveKeyword(template_url->id()); | 1947 service_->RemoveKeyword(template_url->id()); |
2363 delete template_url; | 1948 delete template_url; |
2364 } else { | 1949 } else { |
2365 ++i; | 1950 ++i; |
2366 } | 1951 } |
2367 } | 1952 } |
| 1953 |
| 1954 if (default_from_prefs) { |
| 1955 default_search_provider_ = NULL; |
| 1956 default_search_provider_source_ = DefaultSearchManager::FROM_POLICY; |
| 1957 TemplateURLData new_data(*default_from_prefs); |
| 1958 new_data.created_by_policy = true; |
| 1959 TemplateURL* new_dse = new TemplateURL(profile_, new_data); |
| 1960 if (!AddNoNotify(new_dse, true)) |
| 1961 delete new_dse; |
| 1962 else |
| 1963 default_search_provider_ = new_dse; |
| 1964 } |
2368 } | 1965 } |
2369 | 1966 |
2370 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url, | 1967 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url, |
2371 const std::string& guid) { | 1968 const std::string& guid) { |
2372 DCHECK(loaded_); | 1969 DCHECK(loaded_); |
2373 DCHECK(!guid.empty()); | 1970 DCHECK(!guid.empty()); |
2374 | 1971 |
2375 TemplateURLData data(url->data()); | 1972 TemplateURLData data(url->data()); |
2376 data.sync_guid = guid; | 1973 data.sync_guid = guid; |
2377 TemplateURL new_url(url->profile(), data); | |
2378 UIThreadSearchTermsData search_terms_data(url->profile()); | 1974 UIThreadSearchTermsData search_terms_data(url->profile()); |
2379 UpdateNoNotify(url, new_url, search_terms_data); | 1975 UpdateNoNotify(url, data, search_terms_data); |
2380 } | 1976 } |
2381 | 1977 |
2382 base::string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl, | 1978 base::string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl, |
2383 bool force) { | 1979 bool force) { |
2384 if (!force) { | 1980 if (!force) { |
2385 // Already unique. | 1981 // Already unique. |
2386 if (!GetTemplateURLForKeyword(turl.keyword())) | 1982 if (!GetTemplateURLForKeyword(turl.keyword())) |
2387 return turl.keyword(); | 1983 return turl.keyword(); |
2388 | 1984 |
2389 // First, try to return the generated keyword for the TemplateURL (except | 1985 // First, try to return the generated keyword for the TemplateURL (except |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2440 base::string16 new_keyword = UniquifyKeyword(*loser, false); | 2036 base::string16 new_keyword = UniquifyKeyword(*loser, false); |
2441 DCHECK(!GetTemplateURLForKeyword(new_keyword)); | 2037 DCHECK(!GetTemplateURLForKeyword(new_keyword)); |
2442 if (applied_turl_is_better) { | 2038 if (applied_turl_is_better) { |
2443 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible | 2039 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible |
2444 // for adding or updating unapplied_sync_turl in the local model. | 2040 // for adding or updating unapplied_sync_turl in the local model. |
2445 unapplied_sync_turl->data_.SetKeyword(new_keyword); | 2041 unapplied_sync_turl->data_.SetKeyword(new_keyword); |
2446 } else { | 2042 } else { |
2447 // Update |applied_sync_turl| in the local model with the new keyword. | 2043 // Update |applied_sync_turl| in the local model with the new keyword. |
2448 TemplateURLData data(applied_sync_turl->data()); | 2044 TemplateURLData data(applied_sync_turl->data()); |
2449 data.SetKeyword(new_keyword); | 2045 data.SetKeyword(new_keyword); |
2450 TemplateURL new_turl(applied_sync_turl->profile(), data); | |
2451 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile()); | 2046 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile()); |
2452 if (UpdateNoNotify(applied_sync_turl, new_turl, search_terms_data)) | 2047 if (UpdateNoNotify(applied_sync_turl, data, search_terms_data)) |
2453 NotifyObservers(); | 2048 NotifyObservers(); |
2454 } | 2049 } |
2455 // The losing TemplateURL should have their keyword updated. Send a change to | 2050 // The losing TemplateURL should have their keyword updated. Send a change to |
2456 // the server to reflect this change. | 2051 // the server to reflect this change. |
2457 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser); | 2052 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser); |
2458 change_list->push_back(syncer::SyncChange(FROM_HERE, | 2053 change_list->push_back(syncer::SyncChange(FROM_HERE, |
2459 syncer::SyncChange::ACTION_UPDATE, | 2054 syncer::SyncChange::ACTION_UPDATE, |
2460 sync_data)); | 2055 sync_data)); |
2461 } | 2056 } |
2462 | 2057 |
(...skipping 28 matching lines...) Expand all Loading... |
2491 // |conflicting_turl| is not yet known to Sync. If it is better, then we | 2086 // |conflicting_turl| is not yet known to Sync. If it is better, then we |
2492 // want to transfer its values up to sync. Otherwise, we remove it and | 2087 // want to transfer its values up to sync. Otherwise, we remove it and |
2493 // allow the entry from Sync to overtake it in the model. | 2088 // allow the entry from Sync to overtake it in the model. |
2494 const std::string guid = conflicting_turl->sync_guid(); | 2089 const std::string guid = conflicting_turl->sync_guid(); |
2495 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) { | 2090 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) { |
2496 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid()); | 2091 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid()); |
2497 syncer::SyncData sync_data = | 2092 syncer::SyncData sync_data = |
2498 CreateSyncDataFromTemplateURL(*conflicting_turl); | 2093 CreateSyncDataFromTemplateURL(*conflicting_turl); |
2499 change_list->push_back(syncer::SyncChange( | 2094 change_list->push_back(syncer::SyncChange( |
2500 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data)); | 2095 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data)); |
2501 if (conflicting_turl == GetDefaultSearchProvider() && | |
2502 !pending_synced_default_search_) { | |
2503 // If we're not waiting for the Synced default to come in, we should | |
2504 // override the pref with our new GUID. If we are waiting for the | |
2505 // arrival of a synced default, setting the pref here would cause us | |
2506 // to lose the GUID we are waiting on. | |
2507 PrefService* prefs = GetPrefs(); | |
2508 if (prefs) { | |
2509 prefs->SetString(prefs::kSyncedDefaultSearchProviderGUID, | |
2510 conflicting_turl->sync_guid()); | |
2511 } | |
2512 } | |
2513 // Note that in this case we do not add the Sync TemplateURL to the | 2096 // Note that in this case we do not add the Sync TemplateURL to the |
2514 // local model, since we've effectively "merged" it in by updating the | 2097 // local model, since we've effectively "merged" it in by updating the |
2515 // local conflicting entry with its sync_guid. | 2098 // local conflicting entry with its sync_guid. |
2516 should_add_sync_turl = false; | 2099 should_add_sync_turl = false; |
2517 merge_result->set_num_items_modified( | 2100 merge_result->set_num_items_modified( |
2518 merge_result->num_items_modified() + 1); | 2101 merge_result->num_items_modified() + 1); |
2519 } else { | 2102 } else { |
2520 // We guarantee that this isn't the local search provider. Otherwise, | 2103 // We guarantee that this isn't the local search provider. Otherwise, |
2521 // local would have won. | 2104 // local would have won. |
2522 DCHECK(conflicting_turl != GetDefaultSearchProvider()); | 2105 DCHECK(conflicting_turl != GetDefaultSearchProvider()); |
(...skipping 10 matching lines...) Expand all Loading... |
2533 if (should_add_sync_turl) { | 2116 if (should_add_sync_turl) { |
2534 // Force the local ID to kInvalidTemplateURLID so we can add it. | 2117 // Force the local ID to kInvalidTemplateURLID so we can add it. |
2535 TemplateURLData data(sync_turl->data()); | 2118 TemplateURLData data(sync_turl->data()); |
2536 data.id = kInvalidTemplateURLID; | 2119 data.id = kInvalidTemplateURLID; |
2537 Add(new TemplateURL(profile_, data)); | 2120 Add(new TemplateURL(profile_, data)); |
2538 merge_result->set_num_items_added( | 2121 merge_result->set_num_items_added( |
2539 merge_result->num_items_added() + 1); | 2122 merge_result->num_items_added() + 1); |
2540 } | 2123 } |
2541 } | 2124 } |
2542 | 2125 |
2543 void TemplateURLService::SetDefaultSearchProviderIfNewlySynced( | |
2544 const std::string& guid) { | |
2545 // If we're not syncing or if default search is managed by policy, ignore. | |
2546 if (!sync_processor_.get() || is_default_search_managed_) | |
2547 return; | |
2548 | |
2549 PrefService* prefs = GetPrefs(); | |
2550 if (prefs && pending_synced_default_search_ && | |
2551 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID) == guid) { | |
2552 // Make sure this actually exists. We should not be calling this unless we | |
2553 // really just added this TemplateURL. | |
2554 TemplateURL* turl_from_sync = GetTemplateURLForGUID(guid); | |
2555 if (turl_from_sync && turl_from_sync->SupportsReplacement()) { | |
2556 base::AutoReset<DefaultSearchChangeOrigin> change_origin( | |
2557 &dsp_change_origin_, DSP_CHANGE_SYNC_ADD); | |
2558 SetDefaultSearchProvider(turl_from_sync); | |
2559 } | |
2560 pending_synced_default_search_ = false; | |
2561 } | |
2562 } | |
2563 | |
2564 TemplateURL* TemplateURLService::GetPendingSyncedDefaultSearchProvider() { | |
2565 PrefService* prefs = GetPrefs(); | |
2566 if (!prefs || !pending_synced_default_search_) | |
2567 return NULL; | |
2568 | |
2569 // Could be NULL if no such thing exists. | |
2570 return GetTemplateURLForGUID( | |
2571 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID)); | |
2572 } | |
2573 | |
2574 void TemplateURLService::PatchMissingSyncGUIDs( | 2126 void TemplateURLService::PatchMissingSyncGUIDs( |
2575 TemplateURLVector* template_urls) { | 2127 TemplateURLVector* template_urls) { |
2576 DCHECK(template_urls); | 2128 DCHECK(template_urls); |
2577 for (TemplateURLVector::iterator i = template_urls->begin(); | 2129 for (TemplateURLVector::iterator i = template_urls->begin(); |
2578 i != template_urls->end(); ++i) { | 2130 i != template_urls->end(); ++i) { |
2579 TemplateURL* template_url = *i; | 2131 TemplateURL* template_url = *i; |
2580 DCHECK(template_url); | 2132 DCHECK(template_url); |
2581 if (template_url->sync_guid().empty() && | 2133 if (template_url->sync_guid().empty() && |
2582 (template_url->GetType() != | 2134 (template_url->GetType() != |
2583 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) { | 2135 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) { |
2584 template_url->data_.sync_guid = base::GenerateGUID(); | 2136 template_url->data_.sync_guid = base::GenerateGUID(); |
2585 if (service_.get()) | 2137 if (service_.get()) |
2586 service_->UpdateKeyword(template_url->data()); | 2138 service_->UpdateKeyword(template_url->data()); |
2587 } | 2139 } |
2588 } | 2140 } |
2589 } | 2141 } |
2590 | 2142 |
2591 void TemplateURLService::AddTemplateURLsAndSetupDefaultEngine( | 2143 TemplateURL* TemplateURLService::FindPrepopulatedTemplateURL( |
2592 TemplateURLVector* template_urls, | 2144 int prepopulated_id) { |
2593 TemplateURL* default_search_provider) { | 2145 for (TemplateURLVector::const_iterator i = template_urls_.begin(); |
2594 DCHECK(template_urls); | 2146 i != template_urls_.end(); ++i) { |
2595 is_default_search_managed_ = false; | 2147 if ((*i)->prepopulate_id() == prepopulated_id) |
2596 bool database_specified_a_default = (default_search_provider != NULL); | 2148 return *i; |
| 2149 } |
2597 | 2150 |
2598 // Check if default search provider is now managed. | 2151 return NULL; |
2599 scoped_ptr<TemplateURLData> default_from_prefs; | |
2600 LoadDefaultSearchProviderFromPrefs( | |
2601 GetPrefs(), &default_from_prefs, &is_default_search_managed_); | |
2602 | |
2603 // Remove entries that were created because of policy as they may have | |
2604 // changed since the database was saved. | |
2605 RemoveProvidersCreatedByPolicy(template_urls, | |
2606 &default_search_provider, | |
2607 default_from_prefs.get()); | |
2608 | |
2609 PatchMissingSyncGUIDs(template_urls); | |
2610 | |
2611 if (is_default_search_managed_) { | |
2612 SetTemplateURLs(template_urls); | |
2613 | |
2614 if (TemplateURLMatchesData(default_search_provider, | |
2615 default_from_prefs.get())) { | |
2616 // The value from the preferences was previously stored in the database. | |
2617 // Reuse it. | |
2618 } else { | |
2619 // The value from the preferences takes over. | |
2620 default_search_provider = NULL; | |
2621 if (default_from_prefs) { | |
2622 default_from_prefs->created_by_policy = true; | |
2623 default_from_prefs->id = kInvalidTemplateURLID; | |
2624 default_search_provider = | |
2625 new TemplateURL(profile_, *default_from_prefs); | |
2626 if (!AddNoNotify(default_search_provider, true)) | |
2627 default_search_provider = NULL; | |
2628 } | |
2629 } | |
2630 // Note that this saves the default search provider to prefs. | |
2631 if (!default_search_provider || | |
2632 ((default_search_provider->GetType() != | |
2633 TemplateURL::OMNIBOX_API_EXTENSION) && | |
2634 default_search_provider->SupportsReplacement())) { | |
2635 bool success = SetDefaultSearchProviderNoNotify(default_search_provider); | |
2636 DCHECK(success); | |
2637 } | |
2638 } else { | |
2639 // If we had a managed default, replace it with the synced default if | |
2640 // applicable, or the first provider of the list. | |
2641 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider(); | |
2642 if (synced_default) { | |
2643 default_search_provider = synced_default; | |
2644 pending_synced_default_search_ = false; | |
2645 } else if (database_specified_a_default && | |
2646 default_search_provider == NULL) { | |
2647 UMA_HISTOGRAM_ENUMERATION(kFirstPotentialEngineHistogramName, | |
2648 FIRST_POTENTIAL_CALLSITE_ON_LOAD, | |
2649 FIRST_POTENTIAL_CALLSITE_MAX); | |
2650 default_search_provider = FirstPotentialDefaultEngine(*template_urls); | |
2651 } | |
2652 | |
2653 // If the default search provider existed previously, then just | |
2654 // set the member variable. Otherwise, we'll set it using the method | |
2655 // to ensure that it is saved properly after its id is set. | |
2656 if (default_search_provider && | |
2657 (default_search_provider->id() != kInvalidTemplateURLID)) { | |
2658 default_search_provider_ = default_search_provider; | |
2659 default_search_provider = NULL; | |
2660 } | |
2661 SetTemplateURLs(template_urls); | |
2662 | |
2663 if (default_search_provider) { | |
2664 base::AutoReset<DefaultSearchChangeOrigin> change_origin( | |
2665 &dsp_change_origin_, default_from_prefs ? | |
2666 dsp_change_origin_ : DSP_CHANGE_NEW_ENGINE_NO_PREFS); | |
2667 // Note that this saves the default search provider to prefs. | |
2668 SetDefaultSearchProvider(default_search_provider); | |
2669 } else { | |
2670 // Always save the default search provider to prefs. That way we don't | |
2671 // have to worry about it being out of sync. | |
2672 if (default_search_provider_) | |
2673 SaveDefaultSearchProviderToPrefs(default_search_provider_, GetPrefs()); | |
2674 } | |
2675 } | |
2676 } | |
2677 | |
2678 void TemplateURLService::EnsureDefaultSearchProviderExists() { | |
2679 if (!is_default_search_managed()) { | |
2680 bool has_default_search_provider = default_search_provider_ && | |
2681 default_search_provider_->SupportsReplacement(); | |
2682 UMA_HISTOGRAM_BOOLEAN("Search.HasDefaultSearchProvider", | |
2683 has_default_search_provider); | |
2684 // Ensure that default search provider exists. See http://crbug.com/116952. | |
2685 if (!has_default_search_provider) { | |
2686 bool success = | |
2687 SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider()); | |
2688 DCHECK(success); | |
2689 } | |
2690 // Don't log anything if the user has a NULL default search provider. | |
2691 if (default_search_provider_) { | |
2692 UMA_HISTOGRAM_ENUMERATION("Search.DefaultSearchProviderType", | |
2693 TemplateURLPrepopulateData::GetEngineType(*default_search_provider_), | |
2694 SEARCH_ENGINE_MAX); | |
2695 } | |
2696 } | |
2697 } | 2152 } |
2698 | 2153 |
2699 TemplateURL* TemplateURLService::CreateTemplateURLForExtension( | 2154 TemplateURL* TemplateURLService::CreateTemplateURLForExtension( |
2700 const ExtensionKeyword& extension_keyword) const { | 2155 const ExtensionKeyword& extension_keyword) { |
2701 TemplateURLData data; | 2156 TemplateURLData data; |
2702 data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name); | 2157 data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name); |
2703 data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword)); | 2158 data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword)); |
2704 // This URL is not actually used for navigation. It holds the extension's | 2159 // This URL is not actually used for navigation. It holds the extension's |
2705 // ID, as well as forcing the TemplateURL to be treated as a search keyword. | 2160 // ID, as well as forcing the TemplateURL to be treated as a search keyword. |
2706 data.SetURL(std::string(extensions::kExtensionScheme) + "://" + | 2161 data.SetURL(std::string(extensions::kExtensionScheme) + "://" + |
2707 extension_keyword.extension_id + "/?q={searchTerms}"); | 2162 extension_keyword.extension_id + "/?q={searchTerms}"); |
2708 return new TemplateURL(profile_, data); | 2163 return new TemplateURL(profile_, data); |
2709 } | 2164 } |
2710 | 2165 |
2711 TemplateURL* TemplateURLService::FindTemplateURLForExtension( | 2166 TemplateURL* TemplateURLService::FindTemplateURLForExtension( |
2712 const std::string& extension_id, | 2167 const std::string& extension_id, |
2713 TemplateURL::Type type) const { | 2168 TemplateURL::Type type) { |
2714 DCHECK_NE(TemplateURL::NORMAL, type); | 2169 DCHECK_NE(TemplateURL::NORMAL, type); |
2715 for (TemplateURLVector::const_iterator i = template_urls_.begin(); | 2170 for (TemplateURLVector::const_iterator i = template_urls_.begin(); |
2716 i != template_urls_.end(); ++i) { | 2171 i != template_urls_.end(); ++i) { |
2717 if ((*i)->GetType() == type && | 2172 if ((*i)->GetType() == type && |
2718 (*i)->GetExtensionId() == extension_id) | 2173 (*i)->GetExtensionId() == extension_id) |
2719 return *i; | 2174 return *i; |
2720 } | 2175 } |
2721 | 2176 |
2722 return NULL; | 2177 return NULL; |
2723 } | 2178 } |
2724 | 2179 |
2725 TemplateURL* TemplateURLService::FindExtensionDefaultSearchEngine() const { | 2180 TemplateURL* TemplateURLService::FindMatchingExtensionTemplateURL( |
| 2181 const TemplateURLData& data, |
| 2182 TemplateURL::Type type) { |
| 2183 DCHECK_NE(TemplateURL::NORMAL, type); |
| 2184 for (TemplateURLVector::const_iterator i = template_urls_.begin(); |
| 2185 i != template_urls_.end(); ++i) { |
| 2186 if ((*i)->GetType() == type && TemplateURLMatchesData(*i, &data)) |
| 2187 return *i; |
| 2188 } |
| 2189 |
| 2190 return NULL; |
| 2191 } |
| 2192 |
| 2193 void TemplateURLService::UpdateExtensionDefaultSearchEngine() { |
2726 TemplateURL* most_recently_intalled_default = NULL; | 2194 TemplateURL* most_recently_intalled_default = NULL; |
2727 for (TemplateURLVector::const_iterator i = template_urls_.begin(); | 2195 for (TemplateURLVector::const_iterator i = template_urls_.begin(); |
2728 i != template_urls_.end(); ++i) { | 2196 i != template_urls_.end(); ++i) { |
2729 if (((*i)->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) && | 2197 if (((*i)->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) && |
2730 (*i)->extension_info_->wants_to_be_default_engine && | 2198 (*i)->extension_info_->wants_to_be_default_engine && |
2731 (*i)->SupportsReplacement() && | 2199 (*i)->SupportsReplacement() && |
2732 (!most_recently_intalled_default || | 2200 (!most_recently_intalled_default || |
2733 (most_recently_intalled_default->extension_info_->install_time < | 2201 (most_recently_intalled_default->extension_info_->install_time < |
2734 (*i)->extension_info_->install_time))) | 2202 (*i)->extension_info_->install_time))) |
2735 most_recently_intalled_default = *i; | 2203 most_recently_intalled_default = *i; |
2736 } | 2204 } |
2737 | 2205 |
2738 return most_recently_intalled_default; | 2206 if (most_recently_intalled_default) { |
| 2207 default_search_manager_.SetExtensionControlledDefaultSearchEngine( |
| 2208 most_recently_intalled_default->data()); |
| 2209 } else { |
| 2210 default_search_manager_.ClearExtensionControlledDefaultSearchEngine(); |
| 2211 } |
2739 } | 2212 } |
2740 | |
2741 void TemplateURLService:: | |
2742 SetDefaultSearchProviderAfterRemovingDefaultExtension() { | |
2743 DCHECK(!is_default_search_managed()); | |
2744 TemplateURL* new_dse = FindExtensionDefaultSearchEngine(); | |
2745 if (!new_dse) { | |
2746 scoped_ptr<TemplateURLData> default_provider; | |
2747 bool is_managed; | |
2748 if (LoadDefaultSearchProviderFromPrefs( | |
2749 GetPrefs(), &default_provider, &is_managed) && | |
2750 default_provider) { | |
2751 for (TemplateURLVector::const_iterator i = template_urls_.begin(); | |
2752 i != template_urls_.end(); ++i) { | |
2753 if ((*i)->id() == default_provider->id) { | |
2754 new_dse = *i; | |
2755 break; | |
2756 } | |
2757 } | |
2758 } | |
2759 } | |
2760 if (!new_dse) | |
2761 new_dse = FindNewDefaultSearchProvider(); | |
2762 SetDefaultSearchProviderNoNotify(new_dse); | |
2763 } | |
OLD | NEW |