Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / profile_resetter / automatic_profile_resetter_delegate.cc
blobb2515fcda7dfd8808fd0b114779dcf2dfbb89fba
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 <string>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/logging.h"
13 #include "base/md5.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "base/values.h"
18 #include "chrome/app/chrome_command_ids.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/google/google_util.h"
21 #include "chrome/browser/profile_resetter/brandcode_config_fetcher.h"
22 #include "chrome/browser/profile_resetter/profile_reset_global_error.h"
23 #include "chrome/browser/profile_resetter/profile_resetter.h"
24 #include "chrome/browser/profile_resetter/resettable_settings_snapshot.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
27 #include "chrome/browser/search_engines/template_url_service.h"
28 #include "chrome/browser/search_engines/template_url_service_factory.h"
29 #include "chrome/browser/ui/browser.h"
30 #include "chrome/browser/ui/browser_finder.h"
31 #include "chrome/browser/ui/global_error/global_error_service.h"
32 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
33 #include "content/public/browser/browser_thread.h"
34 #include "content/public/browser/notification_service.h"
36 #if defined(OS_WIN)
37 #include "chrome/browser/enumerate_modules_model_win.h"
38 #endif
40 namespace {
42 scoped_ptr<base::DictionaryValue> BuildSubTreeFromTemplateURL(
43 const TemplateURL* template_url) {
44 scoped_ptr<base::DictionaryValue> tree(new base::DictionaryValue);
45 tree->SetString("search_url", template_url->url());
46 // If this value contains a placeholder in the pre-populated data, it will
47 // have been replaced as it was loaded into a TemplateURL.
48 // BuildSubTreeFromTemplateURL works with TemplateURL (not TemplateURLData)
49 // in order to maintain this behaviour.
50 // TODO(engedy): Confirm the expected behaviour and convert to use
51 // TemplateURLData if possible."
52 tree->SetString("search_terms_replacement_key",
53 template_url->search_terms_replacement_key());
54 tree->SetString("suggest_url", template_url->suggestions_url());
55 tree->SetString("instant_url", template_url->instant_url());
56 tree->SetString("image_url", template_url->image_url());
57 tree->SetString("new_tab_url", template_url->new_tab_url());
58 tree->SetString("search_url_post_params",
59 template_url->search_url_post_params());
60 tree->SetString("suggest_url_post_params",
61 template_url->suggestions_url_post_params());
62 tree->SetString("instant_url_post_params",
63 template_url->instant_url_post_params());
64 tree->SetString("image_url_post_params",
65 template_url->image_url_post_params());
66 tree->SetString("icon_url", template_url->favicon_url().spec());
67 tree->SetString("name", template_url->short_name());
68 tree->SetString("keyword", template_url->keyword());
69 base::ListValue* input_encodings = new base::ListValue;
70 input_encodings->AppendStrings(template_url->input_encodings());
71 tree->Set("encodings", input_encodings);
72 tree->SetString("id", base::Int64ToString(template_url->id()));
73 tree->SetString("prepopulate_id",
74 base::IntToString(template_url->prepopulate_id()));
75 base::ListValue* alternate_urls = new base::ListValue;
76 alternate_urls->AppendStrings(template_url->alternate_urls());
77 tree->Set("alternate_urls", alternate_urls);
78 return tree.Pass();
81 #if defined(OS_WIN)
82 void ExtractLoadedModuleNameDigests(
83 const base::ListValue& module_list,
84 base::ListValue* module_name_digests) {
85 DCHECK(module_name_digests);
87 // EnumerateModulesModel produces a list of dictionaries.
88 // Each dictionary corresponds to a module and exposes a number of properties.
89 // We care only about 'type' and 'name'.
90 for (size_t i = 0; i < module_list.GetSize(); ++i) {
91 const base::DictionaryValue* module_dictionary = NULL;
92 if (!module_list.GetDictionary(i, &module_dictionary))
93 continue;
94 ModuleEnumerator::ModuleType module_type =
95 ModuleEnumerator::LOADED_MODULE;
96 if (!module_dictionary->GetInteger(
97 "type", reinterpret_cast<int*>(&module_type)) ||
98 module_type != ModuleEnumerator::LOADED_MODULE) {
99 continue;
101 std::string module_name;
102 if (!module_dictionary->GetString("name", &module_name))
103 continue;
104 StringToLowerASCII(&module_name);
105 module_name_digests->AppendString(base::MD5String(module_name));
108 #endif
110 } // namespace
113 // AutomaticProfileResetterDelegateImpl --------------------------------------
115 AutomaticProfileResetterDelegateImpl::AutomaticProfileResetterDelegateImpl(
116 Profile* profile,
117 ProfileResetter::ResettableFlags resettable_aspects)
118 : profile_(profile),
119 global_error_service_(GlobalErrorServiceFactory::GetForProfile(profile_)),
120 template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_)),
121 resettable_aspects_(resettable_aspects) {
122 DCHECK(profile_);
123 if (template_url_service_) {
124 template_url_service_->AddObserver(this);
125 // Needed so that |template_url_service_ready_event_| will be signaled even
126 // when TemplateURLService had been already initialized before this point.
127 OnTemplateURLServiceChanged();
130 #if defined(OS_WIN)
131 module_list_.reset(EnumerateModulesModel::GetInstance()->GetModuleList());
132 #endif
133 if (module_list_) {
134 // Having a non-empty module list proves that enumeration had been already
135 // performed before this point.
136 modules_have_been_enumerated_event_.Signal();
138 registrar_.Add(this,
139 chrome::NOTIFICATION_MODULE_LIST_ENUMERATED,
140 content::NotificationService::AllSources());
143 AutomaticProfileResetterDelegateImpl::~AutomaticProfileResetterDelegateImpl() {
144 if (template_url_service_)
145 template_url_service_->RemoveObserver(this);
148 void AutomaticProfileResetterDelegateImpl::EnumerateLoadedModulesIfNeeded() {
149 if (!modules_have_been_enumerated_event_.is_signaled()) {
150 #if defined(OS_WIN)
151 EnumerateModulesModel::GetInstance()->ScanNow();
152 #else
153 modules_have_been_enumerated_event_.Signal();
154 #endif
158 void AutomaticProfileResetterDelegateImpl::
159 RequestCallbackWhenLoadedModulesAreEnumerated(
160 const base::Closure& ready_callback) const {
161 DCHECK(!ready_callback.is_null());
162 modules_have_been_enumerated_event_.Post(FROM_HERE, ready_callback);
165 void AutomaticProfileResetterDelegateImpl::LoadTemplateURLServiceIfNeeded() {
166 DCHECK(template_url_service_);
167 template_url_service_->Load(); // Safe to call even if it has loaded already.
170 void AutomaticProfileResetterDelegateImpl::
171 RequestCallbackWhenTemplateURLServiceIsLoaded(
172 const base::Closure& ready_callback) const {
173 DCHECK(!ready_callback.is_null());
174 template_url_service_ready_event_.Post(FROM_HERE, ready_callback);
177 void AutomaticProfileResetterDelegateImpl::
178 FetchBrandcodedDefaultSettingsIfNeeded() {
179 if (brandcoded_config_fetcher_ ||
180 brandcoded_defaults_fetched_event_.is_signaled())
181 return;
183 std::string brandcode;
184 google_util::GetBrand(&brandcode);
185 if (brandcode.empty()) {
186 brandcoded_defaults_.reset(new BrandcodedDefaultSettings);
187 brandcoded_defaults_fetched_event_.Signal();
188 } else {
189 brandcoded_config_fetcher_.reset(new BrandcodeConfigFetcher(
190 base::Bind(
191 &AutomaticProfileResetterDelegateImpl::OnBrandcodedDefaultsFetched,
192 base::Unretained(this)),
193 GURL("https://tools.google.com/service/update2"),
194 brandcode));
198 void AutomaticProfileResetterDelegateImpl::
199 RequestCallbackWhenBrandcodedDefaultsAreFetched(
200 const base::Closure& ready_callback) const {
201 DCHECK(!ready_callback.is_null());
202 brandcoded_defaults_fetched_event_.Post(FROM_HERE, ready_callback);
205 scoped_ptr<base::ListValue> AutomaticProfileResetterDelegateImpl::
206 GetLoadedModuleNameDigests() const {
207 DCHECK(modules_have_been_enumerated_event_.is_signaled());
208 scoped_ptr<base::ListValue> result(new base::ListValue);
209 #if defined(OS_WIN)
210 if (module_list_)
211 ExtractLoadedModuleNameDigests(*module_list_, result.get());
212 #endif
213 return result.Pass();
216 scoped_ptr<base::DictionaryValue> AutomaticProfileResetterDelegateImpl::
217 GetDefaultSearchProviderDetails() const {
218 DCHECK(template_url_service_);
219 DCHECK(template_url_service_->loaded());
221 const TemplateURL* default_search_provider =
222 template_url_service_->GetDefaultSearchProvider();
224 // Having a NULL default search provider is due to either:
225 // 1.) default search providers being disabled by policy,
226 // 2.) directly tampering with the Preferences and/or the SQLite DBs.
227 // In this state, Omnibox non-keyword search functionality is disabled.
228 return default_search_provider ?
229 BuildSubTreeFromTemplateURL(default_search_provider) :
230 scoped_ptr<base::DictionaryValue>(new base::DictionaryValue);
233 bool AutomaticProfileResetterDelegateImpl::
234 IsDefaultSearchProviderManaged() const {
235 DCHECK(template_url_service_);
236 DCHECK(template_url_service_->loaded());
237 return template_url_service_->is_default_search_managed();
240 scoped_ptr<base::ListValue> AutomaticProfileResetterDelegateImpl::
241 GetPrepopulatedSearchProvidersDetails() const {
242 size_t default_search_index = 0;
243 ScopedVector<TemplateURLData> engines(
244 TemplateURLPrepopulateData::GetPrepopulatedEngines(
245 profile_->GetPrefs(), &default_search_index));
246 scoped_ptr<base::ListValue> engines_details_list(new base::ListValue);
247 for (ScopedVector<TemplateURLData>::const_iterator it = engines.begin();
248 it != engines.end(); ++it) {
249 TemplateURL template_url(profile_, **it);
250 engines_details_list->Append(
251 BuildSubTreeFromTemplateURL(&template_url).release());
253 return engines_details_list.Pass();
256 bool AutomaticProfileResetterDelegateImpl::TriggerPrompt() {
257 DCHECK(global_error_service_);
259 if (!ProfileResetGlobalError::IsSupportedOnPlatform())
260 return false;
262 ProfileResetGlobalError* global_error = new ProfileResetGlobalError(profile_);
263 global_error_service_->AddGlobalError(global_error);
265 // Do not try to show bubble if another GlobalError is already showing one.
266 const GlobalErrorService::GlobalErrorList& global_errors(
267 global_error_service_->errors());
268 GlobalErrorService::GlobalErrorList::const_iterator it;
269 for (it = global_errors.begin(); it != global_errors.end(); ++it) {
270 if ((*it)->GetBubbleView())
271 break;
273 if (it == global_errors.end()) {
274 Browser* browser = chrome::FindTabbedBrowser(
275 profile_,
276 false /*match_original_profiles*/,
277 chrome::GetActiveDesktop());
278 if (browser)
279 global_error->ShowBubbleView(browser);
281 return true;
284 void AutomaticProfileResetterDelegateImpl::TriggerProfileSettingsReset(
285 bool send_feedback,
286 const base::Closure& completion) {
287 DCHECK(!profile_resetter_);
288 DCHECK(!completion.is_null());
290 profile_resetter_.reset(new ProfileResetter(profile_));
291 FetchBrandcodedDefaultSettingsIfNeeded();
292 RequestCallbackWhenBrandcodedDefaultsAreFetched(base::Bind(
293 &AutomaticProfileResetterDelegateImpl::RunProfileSettingsReset,
294 AsWeakPtr(),
295 send_feedback,
296 completion));
299 void AutomaticProfileResetterDelegateImpl::OnTemplateURLServiceChanged() {
300 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
301 DCHECK(template_url_service_);
302 if (template_url_service_->loaded() &&
303 !template_url_service_ready_event_.is_signaled())
304 template_url_service_ready_event_.Signal();
307 void AutomaticProfileResetterDelegateImpl::DismissPrompt() {
308 DCHECK(global_error_service_);
309 GlobalError* global_error =
310 global_error_service_->GetGlobalErrorByMenuItemCommandID(
311 IDC_SHOW_SETTINGS_RESET_BUBBLE);
312 if (global_error) {
313 // This will also close/destroy the Bubble UI if it is currently shown.
314 global_error_service_->RemoveGlobalError(global_error);
315 delete global_error;
319 void AutomaticProfileResetterDelegateImpl::Observe(
320 int type,
321 const content::NotificationSource& source,
322 const content::NotificationDetails& details) {
323 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
324 if (type == chrome::NOTIFICATION_MODULE_LIST_ENUMERATED &&
325 !modules_have_been_enumerated_event_.is_signaled()) {
326 #if defined(OS_WIN)
327 module_list_.reset(EnumerateModulesModel::GetInstance()->GetModuleList());
328 #endif
329 modules_have_been_enumerated_event_.Signal();
333 void AutomaticProfileResetterDelegateImpl::SendFeedback(
334 const std::string& report) const {
335 SendSettingsFeedback(report, profile_, PROFILE_RESET_PROMPT);
338 void AutomaticProfileResetterDelegateImpl::RunProfileSettingsReset(
339 bool send_feedback,
340 const base::Closure& completion) {
341 DCHECK(brandcoded_defaults_);
342 scoped_ptr<ResettableSettingsSnapshot> old_settings_snapshot;
343 if (send_feedback) {
344 old_settings_snapshot.reset(new ResettableSettingsSnapshot(profile_));
345 old_settings_snapshot->RequestShortcuts(base::Closure());
347 profile_resetter_->Reset(
348 resettable_aspects_,
349 brandcoded_defaults_.Pass(),
350 base::Bind(&AutomaticProfileResetterDelegateImpl::
351 OnProfileSettingsResetCompleted,
352 AsWeakPtr(),
353 completion,
354 base::Passed(&old_settings_snapshot)));
357 void AutomaticProfileResetterDelegateImpl::
358 OnBrandcodedDefaultsFetched() {
359 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
360 DCHECK(brandcoded_config_fetcher_);
361 DCHECK(!brandcoded_config_fetcher_->IsActive());
362 brandcoded_defaults_ = brandcoded_config_fetcher_->GetSettings();
363 if (!brandcoded_defaults_)
364 brandcoded_defaults_.reset(new BrandcodedDefaultSettings);
365 brandcoded_defaults_fetched_event_.Signal();
368 void AutomaticProfileResetterDelegateImpl::OnProfileSettingsResetCompleted(
369 const base::Closure& user_callback,
370 scoped_ptr<ResettableSettingsSnapshot> old_settings_snapshot) {
371 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
372 if (old_settings_snapshot) {
373 ResettableSettingsSnapshot new_settings_snapshot(profile_);
374 int difference =
375 old_settings_snapshot->FindDifferentFields(new_settings_snapshot);
376 if (difference) {
377 old_settings_snapshot->Subtract(new_settings_snapshot);
378 std::string report =
379 SerializeSettingsReport(*old_settings_snapshot, difference);
380 SendFeedback(report);
383 content::BrowserThread::PostTask(
384 content::BrowserThread::UI, FROM_HERE, user_callback);