OLD | NEW |
(Empty) | |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ios/chrome/browser/search_engines/search_engines_util.h" |
| 6 |
| 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/prefs/pref_service.h" |
| 9 #include "components/search_engines/search_engines_pref_names.h" |
| 10 #include "components/search_engines/template_url_prepopulate_data.h" |
| 11 #include "components/search_engines/template_url_service.h" |
| 12 #include "components/search_engines/template_url_service_observer.h" |
| 13 |
| 14 namespace { |
| 15 |
| 16 // Id of the google id in template_url_prepopulate_data.cc. |
| 17 static const int kGoogleEnginePrepopulatedId = 1; |
| 18 |
| 19 // Update the search engine of the given service to the default ones for the |
| 20 // current locale. |
| 21 void UpdateSearchEngine(TemplateURLService* service) { |
| 22 DCHECK(service); |
| 23 DCHECK(service->loaded()); |
| 24 std::vector<TemplateURL*> old_engines = service->GetTemplateURLs(); |
| 25 size_t default_engine; |
| 26 ScopedVector<TemplateURLData> new_engines = |
| 27 TemplateURLPrepopulateData::GetPrepopulatedEngines(nullptr, |
| 28 &default_engine); |
| 29 DCHECK(default_engine == 0); |
| 30 DCHECK(new_engines[0]->prepopulate_id == kGoogleEnginePrepopulatedId); |
| 31 // The aim is to replace the old search engines with the new ones. |
| 32 // It is not possible to remove all of them, because removing the current |
| 33 // selected engine is not allowed. |
| 34 // It is not possible to add all the new ones first, because the service gets |
| 35 // confused when a prepopulated engine is there more than once. |
| 36 // Instead, this will in a first pass makes google as the default engine. In |
| 37 // a second pass, it will remove all other search engine. At last, in a third |
| 38 // pass, it will add all new engine but google. |
| 39 for (const auto& engine : old_engines) { |
| 40 if (engine->prepopulate_id() == kGoogleEnginePrepopulatedId) |
| 41 service->SetUserSelectedDefaultSearchProvider(engine); |
| 42 } |
| 43 for (const auto& engine : old_engines) { |
| 44 if (engine->prepopulate_id() != kGoogleEnginePrepopulatedId) |
| 45 service->Remove(engine); |
| 46 } |
| 47 ScopedVector<TemplateURLData>::iterator it = new_engines.begin(); |
| 48 while (it != new_engines.end()) { |
| 49 if ((*it)->prepopulate_id != kGoogleEnginePrepopulatedId) { |
| 50 // service->Add takes ownership on Added TemplateURL. |
| 51 service->Add(new TemplateURL(**it)); |
| 52 it = new_engines.weak_erase(it); |
| 53 } else { |
| 54 ++it; |
| 55 } |
| 56 } |
| 57 } |
| 58 |
| 59 // Observer class that allows to wait for the TemplateURLService to be loaded. |
| 60 // This class will delete itself as soon as the TemplateURLService is loaded. |
| 61 class LoadedObserver : public TemplateURLServiceObserver { |
| 62 public: |
| 63 explicit LoadedObserver(TemplateURLService* service) : service_(service) { |
| 64 DCHECK(service_); |
| 65 DCHECK(!service_->loaded()); |
| 66 service_->AddObserver(this); |
| 67 service_->Load(); |
| 68 } |
| 69 |
| 70 ~LoadedObserver() override { service_->RemoveObserver(this); } |
| 71 |
| 72 void OnTemplateURLServiceChanged() override { |
| 73 service_->RemoveObserver(this); |
| 74 UpdateSearchEngine(service_); |
| 75 // Only delete this class when this callback is finished. |
| 76 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 77 } |
| 78 |
| 79 private: |
| 80 TemplateURLService* service_; |
| 81 }; |
| 82 |
| 83 } // namespace |
| 84 |
| 85 namespace search_engines { |
| 86 |
| 87 void UpdateSearchEnginesIfNeeded(PrefService* preferences, |
| 88 TemplateURLService* service) { |
| 89 if (!preferences->HasPrefPath(prefs::kCountryIDAtInstall)) { |
| 90 // No search engines were ever installed, just return. |
| 91 return; |
| 92 } |
| 93 int old_country_id = preferences->GetInteger(prefs::kCountryIDAtInstall); |
| 94 int country_id = TemplateURLPrepopulateData::GetCurrentCountryID(); |
| 95 if (country_id == old_country_id) { |
| 96 // User's locale did not change, just return. |
| 97 return; |
| 98 } |
| 99 preferences->SetInteger(prefs::kCountryIDAtInstall, country_id); |
| 100 // If the current search engine is managed by policy then we can't set the |
| 101 // default search engine, which is required by UpdateSearchEngine(). This |
| 102 // isn't a problem as long as the default search engine is enforced via |
| 103 // policy, because it can't be changed by the user anyway; if the policy is |
| 104 // removed then the engines can be updated again. |
| 105 if (!service || service->is_default_search_managed()) |
| 106 return; |
| 107 if (service->loaded()) |
| 108 UpdateSearchEngine(service); |
| 109 else |
| 110 new LoadedObserver(service); // The observer manages its own lifetime. |
| 111 } |
| 112 |
| 113 } // namespace search_engines |
OLD | NEW |