11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file.
41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h"
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string>
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind_helpers.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/callback.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/logging.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/md5.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/memory/scoped_vector.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/strings/string_util.h"
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/values.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/google/google_util.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/profile_resetter/brandcode_config_fetcher.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/profile_resetter/profile_reset_global_error.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/profile_resetter/profile_resetter.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/profile_resetter/resettable_settings_snapshot.h"
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/search_engines/template_url_service.h"
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/search_engines/template_url_service_factory.h"
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service.h"
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service_factory.h"
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/notification_service.h"
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_WIN)
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/enumerate_modules_model_win.h"
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace {
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)scoped_ptr<base::DictionaryValue> BuildSubTreeFromTemplateURL(
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const TemplateURL* template_url) {
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> tree(new base::DictionaryValue);
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("search_url", template_url->url());
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("search_terms_replacement_key",
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  template_url->search_terms_replacement_key());
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("suggest_url", template_url->suggestions_url());
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("instant_url", template_url->instant_url());
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("image_url", template_url->image_url());
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("new_tab_url", template_url->new_tab_url());
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("search_url_post_params",
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  template_url->search_url_post_params());
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("suggest_url_post_params",
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  template_url->suggestions_url_post_params());
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("instant_url_post_params",
571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  template_url->instant_url_post_params());
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("image_url_post_params",
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  template_url->image_url_post_params());
601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("icon_url", template_url->favicon_url().spec());
611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("name", template_url->short_name());
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("keyword", template_url->keyword());
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::ListValue* input_encodings = new base::ListValue;
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  input_encodings->AppendStrings(template_url->input_encodings());
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->Set("encodings", input_encodings);
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("id", base::Int64ToString(template_url->id()));
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->SetString("prepopulate_id",
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  base::IntToString(template_url->prepopulate_id()));
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::ListValue* alternate_urls = new base::ListValue;
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  alternate_urls->AppendStrings(template_url->alternate_urls());
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  tree->Set("alternate_urls", alternate_urls);
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return tree.Pass();
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtractLoadedModuleNameDigests(
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::ListValue& module_list,
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::ListValue* module_name_digests) {
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(module_name_digests);
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // EnumerateModulesModel produces a list of dictionaries.
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Each dictionary corresponds to a module and exposes a number of properties.
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We care only about 'type' and 'name'.
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < module_list.GetSize(); ++i) {
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::DictionaryValue* module_dictionary = NULL;
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!module_list.GetDictionary(i, &module_dictionary))
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      continue;
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ModuleEnumerator::ModuleType module_type =
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ModuleEnumerator::LOADED_MODULE;
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!module_dictionary->GetInteger(
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            "type", reinterpret_cast<int*>(&module_type)) ||
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        module_type != ModuleEnumerator::LOADED_MODULE) {
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      continue;
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string module_name;
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!module_dictionary->GetString("name", &module_name))
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      continue;
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    StringToLowerASCII(&module_name);
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    module_name_digests->AppendString(base::MD5String(module_name));
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// AutomaticProfileResetterDelegateImpl --------------------------------------
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)AutomaticProfileResetterDelegateImpl::AutomaticProfileResetterDelegateImpl(
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Profile* profile,
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ProfileResetter::ResettableFlags resettable_aspects)
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : profile_(profile),
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      global_error_service_(GlobalErrorServiceFactory::GetForProfile(profile_)),
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_)),
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      resettable_aspects_(resettable_aspects) {
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(profile_);
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (template_url_service_) {
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    template_url_service_->AddObserver(this);
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Needed so that |template_url_service_ready_event_| will be signaled even
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // when TemplateURLService had been already initialized before this point.
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    OnTemplateURLServiceChanged();
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_WIN)
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  module_list_.reset(EnumerateModulesModel::GetInstance()->GetModuleList());
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (module_list_) {
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Having a non-empty module list proves that enumeration had been already
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // performed before this point.
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    modules_have_been_enumerated_event_.Signal();
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  registrar_.Add(this,
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 chrome::NOTIFICATION_MODULE_LIST_ENUMERATED,
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 content::NotificationService::AllSources());
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)AutomaticProfileResetterDelegateImpl::~AutomaticProfileResetterDelegateImpl() {
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (template_url_service_)
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    template_url_service_->RemoveObserver(this);
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetterDelegateImpl::EnumerateLoadedModulesIfNeeded() {
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!modules_have_been_enumerated_event_.is_signaled()) {
1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_WIN)
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EnumerateModulesModel::GetInstance()->ScanNow();
1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#else
1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    modules_have_been_enumerated_event_.Signal();
1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetterDelegateImpl::
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    RequestCallbackWhenLoadedModulesAreEnumerated(
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const base::Closure& ready_callback) const {
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!ready_callback.is_null());
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  modules_have_been_enumerated_event_.Post(FROM_HERE, ready_callback);
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetterDelegateImpl::LoadTemplateURLServiceIfNeeded() {
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(template_url_service_);
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  template_url_service_->Load();  // Safe to call even if it has loaded already.
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetterDelegateImpl::
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    RequestCallbackWhenTemplateURLServiceIsLoaded(
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const base::Closure& ready_callback) const {
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!ready_callback.is_null());
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  template_url_service_ready_event_.Post(FROM_HERE, ready_callback);
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetterDelegateImpl::
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FetchBrandcodedDefaultSettingsIfNeeded() {
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (brandcoded_config_fetcher_ ||
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      brandcoded_defaults_fetched_event_.is_signaled())
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string brandcode;
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  google_util::GetBrand(&brandcode);
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (brandcode.empty()) {
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    brandcoded_defaults_.reset(new BrandcodedDefaultSettings);
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    brandcoded_defaults_fetched_event_.Signal();
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    brandcoded_config_fetcher_.reset(new BrandcodeConfigFetcher(
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            &AutomaticProfileResetterDelegateImpl::OnBrandcodedDefaultsFetched,
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            base::Unretained(this)),
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        GURL("https://tools.google.com/service/update2"),
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        brandcode));
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetterDelegateImpl::
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RequestCallbackWhenBrandcodedDefaultsAreFetched(
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Closure& ready_callback) const {
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!ready_callback.is_null());
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  brandcoded_defaults_fetched_event_.Post(FROM_HERE, ready_callback);
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)scoped_ptr<base::ListValue> AutomaticProfileResetterDelegateImpl::
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GetLoadedModuleNameDigests() const {
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(modules_have_been_enumerated_event_.is_signaled());
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::ListValue> result(new base::ListValue);
2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_WIN)
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (module_list_)
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ExtractLoadedModuleNameDigests(*module_list_, result.get());
2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return result.Pass();
2081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)scoped_ptr<base::DictionaryValue> AutomaticProfileResetterDelegateImpl::
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GetDefaultSearchProviderDetails() const {
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(template_url_service_);
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(template_url_service_->loaded());
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const TemplateURL* default_search_provider =
2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      template_url_service_->GetDefaultSearchProvider();
2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Having a NULL default search provider is due to either:
2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  //  1.) default search providers being disabled by policy,
2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  //  2.) directly tampering with the Preferences and/or the SQLite DBs.
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // In this state, Omnibox non-keyword search functionality is disabled.
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return default_search_provider ?
2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      BuildSubTreeFromTemplateURL(default_search_provider) :
2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      scoped_ptr<base::DictionaryValue>(new base::DictionaryValue);
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool AutomaticProfileResetterDelegateImpl::
2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    IsDefaultSearchProviderManaged() const {
2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(template_url_service_);
2301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(template_url_service_->loaded());
2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return template_url_service_->is_default_search_managed();
2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)scoped_ptr<base::ListValue> AutomaticProfileResetterDelegateImpl::
2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GetPrepopulatedSearchProvidersDetails() const {
2361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t default_search_index = 0;
2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ScopedVector<TemplateURL> engines(
2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      TemplateURLPrepopulateData::GetPrepopulatedEngines(
2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          template_url_service_->profile(), &default_search_index));
2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<base::ListValue> engines_details_list(new base::ListValue);
2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (ScopedVector<TemplateURL>::const_iterator it = engines.begin();
2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       it != engines.end(); ++it)
2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    engines_details_list->Append(BuildSubTreeFromTemplateURL(*it).release());
2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return engines_details_list.Pass();
2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool AutomaticProfileResetterDelegateImpl::TriggerPrompt() {
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(global_error_service_);
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!ProfileResetGlobalError::IsSupportedOnPlatform())
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ProfileResetGlobalError* global_error = new ProfileResetGlobalError(profile_);
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  global_error_service_->AddGlobalError(global_error);
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Do not try to show bubble if another GlobalError is already showing one.
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GlobalErrorService::GlobalErrorList& global_errors(
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      global_error_service_->errors());
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GlobalErrorService::GlobalErrorList::const_iterator it;
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (it = global_errors.begin(); it != global_errors.end(); ++it) {
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if ((*it)->GetBubbleView())
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (it == global_errors.end()) {
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Browser* browser = chrome::FindTabbedBrowser(
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        profile_,
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        false /*match_original_profiles*/,
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        chrome::GetActiveDesktop());
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (browser)
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      global_error->ShowBubbleView(browser);
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetterDelegateImpl::TriggerProfileSettingsReset(
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool send_feedback,
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Closure& completion) {
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!profile_resetter_);
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!completion.is_null());
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  profile_resetter_.reset(new ProfileResetter(profile_));
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FetchBrandcodedDefaultSettingsIfNeeded();
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RequestCallbackWhenBrandcodedDefaultsAreFetched(base::Bind(
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &AutomaticProfileResetterDelegateImpl::RunProfileSettingsReset,
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      AsWeakPtr(),
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      send_feedback,
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      completion));
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetterDelegateImpl::OnTemplateURLServiceChanged() {
2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(template_url_service_);
2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (template_url_service_->loaded() &&
2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      !template_url_service_ready_event_.is_signaled())
2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    template_url_service_ready_event_.Signal();
2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetterDelegateImpl::DismissPrompt() {
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(global_error_service_);
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GlobalError* global_error =
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      global_error_service_->GetGlobalErrorByMenuItemCommandID(
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          IDC_SHOW_SETTINGS_RESET_BUBBLE);
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (global_error) {
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // This will also close/destroy the Bubble UI if it is currently shown.
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    global_error_service_->RemoveGlobalError(global_error);
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delete global_error;
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetterDelegateImpl::Observe(
3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    int type,
3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const content::NotificationSource& source,
3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const content::NotificationDetails& details) {
3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (type == chrome::NOTIFICATION_MODULE_LIST_ENUMERATED &&
3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      !modules_have_been_enumerated_event_.is_signaled()) {
3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_WIN)
3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    module_list_.reset(EnumerateModulesModel::GetInstance()->GetModuleList());
3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    modules_have_been_enumerated_event_.Signal();
3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetterDelegateImpl::SendFeedback(
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& report) const {
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SendSettingsFeedback(report, profile_, PROFILE_RESET_PROMPT);
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetterDelegateImpl::RunProfileSettingsReset(
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool send_feedback,
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Closure& completion) {
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(brandcoded_defaults_);
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ResettableSettingsSnapshot> old_settings_snapshot(
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      send_feedback ? new ResettableSettingsSnapshot(profile_) : NULL);
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  profile_resetter_->Reset(
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      resettable_aspects_,
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      brandcoded_defaults_.Pass(),
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&AutomaticProfileResetterDelegateImpl::
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     OnProfileSettingsResetCompleted,
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 AsWeakPtr(),
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 completion,
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 base::Passed(&old_settings_snapshot)));
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetterDelegateImpl::
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    OnBrandcodedDefaultsFetched() {
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(brandcoded_config_fetcher_);
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!brandcoded_config_fetcher_->IsActive());
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  brandcoded_defaults_ = brandcoded_config_fetcher_->GetSettings();
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!brandcoded_defaults_)
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    brandcoded_defaults_.reset(new BrandcodedDefaultSettings);
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  brandcoded_defaults_fetched_event_.Signal();
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetterDelegateImpl::OnProfileSettingsResetCompleted(
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Closure& user_callback,
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<ResettableSettingsSnapshot> old_settings_snapshot) {
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (old_settings_snapshot) {
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ResettableSettingsSnapshot new_settings_snapshot(profile_);
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int difference =
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        old_settings_snapshot->FindDifferentFields(new_settings_snapshot);
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (difference) {
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      old_settings_snapshot->Subtract(new_settings_snapshot);
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      std::string report =
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          SerializeSettingsReport(*old_settings_snapshot, difference);
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SendFeedback(report);
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::BrowserThread::PostTask(
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      content::BrowserThread::UI, FROM_HERE, user_callback);
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
374