| Index: chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc
|
| diff --git a/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3a8bb83f7ac8936ab0b7fbdf0f8d8d88b5fcbbef
|
| --- /dev/null
|
| +++ b/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc
|
| @@ -0,0 +1,241 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.h"
|
| +
|
| +#include <algorithm>
|
| +#include <iterator>
|
| +#include <memory>
|
| +#include <utility>
|
| +#include <vector>
|
| +
|
| +#include "base/barrier_closure.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/callback_helpers.h"
|
| +#include "base/macros.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/synchronization/lock.h"
|
| +#include "base/win/registry.h"
|
| +#include "chrome/browser/browser_process.h"
|
| +#include "chrome/browser/profile_resetter/profile_resetter.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/profiles/profile_manager.h"
|
| +#include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
|
| +#include "chrome/browser/ui/browser.h"
|
| +#include "chrome/browser/ui/browser_finder.h"
|
| +#include "chrome/common/pref_names.h"
|
| +#include "components/chrome_cleaner/public/constants/constants.h"
|
| +#include "components/pref_registry/pref_registry_syncable.h"
|
| +#include "components/prefs/pref_service.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +
|
| +namespace safe_browsing {
|
| +
|
| +namespace {
|
| +
|
| +// Returns the post-cleanup reset pending prefs for |profile|.
|
| +bool ResetPending(Profile* profile) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + DCHECK(PostCleanupSettingsResetter::IsEnabled());
|
| + DCHECK(profile);
|
| +
|
| + PrefService* prefs = profile->GetPrefs();
|
| + return prefs->GetBoolean(prefs::kChromeCleanerResetPending);
|
| +}
|
| +
|
| +// Updates the post-cleanup reset pending prefs for |profile|.
|
| +void RecordResetPending(bool value, Profile* profile) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + DCHECK(PostCleanupSettingsResetter::IsEnabled());
|
| + DCHECK(profile);
|
| +
|
| + PrefService* prefs = profile->GetPrefs();
|
| + prefs->SetBoolean(prefs::kChromeCleanerResetPending, value);
|
| +}
|
| +
|
| +bool CopyProfilesToReset(const std::vector<Profile*>& profiles,
|
| + std::vector<Profile*>* profiles_to_reset) {
|
| + std::copy_if(profiles.begin(), profiles.end(),
|
| + std::back_inserter(*profiles_to_reset),
|
| + [](Profile* profile) -> bool { return ResetPending(profile); });
|
| + return profiles_to_reset->size() > 0;
|
| +}
|
| +
|
| +// Manages post-cleanup settings reset for a list of profiles.
|
| +// An instance of this class is created by ResetTaggedProfiles() and will
|
| +// self-delete once all profiles in the list have been reset.
|
| +class SettingsResetter : public base::RefCounted<SettingsResetter> {
|
| + public:
|
| + SettingsResetter(
|
| + std::vector<Profile*> profiles_to_reset,
|
| + std::unique_ptr<PostCleanupSettingsResetter::Delegate> delegate,
|
| + base::OnceClosure done_callback);
|
| +
|
| + // Resets settings for all profiles in |profiles_to_reset_| and invokes
|
| + // |done_callback_| when done.
|
| + void Run();
|
| +
|
| + protected:
|
| + virtual ~SettingsResetter();
|
| +
|
| + private:
|
| + friend class base::RefCounted<SettingsResetter>;
|
| +
|
| + // Resets settings for |profile| according to default values given by
|
| + // |master_settings|. Used as a callback for
|
| + // DefaultSettingsFetcher::FetchDefaultSettings().
|
| + void OnFetchCompleted(
|
| + Profile* profile,
|
| + std::unique_ptr<BrandcodedDefaultSettings> master_settings);
|
| +
|
| + // Removes the settings reset tag for |profile|. If there are no more
|
| + // profiles to reset, invokes |done_callback_| and deletes this object.
|
| + void OnResetCompleted(Profile* profile);
|
| +
|
| + // The profiles to be reset.
|
| + std::vector<Profile*> profiles_to_reset_;
|
| +
|
| + // The number of profiles that need to be reset.
|
| + int num_pending_resets_;
|
| +
|
| + // The callback to be invoked once settings reset completes.
|
| + base::OnceClosure done_callback_;
|
| +
|
| + std::unique_ptr<PostCleanupSettingsResetter::Delegate> delegate_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SettingsResetter);
|
| +};
|
| +
|
| +SettingsResetter::SettingsResetter(
|
| + std::vector<Profile*> profiles_to_reset,
|
| + std::unique_ptr<PostCleanupSettingsResetter::Delegate> delegate,
|
| + base::OnceClosure done_callback)
|
| + : profiles_to_reset_(std::move(profiles_to_reset)),
|
| + num_pending_resets_(profiles_to_reset_.size()),
|
| + done_callback_(std::move(done_callback)),
|
| + delegate_(std::move(delegate)) {
|
| + DCHECK_LT(0, num_pending_resets_);
|
| + DCHECK(done_callback_);
|
| + DCHECK(delegate_);
|
| +}
|
| +
|
| +SettingsResetter::~SettingsResetter() {
|
| + DCHECK(!done_callback_);
|
| + DCHECK(!num_pending_resets_);
|
| +}
|
| +
|
| +void SettingsResetter::Run() {
|
| + for (Profile* profile : profiles_to_reset_) {
|
| + delegate_->FetchDefaultSettings(
|
| + base::Bind(&SettingsResetter::OnFetchCompleted, this, profile));
|
| + }
|
| +}
|
| +
|
| +void SettingsResetter::OnFetchCompleted(
|
| + Profile* profile,
|
| + std::unique_ptr<BrandcodedDefaultSettings> master_settings) {
|
| + static const ProfileResetter::ResettableFlags kSettingsToReset =
|
| + ProfileResetter::DEFAULT_SEARCH_ENGINE | ProfileResetter::HOMEPAGE |
|
| + ProfileResetter::EXTENSIONS | ProfileResetter::STARTUP_PAGES |
|
| + ProfileResetter::SHORTCUTS;
|
| +
|
| + delegate_->GetProfileResetter(profile)->Reset(
|
| + kSettingsToReset, std::move(master_settings),
|
| + base::Bind(&SettingsResetter::OnResetCompleted, this, profile));
|
| +}
|
| +
|
| +void SettingsResetter::OnResetCompleted(Profile* profile) {
|
| + DCHECK_LT(0, num_pending_resets_);
|
| +
|
| + RecordResetPending(false, profile);
|
| +
|
| + --num_pending_resets_;
|
| + if (!num_pending_resets_)
|
| + std::move(done_callback_).Run();
|
| +}
|
| +
|
| +// Returns true if there is information of a completed cleanup in the registry.
|
| +bool CleanupCompletedFromRegistry() {
|
| + base::string16 cleaner_key_path(
|
| + chrome_cleaner::kSoftwareRemovalToolRegistryKey);
|
| + cleaner_key_path.append(L"\\").append(chrome_cleaner::kCleanerSubKey);
|
| +
|
| + base::win::RegKey srt_cleaner_key(HKEY_CURRENT_USER, cleaner_key_path.c_str(),
|
| + KEY_QUERY_VALUE);
|
| + DWORD cleanup_completed = 0;
|
| + return srt_cleaner_key.Valid() &&
|
| + srt_cleaner_key.ReadValueDW(chrome_cleaner::kCleanupCompletedValueName,
|
| + &cleanup_completed) == ERROR_SUCCESS &&
|
| + cleanup_completed == 1;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +PostCleanupSettingsResetter::Delegate::Delegate() {}
|
| +
|
| +PostCleanupSettingsResetter::Delegate::~Delegate() {}
|
| +
|
| +void PostCleanupSettingsResetter::Delegate::FetchDefaultSettings(
|
| + DefaultSettingsFetcher::SettingsCallback callback) {
|
| + DefaultSettingsFetcher::FetchDefaultSettings(std::move(callback));
|
| +}
|
| +
|
| +PostCleanupSettingsResetter::PostCleanupSettingsResetter() = default;
|
| +
|
| +PostCleanupSettingsResetter::~PostCleanupSettingsResetter() = default;
|
| +
|
| +// static
|
| +bool PostCleanupSettingsResetter::IsEnabled() {
|
| +#if defined(OS_WIN)
|
| + return base::FeatureList::IsEnabled(
|
| + safe_browsing::kInBrowserCleanerUIFeature);
|
| +#else
|
| + return false;
|
| +#endif
|
| +}
|
| +
|
| +std::unique_ptr<ProfileResetter>
|
| +PostCleanupSettingsResetter::Delegate::GetProfileResetter(Profile* profile) {
|
| + return base::MakeUnique<ProfileResetter>(profile);
|
| +}
|
| +
|
| +void PostCleanupSettingsResetter::TagForResetting(Profile* profile) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + DCHECK(IsEnabled());
|
| + DCHECK(profile);
|
| +
|
| + RecordResetPending(true, profile);
|
| +}
|
| +
|
| +void PostCleanupSettingsResetter::ResetTaggedProfiles(
|
| + std::vector<Profile*> profiles,
|
| + base::OnceClosure done_callback,
|
| + std::unique_ptr<PostCleanupSettingsResetter::Delegate> delegate) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + DCHECK(IsEnabled());
|
| + DCHECK(delegate);
|
| +
|
| + std::vector<Profile*> profiles_to_reset;
|
| + if (!CopyProfilesToReset(profiles, &profiles_to_reset) ||
|
| + !CleanupCompletedFromRegistry()) {
|
| + std::move(done_callback).Run();
|
| + return;
|
| + }
|
| +
|
| + // The SettingsResetter object will self-delete once |done_callback| is
|
| + // invoked.
|
| + make_scoped_refptr(new SettingsResetter(std::move(profiles_to_reset),
|
| + std::move(delegate),
|
| + std::move(done_callback)))
|
| + ->Run();
|
| +}
|
| +
|
| +// static
|
| +void PostCleanupSettingsResetter::RegisterProfilePrefs(
|
| + user_prefs::PrefRegistrySyncable* registry) {
|
| + DCHECK(registry);
|
| + registry->RegisterBooleanPref(prefs::kChromeCleanerResetPending, false);
|
| +}
|
| +
|
| +} // namespace safe_browsing
|
|
|