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

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

Issue 268643002: Use the DefaultSearchManager as the exclusive authority on DSE, ignoring Web Data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Modify SearchProviderInstallData to use TemplateURLService rather than WebData. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/search_engines/template_url_service.h" 5 #include "chrome/browser/search_engines/template_url_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/environment.h" 13 #include "base/environment.h"
14 #include "base/guid.h" 14 #include "base/guid.h"
15 #include "base/i18n/case_conversion.h" 15 #include "base/i18n/case_conversion.h"
16 #include "base/memory/scoped_vector.h" 16 #include "base/memory/scoped_vector.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/prefs/pref_service.h" 18 #include "base/prefs/pref_service.h"
19 #include "base/stl_util.h" 19 #include "base/stl_util.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_split.h" 20 #include "base/strings/string_split.h"
22 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
23 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
24 #include "base/time/time.h" 23 #include "base/time/time.h"
25 #include "chrome/browser/chrome_notification_types.h" 24 #include "chrome/browser/chrome_notification_types.h"
26 #include "chrome/browser/extensions/extension_service.h" 25 #include "chrome/browser/extensions/extension_service.h"
27 #include "chrome/browser/google/google_url_tracker.h" 26 #include "chrome/browser/google/google_url_tracker.h"
28 #include "chrome/browser/history/history_notifications.h" 27 #include "chrome/browser/history/history_notifications.h"
29 #include "chrome/browser/history/history_service.h" 28 #include "chrome/browser/history/history_service.h"
30 #include "chrome/browser/history/history_service_factory.h" 29 #include "chrome/browser/history/history_service_factory.h"
(...skipping 13 matching lines...) Expand all
44 #include "chrome/common/pref_names.h" 43 #include "chrome/common/pref_names.h"
45 #include "chrome/common/url_constants.h" 44 #include "chrome/common/url_constants.h"
46 #include "content/public/browser/notification_service.h" 45 #include "content/public/browser/notification_service.h"
47 #include "extensions/common/constants.h" 46 #include "extensions/common/constants.h"
48 #include "net/base/net_util.h" 47 #include "net/base/net_util.h"
49 #include "sync/api/sync_change.h" 48 #include "sync/api/sync_change.h"
50 #include "sync/api/sync_error_factory.h" 49 #include "sync/api/sync_error_factory.h"
51 #include "sync/protocol/search_engine_specifics.pb.h" 50 #include "sync/protocol/search_engine_specifics.pb.h"
52 #include "sync/protocol/sync.pb.h" 51 #include "sync/protocol/sync.pb.h"
53 #include "ui/base/l10n/l10n_util.h" 52 #include "ui/base/l10n/l10n_util.h"
53 #include "url/gurl.h"
54 54
55 typedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet; 55 typedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet;
56 typedef TemplateURLService::SyncDataMap SyncDataMap; 56 typedef TemplateURLService::SyncDataMap SyncDataMap;
57 57
58 namespace { 58 namespace {
59 59
60 bool 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
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
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
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
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
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
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
917 size_t default_search_provider_index = 0; 686 size_t default_search_provider_index = 0;
918 ScopedVector<TemplateURLData> prepopulated_urls = 687 ScopedVector<TemplateURLData> prepopulated_urls =
919 TemplateURLPrepopulateData::GetPrepopulatedEngines( 688 TemplateURLPrepopulateData::GetPrepopulatedEngines(
920 GetPrefs(), &default_search_provider_index); 689 GetPrefs(), &default_search_provider_index);
921 DCHECK(!prepopulated_urls.empty()); 690 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( 691 ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData(
926 &prepopulated_urls, template_urls_, current_dse)); 692 &prepopulated_urls, template_urls_, default_search_provider_));
927 693
928 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 694 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
929 695
930 // Remove items. 696 // Remove items.
931 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin(); 697 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin();
932 i < actions.removed_engines.end(); ++i) 698 i < actions.removed_engines.end(); ++i)
933 RemoveNoNotify(*i); 699 RemoveNoNotify(*i);
934 700
935 // Edit items. 701 // Edit items.
936 for (EditedEngines::iterator i(actions.edited_engines.begin()); 702 for (EditedEngines::iterator i(actions.edited_engines.begin());
937 i < actions.edited_engines.end(); ++i) { 703 i < actions.edited_engines.end(); ++i) {
938 UIThreadSearchTermsData search_terms_data(profile()); 704 UIThreadSearchTermsData search_terms_data(profile());
939 TemplateURL new_values(profile(), i->second); 705 UpdateNoNotify(i->first, i->second, search_terms_data);
940 UpdateNoNotify(i->first, new_values, search_terms_data);
941 } 706 }
942 707
943 // Add items. 708 // Add items.
944 for (std::vector<TemplateURLData>::const_iterator i = 709 for (std::vector<TemplateURLData>::const_iterator i =
945 actions.added_engines.begin(); 710 actions.added_engines.begin();
946 i < actions.added_engines.end(); 711 i < actions.added_engines.end();
947 ++i) { 712 ++i) {
948 AddNoNotify(new TemplateURL(profile_, *i), true); 713 AddNoNotify(new TemplateURL(profile_, *i), true);
949 } 714 }
950 715
951 // Change the DSE.
952 TemplateURL* new_dse = FindURLByPrepopulateID(template_urls_,
953 default_search_engine_id);
954 DCHECK(new_dse);
955 if (CanMakeDefault(new_dse)) {
956 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
957 &dsp_change_origin_, DSP_CHANGE_PROFILE_RESET);
958 SetDefaultSearchProviderNoNotify(new_dse);
959 }
960 NotifyObservers(); 716 NotifyObservers();
961 } 717 }
962 718
963 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) { 719 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) {
964 model_observers_.AddObserver(observer); 720 model_observers_.AddObserver(observer);
965 } 721 }
966 722
967 void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) { 723 void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) {
968 model_observers_.RemoveObserver(observer); 724 model_observers_.RemoveObserver(observer);
969 } 725 }
(...skipping 25 matching lines...) Expand all
995 void TemplateURLService::OnWebDataServiceRequestDone( 751 void TemplateURLService::OnWebDataServiceRequestDone(
996 WebDataService::Handle h, 752 WebDataService::Handle h,
997 const WDTypedResult* result) { 753 const WDTypedResult* result) {
998 // Reset the load_handle so that we don't try and cancel the load in 754 // Reset the load_handle so that we don't try and cancel the load in
999 // the destructor. 755 // the destructor.
1000 load_handle_ = 0; 756 load_handle_ = 0;
1001 757
1002 if (!result) { 758 if (!result) {
1003 // Results are null if the database went away or (most likely) wasn't 759 // Results are null if the database went away or (most likely) wasn't
1004 // loaded. 760 // loaded.
1005 load_failed_ = true;
1006 ChangeToLoadedState(); 761 ChangeToLoadedState();
1007 on_loaded_callbacks_.Notify(); 762 on_loaded_callbacks_.Notify();
1008 return; 763 return;
1009 } 764 }
1010 765
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; 766 TemplateURLVector template_urls;
1016 TemplateURL* default_search_provider = NULL;
1017 int new_resource_keyword_version = 0; 767 int new_resource_keyword_version = 0;
1018 GetSearchProvidersUsingKeywordResult(*result, service_.get(), profile_, 768 GetSearchProvidersUsingKeywordResult(
1019 &template_urls, &default_search_provider, &new_resource_keyword_version, 769 *result,
770 service_.get(),
771 profile_,
772 &template_urls,
773 (default_search_provider_source_ == DefaultSearchManager::FROM_USER) ?
774 initial_default_search_provider_.get() : NULL,
775 &new_resource_keyword_version,
1020 &pre_sync_deletes_); 776 &pre_sync_deletes_);
1021 777
1022 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 778 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1023 779
1024 AddTemplateURLsAndSetupDefaultEngine(&template_urls, default_search_provider); 780 PatchMissingSyncGUIDs(&template_urls);
781 SetTemplateURLs(&template_urls);
1025 782
1026 // This initializes provider_map_ which should be done before 783 // This initializes provider_map_ which should be done before
1027 // calling UpdateKeywordSearchTermsForURL. 784 // calling UpdateKeywordSearchTermsForURL.
785 // This also calls NotifyObservers.
1028 ChangeToLoadedState(); 786 ChangeToLoadedState();
787 on_loaded_callbacks_.Notify();
1029 788
1030 // Index any visits that occurred before we finished loading. 789 // Index any visits that occurred before we finished loading.
1031 for (size_t i = 0; i < visits_to_add_.size(); ++i) 790 for (size_t i = 0; i < visits_to_add_.size(); ++i)
1032 UpdateKeywordSearchTermsForURL(visits_to_add_[i]); 791 UpdateKeywordSearchTermsForURL(visits_to_add_[i]);
1033 visits_to_add_.clear(); 792 visits_to_add_.clear();
1034 793
1035 if (new_resource_keyword_version) 794 if (new_resource_keyword_version)
1036 service_->SetBuiltinKeywordVersion(new_resource_keyword_version); 795 service_->SetBuiltinKeywordVersion(new_resource_keyword_version);
1037
1038 EnsureDefaultSearchProviderExists();
1039
1040 NotifyObservers();
1041 on_loaded_callbacks_.Notify();
1042 } 796 }
1043 797
1044 base::string16 TemplateURLService::GetKeywordShortName( 798 base::string16 TemplateURLService::GetKeywordShortName(
1045 const base::string16& keyword, 799 const base::string16& keyword,
1046 bool* is_omnibox_api_extension_keyword) { 800 bool* is_omnibox_api_extension_keyword) {
1047 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); 801 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword);
1048 802
1049 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService 803 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService
1050 // to track changes to the model, this should become a DCHECK. 804 // to track changes to the model, this should become a DCHECK.
1051 if (template_url) { 805 if (template_url) {
1052 *is_omnibox_api_extension_keyword = 806 *is_omnibox_api_extension_keyword =
1053 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION; 807 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION;
1054 return template_url->AdjustedShortNameForLocaleDirection(); 808 return template_url->AdjustedShortNameForLocaleDirection();
1055 } 809 }
1056 *is_omnibox_api_extension_keyword = false; 810 *is_omnibox_api_extension_keyword = false;
1057 return base::string16(); 811 return base::string16();
1058 } 812 }
1059 813
1060 void TemplateURLService::Observe(int type, 814 void TemplateURLService::Observe(int type,
1061 const content::NotificationSource& source, 815 const content::NotificationSource& source,
1062 const content::NotificationDetails& details) { 816 const content::NotificationDetails& details) {
1063 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) { 817 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) {
1064 content::Details<history::URLVisitedDetails> visit_details(details); 818 content::Details<history::URLVisitedDetails> visit_details(details);
1065 if (!loaded_) 819 if (!loaded_)
1066 visits_to_add_.push_back(*visit_details.ptr()); 820 visits_to_add_.push_back(*visit_details.ptr());
1067 else 821 else
1068 UpdateKeywordSearchTermsForURL(*visit_details.ptr()); 822 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 { 823 } else {
1076 DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_URL_UPDATED, type); 824 DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_URL_UPDATED, type);
1077 if (loaded_) { 825 if (loaded_) {
1078 GoogleBaseURLChanged( 826 GoogleBaseURLChanged(
1079 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first); 827 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first);
1080 } 828 }
1081 } 829 }
1082 } 830 }
1083 831
1084 void TemplateURLService::Shutdown() { 832 void TemplateURLService::Shutdown() {
1085 // This check has to be done at Shutdown() instead of in the dtor to ensure 833 // 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 834 // that no clients of WebDataService are holding ptrs to it after the first
1087 // phase of the KeyedService Shutdown() process. 835 // phase of the KeyedService Shutdown() process.
1088 if (load_handle_) { 836 if (load_handle_) {
1089 DCHECK(service_.get()); 837 DCHECK(service_.get());
1090 service_->CancelRequest(load_handle_); 838 service_->CancelRequest(load_handle_);
1091 } 839 }
1092 service_ = NULL; 840 service_ = NULL;
1093 } 841 }
1094 842
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( 843 syncer::SyncDataList TemplateURLService::GetAllSyncData(
1117 syncer::ModelType type) const { 844 syncer::ModelType type) const {
1118 DCHECK_EQ(syncer::SEARCH_ENGINES, type); 845 DCHECK_EQ(syncer::SEARCH_ENGINES, type);
1119 846
1120 syncer::SyncDataList current_data; 847 syncer::SyncDataList current_data;
1121 for (TemplateURLVector::const_iterator iter = template_urls_.begin(); 848 for (TemplateURLVector::const_iterator iter = template_urls_.begin();
1122 iter != template_urls_.end(); ++iter) { 849 iter != template_urls_.end(); ++iter) {
1123 // We don't sync keywords managed by policy. 850 // We don't sync keywords managed by policy.
1124 if ((*iter)->created_by_policy()) 851 if ((*iter)->created_by_policy())
1125 continue; 852 continue;
(...skipping 13 matching lines...) Expand all
1139 syncer::SyncError error(FROM_HERE, 866 syncer::SyncError error(FROM_HERE,
1140 syncer::SyncError::DATATYPE_ERROR, 867 syncer::SyncError::DATATYPE_ERROR,
1141 "Models not yet associated.", 868 "Models not yet associated.",
1142 syncer::SEARCH_ENGINES); 869 syncer::SEARCH_ENGINES);
1143 return error; 870 return error;
1144 } 871 }
1145 DCHECK(loaded_); 872 DCHECK(loaded_);
1146 873
1147 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); 874 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
1148 875
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()); 876 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1156 877
1157 syncer::SyncChangeList new_changes; 878 syncer::SyncChangeList new_changes;
1158 syncer::SyncError error; 879 syncer::SyncError error;
1159 for (syncer::SyncChangeList::const_iterator iter = change_list.begin(); 880 for (syncer::SyncChangeList::const_iterator iter = change_list.begin();
1160 iter != change_list.end(); ++iter) { 881 iter != change_list.end(); ++iter) {
1161 DCHECK_EQ(syncer::SEARCH_ENGINES, iter->sync_data().GetDataType()); 882 DCHECK_EQ(syncer::SEARCH_ENGINES, iter->sync_data().GetDataType());
1162 883
1163 std::string guid = 884 std::string guid =
1164 iter->sync_data().GetSpecifics().search_engine().sync_guid(); 885 iter->sync_data().GetSpecifics().search_engine().sync_guid();
(...skipping 11 matching lines...) Expand all
1176 TemplateURL* existing_keyword_turl = 897 TemplateURL* existing_keyword_turl =
1177 FindNonExtensionTemplateURLForKeyword(turl->keyword()); 898 FindNonExtensionTemplateURLForKeyword(turl->keyword());
1178 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { 899 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) {
1179 if (!existing_turl) { 900 if (!existing_turl) {
1180 error = sync_error_factory_->CreateAndUploadError( 901 error = sync_error_factory_->CreateAndUploadError(
1181 FROM_HERE, 902 FROM_HERE,
1182 "ProcessSyncChanges failed on ChangeType ACTION_DELETE"); 903 "ProcessSyncChanges failed on ChangeType ACTION_DELETE");
1183 continue; 904 continue;
1184 } 905 }
1185 if (existing_turl == GetDefaultSearchProvider()) { 906 if (existing_turl == GetDefaultSearchProvider()) {
1186 // The only way Sync can attempt to delete the default search provider 907 // TODO(erikwright): This could happen if the user changes the default
1187 // is if we had changed the kSyncedDefaultSearchProviderGUID 908 // and then deletes the former default. If we receive the keyword sync
1188 // preference, but perhaps it has not yet been received. To avoid 909 // 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 910 // 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 911 // 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; 912 continue;
1215 } 913 }
1216 914
1217 Remove(existing_turl); 915 Remove(existing_turl);
1218 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { 916 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) {
1219 if (existing_turl) { 917 if (existing_turl) {
1220 error = sync_error_factory_->CreateAndUploadError( 918 error = sync_error_factory_->CreateAndUploadError(
1221 FROM_HERE, 919 FROM_HERE,
1222 "ProcessSyncChanges failed on ChangeType ACTION_ADD"); 920 "ProcessSyncChanges failed on ChangeType ACTION_ADD");
1223 continue; 921 continue;
1224 } 922 }
1225 const std::string guid = turl->sync_guid(); 923 const std::string guid = turl->sync_guid();
1226 if (existing_keyword_turl) { 924 if (existing_keyword_turl) {
1227 // Resolve any conflicts so we can safely add the new entry. 925 // Resolve any conflicts so we can safely add the new entry.
1228 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 926 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1229 &new_changes); 927 &new_changes);
1230 } 928 }
1231 // Force the local ID to kInvalidTemplateURLID so we can add it. 929 // Force the local ID to kInvalidTemplateURLID so we can add it.
1232 TemplateURLData data(turl->data()); 930 TemplateURLData data(turl->data());
1233 data.id = kInvalidTemplateURLID; 931 data.id = kInvalidTemplateURLID;
1234 Add(new TemplateURL(profile_, data)); 932 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) { 933 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) {
1239 if (!existing_turl) { 934 if (!existing_turl) {
1240 error = sync_error_factory_->CreateAndUploadError( 935 error = sync_error_factory_->CreateAndUploadError(
1241 FROM_HERE, 936 FROM_HERE,
1242 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE"); 937 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE");
1243 continue; 938 continue;
1244 } 939 }
1245 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) { 940 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) {
1246 // Resolve any conflicts with other entries so we can safely update the 941 // Resolve any conflicts with other entries so we can safely update the
1247 // keyword. 942 // keyword.
1248 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 943 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1249 &new_changes); 944 &new_changes);
1250 } 945 }
1251 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); 946 UIThreadSearchTermsData search_terms_data(existing_turl->profile());
1252 if (UpdateNoNotify(existing_turl, *turl, search_terms_data)) 947 if (UpdateNoNotify(existing_turl, turl->data(), search_terms_data))
1253 NotifyObservers(); 948 NotifyObservers();
1254 } else { 949 } else {
1255 // We've unexpectedly received an ACTION_INVALID. 950 // We've unexpectedly received an ACTION_INVALID.
1256 error = sync_error_factory_->CreateAndUploadError( 951 error = sync_error_factory_->CreateAndUploadError(
1257 FROM_HERE, 952 FROM_HERE,
1258 "ProcessSyncChanges received an ACTION_INVALID"); 953 "ProcessSyncChanges received an ACTION_INVALID");
1259 } 954 }
1260 } 955 }
1261 956
1262 // If something went wrong, we want to prematurely exit to avoid pushing 957 // If something went wrong, we want to prematurely exit to avoid pushing
(...skipping 13 matching lines...) Expand all
1276 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { 971 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) {
1277 DCHECK(loaded_); 972 DCHECK(loaded_);
1278 DCHECK_EQ(type, syncer::SEARCH_ENGINES); 973 DCHECK_EQ(type, syncer::SEARCH_ENGINES);
1279 DCHECK(!sync_processor_.get()); 974 DCHECK(!sync_processor_.get());
1280 DCHECK(sync_processor.get()); 975 DCHECK(sync_processor.get());
1281 DCHECK(sync_error_factory.get()); 976 DCHECK(sync_error_factory.get());
1282 syncer::SyncMergeResult merge_result(type); 977 syncer::SyncMergeResult merge_result(type);
1283 sync_processor_ = sync_processor.Pass(); 978 sync_processor_ = sync_processor.Pass();
1284 sync_error_factory_ = sync_error_factory.Pass(); 979 sync_error_factory_ = sync_error_factory.Pass();
1285 980
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 981 // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we
1299 // don't step on our own toes. 982 // don't step on our own toes.
1300 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); 983 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
1301 984
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; 985 syncer::SyncChangeList new_changes;
1309 986
1310 // Build maps of our sync GUIDs to syncer::SyncData. 987 // Build maps of our sync GUIDs to syncer::SyncData.
1311 SyncDataMap local_data_map = CreateGUIDToSyncDataMap( 988 SyncDataMap local_data_map = CreateGUIDToSyncDataMap(
1312 GetAllSyncData(syncer::SEARCH_ENGINES)); 989 GetAllSyncData(syncer::SEARCH_ENGINES));
1313 SyncDataMap sync_data_map = CreateGUIDToSyncDataMap(initial_sync_data); 990 SyncDataMap sync_data_map = CreateGUIDToSyncDataMap(initial_sync_data);
1314 991
1315 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 992 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1316 993
1317 merge_result.set_num_items_before_association(local_data_map.size()); 994 merge_result.set_num_items_before_association(local_data_map.size());
(...skipping 25 matching lines...) Expand all
1343 // This local search engine is already synced. If the timestamp differs 1020 // 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 1021 // from Sync, we need to update locally or to the cloud. Note that if the
1345 // timestamps are equal, we touch neither. 1022 // timestamps are equal, we touch neither.
1346 if (sync_turl->last_modified() > local_turl->last_modified()) { 1023 if (sync_turl->last_modified() > local_turl->last_modified()) {
1347 // We've received an update from Sync. We should replace all synced 1024 // We've received an update from Sync. We should replace all synced
1348 // fields in the local TemplateURL. Note that this includes the 1025 // fields in the local TemplateURL. Note that this includes the
1349 // TemplateURLID and the TemplateURL may have to be reparsed. This 1026 // TemplateURLID and the TemplateURL may have to be reparsed. This
1350 // also makes the local data's last_modified timestamp equal to Sync's, 1027 // also makes the local data's last_modified timestamp equal to Sync's,
1351 // avoiding an Update on the next MergeData call. 1028 // avoiding an Update on the next MergeData call.
1352 UIThreadSearchTermsData search_terms_data(local_turl->profile()); 1029 UIThreadSearchTermsData search_terms_data(local_turl->profile());
1353 if (UpdateNoNotify(local_turl, *sync_turl, search_terms_data)) 1030 if (UpdateNoNotify(local_turl, sync_turl->data(), search_terms_data))
1354 NotifyObservers(); 1031 NotifyObservers();
1355 merge_result.set_num_items_modified( 1032 merge_result.set_num_items_modified(
1356 merge_result.num_items_modified() + 1); 1033 merge_result.num_items_modified() + 1);
1357 } else if (sync_turl->last_modified() < local_turl->last_modified()) { 1034 } else if (sync_turl->last_modified() < local_turl->last_modified()) {
1358 // Otherwise, we know we have newer data, so update Sync with our 1035 // Otherwise, we know we have newer data, so update Sync with our
1359 // data fields. 1036 // data fields.
1360 new_changes.push_back( 1037 new_changes.push_back(
1361 syncer::SyncChange(FROM_HERE, 1038 syncer::SyncChange(FROM_HERE,
1362 syncer::SyncChange::ACTION_UPDATE, 1039 syncer::SyncChange::ACTION_UPDATE,
1363 local_data_map[local_turl->sync_guid()])); 1040 local_data_map[local_turl->sync_guid()]));
1364 } 1041 }
1365 local_data_map.erase(iter->first); 1042 local_data_map.erase(iter->first);
1366 } else { 1043 } else {
1367 // The search engine from the cloud has not been synced locally. Merge it 1044 // 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 1045 // into our local model. This will handle any conflicts with local (and
1369 // already-synced) TemplateURLs. It will prefer to keep entries from Sync 1046 // already-synced) TemplateURLs. It will prefer to keep entries from Sync
1370 // over not-yet-synced TemplateURLs. 1047 // over not-yet-synced TemplateURLs.
1371 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes, 1048 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes,
1372 &local_data_map, &merge_result); 1049 &local_data_map, &merge_result);
1373 } 1050 }
1374 } 1051 }
1375 1052
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 1053 // The remaining SyncData in local_data_map should be everything that needs to
1386 // be pushed as ADDs to sync. 1054 // be pushed as ADDs to sync.
1387 for (SyncDataMap::const_iterator iter = local_data_map.begin(); 1055 for (SyncDataMap::const_iterator iter = local_data_map.begin();
1388 iter != local_data_map.end(); ++iter) { 1056 iter != local_data_map.end(); ++iter) {
1389 new_changes.push_back( 1057 new_changes.push_back(
1390 syncer::SyncChange(FROM_HERE, 1058 syncer::SyncChange(FROM_HERE,
1391 syncer::SyncChange::ACTION_ADD, 1059 syncer::SyncChange::ACTION_ADD,
1392 iter->second)); 1060 iter->second));
1393 } 1061 }
1394 1062
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1619 if (profile_) { 1287 if (profile_) {
1620 // TODO(sky): bug 1166191. The keywords should be moved into the history 1288 // 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 1289 // 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 1290 // backend can handle automatically adding the search terms as the user
1623 // navigates. 1291 // navigates.
1624 content::Source<Profile> profile_source(profile_->GetOriginalProfile()); 1292 content::Source<Profile> profile_source(profile_->GetOriginalProfile());
1625 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, 1293 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED,
1626 profile_source); 1294 profile_source);
1627 notification_registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED, 1295 notification_registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED,
1628 profile_source); 1296 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 } 1297 }
1636 notification_registrar_.Add( 1298
1637 this, chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED, 1299 DefaultSearchManager::Source source = DefaultSearchManager::FROM_USER;
1638 content::NotificationService::AllSources()); 1300 TemplateURLData* dse =
1301 default_search_manager_.GetDefaultSearchEngine(&source);
1302 OnDefaultSearchChange(dse, source);
1639 1303
1640 if (num_initializers > 0) { 1304 if (num_initializers > 0) {
1641 // This path is only hit by test code and is used to simulate a loaded 1305 // This path is only hit by test code and is used to simulate a loaded
1642 // TemplateURLService. 1306 // TemplateURLService.
1643 ChangeToLoadedState(); 1307 ChangeToLoadedState();
1644 1308
1645 // Add specific initializers, if any. 1309 // Add specific initializers, if any.
1646 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 1310 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1647 for (int i(0); i < num_initializers; ++i) { 1311 for (int i(0); i < num_initializers; ++i) {
1648 DCHECK(initializers[i].keyword); 1312 DCHECK(initializers[i].keyword);
1649 DCHECK(initializers[i].url); 1313 DCHECK(initializers[i].url);
1650 DCHECK(initializers[i].content); 1314 DCHECK(initializers[i].content);
1651 1315
1652 // TemplateURLService ends up owning the TemplateURL, don't try and free 1316 // TemplateURLService ends up owning the TemplateURL, don't try and free
1653 // it. 1317 // it.
1654 TemplateURLData data; 1318 TemplateURLData data;
1655 data.short_name = base::UTF8ToUTF16(initializers[i].content); 1319 data.short_name = base::UTF8ToUTF16(initializers[i].content);
1656 data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword)); 1320 data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword));
1657 data.SetURL(initializers[i].url); 1321 data.SetURL(initializers[i].url);
1658 TemplateURL* template_url = new TemplateURL(profile_, data); 1322 TemplateURL* template_url = new TemplateURL(profile_, data);
1659 AddNoNotify(template_url, true); 1323 AddNoNotify(template_url, true);
1660 1324
1661 // Set the first provided identifier to be the default. 1325 // Set the first provided identifier to be the default.
1662 if (i == 0) 1326 if (i == 0)
1663 SetDefaultSearchProviderNoNotify(template_url); 1327 default_search_manager_.SetUserSelectedDefaultSearchEngine(data);
1664 } 1328 }
1665 } 1329 }
1666 1330
1667 // Initialize default search.
1668 UpdateDefaultSearch();
1669
1670 // Request a server check for the correct Google URL if Google is the 1331 // Request a server check for the correct Google URL if Google is the
1671 // default search engine and not in headless mode. 1332 // default search engine and not in headless mode.
1672 if (profile_ && initial_default_search_provider_.get() && 1333 TemplateURL* default_search_provider = GetDefaultSearchProvider();
1673 initial_default_search_provider_->url_ref().HasGoogleBaseURLs()) { 1334 if (profile_ && default_search_provider &&
1335 default_search_provider->url_ref().HasGoogleBaseURLs()) {
1674 scoped_ptr<base::Environment> env(base::Environment::Create()); 1336 scoped_ptr<base::Environment> env(base::Environment::Create());
1675 if (!env->HasVar(env_vars::kHeadless)) 1337 if (!env->HasVar(env_vars::kHeadless))
1676 GoogleURLTracker::RequestServerCheck(profile_, false); 1338 GoogleURLTracker::RequestServerCheck(profile_, false);
1677 } 1339 }
1678 } 1340 }
1679 1341
1680 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) { 1342 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) {
1681 const base::string16& keyword = template_url->keyword(); 1343 const base::string16& keyword = template_url->keyword();
1682 DCHECK_NE(0U, keyword_to_template_map_.count(keyword)); 1344 DCHECK_NE(0U, keyword_to_template_map_.count(keyword));
1683 if (keyword_to_template_map_[keyword] == template_url) { 1345 if (keyword_to_template_map_[keyword] == template_url) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1776 // (possibly deleted) entry. 1438 // (possibly deleted) entry.
1777 urls->clear(); 1439 urls->clear();
1778 } 1440 }
1779 1441
1780 void TemplateURLService::ChangeToLoadedState() { 1442 void TemplateURLService::ChangeToLoadedState() {
1781 DCHECK(!loaded_); 1443 DCHECK(!loaded_);
1782 1444
1783 UIThreadSearchTermsData search_terms_data(profile_); 1445 UIThreadSearchTermsData search_terms_data(profile_);
1784 provider_map_->Init(template_urls_, search_terms_data); 1446 provider_map_->Init(template_urls_, search_terms_data);
1785 loaded_ = true; 1447 loaded_ = true;
1786 }
1787 1448
1788 void TemplateURLService::ClearDefaultProviderFromPrefs() { 1449 // This will cause a call to NotifyObservers().
1789 // We overwrite user preferences. If the default search engine is managed, 1450 OnDefaultSearchChange(initial_default_search_provider_
1790 // there is no effect. 1451 ? &initial_default_search_provider_->data() : NULL,
1791 SaveDefaultSearchProviderToPrefs(NULL, GetPrefs()); 1452 default_search_provider_source_);
1792 // Default value for kDefaultSearchProviderEnabled is true. 1453 initial_default_search_provider_.reset();
1793 PrefService* prefs = GetPrefs();
1794 if (prefs)
1795 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, true);
1796 } 1454 }
1797 1455
1798 bool TemplateURLService::CanReplaceKeywordForHost( 1456 bool TemplateURLService::CanReplaceKeywordForHost(
1799 const std::string& host, 1457 const std::string& host,
1800 TemplateURL** to_replace) { 1458 TemplateURL** to_replace) {
1801 DCHECK(!to_replace || !*to_replace); 1459 DCHECK(!to_replace || !*to_replace);
1802 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host); 1460 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host);
1803 if (!urls) 1461 if (!urls)
1804 return true; 1462 return true;
1805 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) { 1463 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) {
(...skipping 22 matching lines...) Expand all
1828 i != template_urls_.end(); ++i) { 1486 i != template_urls_.end(); ++i) {
1829 if (((*i)->GetType() == TemplateURL::NORMAL) && 1487 if (((*i)->GetType() == TemplateURL::NORMAL) &&
1830 ((*i)->keyword() == keyword)) 1488 ((*i)->keyword() == keyword))
1831 return *i; 1489 return *i;
1832 } 1490 }
1833 return NULL; 1491 return NULL;
1834 } 1492 }
1835 1493
1836 bool TemplateURLService::UpdateNoNotify( 1494 bool TemplateURLService::UpdateNoNotify(
1837 TemplateURL* existing_turl, 1495 TemplateURL* existing_turl,
1838 const TemplateURL& new_values, 1496 const TemplateURLData& new_values,
1839 const SearchTermsData& old_search_terms_data) { 1497 const SearchTermsData& old_search_terms_data) {
1840 DCHECK(loaded_); 1498 DCHECK(loaded_);
1841 DCHECK(existing_turl); 1499 DCHECK(existing_turl);
1842 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == 1500 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) ==
1843 template_urls_.end()) 1501 template_urls_.end())
1844 return false; 1502 return false;
1845 1503
1846 base::string16 old_keyword(existing_turl->keyword()); 1504 base::string16 old_keyword(existing_turl->keyword());
1847 keyword_to_template_map_.erase(old_keyword); 1505 keyword_to_template_map_.erase(old_keyword);
1848 if (!existing_turl->sync_guid().empty()) 1506 if (!existing_turl->sync_guid().empty())
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl; 1544 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl;
1887 1545
1888 if (service_.get()) 1546 if (service_.get())
1889 service_->UpdateKeyword(existing_turl->data()); 1547 service_->UpdateKeyword(existing_turl->data());
1890 1548
1891 // Inform sync of the update. 1549 // Inform sync of the update.
1892 ProcessTemplateURLChange(FROM_HERE, 1550 ProcessTemplateURLChange(FROM_HERE,
1893 existing_turl, 1551 existing_turl,
1894 syncer::SyncChange::ACTION_UPDATE); 1552 syncer::SyncChange::ACTION_UPDATE);
1895 1553
1896 if (default_search_provider_ == existing_turl) { 1554 if (default_search_provider_ == existing_turl &&
1897 bool success = SetDefaultSearchProviderNoNotify(existing_turl); 1555 default_search_provider_source_ == DefaultSearchManager::FROM_USER) {
1898 DCHECK(success); 1556 default_search_manager_.SetUserSelectedDefaultSearchEngine(
1557 default_search_provider_->data());
1899 } 1558 }
1900 return true; 1559 return true;
1901 } 1560 }
1902 1561
1903 // static 1562 // static
1904 void TemplateURLService::UpdateTemplateURLIfPrepopulated( 1563 void TemplateURLService::UpdateTemplateURLIfPrepopulated(
1905 TemplateURL* template_url, 1564 TemplateURL* template_url,
1906 Profile* profile) { 1565 Profile* profile) {
1907 int prepopulate_id = template_url->prepopulate_id(); 1566 int prepopulate_id = template_url->prepopulate_id();
1908 if (template_url->prepopulate_id() == 0) 1567 if (template_url->prepopulate_id() == 0)
1909 return; 1568 return;
1910 1569
1911 size_t default_search_index; 1570 size_t default_search_index;
1912 ScopedVector<TemplateURLData> prepopulated_urls = 1571 ScopedVector<TemplateURLData> prepopulated_urls =
1913 TemplateURLPrepopulateData::GetPrepopulatedEngines( 1572 TemplateURLPrepopulateData::GetPrepopulatedEngines(
1914 profile ? profile->GetPrefs() : NULL, &default_search_index); 1573 profile ? profile->GetPrefs() : NULL, &default_search_index);
1915 1574
1916 for (size_t i = 0; i < prepopulated_urls.size(); ++i) { 1575 for (size_t i = 0; i < prepopulated_urls.size(); ++i) {
1917 if (prepopulated_urls[i]->prepopulate_id == prepopulate_id) { 1576 if (prepopulated_urls[i]->prepopulate_id == prepopulate_id) {
1918 MergeIntoPrepopulatedEngineData(template_url, prepopulated_urls[i]); 1577 MergeIntoPrepopulatedEngineData(template_url, prepopulated_urls[i]);
1919 template_url->CopyFrom(TemplateURL(profile, *prepopulated_urls[i])); 1578 template_url->CopyFrom(*prepopulated_urls[i]);
1920 } 1579 }
1921 } 1580 }
1922 } 1581 }
1923 1582
1924 PrefService* TemplateURLService::GetPrefs() { 1583 PrefService* TemplateURLService::GetPrefs() {
1925 return profile_ ? profile_->GetPrefs() : NULL; 1584 return profile_ ? profile_->GetPrefs() : NULL;
1926 } 1585 }
1927 1586
1928 void TemplateURLService::UpdateKeywordSearchTermsForURL( 1587 void TemplateURLService::UpdateKeywordSearchTermsForURL(
1929 const history::URLVisitedDetails& details) { 1588 const history::URLVisitedDetails& details) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2004 // |provider_map_| will not be updated correctly. 1663 // |provider_map_| will not be updated correctly.
2005 if (CanReplace(existing_entry->second)) 1664 if (CanReplace(existing_entry->second))
2006 RemoveNoNotify(existing_entry->second); 1665 RemoveNoNotify(existing_entry->second);
2007 else 1666 else
2008 updated_turl.data_.SetKeyword(t_url->keyword()); 1667 updated_turl.data_.SetKeyword(t_url->keyword());
2009 } 1668 }
2010 something_changed = true; 1669 something_changed = true;
2011 // This will send the keyword change to sync. Note that other clients 1670 // 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 1671 // need to reset the keyword to an appropriate local value when this
2013 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData(). 1672 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData().
2014 UpdateNoNotify(t_url, updated_turl, 1673 UpdateNoNotify(t_url, updated_turl.data(),
2015 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec())); 1674 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec()));
2016 } 1675 }
2017 } 1676 }
2018 if (something_changed) 1677 if (something_changed)
2019 NotifyObservers(); 1678 NotifyObservers();
2020 } 1679 }
2021 1680
2022 void TemplateURLService::UpdateDefaultSearch() { 1681 void TemplateURLService::OnDefaultSearchChange(
1682 const TemplateURLData* data,
1683 DefaultSearchManager::Source source) {
2023 if (!loaded_) { 1684 if (!loaded_) {
2024 // Set |initial_default_search_provider_| from the preferences. We use this 1685 // Set |initial_default_search_provider_| from the preferences. This is
2025 // value for default search provider until the database has been loaded. 1686 // mainly so we can hold ownership until we get to the point where the list
2026 scoped_ptr<TemplateURLData> data; 1687 // of keywords from Web Data is the owner of everything including the
2027 if (!LoadDefaultSearchProviderFromPrefs( 1688 // default.
2028 GetPrefs(), &data, &is_default_search_managed_)) { 1689 initial_default_search_provider_.reset(
2029 // Prefs does not specify, so rely on the prepopulated engines. This 1690 data ? new TemplateURL(profile_, *data) : NULL);
2030 // should happen only the first time Chrome is started. 1691 default_search_provider_source_ = source;
2031 data = 1692 return;
2032 TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs()); 1693 }
2033 is_default_search_managed_ = false; 1694
1695 // Prevent recursion if we update the value stored in default_search_manager_.
1696 // Note that we exclude if data == NULL because that could cause a false
1697 // positive for recursion when the initial_default_search_provider_ is NULL
1698 // due to policy. No recursion case could lead to recursion with NULL.
1699 if (source == default_search_provider_source_ && data != NULL &&
1700 TemplateURLMatchesData(default_search_provider_, data))
1701 return;
1702
1703 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1704 if (default_search_provider_source_ == DefaultSearchManager::FROM_POLICY ||
1705 source == DefaultSearchManager::FROM_POLICY) {
1706 // We do this both to clear up removed policy-defined DSE as well as to add
1707 // the new one, if appropriate.
1708 UpdateProvidersCreatedByPolicy(
1709 &template_urls_,
1710 source == DefaultSearchManager::FROM_POLICY ? data : NULL);
1711 }
1712
1713 if (!data) {
1714 default_search_provider_ = NULL;
1715 default_search_provider_source_ = source;
1716 NotifyObservers();
1717 return;
1718 }
1719
1720 if (source == DefaultSearchManager::FROM_EXTENSION) {
1721 default_search_provider_ = FindMatchingExtensionTemplateURL(
1722 *data, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);
1723 }
1724
1725 if (source == DefaultSearchManager::FROM_FALLBACK) {
1726 default_search_provider_ =
1727 FindPrepopulatedTemplateURL(data->prepopulate_id);
1728 if (default_search_provider_) {
1729 TemplateURLData update_data(*data);
1730 update_data.sync_guid = default_search_provider_->sync_guid();
1731 UIThreadSearchTermsData search_terms_data(
1732 default_search_provider_->profile());
1733 UpdateNoNotify(default_search_provider_, update_data, search_terms_data);
1734 } else {
1735 // Normally the prepopulated fallback should be present in
1736 // |template_urls_|, but in a few cases it might not be:
1737 // (1) Tests that initialize the TemplateURLService in peculiar ways.
1738 // (2) If the user deleted the pre-populated default and we subsequently
1739 // lost their user-selected value.
1740 TemplateURL* new_dse = new TemplateURL(profile_, *data);
1741 if (AddNoNotify(new_dse, true))
1742 default_search_provider_ = new_dse;
1743 else
1744 delete new_dse;
1745 }
1746 }
1747 if (source == DefaultSearchManager::FROM_USER) {
1748 default_search_provider_ = GetTemplateURLForGUID(data->sync_guid);
1749 if (!default_search_provider_ && data->prepopulate_id) {
1750 default_search_provider_ =
1751 FindPrepopulatedTemplateURL(data->prepopulate_id);
1752 }
1753 if (default_search_provider_) {
1754 TemplateURLData new_data(*data);
1755 new_data.show_in_default_list = true;
1756 UIThreadSearchTermsData search_terms_data(
1757 default_search_provider_->profile());
1758 UpdateNoNotify(default_search_provider_, new_data, search_terms_data);
1759 } else {
1760 TemplateURL* new_dse = new TemplateURL(profile_, *data);
1761 new_dse->data_.show_in_default_list = true;
1762 new_dse->data_.id = kInvalidTemplateURLID;
1763 if (!AddNoNotify(new_dse, true))
1764 delete new_dse;
1765 else
1766 default_search_provider_ = new_dse;
1767 }
1768 if (default_search_provider_ && GetPrefs()) {
1769 GetPrefs()->SetString(
1770 prefs::kSyncedDefaultSearchProviderGUID,
1771 default_search_provider_->sync_guid());
2034 } 1772 }
2035 1773
2036 initial_default_search_provider_.reset( 1774 }
2037 data ? new TemplateURL(profile_, *data) : NULL);
2038 1775
2039 return; 1776 default_search_provider_source_ = source;
1777
1778 if (default_search_provider_ &&
1779 default_search_provider_->url_ref().HasGoogleBaseURLs()) {
1780 if (profile_)
1781 GoogleURLTracker::RequestServerCheck(profile_, false);
1782 #if defined(ENABLE_RLZ)
1783 // TODO(erikwright): should this only be if user-selected?
1784 RLZTracker::RecordProductEvent(
1785 rlz_lib::CHROME, RLZTracker::CHROME_OMNIBOX, rlz_lib::SET_TO_GOOGLE);
1786 #endif
2040 } 1787 }
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 1788
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(); 1789 NotifyObservers();
2129 } 1790 }
2130 1791
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, 1792 bool TemplateURLService::AddNoNotify(TemplateURL* template_url,
2224 bool newly_adding) { 1793 bool newly_adding) {
2225 DCHECK(template_url); 1794 DCHECK(template_url);
2226 1795
2227 if (newly_adding) { 1796 if (newly_adding) {
2228 DCHECK_EQ(kInvalidTemplateURLID, template_url->id()); 1797 DCHECK_EQ(kInvalidTemplateURLID, template_url->id());
2229 DCHECK(std::find(template_urls_.begin(), template_urls_.end(), 1798 DCHECK(std::find(template_urls_.begin(), template_urls_.end(),
2230 template_url) == template_urls_.end()); 1799 template_url) == template_urls_.end());
2231 template_url->data_.id = ++next_id_; 1800 template_url->data_.id = ++next_id_;
2232 } 1801 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2315 1884
2316 void TemplateURLService::NotifyObservers() { 1885 void TemplateURLService::NotifyObservers() {
2317 if (!loaded_) 1886 if (!loaded_)
2318 return; 1887 return;
2319 1888
2320 FOR_EACH_OBSERVER(TemplateURLServiceObserver, model_observers_, 1889 FOR_EACH_OBSERVER(TemplateURLServiceObserver, model_observers_,
2321 OnTemplateURLServiceChanged()); 1890 OnTemplateURLServiceChanged());
2322 } 1891 }
2323 1892
2324 // |template_urls| are the TemplateURLs loaded from the database. 1893 // |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. 1894 // |default_from_prefs| is the default search provider from the preferences, or
2326 // |default_from_prefs| is the default search provider from the preferences. 1895 // NULL if the DSE is not policy-defined.
2327 // Check |is_default_search_managed_| to determine if it was set by policy.
2328 // 1896 //
2329 // This function removes from the vector and the database all the TemplateURLs 1897 // 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 1898 // that were set by policy, unless it is the current default search provider, in
2331 // and matches what is set by a managed preference. 1899 // which case it is updated with the data from prefs.
2332 void TemplateURLService::RemoveProvidersCreatedByPolicy( 1900 void TemplateURLService::UpdateProvidersCreatedByPolicy(
2333 TemplateURLVector* template_urls, 1901 TemplateURLVector* template_urls,
2334 TemplateURL** default_search_provider, 1902 const TemplateURLData* default_from_prefs) {
2335 TemplateURLData* default_from_prefs) {
2336 DCHECK(template_urls); 1903 DCHECK(template_urls);
2337 DCHECK(default_search_provider); 1904
2338 for (TemplateURLVector::iterator i = template_urls->begin(); 1905 for (TemplateURLVector::iterator i = template_urls->begin();
2339 i != template_urls->end(); ) { 1906 i != template_urls->end(); ) {
2340 TemplateURL* template_url = *i; 1907 TemplateURL* template_url = *i;
2341 if (template_url->created_by_policy()) { 1908 if (template_url->created_by_policy()) {
2342 if (template_url == *default_search_provider && 1909 if (default_from_prefs &&
2343 is_default_search_managed_ &&
2344 TemplateURLMatchesData(template_url, default_from_prefs)) { 1910 TemplateURLMatchesData(template_url, default_from_prefs)) {
2345 // If the database specified a default search provider that was set 1911 // If the database specified a default search provider that was set
2346 // by policy, and the default search provider from the preferences 1912 // 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 1913 // is also set by policy and they are the same, keep the entry in the
2348 // database and the |default_search_provider|. 1914 // database and the |default_search_provider|.
1915 default_search_provider_ = template_url;
1916 // Prevent us from saving any other entries, or creating a new one.
1917 default_from_prefs = NULL;
2349 ++i; 1918 ++i;
2350 continue; 1919 continue;
2351 } 1920 }
2352 1921
2353 // The database loaded a managed |default_search_provider|, but it has 1922 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); 1923 i = template_urls->erase(i);
2361 if (service_.get()) 1924 if (service_.get())
2362 service_->RemoveKeyword(template_url->id()); 1925 service_->RemoveKeyword(template_url->id());
2363 delete template_url; 1926 delete template_url;
2364 } else { 1927 } else {
2365 ++i; 1928 ++i;
2366 } 1929 }
2367 } 1930 }
1931
1932 if (default_from_prefs) {
1933 default_search_provider_ = NULL;
1934 default_search_provider_source_ = DefaultSearchManager::FROM_POLICY;
1935 TemplateURLData new_data(*default_from_prefs);
1936 new_data.created_by_policy = true;
1937 TemplateURL* new_dse = new TemplateURL(profile_, new_data);
1938 if (!AddNoNotify(new_dse, true))
1939 delete new_dse;
1940 else
1941 default_search_provider_ = new_dse;
1942 }
2368 } 1943 }
2369 1944
2370 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url, 1945 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url,
2371 const std::string& guid) { 1946 const std::string& guid) {
2372 DCHECK(loaded_); 1947 DCHECK(loaded_);
2373 DCHECK(!guid.empty()); 1948 DCHECK(!guid.empty());
2374 1949
2375 TemplateURLData data(url->data()); 1950 TemplateURLData data(url->data());
2376 data.sync_guid = guid; 1951 data.sync_guid = guid;
2377 TemplateURL new_url(url->profile(), data);
2378 UIThreadSearchTermsData search_terms_data(url->profile()); 1952 UIThreadSearchTermsData search_terms_data(url->profile());
2379 UpdateNoNotify(url, new_url, search_terms_data); 1953 UpdateNoNotify(url, data, search_terms_data);
2380 } 1954 }
2381 1955
2382 base::string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl, 1956 base::string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl,
2383 bool force) { 1957 bool force) {
2384 if (!force) { 1958 if (!force) {
2385 // Already unique. 1959 // Already unique.
2386 if (!GetTemplateURLForKeyword(turl.keyword())) 1960 if (!GetTemplateURLForKeyword(turl.keyword()))
2387 return turl.keyword(); 1961 return turl.keyword();
2388 1962
2389 // First, try to return the generated keyword for the TemplateURL (except 1963 // First, try to return the generated keyword for the TemplateURL (except
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2440 base::string16 new_keyword = UniquifyKeyword(*loser, false); 2014 base::string16 new_keyword = UniquifyKeyword(*loser, false);
2441 DCHECK(!GetTemplateURLForKeyword(new_keyword)); 2015 DCHECK(!GetTemplateURLForKeyword(new_keyword));
2442 if (applied_turl_is_better) { 2016 if (applied_turl_is_better) {
2443 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible 2017 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible
2444 // for adding or updating unapplied_sync_turl in the local model. 2018 // for adding or updating unapplied_sync_turl in the local model.
2445 unapplied_sync_turl->data_.SetKeyword(new_keyword); 2019 unapplied_sync_turl->data_.SetKeyword(new_keyword);
2446 } else { 2020 } else {
2447 // Update |applied_sync_turl| in the local model with the new keyword. 2021 // Update |applied_sync_turl| in the local model with the new keyword.
2448 TemplateURLData data(applied_sync_turl->data()); 2022 TemplateURLData data(applied_sync_turl->data());
2449 data.SetKeyword(new_keyword); 2023 data.SetKeyword(new_keyword);
2450 TemplateURL new_turl(applied_sync_turl->profile(), data);
2451 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile()); 2024 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile());
2452 if (UpdateNoNotify(applied_sync_turl, new_turl, search_terms_data)) 2025 if (UpdateNoNotify(applied_sync_turl, data, search_terms_data))
2453 NotifyObservers(); 2026 NotifyObservers();
2454 } 2027 }
2455 // The losing TemplateURL should have their keyword updated. Send a change to 2028 // The losing TemplateURL should have their keyword updated. Send a change to
2456 // the server to reflect this change. 2029 // the server to reflect this change.
2457 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser); 2030 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser);
2458 change_list->push_back(syncer::SyncChange(FROM_HERE, 2031 change_list->push_back(syncer::SyncChange(FROM_HERE,
2459 syncer::SyncChange::ACTION_UPDATE, 2032 syncer::SyncChange::ACTION_UPDATE,
2460 sync_data)); 2033 sync_data));
2461 } 2034 }
2462 2035
(...skipping 28 matching lines...) Expand all
2491 // |conflicting_turl| is not yet known to Sync. If it is better, then we 2064 // |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 2065 // 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. 2066 // allow the entry from Sync to overtake it in the model.
2494 const std::string guid = conflicting_turl->sync_guid(); 2067 const std::string guid = conflicting_turl->sync_guid();
2495 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) { 2068 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) {
2496 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid()); 2069 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid());
2497 syncer::SyncData sync_data = 2070 syncer::SyncData sync_data =
2498 CreateSyncDataFromTemplateURL(*conflicting_turl); 2071 CreateSyncDataFromTemplateURL(*conflicting_turl);
2499 change_list->push_back(syncer::SyncChange( 2072 change_list->push_back(syncer::SyncChange(
2500 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data)); 2073 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 2074 // 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 2075 // local model, since we've effectively "merged" it in by updating the
2515 // local conflicting entry with its sync_guid. 2076 // local conflicting entry with its sync_guid.
2516 should_add_sync_turl = false; 2077 should_add_sync_turl = false;
2517 merge_result->set_num_items_modified( 2078 merge_result->set_num_items_modified(
2518 merge_result->num_items_modified() + 1); 2079 merge_result->num_items_modified() + 1);
2519 } else { 2080 } else {
2520 // We guarantee that this isn't the local search provider. Otherwise, 2081 // We guarantee that this isn't the local search provider. Otherwise,
2521 // local would have won. 2082 // local would have won.
2522 DCHECK(conflicting_turl != GetDefaultSearchProvider()); 2083 DCHECK(conflicting_turl != GetDefaultSearchProvider());
(...skipping 10 matching lines...) Expand all
2533 if (should_add_sync_turl) { 2094 if (should_add_sync_turl) {
2534 // Force the local ID to kInvalidTemplateURLID so we can add it. 2095 // Force the local ID to kInvalidTemplateURLID so we can add it.
2535 TemplateURLData data(sync_turl->data()); 2096 TemplateURLData data(sync_turl->data());
2536 data.id = kInvalidTemplateURLID; 2097 data.id = kInvalidTemplateURLID;
2537 Add(new TemplateURL(profile_, data)); 2098 Add(new TemplateURL(profile_, data));
2538 merge_result->set_num_items_added( 2099 merge_result->set_num_items_added(
2539 merge_result->num_items_added() + 1); 2100 merge_result->num_items_added() + 1);
2540 } 2101 }
2541 } 2102 }
2542 2103
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( 2104 void TemplateURLService::PatchMissingSyncGUIDs(
2575 TemplateURLVector* template_urls) { 2105 TemplateURLVector* template_urls) {
2576 DCHECK(template_urls); 2106 DCHECK(template_urls);
2577 for (TemplateURLVector::iterator i = template_urls->begin(); 2107 for (TemplateURLVector::iterator i = template_urls->begin();
2578 i != template_urls->end(); ++i) { 2108 i != template_urls->end(); ++i) {
2579 TemplateURL* template_url = *i; 2109 TemplateURL* template_url = *i;
2580 DCHECK(template_url); 2110 DCHECK(template_url);
2581 if (template_url->sync_guid().empty() && 2111 if (template_url->sync_guid().empty() &&
2582 (template_url->GetType() != 2112 (template_url->GetType() !=
2583 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) { 2113 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) {
2584 template_url->data_.sync_guid = base::GenerateGUID(); 2114 template_url->data_.sync_guid = base::GenerateGUID();
2585 if (service_.get()) 2115 if (service_.get())
2586 service_->UpdateKeyword(template_url->data()); 2116 service_->UpdateKeyword(template_url->data());
2587 } 2117 }
2588 } 2118 }
2589 } 2119 }
2590 2120
2591 void TemplateURLService::AddTemplateURLsAndSetupDefaultEngine( 2121 TemplateURL* TemplateURLService::FindPrepopulatedTemplateURL(
2592 TemplateURLVector* template_urls, 2122 int prepopulated_id) {
2593 TemplateURL* default_search_provider) { 2123 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2594 DCHECK(template_urls); 2124 i != template_urls_.end(); ++i) {
2595 is_default_search_managed_ = false; 2125 if ((*i)->prepopulate_id() == prepopulated_id)
2596 bool database_specified_a_default = (default_search_provider != NULL); 2126 return *i;
2127 }
2597 2128
2598 // Check if default search provider is now managed. 2129 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 } 2130 }
2698 2131
2699 TemplateURL* TemplateURLService::CreateTemplateURLForExtension( 2132 TemplateURL* TemplateURLService::CreateTemplateURLForExtension(
2700 const ExtensionKeyword& extension_keyword) const { 2133 const ExtensionKeyword& extension_keyword) {
2701 TemplateURLData data; 2134 TemplateURLData data;
2702 data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name); 2135 data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name);
2703 data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword)); 2136 data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword));
2704 // This URL is not actually used for navigation. It holds the extension's 2137 // 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. 2138 // ID, as well as forcing the TemplateURL to be treated as a search keyword.
2706 data.SetURL(std::string(extensions::kExtensionScheme) + "://" + 2139 data.SetURL(std::string(extensions::kExtensionScheme) + "://" +
2707 extension_keyword.extension_id + "/?q={searchTerms}"); 2140 extension_keyword.extension_id + "/?q={searchTerms}");
2708 return new TemplateURL(profile_, data); 2141 return new TemplateURL(profile_, data);
2709 } 2142 }
2710 2143
2711 TemplateURL* TemplateURLService::FindTemplateURLForExtension( 2144 TemplateURL* TemplateURLService::FindTemplateURLForExtension(
2712 const std::string& extension_id, 2145 const std::string& extension_id,
2713 TemplateURL::Type type) const { 2146 TemplateURL::Type type) {
2714 DCHECK_NE(TemplateURL::NORMAL, type); 2147 DCHECK_NE(TemplateURL::NORMAL, type);
2715 for (TemplateURLVector::const_iterator i = template_urls_.begin(); 2148 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2716 i != template_urls_.end(); ++i) { 2149 i != template_urls_.end(); ++i) {
2717 if ((*i)->GetType() == type && 2150 if ((*i)->GetType() == type &&
2718 (*i)->GetExtensionId() == extension_id) 2151 (*i)->GetExtensionId() == extension_id)
2719 return *i; 2152 return *i;
2720 } 2153 }
2721 2154
2722 return NULL; 2155 return NULL;
2723 } 2156 }
2724 2157
2725 TemplateURL* TemplateURLService::FindExtensionDefaultSearchEngine() const { 2158 TemplateURL* TemplateURLService::FindMatchingExtensionTemplateURL(
2159 const TemplateURLData& data,
2160 TemplateURL::Type type) {
2161 DCHECK_NE(TemplateURL::NORMAL, type);
2162 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2163 i != template_urls_.end(); ++i) {
2164 if ((*i)->GetType() == type && TemplateURLMatchesData(*i, &data))
2165 return *i;
2166 }
2167
2168 return NULL;
2169 }
2170
2171 void TemplateURLService::UpdateExtensionDefaultSearchEngine() {
2726 TemplateURL* most_recently_intalled_default = NULL; 2172 TemplateURL* most_recently_intalled_default = NULL;
2727 for (TemplateURLVector::const_iterator i = template_urls_.begin(); 2173 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2728 i != template_urls_.end(); ++i) { 2174 i != template_urls_.end(); ++i) {
2729 if (((*i)->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) && 2175 if (((*i)->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) &&
2730 (*i)->extension_info_->wants_to_be_default_engine && 2176 (*i)->extension_info_->wants_to_be_default_engine &&
2731 (*i)->SupportsReplacement() && 2177 (*i)->SupportsReplacement() &&
2732 (!most_recently_intalled_default || 2178 (!most_recently_intalled_default ||
2733 (most_recently_intalled_default->extension_info_->install_time < 2179 (most_recently_intalled_default->extension_info_->install_time <
2734 (*i)->extension_info_->install_time))) 2180 (*i)->extension_info_->install_time)))
2735 most_recently_intalled_default = *i; 2181 most_recently_intalled_default = *i;
2736 } 2182 }
2737 2183
2738 return most_recently_intalled_default; 2184 if (most_recently_intalled_default) {
2185 default_search_manager_.SetExtensionControlledDefaultSearchEngine(
2186 most_recently_intalled_default->data());
2187 } else {
2188 default_search_manager_.ClearExtensionControlledDefaultSearchEngine();
2189 }
2739 } 2190 }
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698