Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/search_engines/template_url_service.h" | 5 #include "chrome/browser/search_engines/template_url_service.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/environment.h" | 9 #include "base/environment.h" |
| 10 #include "base/i18n/case_conversion.h" | 10 #include "base/i18n/case_conversion.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 // the rare case the term replaces the URL it's unlikely another keyword would | 63 // the rare case the term replaces the URL it's unlikely another keyword would |
| 64 // have the same url. | 64 // have the same url. |
| 65 const char kReplacementTerm[] = "blah.blah.blah.blah.blah"; | 65 const char kReplacementTerm[] = "blah.blah.blah.blah.blah"; |
| 66 | 66 |
| 67 bool TemplateURLsHaveSamePrefs(const TemplateURL* url1, | 67 bool TemplateURLsHaveSamePrefs(const TemplateURL* url1, |
| 68 const TemplateURL* url2) { | 68 const TemplateURL* url2) { |
| 69 if (url1 == url2) | 69 if (url1 == url2) |
| 70 return true; | 70 return true; |
| 71 return (url1 != NULL) && (url2 != NULL) && | 71 return (url1 != NULL) && (url2 != NULL) && |
| 72 (url1->short_name() == url2->short_name()) && | 72 (url1->short_name() == url2->short_name()) && |
| 73 (url1->keyword() == url2->keyword()) && | 73 url1->HasSameKeywordAs(*url2) && |
| 74 (url1->url() == url2->url()) && | 74 (url1->url() == url2->url()) && |
| 75 (url1->suggestions_url() == url2->suggestions_url()) && | 75 (url1->suggestions_url() == url2->suggestions_url()) && |
| 76 (url1->instant_url() == url2->instant_url()) && | 76 (url1->instant_url() == url2->instant_url()) && |
| 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 } | 81 } |
| 82 | 82 |
| 83 TemplateURL* FirstPotentialDefaultEngine( | 83 TemplateURL* FirstPotentialDefaultEngine( |
| 84 const TemplateURLService::TemplateURLVector& template_urls) { | 84 const TemplateURLService::TemplateURLVector& template_urls) { |
| 85 for (TemplateURLService::TemplateURLVector::const_iterator i( | 85 for (TemplateURLService::TemplateURLVector::const_iterator i( |
| 86 template_urls.begin()); i != template_urls.end(); ++i) { | 86 template_urls.begin()); i != template_urls.end(); ++i) { |
| 87 if (!(*i)->IsExtensionKeyword() && (*i)->SupportsReplacement()) | 87 if (!(*i)->IsExtensionKeyword() && (*i)->SupportsReplacement()) |
| 88 return *i; | 88 return *i; |
| 89 } | 89 } |
| 90 return NULL; | 90 return NULL; |
| 91 } | 91 } |
| 92 | 92 |
| 93 // If |change_list| contains ACTION_UPDATEs followed by more ACTION_UPDATEs or | |
| 94 // ACTION_ADDs for the same GUID, remove all but the last one. | |
| 95 // | |
| 96 // This is necessary because when syncing we may first need to migrate the | |
| 97 // server-provided TemplateURL in some way, then resolve conflicts against a | |
| 98 // local URL, generating two different UPDATEs. If we send up both UPDATEs, and | |
| 99 // the server does not coalesce them before sending to other clients, then the | |
| 100 // first update could cause conflicts on the other clients, resulting in them | |
| 101 // sending back UPDATEs of their own to try to resolve things, thus causing mass | |
| 102 // confusion. Since the second UPDATE obviates the need for the first, removing | |
| 103 // the first locally is safe and avoids any potential for this problem. | |
| 104 // | |
| 105 // REVIEWERS: Should we instead do this uniquing at a lower level, or guarantee | |
| 106 // that the server will coalesce these so the client need not worry? | |
|
SteveT
2012/05/07 19:33:49
Discussed this with Nick, who is added to the Revi
| |
| 107 void PreventDuplicateGUIDUpdates(SyncChangeList* change_list) { | |
| 108 for (size_t i = change_list->size(); i > 1; ) { | |
| 109 --i; // Prevent underflow that could occur if we did this in the loop body. | |
| 110 const SyncChange& change_i = (*change_list)[i]; | |
| 111 if ((change_i.change_type() != SyncChange::ACTION_ADD) && | |
| 112 (change_i.change_type() != SyncChange::ACTION_UPDATE)) | |
| 113 continue; | |
| 114 std::string guid( | |
| 115 change_i.sync_data().GetSpecifics().search_engine().sync_guid()); | |
| 116 for (size_t j = 0; j < i; ) { | |
| 117 const SyncChange& change_j = (*change_list)[j]; | |
| 118 if ((change_j.change_type() == SyncChange::ACTION_UPDATE) && | |
| 119 (change_j.sync_data().GetSpecifics().search_engine().sync_guid() == | |
| 120 guid)) { | |
| 121 change_list->erase(change_list->begin() + j); | |
| 122 --i; | |
| 123 } else { | |
| 124 ++j; | |
| 125 } | |
| 126 } | |
| 127 } | |
| 128 } | |
| 129 | |
| 93 } // namespace | 130 } // namespace |
| 94 | 131 |
| 95 | 132 |
| 96 class TemplateURLService::LessWithPrefix { | 133 class TemplateURLService::LessWithPrefix { |
| 97 public: | 134 public: |
| 98 // We want to find the set of keywords that begin with a prefix. The STL | 135 // We want to find the set of keywords that begin with a prefix. The STL |
| 99 // algorithms will return the set of elements that are "equal to" the | 136 // algorithms will return the set of elements that are "equal to" the |
| 100 // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When | 137 // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When |
| 101 // cmp() is the typical std::less<>, this results in lexicographic equality; | 138 // cmp() is the typical std::less<>, this results in lexicographic equality; |
| 102 // we need to extend this to mark a prefix as "not less than" a keyword it | 139 // we need to extend this to mark a prefix as "not less than" a keyword it |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 TemplateURLService::~TemplateURLService() { | 190 TemplateURLService::~TemplateURLService() { |
| 154 if (load_handle_) { | 191 if (load_handle_) { |
| 155 DCHECK(service_.get()); | 192 DCHECK(service_.get()); |
| 156 service_->CancelRequest(load_handle_); | 193 service_->CancelRequest(load_handle_); |
| 157 } | 194 } |
| 158 | 195 |
| 159 STLDeleteElements(&template_urls_); | 196 STLDeleteElements(&template_urls_); |
| 160 } | 197 } |
| 161 | 198 |
| 162 // static | 199 // static |
| 163 string16 TemplateURLService::GenerateKeyword(const GURL& url, | 200 string16 TemplateURLService::GenerateKeyword(const GURL& url) { |
| 164 bool autodetected) { | 201 DCHECK(url.is_valid()); |
| 165 // Don't autogenerate keywords for referrers that are the result of a form | |
| 166 // submission (TODO: right now we approximate this by checking for the URL | |
| 167 // having a query, but we should replace this with a call to WebCore to see if | |
| 168 // the originating page was actually a form submission), anything other than | |
| 169 // http, or referrers with a path. | |
| 170 // | |
| 171 // If we relax the path constraint, we need to be sure to sanitize the path | |
| 172 // elements and update AutocompletePopup to look for keywords using the path. | |
| 173 // See http://b/issue?id=863583. | |
| 174 if (!url.is_valid() || | |
| 175 (autodetected && (url.has_query() || !url.SchemeIs(chrome::kHttpScheme) || | |
| 176 ((url.path() != "") && (url.path() != "/"))))) | |
| 177 return string16(); | |
| 178 | |
| 179 // Strip "www." off the front of the keyword; otherwise the keyword won't work | 202 // Strip "www." off the front of the keyword; otherwise the keyword won't work |
| 180 // properly. See http://code.google.com/p/chromium/issues/detail?id=6984 . | 203 // properly. See http://code.google.com/p/chromium/issues/detail?id=6984 . |
| 181 // Special case: if the host was exactly "www." (not sure this can happen but | 204 // Special case: if the host was exactly "www." (not sure this can happen but |
| 182 // perhaps with some weird intranet and custom DNS server?), ensure we at | 205 // perhaps with some weird intranet and custom DNS server?), ensure we at |
| 183 // least don't return the empty string. | 206 // least don't return the empty string. |
| 184 string16 keyword(net::StripWWW(UTF8ToUTF16(url.host()))); | 207 string16 keyword(net::StripWWW(UTF8ToUTF16(url.host()))); |
| 185 return keyword.empty() ? ASCIIToUTF16("www") : keyword; | 208 return keyword.empty() ? ASCIIToUTF16("www") : keyword; |
| 186 } | 209 } |
| 187 | 210 |
| 188 // static | 211 // static |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 DCHECK(t_url); | 247 DCHECK(t_url); |
| 225 UIThreadSearchTermsData search_terms_data; | 248 UIThreadSearchTermsData search_terms_data; |
| 226 return GenerateSearchURLUsingTermsData(t_url, search_terms_data); | 249 return GenerateSearchURLUsingTermsData(t_url, search_terms_data); |
| 227 } | 250 } |
| 228 | 251 |
| 229 // static | 252 // static |
| 230 GURL TemplateURLService::GenerateSearchURLUsingTermsData( | 253 GURL TemplateURLService::GenerateSearchURLUsingTermsData( |
| 231 const TemplateURL* t_url, | 254 const TemplateURL* t_url, |
| 232 const SearchTermsData& search_terms_data) { | 255 const SearchTermsData& search_terms_data) { |
| 233 DCHECK(t_url); | 256 DCHECK(t_url); |
| 257 DCHECK(!t_url->IsExtensionKeyword()); | |
| 258 | |
| 234 const TemplateURLRef& search_ref = t_url->url_ref(); | 259 const TemplateURLRef& search_ref = t_url->url_ref(); |
| 235 // Extension keywords don't have host-based search URLs. | 260 if (!search_ref.IsValidUsingTermsData(search_terms_data)) |
| 236 if (!search_ref.IsValidUsingTermsData(search_terms_data) || | |
| 237 t_url->IsExtensionKeyword()) | |
| 238 return GURL(); | 261 return GURL(); |
| 239 | 262 |
| 240 if (!search_ref.SupportsReplacementUsingTermsData(search_terms_data)) | 263 if (!search_ref.SupportsReplacementUsingTermsData(search_terms_data)) |
| 241 return GURL(t_url->url()); | 264 return GURL(t_url->url()); |
| 242 | 265 |
| 243 return GURL(search_ref.ReplaceSearchTermsUsingTermsData( | 266 return GURL(search_ref.ReplaceSearchTermsUsingTermsData( |
| 244 ASCIIToUTF16(kReplacementTerm), TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, | 267 ASCIIToUTF16(kReplacementTerm), TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, |
| 245 string16(), search_terms_data)); | 268 string16(), search_terms_data)); |
| 246 } | 269 } |
| 247 | 270 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 matches->push_back(i->first); | 323 matches->push_back(i->first); |
| 301 } | 324 } |
| 302 } | 325 } |
| 303 | 326 |
| 304 TemplateURL* TemplateURLService::GetTemplateURLForKeyword( | 327 TemplateURL* TemplateURLService::GetTemplateURLForKeyword( |
| 305 const string16& keyword) { | 328 const string16& keyword) { |
| 306 KeywordToTemplateMap::const_iterator elem( | 329 KeywordToTemplateMap::const_iterator elem( |
| 307 keyword_to_template_map_.find(keyword)); | 330 keyword_to_template_map_.find(keyword)); |
| 308 if (elem != keyword_to_template_map_.end()) | 331 if (elem != keyword_to_template_map_.end()) |
| 309 return elem->second; | 332 return elem->second; |
| 310 return (initial_default_search_provider_.get() && | 333 return ((!loaded_ || load_failed_) && |
| 334 initial_default_search_provider_.get() && | |
| 311 (initial_default_search_provider_->keyword() == keyword)) ? | 335 (initial_default_search_provider_->keyword() == keyword)) ? |
| 312 initial_default_search_provider_.get() : NULL; | 336 initial_default_search_provider_.get() : NULL; |
| 313 } | 337 } |
| 314 | 338 |
| 315 TemplateURL* TemplateURLService::GetTemplateURLForGUID( | 339 TemplateURL* TemplateURLService::GetTemplateURLForGUID( |
| 316 const std::string& sync_guid) { | 340 const std::string& sync_guid) { |
| 317 GUIDToTemplateMap::const_iterator elem( | 341 GUIDToTemplateMap::const_iterator elem(guid_to_template_map_.find(sync_guid)); |
| 318 guid_to_template_map_.find(sync_guid)); | |
| 319 if (elem != guid_to_template_map_.end()) | 342 if (elem != guid_to_template_map_.end()) |
| 320 return elem->second; | 343 return elem->second; |
| 321 return (initial_default_search_provider_.get() && | 344 return ((!loaded_ || load_failed_) && |
| 345 initial_default_search_provider_.get() && | |
| 322 (initial_default_search_provider_->sync_guid() == sync_guid)) ? | 346 (initial_default_search_provider_->sync_guid() == sync_guid)) ? |
| 323 initial_default_search_provider_.get() : NULL; | 347 initial_default_search_provider_.get() : NULL; |
| 324 } | 348 } |
| 325 | 349 |
| 326 TemplateURL* TemplateURLService::GetTemplateURLForHost( | 350 TemplateURL* TemplateURLService::GetTemplateURLForHost( |
| 327 const std::string& host) { | 351 const std::string& host) { |
| 328 TemplateURL* t_url = provider_map_->GetTemplateURLForHost(host); | 352 TemplateURL* t_url = provider_map_->GetTemplateURLForHost(host); |
| 329 if (t_url) | 353 if (t_url) |
| 330 return t_url; | 354 return t_url; |
| 331 return (initial_default_search_provider_.get() && | 355 return ((!loaded_ || load_failed_) && |
| 356 initial_default_search_provider_.get() && | |
| 332 (GenerateSearchURL(initial_default_search_provider_.get()).host() == | 357 (GenerateSearchURL(initial_default_search_provider_.get()).host() == |
| 333 host)) ? initial_default_search_provider_.get() : NULL; | 358 host)) ? initial_default_search_provider_.get() : NULL; |
| 334 } | 359 } |
| 335 | 360 |
| 336 void TemplateURLService::Add(TemplateURL* template_url) { | 361 void TemplateURLService::Add(TemplateURL* template_url) { |
| 337 AddNoNotify(template_url, true); | 362 if (AddNoNotify(template_url, true)) |
| 338 NotifyObservers(); | 363 NotifyObservers(); |
| 339 } | 364 } |
| 340 | 365 |
| 341 void TemplateURLService::AddAndSetProfile(TemplateURL* template_url, | 366 void TemplateURLService::AddAndSetProfile(TemplateURL* template_url, |
| 342 Profile* profile) { | 367 Profile* profile) { |
| 343 template_url->profile_ = profile; | 368 template_url->profile_ = profile; |
| 344 Add(template_url); | 369 Add(template_url); |
| 345 } | 370 } |
| 346 | 371 |
| 347 void TemplateURLService::AddWithOverrides(TemplateURL* template_url, | 372 void TemplateURLService::AddWithOverrides(TemplateURL* template_url, |
| 348 const string16& short_name, | 373 const string16& short_name, |
| 349 const string16& keyword, | 374 const string16& keyword, |
| 350 const std::string& url) { | 375 const std::string& url) { |
| 376 DCHECK(!keyword.empty()); | |
| 351 DCHECK(!url.empty()); | 377 DCHECK(!url.empty()); |
| 352 template_url->data_.short_name = short_name; | 378 template_url->data_.short_name = short_name; |
| 353 template_url->data_.SetKeyword(keyword); | 379 template_url->data_.SetKeyword(keyword); |
| 354 template_url->SetURL(url); | 380 template_url->SetURL(url); |
| 355 Add(template_url); | 381 Add(template_url); |
| 356 } | 382 } |
| 357 | 383 |
| 358 void TemplateURLService::Remove(TemplateURL* template_url) { | 384 void TemplateURLService::Remove(TemplateURL* template_url) { |
| 359 RemoveNoNotify(template_url); | 385 RemoveNoNotify(template_url); |
| 360 NotifyObservers(); | 386 NotifyObservers(); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 } | 466 } |
| 441 | 467 |
| 442 return NULL; | 468 return NULL; |
| 443 } | 469 } |
| 444 | 470 |
| 445 TemplateURLService::TemplateURLVector TemplateURLService::GetTemplateURLs() { | 471 TemplateURLService::TemplateURLVector TemplateURLService::GetTemplateURLs() { |
| 446 return template_urls_; | 472 return template_urls_; |
| 447 } | 473 } |
| 448 | 474 |
| 449 void TemplateURLService::IncrementUsageCount(TemplateURL* url) { | 475 void TemplateURLService::IncrementUsageCount(TemplateURL* url) { |
| 450 DCHECK(url && std::find(template_urls_.begin(), template_urls_.end(), url) != | 476 DCHECK(url); |
| 451 template_urls_.end()); | 477 if (std::find(template_urls_.begin(), template_urls_.end(), url) == |
| 478 template_urls_.end()) | |
| 479 return; | |
| 452 ++url->data_.usage_count; | 480 ++url->data_.usage_count; |
| 453 // Extension keywords are not persisted. | 481 // Extension keywords are not persisted. |
| 454 // TODO(mpcomplete): If we allow editing extension keywords, then those should | 482 // TODO(mpcomplete): If we allow editing extension keywords, then those should |
| 455 // be persisted to disk and synced. | 483 // be persisted to disk and synced. |
| 456 if (service_.get() && !url->IsExtensionKeyword()) | 484 if (service_.get() && !url->IsExtensionKeyword()) |
| 457 service_.get()->UpdateKeyword(*url); | 485 service_.get()->UpdateKeyword(url->data()); |
| 458 } | 486 } |
| 459 | 487 |
| 460 void TemplateURLService::ResetTemplateURL(TemplateURL* url, | 488 void TemplateURLService::ResetTemplateURL(TemplateURL* url, |
| 461 const string16& title, | 489 const string16& title, |
| 462 const string16& keyword, | 490 const string16& keyword, |
| 463 const std::string& search_url) { | 491 const std::string& search_url) { |
| 492 if (!loaded_) | |
| 493 return; | |
| 494 DCHECK(!keyword.empty()); | |
| 464 DCHECK(!search_url.empty()); | 495 DCHECK(!search_url.empty()); |
| 465 TemplateURLData data(url->data()); | 496 TemplateURLData data(url->data()); |
| 466 data.short_name = title; | 497 data.short_name = title; |
| 467 data.SetKeyword(keyword); | 498 data.SetKeyword(keyword); |
| 468 if (search_url != data.url()) { | 499 if (search_url != data.url()) { |
| 469 data.SetURL(search_url); | 500 data.SetURL(search_url); |
| 470 // The urls have changed, reset the favicon url. | 501 // The urls have changed, reset the favicon url. |
| 471 data.favicon_url = GURL(); | 502 data.favicon_url = GURL(); |
| 472 } | 503 } |
| 473 data.safe_for_autoreplace = false; | 504 data.safe_for_autoreplace = false; |
| 474 data.last_modified = time_provider_(); | 505 data.last_modified = time_provider_(); |
| 475 TemplateURL new_url(url->profile(), data); | 506 TemplateURL new_url(url->profile(), data); |
| 476 UpdateNoNotify(url, new_url); | 507 if (UpdateNoNotify(url, new_url)) |
| 477 NotifyObservers(); | 508 NotifyObservers(); |
| 478 } | 509 } |
| 479 | 510 |
| 480 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) { | 511 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) { |
| 481 return url != GetDefaultSearchProvider() && | 512 return url != GetDefaultSearchProvider() && |
| 482 url->url_ref().SupportsReplacement() && !is_default_search_managed(); | 513 url->url_ref().SupportsReplacement() && !is_default_search_managed(); |
| 483 } | 514 } |
| 484 | 515 |
| 485 void TemplateURLService::SetDefaultSearchProvider(TemplateURL* url) { | 516 void TemplateURLService::SetDefaultSearchProvider(TemplateURL* url) { |
| 486 DCHECK(!is_default_search_managed_); | 517 DCHECK(!is_default_search_managed_); |
| 487 // Extension keywords cannot be made default, as they are inherently async. | 518 // Extension keywords cannot be made default, as they are inherently async. |
| 488 DCHECK(!url || !url->IsExtensionKeyword()); | 519 DCHECK(!url || !url->IsExtensionKeyword()); |
| 489 | 520 |
| 490 // Always persist the setting in the database, that way if the backup | 521 // Always persist the setting in the database, that way if the backup |
| 491 // signature has changed out from under us it gets reset correctly. | 522 // signature has changed out from under us it gets reset correctly. |
| 492 SetDefaultSearchProviderNoNotify(url); | 523 if (SetDefaultSearchProviderNoNotify(url)) |
| 493 NotifyObservers(); | 524 NotifyObservers(); |
| 494 } | 525 } |
| 495 | 526 |
| 496 TemplateURL* TemplateURLService::GetDefaultSearchProvider() { | 527 TemplateURL* TemplateURLService::GetDefaultSearchProvider() { |
| 497 if (loaded_ && !load_failed_) | 528 if (loaded_ && !load_failed_) |
| 498 return default_search_provider_; | 529 return default_search_provider_; |
| 499 | 530 |
| 500 // We're not loaded, rely on the default search provider stored in prefs. | 531 // We're not loaded, rely on the default search provider stored in prefs. |
| 501 return initial_default_search_provider_.get(); | 532 return initial_default_search_provider_.get(); |
| 502 } | 533 } |
| 503 | 534 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 // The value from the preferences was previously stored in the database. | 635 // The value from the preferences was previously stored in the database. |
| 605 // Reuse it. | 636 // Reuse it. |
| 606 } else { | 637 } else { |
| 607 // The value from the preferences takes over. | 638 // The value from the preferences takes over. |
| 608 default_search_provider = NULL; | 639 default_search_provider = NULL; |
| 609 if (default_from_prefs.get()) { | 640 if (default_from_prefs.get()) { |
| 610 TemplateURLData data(default_from_prefs->data()); | 641 TemplateURLData data(default_from_prefs->data()); |
| 611 data.created_by_policy = true; | 642 data.created_by_policy = true; |
| 612 data.id = kInvalidTemplateURLID; | 643 data.id = kInvalidTemplateURLID; |
| 613 default_search_provider = new TemplateURL(profile_, data); | 644 default_search_provider = new TemplateURL(profile_, data); |
| 614 AddNoNotify(default_search_provider, true); | 645 if (!AddNoNotify(default_search_provider, true)) |
| 646 default_search_provider = NULL; | |
| 615 } | 647 } |
| 616 } | 648 } |
| 617 // Note that this saves the default search provider to prefs. | 649 // Note that this saves the default search provider to prefs. |
| 618 if (!default_search_provider || | 650 if (!default_search_provider || |
| 619 (!default_search_provider->IsExtensionKeyword() && | 651 (!default_search_provider->IsExtensionKeyword() && |
| 620 default_search_provider->SupportsReplacement())) | 652 default_search_provider->SupportsReplacement())) { |
| 621 SetDefaultSearchProviderNoNotify(default_search_provider); | 653 bool success = SetDefaultSearchProviderNoNotify(default_search_provider); |
| 654 DCHECK(success); | |
| 655 } | |
| 622 } else { | 656 } else { |
| 623 // If we had a managed default, replace it with the synced default if | 657 // If we had a managed default, replace it with the synced default if |
| 624 // applicable, or the first provider of the list. | 658 // applicable, or the first provider of the list. |
| 625 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider(); | 659 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider(); |
| 626 if (synced_default) { | 660 if (synced_default) { |
| 627 default_search_provider = synced_default; | 661 default_search_provider = synced_default; |
| 628 pending_synced_default_search_ = false; | 662 pending_synced_default_search_ = false; |
| 629 } else if (database_specified_a_default && | 663 } else if (database_specified_a_default && |
| 630 default_search_provider == NULL) { | 664 default_search_provider == NULL) { |
| 631 default_search_provider = FirstPotentialDefaultEngine(template_urls); | 665 default_search_provider = FirstPotentialDefaultEngine(template_urls); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 692 check_if_default_search_valid = false; | 726 check_if_default_search_valid = false; |
| 693 } | 727 } |
| 694 #endif | 728 #endif |
| 695 | 729 |
| 696 if (check_if_default_search_valid) { | 730 if (check_if_default_search_valid) { |
| 697 bool has_default_search_provider = default_search_provider_ != NULL && | 731 bool has_default_search_provider = default_search_provider_ != NULL && |
| 698 default_search_provider_->SupportsReplacement(); | 732 default_search_provider_->SupportsReplacement(); |
| 699 UMA_HISTOGRAM_BOOLEAN("Search.HasDefaultSearchProvider", | 733 UMA_HISTOGRAM_BOOLEAN("Search.HasDefaultSearchProvider", |
| 700 has_default_search_provider); | 734 has_default_search_provider); |
| 701 // Ensure that default search provider exists. See http://crbug.com/116952. | 735 // Ensure that default search provider exists. See http://crbug.com/116952. |
| 702 if (!has_default_search_provider) | 736 if (!has_default_search_provider) { |
| 703 SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider()); | 737 bool success = |
| 738 SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider()); | |
| 739 DCHECK(success); | |
| 740 } | |
| 704 } | 741 } |
| 705 | 742 |
| 706 NotifyObservers(); | 743 NotifyObservers(); |
| 707 NotifyLoaded(); | 744 NotifyLoaded(); |
| 708 } | 745 } |
| 709 | 746 |
| 710 string16 TemplateURLService::GetKeywordShortName(const string16& keyword, | 747 string16 TemplateURLService::GetKeywordShortName(const string16& keyword, |
| 711 bool* is_extension_keyword) { | 748 bool* is_extension_keyword) { |
| 712 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); | 749 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); |
| 713 | 750 |
| 714 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService | 751 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService |
| 715 // to track changes to the model, this should become a DCHECK. | 752 // to track changes to the model, this should become a DCHECK. |
| 716 if (template_url) { | 753 if (template_url) { |
| 717 *is_extension_keyword = template_url->IsExtensionKeyword(); | 754 *is_extension_keyword = template_url->IsExtensionKeyword(); |
| 718 return template_url->AdjustedShortNameForLocaleDirection(); | 755 return template_url->AdjustedShortNameForLocaleDirection(); |
| 719 } | 756 } |
| 720 *is_extension_keyword = false; | 757 *is_extension_keyword = false; |
| 721 return string16(); | 758 return string16(); |
| 722 } | 759 } |
| 723 | 760 |
| 724 void TemplateURLService::Observe(int type, | 761 void TemplateURLService::Observe(int type, |
| 725 const content::NotificationSource& source, | 762 const content::NotificationSource& source, |
| 726 const content::NotificationDetails& details) { | 763 const content::NotificationDetails& details) { |
| 727 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) { | 764 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) { |
| 728 content::Details<history::URLVisitedDetails> visit_details(details); | 765 content::Details<history::URLVisitedDetails> visit_details(details); |
| 729 if (!loaded()) | 766 if (!loaded_) |
| 730 visits_to_add_.push_back(*visit_details.ptr()); | 767 visits_to_add_.push_back(*visit_details.ptr()); |
| 731 else | 768 else |
| 732 UpdateKeywordSearchTermsForURL(*visit_details.ptr()); | 769 UpdateKeywordSearchTermsForURL(*visit_details.ptr()); |
| 733 } else if (type == chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED) { | 770 } else if (type == chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED) { |
| 734 // Policy has been updated, so the default search prefs may be different. | 771 // Policy has been updated, so the default search prefs may be different. |
| 735 // Reload the default search provider from them. | 772 // Reload the default search provider from them. |
| 736 // TODO(pkasting): Rather than communicating via prefs, we should eventually | 773 // TODO(pkasting): Rather than communicating via prefs, we should eventually |
| 737 // observe policy changes directly. | 774 // observe policy changes directly. |
| 738 UpdateDefaultSearch(); | 775 UpdateDefaultSearch(); |
| 739 } else if (type == chrome::NOTIFICATION_GOOGLE_URL_UPDATED) { | 776 } else if (type == chrome::NOTIFICATION_GOOGLE_URL_UPDATED) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 785 } | 822 } |
| 786 | 823 |
| 787 SyncError TemplateURLService::ProcessSyncChanges( | 824 SyncError TemplateURLService::ProcessSyncChanges( |
| 788 const tracked_objects::Location& from_here, | 825 const tracked_objects::Location& from_here, |
| 789 const SyncChangeList& change_list) { | 826 const SyncChangeList& change_list) { |
| 790 if (!models_associated_) { | 827 if (!models_associated_) { |
| 791 SyncError error(FROM_HERE, "Models not yet associated.", | 828 SyncError error(FROM_HERE, "Models not yet associated.", |
| 792 syncable::SEARCH_ENGINES); | 829 syncable::SEARCH_ENGINES); |
| 793 return error; | 830 return error; |
| 794 } | 831 } |
| 832 DCHECK(loaded_); | |
| 795 | 833 |
| 796 AutoReset<bool> processing_changes(&processing_syncer_changes_, true); | 834 AutoReset<bool> processing_changes(&processing_syncer_changes_, true); |
| 797 | 835 |
| 798 SyncChangeList new_changes; | 836 SyncChangeList new_changes; |
| 799 SyncError error; | 837 SyncError error; |
| 800 for (SyncChangeList::const_iterator iter = change_list.begin(); | 838 for (SyncChangeList::const_iterator iter = change_list.begin(); |
| 801 iter != change_list.end(); ++iter) { | 839 iter != change_list.end(); ++iter) { |
| 802 DCHECK_EQ(syncable::SEARCH_ENGINES, iter->sync_data().GetDataType()); | 840 DCHECK_EQ(syncable::SEARCH_ENGINES, iter->sync_data().GetDataType()); |
| 803 | 841 |
| 804 std::string guid = | 842 std::string guid = |
| 805 iter->sync_data().GetSpecifics().search_engine().sync_guid(); | 843 iter->sync_data().GetSpecifics().search_engine().sync_guid(); |
| 806 TemplateURL* existing_turl = GetTemplateURLForGUID(guid); | 844 TemplateURL* existing_turl = GetTemplateURLForGUID(guid); |
| 807 scoped_ptr<TemplateURL> turl(CreateTemplateURLFromTemplateURLAndSyncData( | 845 scoped_ptr<TemplateURL> turl(CreateTemplateURLFromTemplateURLAndSyncData( |
| 808 profile_, existing_turl, iter->sync_data(), &new_changes)); | 846 profile_, existing_turl, iter->sync_data(), &new_changes)); |
| 809 if (!turl.get()) | 847 if (!turl.get()) |
| 810 continue; | 848 continue; |
| 811 | 849 |
| 850 // Explicitly don't check for conflicts against extension keywords; in this | |
| 851 // case the functions which modify the keyword map know how to handle the | |
| 852 // conflicts. | |
| 853 // TODO(mpcomplete): If we allow editing extension keywords, then those will | |
| 854 // need to undergo conflict resolution. | |
| 812 TemplateURL* existing_keyword_turl = | 855 TemplateURL* existing_keyword_turl = |
| 813 GetTemplateURLForKeyword(turl->keyword()); | 856 FindNonExtensionTemplateURLForKeyword(turl->keyword()); |
| 814 | |
| 815 if (iter->change_type() == SyncChange::ACTION_DELETE && existing_turl) { | 857 if (iter->change_type() == SyncChange::ACTION_DELETE && existing_turl) { |
| 816 bool delete_default = (existing_turl == GetDefaultSearchProvider()); | 858 bool delete_default = (existing_turl == GetDefaultSearchProvider()); |
| 817 | 859 |
| 818 if (delete_default && is_default_search_managed_) { | 860 if (delete_default && is_default_search_managed_) { |
| 819 NOTREACHED() << "Tried to delete managed default search provider"; | 861 NOTREACHED() << "Tried to delete managed default search provider"; |
| 820 } else { | 862 } else { |
| 821 if (delete_default) | 863 if (delete_default) |
| 822 default_search_provider_ = NULL; | 864 default_search_provider_ = NULL; |
| 823 | 865 |
| 824 Remove(existing_turl); | 866 Remove(existing_turl); |
| 825 | 867 |
| 826 if (delete_default) | 868 if (delete_default) |
| 827 SetDefaultSearchProvider(FindNewDefaultSearchProvider()); | 869 SetDefaultSearchProvider(FindNewDefaultSearchProvider()); |
| 828 } | 870 } |
| 829 } else if (iter->change_type() == SyncChange::ACTION_ADD && | 871 } else if (iter->change_type() == SyncChange::ACTION_ADD && |
| 830 !existing_turl) { | 872 !existing_turl) { |
| 831 std::string guid = turl->sync_guid(); | 873 std::string guid = turl->sync_guid(); |
| 832 if (existing_keyword_turl) | 874 if (existing_keyword_turl) { |
| 833 ResolveSyncKeywordConflict(turl.get(), &new_changes); | 875 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, |
| 876 &new_changes); | |
| 877 } | |
| 834 // Force the local ID to kInvalidTemplateURLID so we can add it. | 878 // Force the local ID to kInvalidTemplateURLID so we can add it. |
| 835 TemplateURLData data(turl->data()); | 879 TemplateURLData data(turl->data()); |
| 836 data.id = kInvalidTemplateURLID; | 880 data.id = kInvalidTemplateURLID; |
| 837 Add(new TemplateURL(profile_, data)); | 881 Add(new TemplateURL(profile_, data)); |
| 838 | 882 |
| 839 // Possibly set the newly added |turl| as the default search provider. | 883 // Possibly set the newly added |turl| as the default search provider. |
| 840 SetDefaultSearchProviderIfNewlySynced(guid); | 884 SetDefaultSearchProviderIfNewlySynced(guid); |
| 841 } else if (iter->change_type() == SyncChange::ACTION_UPDATE && | 885 } else if (iter->change_type() == SyncChange::ACTION_UPDATE && |
| 842 existing_turl) { | 886 existing_turl) { |
| 843 // Possibly resolve a keyword conflict if they have the same keywords but | 887 // Possibly resolve a keyword conflict if they have the same keywords but |
| 844 // are not the same entry. | 888 // are not the same entry. |
| 845 if (existing_keyword_turl && existing_keyword_turl != existing_turl) | 889 if (existing_keyword_turl && existing_keyword_turl != existing_turl) { |
| 846 ResolveSyncKeywordConflict(turl.get(), &new_changes); | 890 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, |
| 847 UpdateNoNotify(existing_turl, *turl); | 891 &new_changes); |
| 848 NotifyObservers(); | 892 } |
| 893 if (UpdateNoNotify(existing_turl, *turl)) | |
| 894 NotifyObservers(); | |
| 849 } else { | 895 } else { |
| 850 // Something really unexpected happened. Either we received an | 896 // Something really unexpected happened. Either we received an |
| 851 // ACTION_INVALID, or Sync is in a crazy state: | 897 // ACTION_INVALID, or Sync is in a crazy state: |
| 852 // . Trying to DELETE or UPDATE a non-existent search engine. | 898 // . Trying to DELETE or UPDATE a non-existent search engine. |
| 853 // . Trying to ADD a search engine that already exists. | 899 // . Trying to ADD a search engine that already exists. |
| 854 NOTREACHED() << "Unexpected sync change state."; | 900 NOTREACHED() << "Unexpected sync change state."; |
| 855 error = sync_error_factory_->CreateAndUploadError( | 901 error = sync_error_factory_->CreateAndUploadError( |
| 856 FROM_HERE, | 902 FROM_HERE, |
| 857 "ProcessSyncChanges failed on ChangeType " + | 903 "ProcessSyncChanges failed on ChangeType " + |
| 858 SyncChange::ChangeTypeToString(iter->change_type())); | 904 SyncChange::ChangeTypeToString(iter->change_type())); |
| 859 } | 905 } |
| 860 } | 906 } |
| 907 PreventDuplicateGUIDUpdates(&new_changes); | |
| 861 | 908 |
| 862 // If something went wrong, we want to prematurely exit to avoid pushing | 909 // If something went wrong, we want to prematurely exit to avoid pushing |
| 863 // inconsistent data to Sync. We return the last error we received. | 910 // inconsistent data to Sync. We return the last error we received. |
| 864 if (error.IsSet()) | 911 if (error.IsSet()) |
| 865 return error; | 912 return error; |
| 866 | 913 |
| 867 error = sync_processor_->ProcessSyncChanges(from_here, new_changes); | 914 error = sync_processor_->ProcessSyncChanges(from_here, new_changes); |
| 868 | 915 |
| 869 return error; | 916 return error; |
| 870 } | 917 } |
| 871 | 918 |
| 872 SyncError TemplateURLService::MergeDataAndStartSyncing( | 919 SyncError TemplateURLService::MergeDataAndStartSyncing( |
| 873 syncable::ModelType type, | 920 syncable::ModelType type, |
| 874 const SyncDataList& initial_sync_data, | 921 const SyncDataList& initial_sync_data, |
| 875 scoped_ptr<SyncChangeProcessor> sync_processor, | 922 scoped_ptr<SyncChangeProcessor> sync_processor, |
| 876 scoped_ptr<SyncErrorFactory> sync_error_factory) { | 923 scoped_ptr<SyncErrorFactory> sync_error_factory) { |
| 877 DCHECK(loaded()); | 924 DCHECK(loaded_); |
| 878 DCHECK_EQ(type, syncable::SEARCH_ENGINES); | 925 DCHECK_EQ(type, syncable::SEARCH_ENGINES); |
| 879 DCHECK(!sync_processor_.get()); | 926 DCHECK(!sync_processor_.get()); |
| 880 DCHECK(sync_processor.get()); | 927 DCHECK(sync_processor.get()); |
| 881 DCHECK(sync_error_factory.get()); | 928 DCHECK(sync_error_factory.get()); |
| 882 sync_processor_ = sync_processor.Pass(); | 929 sync_processor_ = sync_processor.Pass(); |
| 883 sync_error_factory_ = sync_error_factory.Pass(); | 930 sync_error_factory_ = sync_error_factory.Pass(); |
| 884 | 931 |
| 885 // We just started syncing, so set our wait-for-default flag if we are | 932 // We just started syncing, so set our wait-for-default flag if we are |
| 886 // expecting a default from Sync. | 933 // expecting a default from Sync. |
| 887 if (GetPrefs()) { | 934 if (GetPrefs()) { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 917 if (local_turl) { | 964 if (local_turl) { |
| 918 // This local search engine is already synced. If the timestamp differs | 965 // This local search engine is already synced. If the timestamp differs |
| 919 // from Sync, we need to update locally or to the cloud. Note that if the | 966 // from Sync, we need to update locally or to the cloud. Note that if the |
| 920 // timestamps are equal, we touch neither. | 967 // timestamps are equal, we touch neither. |
| 921 if (sync_turl->last_modified() > local_turl->last_modified()) { | 968 if (sync_turl->last_modified() > local_turl->last_modified()) { |
| 922 // We've received an update from Sync. We should replace all synced | 969 // We've received an update from Sync. We should replace all synced |
| 923 // fields in the local TemplateURL. Note that this includes the | 970 // fields in the local TemplateURL. Note that this includes the |
| 924 // TemplateURLID and the TemplateURL may have to be reparsed. This | 971 // TemplateURLID and the TemplateURL may have to be reparsed. This |
| 925 // also makes the local data's last_modified timestamp equal to Sync's, | 972 // also makes the local data's last_modified timestamp equal to Sync's, |
| 926 // avoiding an Update on the next MergeData call. | 973 // avoiding an Update on the next MergeData call. |
| 927 UpdateNoNotify(local_turl, *sync_turl); | 974 if (UpdateNoNotify(local_turl, *sync_turl)) |
| 928 NotifyObservers(); | 975 NotifyObservers(); |
| 929 } else if (sync_turl->last_modified() < local_turl->last_modified()) { | 976 } else if (sync_turl->last_modified() < local_turl->last_modified()) { |
| 930 // Otherwise, we know we have newer data, so update Sync with our | 977 // Otherwise, we know we have newer data, so update Sync with our |
| 931 // data fields. | 978 // data fields. |
| 932 new_changes.push_back(SyncChange(SyncChange::ACTION_UPDATE, | 979 new_changes.push_back(SyncChange(SyncChange::ACTION_UPDATE, |
| 933 local_data_map[local_turl->sync_guid()])); | 980 local_data_map[local_turl->sync_guid()])); |
| 934 } | 981 } |
| 935 local_data_map.erase(iter->first); | 982 local_data_map.erase(iter->first); |
| 936 } else { | 983 } else { |
| 937 // The search engine from the cloud has not been synced locally, but there | 984 // The search engine from the cloud has not been synced locally, but there |
| 938 // might be a local search engine that is a duplicate that needs to be | 985 // might be a local search engine that is a duplicate that needs to be |
| 939 // merged. | 986 // merged. |
| 940 TemplateURL* dupe_turl = FindDuplicateOfSyncTemplateURL(*sync_turl); | 987 TemplateURL* dupe_turl = FindDuplicateOfSyncTemplateURL(*sync_turl); |
| 941 if (dupe_turl) { | 988 if (dupe_turl) { |
| 942 // Merge duplicates and remove the processed local TURL from the map. | 989 // Merge duplicates and remove the processed local TURL from the map. |
| 943 std::string old_guid = dupe_turl->sync_guid(); | 990 std::string old_guid = dupe_turl->sync_guid(); |
| 944 MergeSyncAndLocalURLDuplicates(sync_turl.release(), dupe_turl, | 991 MergeSyncAndLocalURLDuplicates(sync_turl.release(), dupe_turl, |
| 945 &new_changes); | 992 &new_changes); |
| 946 local_data_map.erase(old_guid); | 993 local_data_map.erase(old_guid); |
| 947 } else { | 994 } else { |
| 948 std::string guid = sync_turl->sync_guid(); | 995 std::string guid = sync_turl->sync_guid(); |
| 949 // Keyword conflict is possible in this case. Resolve it first before | 996 // Keyword conflict is possible in this case. Resolve it first before |
| 950 // adding the new TemplateURL. Note that we don't remove the local TURL | 997 // adding the new TemplateURL. Note that we don't remove the local TURL |
| 951 // from local_data_map in this case as it may still need to be pushed to | 998 // from local_data_map in this case as it may still need to be pushed to |
| 952 // the cloud. | 999 // the cloud. We also explicitly don't resolve conflicts against |
| 953 ResolveSyncKeywordConflict(sync_turl.get(), &new_changes); | 1000 // extension keywords; see comments in ProcessSyncChanges(). |
| 1001 TemplateURL* existing_keyword_turl = | |
| 1002 FindNonExtensionTemplateURLForKeyword(sync_turl->keyword()); | |
| 1003 if (existing_keyword_turl) { | |
| 1004 ResolveSyncKeywordConflict(sync_turl.get(), existing_keyword_turl, | |
| 1005 &new_changes); | |
| 1006 } | |
| 954 // Force the local ID to kInvalidTemplateURLID so we can add it. | 1007 // Force the local ID to kInvalidTemplateURLID so we can add it. |
| 955 TemplateURLData data(sync_turl->data()); | 1008 TemplateURLData data(sync_turl->data()); |
| 956 data.id = kInvalidTemplateURLID; | 1009 data.id = kInvalidTemplateURLID; |
| 957 Add(new TemplateURL(profile_, data)); | 1010 Add(new TemplateURL(profile_, data)); |
| 958 | 1011 |
| 959 // Possibly set the newly added |turl| as the default search provider. | 1012 // Possibly set the newly added |turl| as the default search provider. |
| 960 SetDefaultSearchProviderIfNewlySynced(guid); | 1013 SetDefaultSearchProviderIfNewlySynced(guid); |
| 961 } | 1014 } |
| 962 } | 1015 } |
| 963 } | 1016 } |
| 964 | 1017 |
| 965 // The remaining SyncData in local_data_map should be everything that needs to | 1018 // The remaining SyncData in local_data_map should be everything that needs to |
| 966 // be pushed as ADDs to sync. | 1019 // be pushed as ADDs to sync. |
| 967 for (SyncDataMap::const_iterator iter = local_data_map.begin(); | 1020 for (SyncDataMap::const_iterator iter = local_data_map.begin(); |
| 968 iter != local_data_map.end(); ++iter) { | 1021 iter != local_data_map.end(); ++iter) { |
| 969 new_changes.push_back(SyncChange(SyncChange::ACTION_ADD, iter->second)); | 1022 new_changes.push_back(SyncChange(SyncChange::ACTION_ADD, iter->second)); |
| 970 } | 1023 } |
| 971 | 1024 |
| 1025 PreventDuplicateGUIDUpdates(&new_changes); | |
| 1026 | |
| 972 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); | 1027 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); |
| 973 if (error.IsSet()) | 1028 if (error.IsSet()) |
| 974 return error; | 1029 return error; |
| 975 | 1030 |
| 976 models_associated_ = true; | 1031 models_associated_ = true; |
| 977 return SyncError(); | 1032 return SyncError(); |
| 978 } | 1033 } |
| 979 | 1034 |
| 980 void TemplateURLService::StopSyncing(syncable::ModelType type) { | 1035 void TemplateURLService::StopSyncing(syncable::ModelType type) { |
| 981 DCHECK_EQ(type, syncable::SEARCH_ENGINES); | 1036 DCHECK_EQ(type, syncable::SEARCH_ENGINES); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1024 se_specifics->set_keyword(UTF16ToUTF8(turl.keyword())); | 1079 se_specifics->set_keyword(UTF16ToUTF8(turl.keyword())); |
| 1025 se_specifics->set_favicon_url(turl.favicon_url().spec()); | 1080 se_specifics->set_favicon_url(turl.favicon_url().spec()); |
| 1026 se_specifics->set_url(turl.url()); | 1081 se_specifics->set_url(turl.url()); |
| 1027 se_specifics->set_safe_for_autoreplace(turl.safe_for_autoreplace()); | 1082 se_specifics->set_safe_for_autoreplace(turl.safe_for_autoreplace()); |
| 1028 se_specifics->set_originating_url(turl.originating_url().spec()); | 1083 se_specifics->set_originating_url(turl.originating_url().spec()); |
| 1029 se_specifics->set_date_created(turl.date_created().ToInternalValue()); | 1084 se_specifics->set_date_created(turl.date_created().ToInternalValue()); |
| 1030 se_specifics->set_input_encodings(JoinString(turl.input_encodings(), ';')); | 1085 se_specifics->set_input_encodings(JoinString(turl.input_encodings(), ';')); |
| 1031 se_specifics->set_show_in_default_list(turl.show_in_default_list()); | 1086 se_specifics->set_show_in_default_list(turl.show_in_default_list()); |
| 1032 se_specifics->set_suggestions_url(turl.suggestions_url()); | 1087 se_specifics->set_suggestions_url(turl.suggestions_url()); |
| 1033 se_specifics->set_prepopulate_id(turl.prepopulate_id()); | 1088 se_specifics->set_prepopulate_id(turl.prepopulate_id()); |
| 1034 se_specifics->set_autogenerate_keyword(turl.autogenerate_keyword()); | 1089 // REVIEWERS: Should I instead remove this line entirely? |
| 1090 se_specifics->set_autogenerate_keyword(false); | |
| 1035 se_specifics->set_instant_url(turl.instant_url()); | 1091 se_specifics->set_instant_url(turl.instant_url()); |
| 1036 se_specifics->set_last_modified(turl.last_modified().ToInternalValue()); | 1092 se_specifics->set_last_modified(turl.last_modified().ToInternalValue()); |
| 1037 se_specifics->set_sync_guid(turl.sync_guid()); | 1093 se_specifics->set_sync_guid(turl.sync_guid()); |
| 1038 return SyncData::CreateLocalData(se_specifics->sync_guid(), | 1094 return SyncData::CreateLocalData(se_specifics->sync_guid(), |
| 1039 se_specifics->keyword(), | 1095 se_specifics->keyword(), |
| 1040 specifics); | 1096 specifics); |
| 1041 } | 1097 } |
| 1042 | 1098 |
| 1043 // static | 1099 // static |
| 1044 TemplateURL* TemplateURLService::CreateTemplateURLFromTemplateURLAndSyncData( | 1100 TemplateURL* TemplateURLService::CreateTemplateURLFromTemplateURLAndSyncData( |
| 1045 Profile* profile, | 1101 Profile* profile, |
| 1046 TemplateURL* existing_turl, | 1102 TemplateURL* existing_turl, |
| 1047 const SyncData& sync_data, | 1103 const SyncData& sync_data, |
| 1048 SyncChangeList* change_list) { | 1104 SyncChangeList* change_list) { |
| 1049 DCHECK(change_list); | 1105 DCHECK(change_list); |
| 1050 | 1106 |
| 1051 sync_pb::SearchEngineSpecifics specifics = | 1107 sync_pb::SearchEngineSpecifics specifics = |
| 1052 sync_data.GetSpecifics().search_engine(); | 1108 sync_data.GetSpecifics().search_engine(); |
| 1053 | 1109 |
| 1054 // Past bugs might have caused either of these fields to be empty. Just | 1110 // Past bugs might have caused either of these fields to be empty. Just |
| 1055 // delete this data off the server. | 1111 // delete this data off the server. |
| 1056 if (specifics.url().empty() || specifics.sync_guid().empty()) { | 1112 if (specifics.url().empty() || specifics.sync_guid().empty()) { |
| 1057 change_list->push_back(SyncChange(SyncChange::ACTION_DELETE, sync_data)); | 1113 change_list->push_back(SyncChange(SyncChange::ACTION_DELETE, sync_data)); |
| 1058 return NULL; | 1114 return NULL; |
| 1059 } | 1115 } |
| 1060 | 1116 |
| 1061 TemplateURLData data; | 1117 TemplateURLData data; |
| 1062 data.short_name = UTF8ToUTF16(specifics.short_name()); | 1118 data.short_name = UTF8ToUTF16(specifics.short_name()); |
| 1063 data.originating_url = GURL(specifics.originating_url()); | 1119 data.originating_url = GURL(specifics.originating_url()); |
| 1064 data.SetKeyword(UTF8ToUTF16(specifics.keyword())); | 1120 string16 keyword(UTF8ToUTF16(specifics.keyword())); |
| 1065 data.SetAutogenerateKeyword(specifics.autogenerate_keyword()); | 1121 // REVIEWERS: Can we ever get to a state where this migration code can be |
| 1122 // eliminated? | |
|
SteveT
2012/05/07 19:33:49
This seems like something we want to check for qui
| |
| 1123 bool reset_keyword = | |
| 1124 specifics.autogenerate_keyword() || specifics.keyword().empty(); | |
| 1125 if (reset_keyword) | |
| 1126 keyword = ASCIIToUTF16("dummy"); // Will be replaced below. | |
| 1127 DCHECK(!keyword.empty()); | |
| 1128 data.SetKeyword(keyword); | |
| 1066 data.SetURL(specifics.url()); | 1129 data.SetURL(specifics.url()); |
| 1067 data.suggestions_url = specifics.suggestions_url(); | 1130 data.suggestions_url = specifics.suggestions_url(); |
| 1068 data.instant_url = specifics.instant_url(); | 1131 data.instant_url = specifics.instant_url(); |
| 1069 data.favicon_url = GURL(specifics.favicon_url()); | 1132 data.favicon_url = GURL(specifics.favicon_url()); |
| 1070 data.show_in_default_list = specifics.show_in_default_list(); | 1133 data.show_in_default_list = specifics.show_in_default_list(); |
| 1071 data.safe_for_autoreplace = specifics.safe_for_autoreplace(); | 1134 data.safe_for_autoreplace = specifics.safe_for_autoreplace(); |
| 1072 base::SplitString(specifics.input_encodings(), ';', &data.input_encodings); | 1135 base::SplitString(specifics.input_encodings(), ';', &data.input_encodings); |
| 1073 data.date_created = base::Time::FromInternalValue(specifics.date_created()); | 1136 data.date_created = base::Time::FromInternalValue(specifics.date_created()); |
| 1074 data.last_modified = base::Time::FromInternalValue(specifics.last_modified()); | 1137 data.last_modified = base::Time::FromInternalValue(specifics.last_modified()); |
| 1075 data.prepopulate_id = specifics.prepopulate_id(); | 1138 data.prepopulate_id = specifics.prepopulate_id(); |
| 1076 data.sync_guid = specifics.sync_guid(); | 1139 data.sync_guid = specifics.sync_guid(); |
| 1077 if (existing_turl) { | 1140 if (existing_turl) { |
| 1078 data.id = existing_turl->id(); | 1141 data.id = existing_turl->id(); |
| 1079 data.created_by_policy = existing_turl->created_by_policy(); | 1142 data.created_by_policy = existing_turl->created_by_policy(); |
| 1080 data.usage_count = existing_turl->usage_count(); | 1143 data.usage_count = existing_turl->usage_count(); |
| 1081 } | 1144 } |
| 1082 | 1145 |
| 1083 TemplateURL* turl = new TemplateURL(profile, data); | 1146 TemplateURL* turl = new TemplateURL(profile, data); |
| 1084 DCHECK(!turl->IsExtensionKeyword()); | 1147 DCHECK(!turl->IsExtensionKeyword()); |
| 1148 if (reset_keyword) { | |
| 1149 turl->ResetKeywordIfNecessary(true); | |
| 1150 SyncData sync_data = CreateSyncDataFromTemplateURL(*turl); | |
| 1151 change_list->push_back(SyncChange(SyncChange::ACTION_UPDATE, sync_data)); | |
| 1152 } | |
| 1085 return turl; | 1153 return turl; |
| 1086 } | 1154 } |
| 1087 | 1155 |
| 1088 // static | 1156 // static |
| 1089 SyncDataMap TemplateURLService::CreateGUIDToSyncDataMap( | 1157 SyncDataMap TemplateURLService::CreateGUIDToSyncDataMap( |
| 1090 const SyncDataList& sync_data) { | 1158 const SyncDataList& sync_data) { |
| 1091 SyncDataMap data_map; | 1159 SyncDataMap data_map; |
| 1092 for (SyncDataList::const_iterator i(sync_data.begin()); i != sync_data.end(); | 1160 for (SyncDataList::const_iterator i(sync_data.begin()); i != sync_data.end(); |
| 1093 ++i) | 1161 ++i) |
| 1094 data_map[i->GetSpecifics().search_engine().sync_guid()] = *i; | 1162 data_map[i->GetSpecifics().search_engine().sync_guid()] = *i; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1160 if (initial_default_search_provider_.get() && | 1228 if (initial_default_search_provider_.get() && |
| 1161 initial_default_search_provider_->url_ref().HasGoogleBaseURLs()) { | 1229 initial_default_search_provider_->url_ref().HasGoogleBaseURLs()) { |
| 1162 scoped_ptr<base::Environment> env(base::Environment::Create()); | 1230 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 1163 if (!env->HasVar(env_vars::kHeadless) && | 1231 if (!env->HasVar(env_vars::kHeadless) && |
| 1164 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeFrame)) | 1232 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeFrame)) |
| 1165 GoogleURLTracker::RequestServerCheck(); | 1233 GoogleURLTracker::RequestServerCheck(); |
| 1166 } | 1234 } |
| 1167 } | 1235 } |
| 1168 | 1236 |
| 1169 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) { | 1237 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) { |
| 1170 if (!template_url->keyword().empty()) | 1238 const string16& keyword = template_url->keyword(); |
| 1171 keyword_to_template_map_.erase(template_url->keyword()); | 1239 DCHECK_NE(0U, keyword_to_template_map_.count(keyword)); |
| 1240 if (keyword_to_template_map_[keyword] == template_url) { | |
| 1241 // We need to check whether the keyword can now be provided by another | |
| 1242 // TemplateURL. See the comments in AddToMaps() for more information on | |
| 1243 // extension keywords and how they can coexist with non-extension keywords. | |
| 1244 // In the case of more than one extension, we use the most recently | |
| 1245 // installed (which will be the most recently added, which will have the | |
| 1246 // highest ID). | |
| 1247 TemplateURL* best_fallback = NULL; | |
| 1248 for (TemplateURLVector::const_iterator i(template_urls_.begin()); | |
| 1249 i != template_urls_.end(); ++i) { | |
| 1250 TemplateURL* turl = *i; | |
| 1251 // This next statement relies on the fact that there can only be one | |
| 1252 // non-extension TemplateURL with a given keyword. | |
| 1253 if ((turl != template_url) && (turl->keyword() == keyword) && | |
| 1254 (!best_fallback || !best_fallback->IsExtensionKeyword() || | |
| 1255 (turl->IsExtensionKeyword() && (turl->id() > best_fallback->id())))) | |
| 1256 best_fallback = turl; | |
| 1257 } | |
| 1258 if (best_fallback) | |
| 1259 keyword_to_template_map_[keyword] = best_fallback; | |
| 1260 else | |
| 1261 keyword_to_template_map_.erase(keyword); | |
| 1262 } | |
| 1172 | 1263 |
| 1173 // If the keyword we're removing is from an extension, we're now done, since | 1264 // If the keyword we're removing is from an extension, we're now done, since |
| 1174 // it won't be synced or stored in the provider map. | 1265 // it won't be synced or stored in the provider map. |
| 1175 // TODO(mpcomplete): If we allow editing extension keywords, then those should | 1266 // TODO(mpcomplete): If we allow editing extension keywords, then those should |
| 1176 // be synced. | 1267 // be synced. |
| 1177 if (template_url->IsExtensionKeyword()) | 1268 if (template_url->IsExtensionKeyword()) |
| 1178 return; | 1269 return; |
| 1179 | 1270 |
| 1180 if (!template_url->sync_guid().empty()) | 1271 if (!template_url->sync_guid().empty()) |
| 1181 guid_to_template_map_.erase(template_url->sync_guid()); | 1272 guid_to_template_map_.erase(template_url->sync_guid()); |
| 1182 if (loaded_) | 1273 if (loaded_) |
| 1183 provider_map_->Remove(template_url); | 1274 provider_map_->Remove(template_url); |
| 1184 } | 1275 } |
| 1185 | 1276 |
| 1186 void TemplateURLService::RemoveFromKeywordMapByPointer( | 1277 void TemplateURLService::RemoveFromKeywordMapByPointer( |
| 1187 TemplateURL* template_url) { | 1278 TemplateURL* template_url) { |
| 1188 DCHECK(template_url); | 1279 DCHECK(template_url); |
| 1189 for (KeywordToTemplateMap::iterator i = keyword_to_template_map_.begin(); | 1280 for (KeywordToTemplateMap::iterator i = keyword_to_template_map_.begin(); |
| 1190 i != keyword_to_template_map_.end(); ++i) { | 1281 i != keyword_to_template_map_.end(); ++i) { |
| 1191 if (i->second == template_url) { | 1282 if (i->second == template_url) { |
| 1192 keyword_to_template_map_.erase(i); | 1283 keyword_to_template_map_.erase(i); |
| 1193 // A given TemplateURL only occurs once in the map. As soon as we find the | 1284 // A given TemplateURL only occurs once in the map. As soon as we find the |
| 1194 // entry, stop. | 1285 // entry, stop. |
| 1195 break; | 1286 break; |
| 1196 } | 1287 } |
| 1197 } | 1288 } |
| 1198 } | 1289 } |
| 1199 | 1290 |
| 1200 void TemplateURLService::AddToMaps(TemplateURL* template_url) { | 1291 void TemplateURLService::AddToMaps(TemplateURL* template_url) { |
| 1201 if (!template_url->keyword().empty()) | 1292 bool template_extension = template_url->IsExtensionKeyword(); |
| 1202 keyword_to_template_map_[template_url->keyword()] = template_url; | 1293 const string16& keyword = template_url->keyword(); |
| 1294 KeywordToTemplateMap::const_iterator i = | |
| 1295 keyword_to_template_map_.find(keyword); | |
| 1296 if (i == keyword_to_template_map_.end()) { | |
| 1297 keyword_to_template_map_[keyword] = template_url; | |
| 1298 } else { | |
| 1299 const TemplateURL* existing_url = i->second; | |
| 1300 // We should only have overlapping keywords when at least one comes from | |
| 1301 // an extension. In that case, the ranking order is: | |
| 1302 // Manually-modified keywords > extension keywords > replaceable keywords | |
| 1303 // When there are multiple extensions, the last-added wins. | |
| 1304 bool existing_extension = existing_url->IsExtensionKeyword(); | |
| 1305 DCHECK(existing_extension || template_extension); | |
| 1306 if (existing_extension ? | |
| 1307 !CanReplace(template_url) : CanReplace(existing_url)) | |
| 1308 keyword_to_template_map_[keyword] = template_url; | |
| 1309 } | |
| 1203 | 1310 |
| 1204 // Extension keywords are not synced, so they don't go into the GUID map, | 1311 // Extension keywords are not synced, so they don't go into the GUID map, |
| 1205 // and do not use host-based search URLs, so they don't go into the provider | 1312 // and do not use host-based search URLs, so they don't go into the provider |
| 1206 // map, so at this point we're done. | 1313 // map, so at this point we're done. |
| 1207 // TODO(mpcomplete): If we allow editing extension keywords, then those should | 1314 // TODO(mpcomplete): If we allow editing extension keywords, then those should |
| 1208 // be persisted to disk and synced. | 1315 // be persisted to disk and synced. |
| 1209 if (template_url->IsExtensionKeyword()) | 1316 if (template_extension) |
| 1210 return; | 1317 return; |
| 1211 | 1318 |
| 1212 if (!template_url->sync_guid().empty()) | 1319 if (!template_url->sync_guid().empty()) |
| 1213 guid_to_template_map_[template_url->sync_guid()] = template_url; | 1320 guid_to_template_map_[template_url->sync_guid()] = template_url; |
| 1214 if (loaded_) { | 1321 if (loaded_) { |
| 1215 UIThreadSearchTermsData search_terms_data; | 1322 UIThreadSearchTermsData search_terms_data; |
| 1216 provider_map_->Add(template_url, search_terms_data); | 1323 provider_map_->Add(template_url, search_terms_data); |
| 1217 } | 1324 } |
| 1218 } | 1325 } |
| 1219 | 1326 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1319 if (!prefs->GetBoolean(prefs::kDefaultSearchProviderEnabled)) { | 1426 if (!prefs->GetBoolean(prefs::kDefaultSearchProviderEnabled)) { |
| 1320 // The user doesn't want a default search provider. | 1427 // The user doesn't want a default search provider. |
| 1321 default_provider->reset(NULL); | 1428 default_provider->reset(NULL); |
| 1322 return true; | 1429 return true; |
| 1323 } | 1430 } |
| 1324 | 1431 |
| 1325 string16 name = | 1432 string16 name = |
| 1326 UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderName)); | 1433 UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderName)); |
| 1327 string16 keyword = | 1434 string16 keyword = |
| 1328 UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderKeyword)); | 1435 UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderKeyword)); |
| 1436 // Force keyword to be non-empty. | |
| 1437 // TODO(pkasting): This is only necessary as long as we're potentially loading | |
| 1438 // older prefs where empty keywords are theoretically possible. Eventually | |
| 1439 // this code can be replaced with a DCHECK(!keyword.empty());. | |
| 1440 bool update_keyword = keyword.empty(); | |
| 1441 if (update_keyword) | |
| 1442 keyword = ASCIIToUTF16("dummy"); | |
| 1329 std::string search_url = | 1443 std::string search_url = |
| 1330 prefs->GetString(prefs::kDefaultSearchProviderSearchURL); | 1444 prefs->GetString(prefs::kDefaultSearchProviderSearchURL); |
| 1331 // Force URL to be non-empty. We've never supported this case, but past bugs | 1445 // Force URL to be non-empty. We've never supported this case, but past bugs |
| 1332 // might have resulted in it slipping through; eventually this code can be | 1446 // might have resulted in it slipping through; eventually this code can be |
| 1333 // replaced with a DCHECK(!search_url.empty());. | 1447 // replaced with a DCHECK(!search_url.empty());. |
| 1334 if (search_url.empty()) | 1448 if (search_url.empty()) |
| 1335 return false; | 1449 return false; |
| 1336 std::string suggest_url = | 1450 std::string suggest_url = |
| 1337 prefs->GetString(prefs::kDefaultSearchProviderSuggestURL); | 1451 prefs->GetString(prefs::kDefaultSearchProviderSuggestURL); |
| 1338 std::string instant_url = | 1452 std::string instant_url = |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1359 base::StringToInt64(id_string, &value); | 1473 base::StringToInt64(id_string, &value); |
| 1360 data.id = value; | 1474 data.id = value; |
| 1361 } | 1475 } |
| 1362 if (!prepopulate_id.empty() && !*is_managed) { | 1476 if (!prepopulate_id.empty() && !*is_managed) { |
| 1363 int value; | 1477 int value; |
| 1364 base::StringToInt(prepopulate_id, &value); | 1478 base::StringToInt(prepopulate_id, &value); |
| 1365 data.prepopulate_id = value; | 1479 data.prepopulate_id = value; |
| 1366 } | 1480 } |
| 1367 default_provider->reset(new TemplateURL(profile_, data)); | 1481 default_provider->reset(new TemplateURL(profile_, data)); |
| 1368 DCHECK(!(*default_provider)->IsExtensionKeyword()); | 1482 DCHECK(!(*default_provider)->IsExtensionKeyword()); |
| 1483 if (update_keyword) | |
| 1484 (*default_provider)->ResetKeywordIfNecessary(true); | |
| 1369 return true; | 1485 return true; |
| 1370 } | 1486 } |
| 1371 | 1487 |
| 1372 bool TemplateURLService::CanReplaceKeywordForHost( | 1488 bool TemplateURLService::CanReplaceKeywordForHost( |
| 1373 const std::string& host, | 1489 const std::string& host, |
| 1374 TemplateURL** to_replace) { | 1490 TemplateURL** to_replace) { |
| 1375 DCHECK(!to_replace || !*to_replace); | 1491 DCHECK(!to_replace || !*to_replace); |
| 1376 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host); | 1492 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host); |
| 1377 if (!urls) | 1493 if (!urls) |
| 1378 return true; | 1494 return true; |
| 1379 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) { | 1495 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) { |
| 1380 if (CanReplace(*i)) { | 1496 if (CanReplace(*i)) { |
| 1381 if (to_replace) | 1497 if (to_replace) |
| 1382 *to_replace = *i; | 1498 *to_replace = *i; |
| 1383 return true; | 1499 return true; |
| 1384 } | 1500 } |
| 1385 } | 1501 } |
| 1386 return false; | 1502 return false; |
| 1387 } | 1503 } |
| 1388 | 1504 |
| 1389 bool TemplateURLService::CanReplace(const TemplateURL* t_url) { | 1505 bool TemplateURLService::CanReplace(const TemplateURL* t_url) { |
| 1390 return (t_url != default_search_provider_ && !t_url->show_in_default_list() && | 1506 return (t_url != default_search_provider_ && !t_url->show_in_default_list() && |
| 1391 t_url->safe_for_autoreplace()); | 1507 t_url->safe_for_autoreplace()); |
| 1392 } | 1508 } |
| 1393 | 1509 |
| 1394 void TemplateURLService::UpdateNoNotify(TemplateURL* existing_turl, | 1510 TemplateURL* TemplateURLService::FindNonExtensionTemplateURLForKeyword( |
| 1511 const string16& keyword) { | |
| 1512 TemplateURL* keyword_turl = GetTemplateURLForKeyword(keyword); | |
| 1513 if (!keyword_turl || !keyword_turl->IsExtensionKeyword()) | |
| 1514 return keyword_turl; | |
| 1515 // The extension keyword in the model may be hiding a replaceable | |
| 1516 // non-extension keyword. Look for it. | |
| 1517 for (TemplateURLVector::const_iterator i(template_urls_.begin()); | |
| 1518 i != template_urls_.end(); ++i) { | |
| 1519 if (!(*i)->IsExtensionKeyword() && ((*i)->keyword() == keyword)) | |
| 1520 return *i; | |
| 1521 } | |
| 1522 return NULL; | |
| 1523 } | |
| 1524 | |
| 1525 bool TemplateURLService::UpdateNoNotify(TemplateURL* existing_turl, | |
| 1395 const TemplateURL& new_values) { | 1526 const TemplateURL& new_values) { |
| 1396 DCHECK(loaded_); | 1527 DCHECK(loaded_); |
| 1397 DCHECK(existing_turl); | 1528 DCHECK(existing_turl); |
| 1398 DCHECK(std::find(template_urls_.begin(), template_urls_.end(), | 1529 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == |
| 1399 existing_turl) != template_urls_.end()); | 1530 template_urls_.end()) |
| 1531 return false; | |
| 1400 | 1532 |
| 1401 // TODO(mpcomplete): If we allow editing extension keywords, then those should | 1533 // TODO(mpcomplete): If we allow editing extension keywords, then those should |
| 1402 // be persisted to disk and synced. In this case this DCHECK should be | 1534 // be persisted to disk and synced. In this case this DCHECK should be |
| 1403 // removed. | 1535 // removed. |
| 1404 DCHECK(!existing_turl->IsExtensionKeyword()); | 1536 DCHECK(!existing_turl->IsExtensionKeyword()); |
| 1405 | 1537 |
| 1406 string16 old_keyword(existing_turl->keyword()); | 1538 string16 old_keyword(existing_turl->keyword()); |
| 1407 if (!old_keyword.empty()) | 1539 keyword_to_template_map_.erase(old_keyword); |
| 1408 keyword_to_template_map_.erase(old_keyword); | |
| 1409 if (!existing_turl->sync_guid().empty()) | 1540 if (!existing_turl->sync_guid().empty()) |
| 1410 guid_to_template_map_.erase(existing_turl->sync_guid()); | 1541 guid_to_template_map_.erase(existing_turl->sync_guid()); |
| 1411 | 1542 |
| 1412 provider_map_->Remove(existing_turl); | 1543 provider_map_->Remove(existing_turl); |
| 1413 TemplateURLID previous_id = existing_turl->id(); | 1544 TemplateURLID previous_id = existing_turl->id(); |
| 1414 *existing_turl = new_values; | 1545 *existing_turl = new_values; |
| 1415 existing_turl->data_.id = previous_id; | 1546 existing_turl->data_.id = previous_id; |
| 1416 UIThreadSearchTermsData search_terms_data; | 1547 UIThreadSearchTermsData search_terms_data; |
| 1417 provider_map_->Add(existing_turl, search_terms_data); | 1548 provider_map_->Add(existing_turl, search_terms_data); |
| 1418 | 1549 |
| 1419 const string16& keyword = existing_turl->keyword(); | 1550 const string16& keyword = existing_turl->keyword(); |
| 1420 if (!keyword.empty()) | 1551 KeywordToTemplateMap::const_iterator i = |
| 1552 keyword_to_template_map_.find(keyword); | |
| 1553 if (i == keyword_to_template_map_.end()) { | |
| 1421 keyword_to_template_map_[keyword] = existing_turl; | 1554 keyword_to_template_map_[keyword] = existing_turl; |
| 1555 } else { | |
| 1556 // We can theoretically reach here in two cases: | |
| 1557 // * There is an existing extension keyword and sync brings in a rename of | |
| 1558 // a non-extension keyword to match. In this case we just need to pick | |
| 1559 // which keyword has priority to update the keyword map. | |
| 1560 // * Autogeneration of the keyword for a Google default search provider | |
| 1561 // at load time causes it to conflict with an existing keyword. In this | |
| 1562 // case we delete the existing keyword if it's replaceable, or else undo | |
| 1563 // the change in keyword for |existing_turl|. | |
| 1564 DCHECK(!existing_turl->IsExtensionKeyword()); | |
| 1565 TemplateURL* existing_keyword_turl = i->second; | |
| 1566 if (existing_keyword_turl->IsExtensionKeyword()) { | |
| 1567 if (!CanReplace(existing_turl)) | |
| 1568 keyword_to_template_map_[keyword] = existing_turl; | |
| 1569 } else { | |
| 1570 if (CanReplace(existing_keyword_turl)) { | |
| 1571 RemoveNoNotify(existing_keyword_turl); | |
| 1572 } else { | |
| 1573 existing_turl->data_.SetKeyword(old_keyword); | |
| 1574 keyword_to_template_map_[old_keyword] = existing_turl; | |
| 1575 } | |
| 1576 } | |
| 1577 } | |
| 1422 if (!existing_turl->sync_guid().empty()) | 1578 if (!existing_turl->sync_guid().empty()) |
| 1423 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl; | 1579 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl; |
| 1424 | 1580 |
| 1425 if (service_.get()) | 1581 if (service_.get()) |
| 1426 service_->UpdateKeyword(*existing_turl); | 1582 service_->UpdateKeyword(existing_turl->data()); |
| 1427 | 1583 |
| 1428 // Inform sync of the update. | 1584 // Inform sync of the update. |
| 1429 ProcessTemplateURLChange(existing_turl, SyncChange::ACTION_UPDATE); | 1585 ProcessTemplateURLChange(existing_turl, SyncChange::ACTION_UPDATE); |
| 1430 | 1586 |
| 1431 if (default_search_provider_ == existing_turl) | 1587 if (default_search_provider_ == existing_turl) { |
| 1432 SetDefaultSearchProviderNoNotify(existing_turl); | 1588 bool success = SetDefaultSearchProviderNoNotify(existing_turl); |
| 1589 DCHECK(success); | |
| 1590 } | |
| 1591 return true; | |
| 1433 } | 1592 } |
| 1434 | 1593 |
| 1435 PrefService* TemplateURLService::GetPrefs() { | 1594 PrefService* TemplateURLService::GetPrefs() { |
| 1436 return profile_ ? profile_->GetPrefs() : NULL; | 1595 return profile_ ? profile_->GetPrefs() : NULL; |
| 1437 } | 1596 } |
| 1438 | 1597 |
| 1439 void TemplateURLService::UpdateKeywordSearchTermsForURL( | 1598 void TemplateURLService::UpdateKeywordSearchTermsForURL( |
| 1440 const history::URLVisitedDetails& details) { | 1599 const history::URLVisitedDetails& details) { |
| 1441 const history::URLRow& row = details.row; | 1600 const history::URLRow& row = details.row; |
| 1442 if (!row.url().is_valid() || | 1601 if (!row.url().is_valid() || |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1557 bool something_changed = false; | 1716 bool something_changed = false; |
| 1558 for (TemplateURLVector::iterator i(template_urls_.begin()); | 1717 for (TemplateURLVector::iterator i(template_urls_.begin()); |
| 1559 i != template_urls_.end(); ++i) { | 1718 i != template_urls_.end(); ++i) { |
| 1560 TemplateURL* t_url = *i; | 1719 TemplateURL* t_url = *i; |
| 1561 if (t_url->url_ref().HasGoogleBaseURLs() || | 1720 if (t_url->url_ref().HasGoogleBaseURLs() || |
| 1562 t_url->suggestions_url_ref().HasGoogleBaseURLs()) { | 1721 t_url->suggestions_url_ref().HasGoogleBaseURLs()) { |
| 1563 something_changed = true; | 1722 something_changed = true; |
| 1564 string16 original_keyword(t_url->keyword()); | 1723 string16 original_keyword(t_url->keyword()); |
| 1565 t_url->InvalidateCachedValues(); | 1724 t_url->InvalidateCachedValues(); |
| 1566 const string16& new_keyword(t_url->keyword()); | 1725 const string16& new_keyword(t_url->keyword()); |
| 1726 KeywordToTemplateMap::const_iterator i = | |
| 1727 keyword_to_template_map_.find(new_keyword); | |
| 1728 if ((i != keyword_to_template_map_.end()) && (i->second != t_url)) { | |
| 1729 // The new autogenerated keyword conflicts with another TemplateURL. | |
| 1730 // Overwrite it if it's replaceable; otherwise just reset |t_url|'s | |
| 1731 // keyword. (This will not prevent |t_url| from auto-updating the | |
| 1732 // keyword in the future if the conflicting TemplateURL disappears.) | |
| 1733 if (!CanReplace(i->second)) { | |
| 1734 t_url->data_.SetKeyword(original_keyword); | |
| 1735 continue; | |
| 1736 } | |
| 1737 RemoveNoNotify(i->second); | |
| 1738 } | |
| 1567 RemoveFromKeywordMapByPointer(t_url); | 1739 RemoveFromKeywordMapByPointer(t_url); |
| 1568 if (!new_keyword.empty()) | 1740 keyword_to_template_map_[new_keyword] = t_url; |
| 1569 keyword_to_template_map_[new_keyword] = t_url; | |
| 1570 } | 1741 } |
| 1571 } | 1742 } |
| 1572 | 1743 |
| 1573 if (something_changed && loaded_) { | 1744 if (something_changed && loaded_) { |
| 1574 UIThreadSearchTermsData search_terms_data; | 1745 UIThreadSearchTermsData search_terms_data; |
| 1575 provider_map_->UpdateGoogleBaseURLs(search_terms_data); | 1746 provider_map_->UpdateGoogleBaseURLs(search_terms_data); |
| 1576 NotifyObservers(); | 1747 NotifyObservers(); |
| 1577 } | 1748 } |
| 1578 } | 1749 } |
| 1579 | 1750 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1611 // if it has changed; we don't want to respond to changes triggered by | 1782 // if it has changed; we don't want to respond to changes triggered by |
| 1612 // SaveDefaultSearchProviderToPrefs. | 1783 // SaveDefaultSearchProviderToPrefs. |
| 1613 if (TemplateURLsHaveSamePrefs(default_search_provider_, | 1784 if (TemplateURLsHaveSamePrefs(default_search_provider_, |
| 1614 new_default_from_prefs.get())) | 1785 new_default_from_prefs.get())) |
| 1615 return; | 1786 return; |
| 1616 if (new_default_from_prefs.get() == NULL) { | 1787 if (new_default_from_prefs.get() == NULL) { |
| 1617 // default_search_provider_ can't be NULL otherwise | 1788 // default_search_provider_ can't be NULL otherwise |
| 1618 // TemplateURLsHaveSamePrefs would have returned true. Remove this now | 1789 // TemplateURLsHaveSamePrefs would have returned true. Remove this now |
| 1619 // invalid value. | 1790 // invalid value. |
| 1620 TemplateURL* old_default = default_search_provider_; | 1791 TemplateURL* old_default = default_search_provider_; |
| 1621 SetDefaultSearchProviderNoNotify(NULL); | 1792 bool success = SetDefaultSearchProviderNoNotify(NULL); |
| 1793 DCHECK(success); | |
| 1622 RemoveNoNotify(old_default); | 1794 RemoveNoNotify(old_default); |
| 1623 } else if (default_search_provider_) { | 1795 } else if (default_search_provider_) { |
| 1624 TemplateURLData data(new_default_from_prefs->data()); | 1796 TemplateURLData data(new_default_from_prefs->data()); |
| 1625 data.created_by_policy = true; | 1797 data.created_by_policy = true; |
| 1626 TemplateURL new_values(profile_, data); | 1798 TemplateURL new_values(profile_, data); |
| 1627 UpdateNoNotify(default_search_provider_, new_values); | 1799 UpdateNoNotify(default_search_provider_, new_values); |
| 1628 } else { | 1800 } else { |
| 1629 TemplateURL* new_template = NULL; | 1801 TemplateURL* new_template = NULL; |
| 1630 if (new_default_from_prefs.get()) { | 1802 if (new_default_from_prefs.get()) { |
| 1631 TemplateURLData data(new_default_from_prefs->data()); | 1803 TemplateURLData data(new_default_from_prefs->data()); |
| 1632 data.created_by_policy = true; | 1804 data.created_by_policy = true; |
| 1633 new_template = new TemplateURL(profile_, data); | 1805 new_template = new TemplateURL(profile_, data); |
| 1634 AddNoNotify(new_template, true); | 1806 if (!AddNoNotify(new_template, true)) |
| 1807 return; | |
| 1635 } | 1808 } |
| 1636 SetDefaultSearchProviderNoNotify(new_template); | 1809 bool success = SetDefaultSearchProviderNoNotify(new_template); |
| 1810 DCHECK(success); | |
| 1637 } | 1811 } |
| 1638 } else if (!is_default_search_managed_ && new_is_default_managed) { | 1812 } else if (!is_default_search_managed_ && new_is_default_managed) { |
| 1639 // The default used to be unmanaged and is now managed. Add the new | 1813 // The default used to be unmanaged and is now managed. Add the new |
| 1640 // managed default to the list of URLs and set it as default. | 1814 // managed default to the list of URLs and set it as default. |
| 1641 is_default_search_managed_ = new_is_default_managed; | 1815 is_default_search_managed_ = new_is_default_managed; |
| 1642 TemplateURL* new_template = NULL; | 1816 TemplateURL* new_template = NULL; |
| 1643 if (new_default_from_prefs.get()) { | 1817 if (new_default_from_prefs.get()) { |
| 1644 TemplateURLData data(new_default_from_prefs->data()); | 1818 TemplateURLData data(new_default_from_prefs->data()); |
| 1645 data.created_by_policy = true; | 1819 data.created_by_policy = true; |
| 1646 new_template = new TemplateURL(profile_, data); | 1820 new_template = new TemplateURL(profile_, data); |
| 1647 AddNoNotify(new_template, true); | 1821 if (!AddNoNotify(new_template, true)) |
| 1822 return; | |
| 1648 } | 1823 } |
| 1649 SetDefaultSearchProviderNoNotify(new_template); | 1824 bool success = SetDefaultSearchProviderNoNotify(new_template); |
| 1825 DCHECK(success); | |
| 1650 } else { | 1826 } else { |
| 1651 // The default was managed and is no longer. | 1827 // The default was managed and is no longer. |
| 1652 DCHECK(is_default_search_managed_ && !new_is_default_managed); | 1828 DCHECK(is_default_search_managed_ && !new_is_default_managed); |
| 1653 is_default_search_managed_ = new_is_default_managed; | 1829 is_default_search_managed_ = new_is_default_managed; |
| 1654 // If we had a default, delete the previous default if created by policy | 1830 // If we had a default, delete the previous default if created by policy |
| 1655 // and set a likely default. | 1831 // and set a likely default. |
| 1656 if ((default_search_provider_ != NULL) && | 1832 if ((default_search_provider_ != NULL) && |
| 1657 default_search_provider_->created_by_policy()) { | 1833 default_search_provider_->created_by_policy()) { |
| 1658 TemplateURL* old_default = default_search_provider_; | 1834 TemplateURL* old_default = default_search_provider_; |
| 1659 default_search_provider_ = NULL; | 1835 default_search_provider_ = NULL; |
| 1660 RemoveNoNotify(old_default); | 1836 RemoveNoNotify(old_default); |
| 1661 } | 1837 } |
| 1662 | 1838 |
| 1663 // The likely default should be from Sync if we were waiting on Sync. | 1839 // The likely default should be from Sync if we were waiting on Sync. |
| 1664 // Otherwise, it should be FindNewDefaultSearchProvider. | 1840 // Otherwise, it should be FindNewDefaultSearchProvider. |
| 1665 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider(); | 1841 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider(); |
| 1666 if (synced_default) | 1842 if (synced_default) |
| 1667 pending_synced_default_search_ = false; | 1843 pending_synced_default_search_ = false; |
| 1668 SetDefaultSearchProviderNoNotify(synced_default ? synced_default : | 1844 SetDefaultSearchProviderNoNotify(synced_default ? synced_default : |
| 1669 FindNewDefaultSearchProvider()); | 1845 FindNewDefaultSearchProvider()); |
| 1670 } | 1846 } |
| 1671 NotifyObservers(); | 1847 NotifyObservers(); |
| 1672 } | 1848 } |
| 1673 | 1849 |
| 1674 void TemplateURLService::SetDefaultSearchProviderNoNotify(TemplateURL* url) { | 1850 bool TemplateURLService::SetDefaultSearchProviderNoNotify(TemplateURL* url) { |
| 1675 if (url) { | 1851 if (url) { |
| 1676 DCHECK(std::find(template_urls_.begin(), template_urls_.end(), url) != | 1852 if (std::find(template_urls_.begin(), template_urls_.end(), url) == |
| 1677 template_urls_.end()); | 1853 template_urls_.end()) |
| 1854 return false; | |
| 1678 // Extension keywords cannot be made default, as they're inherently async. | 1855 // Extension keywords cannot be made default, as they're inherently async. |
| 1679 DCHECK(!url->IsExtensionKeyword()); | 1856 DCHECK(!url->IsExtensionKeyword()); |
| 1680 } | 1857 } |
| 1681 | 1858 |
| 1682 default_search_provider_ = url; | 1859 default_search_provider_ = url; |
| 1683 | 1860 |
| 1684 if (url) { | 1861 if (url) { |
| 1685 // Don't mark the url as edited, otherwise we won't be able to rev the | 1862 // Don't mark the url as edited, otherwise we won't be able to rev the |
| 1686 // template urls we ship with. | 1863 // template urls we ship with. |
| 1687 url->data_.show_in_default_list = true; | 1864 url->data_.show_in_default_list = true; |
| 1688 if (service_.get()) | 1865 if (service_.get()) |
| 1689 service_->UpdateKeyword(*url); | 1866 service_->UpdateKeyword(url->data()); |
| 1690 | 1867 |
| 1691 if (url->url_ref().HasGoogleBaseURLs()) { | 1868 if (url->url_ref().HasGoogleBaseURLs()) { |
| 1692 GoogleURLTracker::RequestServerCheck(); | 1869 GoogleURLTracker::RequestServerCheck(); |
| 1693 #if defined(ENABLE_RLZ) | 1870 #if defined(ENABLE_RLZ) |
| 1694 // Needs to be evaluated. See http://crbug.com/62328. | 1871 // Needs to be evaluated. See http://crbug.com/62328. |
| 1695 base::ThreadRestrictions::ScopedAllowIO allow_io; | 1872 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 1696 RLZTracker::RecordProductEvent(rlz_lib::CHROME, | 1873 RLZTracker::RecordProductEvent(rlz_lib::CHROME, |
| 1697 rlz_lib::CHROME_OMNIBOX, | 1874 rlz_lib::CHROME_OMNIBOX, |
| 1698 rlz_lib::SET_TO_GOOGLE); | 1875 rlz_lib::SET_TO_GOOGLE); |
| 1699 #endif | 1876 #endif |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1711 url->sync_guid()); | 1888 url->sync_guid()); |
| 1712 } | 1889 } |
| 1713 } | 1890 } |
| 1714 | 1891 |
| 1715 if (service_.get()) | 1892 if (service_.get()) |
| 1716 service_->SetDefaultSearchProvider(url); | 1893 service_->SetDefaultSearchProvider(url); |
| 1717 | 1894 |
| 1718 // Inform sync the change to the show_in_default_list flag. | 1895 // Inform sync the change to the show_in_default_list flag. |
| 1719 if (url) | 1896 if (url) |
| 1720 ProcessTemplateURLChange(url, SyncChange::ACTION_UPDATE); | 1897 ProcessTemplateURLChange(url, SyncChange::ACTION_UPDATE); |
| 1898 return true; | |
| 1721 } | 1899 } |
| 1722 | 1900 |
| 1723 void TemplateURLService::AddNoNotify(TemplateURL* template_url, | 1901 bool TemplateURLService::AddNoNotify(TemplateURL* template_url, |
| 1724 bool newly_adding) { | 1902 bool newly_adding) { |
| 1725 DCHECK(template_url); | 1903 DCHECK(template_url); |
| 1726 | 1904 |
| 1727 if (newly_adding) { | 1905 if (newly_adding) { |
| 1728 DCHECK_EQ(kInvalidTemplateURLID, template_url->id()); | 1906 DCHECK_EQ(kInvalidTemplateURLID, template_url->id()); |
| 1729 DCHECK(std::find(template_urls_.begin(), template_urls_.end(), | 1907 DCHECK(std::find(template_urls_.begin(), template_urls_.end(), |
| 1730 template_url) == template_urls_.end()); | 1908 template_url) == template_urls_.end()); |
| 1731 template_url->data_.id = ++next_id_; | 1909 template_url->data_.id = ++next_id_; |
| 1732 } | 1910 } |
| 1733 | 1911 |
| 1912 template_url->ResetKeywordIfNecessary(false); | |
| 1913 if (!template_url->IsExtensionKeyword()) { | |
| 1914 // Check whether |template_url|'s keyword conflicts with any already in the | |
| 1915 // model. | |
| 1916 TemplateURL* existing_keyword_turl = | |
| 1917 FindNonExtensionTemplateURLForKeyword(template_url->keyword()); | |
| 1918 if (existing_keyword_turl != NULL) { | |
| 1919 DCHECK_NE(existing_keyword_turl, template_url); | |
| 1920 if (CanReplace(existing_keyword_turl)) { | |
| 1921 RemoveNoNotify(existing_keyword_turl); | |
| 1922 } else if (CanReplace(template_url)) { | |
| 1923 delete template_url; | |
| 1924 return false; | |
| 1925 } else { | |
| 1926 string16 new_keyword = UniquifyKeyword(*existing_keyword_turl); | |
| 1927 ResetTemplateURL(existing_keyword_turl, | |
| 1928 existing_keyword_turl->short_name(), new_keyword, | |
| 1929 existing_keyword_turl->url()); | |
| 1930 } | |
| 1931 } | |
| 1932 } | |
| 1734 template_urls_.push_back(template_url); | 1933 template_urls_.push_back(template_url); |
| 1735 AddToMaps(template_url); | 1934 AddToMaps(template_url); |
| 1736 | 1935 |
| 1737 if (newly_adding) { | 1936 if (newly_adding) { |
| 1738 // Don't persist extension keywords to disk. They'll get re-added on each | 1937 // Don't persist extension keywords to disk. They'll get re-added on each |
| 1739 // launch as the extensions are loaded. | 1938 // launch as the extensions are loaded. |
| 1740 // TODO(mpcomplete): If we allow editing extension keywords, then those | 1939 // TODO(mpcomplete): If we allow editing extension keywords, then those |
| 1741 // should be persisted to disk and synced. | 1940 // should be persisted to disk and synced. |
| 1742 if (service_.get() && !template_url->IsExtensionKeyword()) | 1941 if (service_.get() && !template_url->IsExtensionKeyword()) |
| 1743 service_->AddKeyword(*template_url); | 1942 service_->AddKeyword(template_url->data()); |
| 1744 | 1943 |
| 1745 // Inform sync of the addition. Note that this will assign a GUID to | 1944 // Inform sync of the addition. Note that this will assign a GUID to |
| 1746 // template_url and add it to the guid_to_template_map_. | 1945 // template_url and add it to the guid_to_template_map_. |
| 1747 ProcessTemplateURLChange(template_url, SyncChange::ACTION_ADD); | 1946 ProcessTemplateURLChange(template_url, SyncChange::ACTION_ADD); |
| 1748 } | 1947 } |
| 1948 | |
| 1949 return true; | |
| 1749 } | 1950 } |
| 1750 | 1951 |
| 1751 void TemplateURLService::RemoveNoNotify(TemplateURL* template_url) { | 1952 void TemplateURLService::RemoveNoNotify(TemplateURL* template_url) { |
| 1752 TemplateURLVector::iterator i = | 1953 TemplateURLVector::iterator i = |
| 1753 std::find(template_urls_.begin(), template_urls_.end(), template_url); | 1954 std::find(template_urls_.begin(), template_urls_.end(), template_url); |
| 1754 if (i == template_urls_.end()) | 1955 if (i == template_urls_.end()) |
| 1755 return; | 1956 return; |
| 1756 | 1957 |
| 1757 if (template_url == default_search_provider_) { | 1958 if (template_url == default_search_provider_) { |
| 1758 // Should never delete the default search provider. | 1959 // Should never delete the default search provider. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1840 service_->RemoveKeyword(template_url->id()); | 2041 service_->RemoveKeyword(template_url->id()); |
| 1841 delete template_url; | 2042 delete template_url; |
| 1842 } else { | 2043 } else { |
| 1843 ++i; | 2044 ++i; |
| 1844 } | 2045 } |
| 1845 } | 2046 } |
| 1846 } | 2047 } |
| 1847 | 2048 |
| 1848 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url, | 2049 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url, |
| 1849 const std::string& guid) { | 2050 const std::string& guid) { |
| 2051 DCHECK(loaded_); | |
| 1850 DCHECK(!guid.empty()); | 2052 DCHECK(!guid.empty()); |
| 1851 | 2053 |
| 1852 TemplateURLData data(url->data()); | 2054 TemplateURLData data(url->data()); |
| 1853 data.sync_guid = guid; | 2055 data.sync_guid = guid; |
| 1854 TemplateURL new_url(url->profile(), data); | 2056 TemplateURL new_url(url->profile(), data); |
| 1855 UpdateNoNotify(url, new_url); | 2057 UpdateNoNotify(url, new_url); |
| 1856 } | 2058 } |
| 1857 | 2059 |
| 1858 string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl) { | 2060 string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl) { |
| 1859 // Already unique. | 2061 // Already unique. |
| 1860 if (!GetTemplateURLForKeyword(turl.keyword())) | 2062 if (!GetTemplateURLForKeyword(turl.keyword())) |
| 1861 return turl.keyword(); | 2063 return turl.keyword(); |
| 1862 | 2064 |
| 1863 // First, try to return the generated keyword for the TemplateURL. | 2065 // First, try to return the generated keyword for the TemplateURL. |
| 1864 GURL gurl(turl.url()); | 2066 GURL gurl(turl.url()); |
| 1865 if (gurl.is_valid()) { | 2067 if (gurl.is_valid()) { |
| 1866 string16 keyword_candidate = GenerateKeyword(gurl, true); | 2068 string16 keyword_candidate = GenerateKeyword(gurl); |
| 1867 if (!GetTemplateURLForKeyword(keyword_candidate) && | 2069 if (!GetTemplateURLForKeyword(keyword_candidate)) |
| 1868 !keyword_candidate.empty()) | |
| 1869 return keyword_candidate; | 2070 return keyword_candidate; |
| 1870 } | 2071 } |
| 1871 | 2072 |
| 1872 // We try to uniquify the keyword by appending a special character to the end. | 2073 // We try to uniquify the keyword by appending a special character to the end. |
| 1873 // This is a best-effort approach where we try to preserve the original | 2074 // This is a best-effort approach where we try to preserve the original |
| 1874 // keyword and let the user do what they will after our attempt. | 2075 // keyword and let the user do what they will after our attempt. |
| 1875 string16 keyword_candidate(turl.keyword()); | 2076 string16 keyword_candidate(turl.keyword()); |
| 1876 do { | 2077 do { |
| 1877 keyword_candidate.append(ASCIIToUTF16("_")); | 2078 keyword_candidate.append(ASCIIToUTF16("_")); |
| 1878 } while (GetTemplateURLForKeyword(keyword_candidate)); | 2079 } while (GetTemplateURLForKeyword(keyword_candidate)); |
| 1879 | 2080 |
| 1880 return keyword_candidate; | 2081 return keyword_candidate; |
| 1881 } | 2082 } |
| 1882 | 2083 |
| 1883 bool TemplateURLService::ResolveSyncKeywordConflict( | 2084 void TemplateURLService::ResolveSyncKeywordConflict( |
| 1884 TemplateURL* sync_turl, | 2085 TemplateURL* sync_turl, |
| 2086 TemplateURL* local_turl, | |
| 1885 SyncChangeList* change_list) { | 2087 SyncChangeList* change_list) { |
| 2088 DCHECK(loaded_); | |
| 1886 DCHECK(sync_turl); | 2089 DCHECK(sync_turl); |
| 2090 DCHECK(local_turl); | |
| 2091 DCHECK(sync_turl->sync_guid() != local_turl->sync_guid()); | |
| 2092 DCHECK(!local_turl->IsExtensionKeyword()); | |
| 1887 DCHECK(change_list); | 2093 DCHECK(change_list); |
| 1888 | 2094 |
| 1889 TemplateURL* existing_turl = | 2095 if (local_turl->last_modified() > sync_turl->last_modified() || |
| 1890 GetTemplateURLForKeyword(sync_turl->keyword()); | 2096 local_turl->created_by_policy()) { |
| 1891 // If there is no conflict, or it's just conflicting with itself, return. | |
| 1892 if (!existing_turl || existing_turl->sync_guid() == sync_turl->sync_guid()) | |
| 1893 return false; | |
| 1894 | |
| 1895 if (existing_turl->last_modified() > sync_turl->last_modified() || | |
| 1896 existing_turl->created_by_policy()) { | |
| 1897 string16 new_keyword = UniquifyKeyword(*sync_turl); | 2097 string16 new_keyword = UniquifyKeyword(*sync_turl); |
| 1898 DCHECK(!GetTemplateURLForKeyword(new_keyword)); | 2098 DCHECK(!GetTemplateURLForKeyword(new_keyword)); |
| 1899 sync_turl->data_.SetKeyword(new_keyword); | 2099 sync_turl->data_.SetKeyword(new_keyword); |
| 1900 // If we update the cloud TURL, we need to push an update back to sync | 2100 // If we update the cloud TURL, we need to push an update back to sync |
| 1901 // informing it that something has changed. | 2101 // informing it that something has changed. |
| 1902 SyncData sync_data = CreateSyncDataFromTemplateURL(*sync_turl); | 2102 SyncData sync_data = CreateSyncDataFromTemplateURL(*sync_turl); |
| 1903 change_list->push_back(SyncChange(SyncChange::ACTION_UPDATE, sync_data)); | 2103 change_list->push_back(SyncChange(SyncChange::ACTION_UPDATE, sync_data)); |
| 1904 } else { | 2104 } else { |
| 1905 string16 new_keyword = UniquifyKeyword(*existing_turl); | 2105 string16 new_keyword = UniquifyKeyword(*local_turl); |
| 1906 TemplateURLData data(existing_turl->data()); | 2106 TemplateURLData data(local_turl->data()); |
| 1907 data.SetKeyword(new_keyword); | 2107 data.SetKeyword(new_keyword); |
| 1908 TemplateURL new_turl(existing_turl->profile(), data); | 2108 TemplateURL new_turl(local_turl->profile(), data); |
| 1909 UpdateNoNotify(existing_turl, new_turl); | 2109 if (UpdateNoNotify(local_turl, new_turl)) |
| 1910 NotifyObservers(); | 2110 NotifyObservers(); |
| 2111 if (!models_associated_) { | |
| 2112 // We're doing our initial sync, so UpdateNoNotify() won't have generated | |
| 2113 // an ACTION_UPDATE. If this local URL is one that was just newly brought | |
| 2114 // down from the sync server, we need to go ahead and generate an update | |
| 2115 // for it. If it was pre-existing, then this is unnecessary (and in fact | |
| 2116 // wrong) because MergeDataAndStartSyncing() will later add an ACTION_ADD | |
| 2117 // for this URL; but in this case, PreventDuplicateGUIDUpdates() will | |
| 2118 // prune out the ACTION_UPDATE we create here. | |
| 2119 SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl); | |
| 2120 change_list->push_back(SyncChange(SyncChange::ACTION_UPDATE, sync_data)); | |
| 2121 } | |
| 1911 } | 2122 } |
| 1912 return true; | |
| 1913 } | 2123 } |
| 1914 | 2124 |
| 1915 TemplateURL* TemplateURLService::FindDuplicateOfSyncTemplateURL( | 2125 TemplateURL* TemplateURLService::FindDuplicateOfSyncTemplateURL( |
| 1916 const TemplateURL& sync_turl) { | 2126 const TemplateURL& sync_turl) { |
| 1917 TemplateURL* existing_turl = GetTemplateURLForKeyword(sync_turl.keyword()); | 2127 TemplateURL* existing_turl = GetTemplateURLForKeyword(sync_turl.keyword()); |
| 1918 return existing_turl && (existing_turl->url() == sync_turl.url()) ? | 2128 return existing_turl && (existing_turl->url() == sync_turl.url()) ? |
| 1919 existing_turl : NULL; | 2129 existing_turl : NULL; |
| 1920 } | 2130 } |
| 1921 | 2131 |
| 1922 void TemplateURLService::MergeSyncAndLocalURLDuplicates( | 2132 void TemplateURLService::MergeSyncAndLocalURLDuplicates( |
| 1923 TemplateURL* sync_turl, | 2133 TemplateURL* sync_turl, |
| 1924 TemplateURL* local_turl, | 2134 TemplateURL* local_turl, |
| 1925 SyncChangeList* change_list) { | 2135 SyncChangeList* change_list) { |
| 2136 DCHECK(loaded_); | |
| 1926 DCHECK(sync_turl); | 2137 DCHECK(sync_turl); |
| 1927 DCHECK(local_turl); | 2138 DCHECK(local_turl); |
| 1928 DCHECK(change_list); | 2139 DCHECK(change_list); |
| 1929 scoped_ptr<TemplateURL> scoped_sync_turl(sync_turl); | 2140 scoped_ptr<TemplateURL> scoped_sync_turl(sync_turl); |
| 1930 if (sync_turl->last_modified() > local_turl->last_modified()) { | 2141 if (sync_turl->last_modified() > local_turl->last_modified()) { |
| 1931 // Fully replace local_url with Sync's copy. Note that because use Add | 2142 // Fully replace local_url with Sync's copy. Note that because use Add |
| 1932 // rather than ResetTemplateURL, |sync_url| is added with a fresh | 2143 // rather than ResetTemplateURL, |sync_url| is added with a fresh |
| 1933 // TemplateURLID. We don't need to sync the new ID back to the server since | 2144 // TemplateURLID. We don't need to sync the new ID back to the server since |
| 1934 // it's only relevant locally. | 2145 // it's only relevant locally. |
| 1935 bool delete_default = (local_turl == GetDefaultSearchProvider()); | 2146 bool delete_default = (local_turl == GetDefaultSearchProvider()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1990 i != template_urls->end(); ++i) { | 2201 i != template_urls->end(); ++i) { |
| 1991 TemplateURL* template_url = *i; | 2202 TemplateURL* template_url = *i; |
| 1992 DCHECK(template_url); | 2203 DCHECK(template_url); |
| 1993 // Extension keywords are never synced. | 2204 // Extension keywords are never synced. |
| 1994 // TODO(mpcomplete): If we allow editing extension keywords, then those | 2205 // TODO(mpcomplete): If we allow editing extension keywords, then those |
| 1995 // should be persisted to disk and synced. | 2206 // should be persisted to disk and synced. |
| 1996 if (template_url->sync_guid().empty() && | 2207 if (template_url->sync_guid().empty() && |
| 1997 !template_url->IsExtensionKeyword()) { | 2208 !template_url->IsExtensionKeyword()) { |
| 1998 template_url->data_.sync_guid = guid::GenerateGUID(); | 2209 template_url->data_.sync_guid = guid::GenerateGUID(); |
| 1999 if (service_.get()) | 2210 if (service_.get()) |
| 2000 service_->UpdateKeyword(*template_url); | 2211 service_->UpdateKeyword(template_url->data()); |
| 2001 } | 2212 } |
| 2002 } | 2213 } |
| 2003 } | 2214 } |
| OLD | NEW |