1 // Copyright 2013 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.
5 #include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h"
7 #include "base/callback.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/values.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
16 #include "chrome/browser/search_engines/template_url_service.h"
17 #include "chrome/browser/search_engines/template_url_service_factory.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/notification_service.h"
22 #include "chrome/browser/enumerate_modules_model_win.h"
23 #include "chrome/browser/install_module_verifier_win.h"
28 scoped_ptr<base::DictionaryValue> BuildSubTreeFromTemplateURL(
29 const TemplateURL* template_url) {
30 scoped_ptr<base::DictionaryValue> tree(new base::DictionaryValue);
31 tree->SetString("search_url", template_url->url());
32 tree->SetString("search_terms_replacement_key",
33 template_url->search_terms_replacement_key());
34 tree->SetString("suggest_url", template_url->suggestions_url());
35 tree->SetString("instant_url", template_url->instant_url());
36 tree->SetString("image_url", template_url->image_url());
37 tree->SetString("new_tab_url", template_url->new_tab_url());
38 tree->SetString("search_url_post_params",
39 template_url->search_url_post_params());
40 tree->SetString("suggest_url_post_params",
41 template_url->suggestions_url_post_params());
42 tree->SetString("instant_url_post_params",
43 template_url->instant_url_post_params());
44 tree->SetString("image_url_post_params",
45 template_url->image_url_post_params());
46 tree->SetString("icon_url", template_url->favicon_url().spec());
47 tree->SetString("name", template_url->short_name());
48 tree->SetString("keyword", template_url->keyword());
49 base::ListValue* input_encodings = new base::ListValue;
50 input_encodings->AppendStrings(template_url->input_encodings());
51 tree->Set("encodings", input_encodings);
52 tree->SetString("id", base::Int64ToString(template_url->id()));
53 tree->SetString("prepopulate_id",
54 base::IntToString(template_url->prepopulate_id()));
55 base::ListValue* alternate_urls = new base::ListValue;
56 alternate_urls->AppendStrings(template_url->alternate_urls());
57 tree->Set("alternate_urls", alternate_urls);
64 // AutomaticProfileResetterDelegateImpl --------------------------------------
66 AutomaticProfileResetterDelegateImpl::AutomaticProfileResetterDelegateImpl(
67 TemplateURLService* template_url_service)
68 : template_url_service_(template_url_service) {
69 if (template_url_service_) {
70 template_url_service_->AddObserver(this);
71 // Needed so that |template_url_service_ready_event_| will be signaled even
72 // when TemplateURLService had been already initialized before this point.
73 OnTemplateURLServiceChanged();
77 module_list_.reset(EnumerateModulesModel::GetInstance()->GetModuleList());
80 // Having a non-empty module list proves that enumeration had been already
81 // performed before this point.
82 modules_have_been_enumerated_event_.Signal();
85 chrome::NOTIFICATION_MODULE_LIST_ENUMERATED,
86 content::NotificationService::AllSources());
89 AutomaticProfileResetterDelegateImpl::~AutomaticProfileResetterDelegateImpl() {
90 if (template_url_service_)
91 template_url_service_->RemoveObserver(this);
94 void AutomaticProfileResetterDelegateImpl::EnumerateLoadedModulesIfNeeded() {
95 if (!modules_have_been_enumerated_event_.is_signaled()) {
97 EnumerateModulesModel::GetInstance()->ScanNow();
99 modules_have_been_enumerated_event_.Signal();
104 void AutomaticProfileResetterDelegateImpl::
105 RequestCallbackWhenLoadedModulesAreEnumerated(
106 const base::Closure& ready_callback) const {
107 DCHECK(!ready_callback.is_null());
108 modules_have_been_enumerated_event_.Post(FROM_HERE, ready_callback);
111 void AutomaticProfileResetterDelegateImpl::LoadTemplateURLServiceIfNeeded() {
112 DCHECK(template_url_service_);
113 template_url_service_->Load(); // Safe to call even if it has loaded already.
116 void AutomaticProfileResetterDelegateImpl::
117 RequestCallbackWhenTemplateURLServiceIsLoaded(
118 const base::Closure& ready_callback) const {
119 DCHECK(!ready_callback.is_null());
120 template_url_service_ready_event_.Post(FROM_HERE, ready_callback);
123 scoped_ptr<base::ListValue> AutomaticProfileResetterDelegateImpl::
124 GetLoadedModuleNameDigests() const {
125 DCHECK(modules_have_been_enumerated_event_.is_signaled());
126 std::set<std::string> module_name_digests;
129 ExtractLoadedModuleNameDigests(*module_list_, &module_name_digests);
131 scoped_ptr<base::ListValue> result(new base::ListValue);
132 for (std::set<std::string>::const_iterator it = module_name_digests.begin();
133 it != module_name_digests.end(); ++it)
134 result->AppendString(*it);
135 return result.Pass();
138 scoped_ptr<base::DictionaryValue> AutomaticProfileResetterDelegateImpl::
139 GetDefaultSearchProviderDetails() const {
140 DCHECK(template_url_service_);
141 DCHECK(template_url_service_->loaded());
143 const TemplateURL* default_search_provider =
144 template_url_service_->GetDefaultSearchProvider();
146 // Having a NULL default search provider is due to either:
147 // 1.) default search providers being disabled by policy,
148 // 2.) directly tampering with the Preferences and/or the SQLite DBs.
149 // In this state, Omnibox non-keyword search functionality is disabled.
150 return default_search_provider ?
151 BuildSubTreeFromTemplateURL(default_search_provider) :
152 scoped_ptr<base::DictionaryValue>(new base::DictionaryValue);
155 bool AutomaticProfileResetterDelegateImpl::
156 IsDefaultSearchProviderManaged() const {
157 DCHECK(template_url_service_);
158 DCHECK(template_url_service_->loaded());
159 return template_url_service_->is_default_search_managed();
162 scoped_ptr<base::ListValue> AutomaticProfileResetterDelegateImpl::
163 GetPrepopulatedSearchProvidersDetails() const {
164 DCHECK(template_url_service_);
165 size_t default_search_index = 0;
166 ScopedVector<TemplateURL> engines(
167 TemplateURLPrepopulateData::GetPrepopulatedEngines(
168 template_url_service_->profile(), &default_search_index));
169 scoped_ptr<base::ListValue> engines_details_list(new base::ListValue);
170 for (ScopedVector<TemplateURL>::const_iterator it = engines.begin();
171 it != engines.end(); ++it)
172 engines_details_list->Append(BuildSubTreeFromTemplateURL(*it).release());
173 return engines_details_list.Pass();
176 void AutomaticProfileResetterDelegateImpl::ShowPrompt() {
177 // TODO(engedy): Call the UI from here once we have it.
180 void AutomaticProfileResetterDelegateImpl::OnTemplateURLServiceChanged() {
181 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
182 DCHECK(template_url_service_);
183 if (template_url_service_->loaded() &&
184 !template_url_service_ready_event_.is_signaled())
185 template_url_service_ready_event_.Signal();
188 void AutomaticProfileResetterDelegateImpl::Observe(
190 const content::NotificationSource& source,
191 const content::NotificationDetails& details) {
192 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
193 if (type == chrome::NOTIFICATION_MODULE_LIST_ENUMERATED &&
194 !modules_have_been_enumerated_event_.is_signaled()) {
196 module_list_.reset(EnumerateModulesModel::GetInstance()->GetModuleList());
198 modules_have_been_enumerated_event_.Signal();