| // Copyright (c) 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/ui/webui/settings/chrome_cleanup_handler.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/feature_list.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/metrics/user_metrics_action.h" |
| #include "base/strings/string16.h" |
| #include "base/synchronization/lock.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h" |
| #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "components/component_updater/pref_names.h" |
| #include "components/prefs/pref_service.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_ui.h" |
| #include "content/public/browser/web_ui_message_handler.h" |
| #include "extensions/browser/extension_system.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| using safe_browsing::ChromeCleanerController; |
| |
| namespace settings { |
| |
| namespace { |
| |
| // Returns a ListValue containing a copy of the file paths stored in |files|. |
| std::unique_ptr<base::ListValue> GetFilesAsListStorage( |
| const std::set<base::FilePath>& files) { |
| auto value = std::make_unique<base::ListValue>(); |
| for (const base::FilePath& path : files) { |
| auto item = std::make_unique<base::DictionaryValue>(); |
| item->SetString("dirname", path.DirName().AsEndingWithSeparator().value()); |
| item->SetString("basename", path.BaseName().value()); |
| value->Append(std::move(item)); |
| } |
| return value; |
| } |
| |
| // Returns a ListValue containing a copy of the strings stored in |string_set|. |
| std::unique_ptr<base::ListValue> GetStringSetAsListStorage( |
| const std::set<base::string16>& string_set) { |
| auto value = std::make_unique<base::ListValue>(); |
| for (const base::string16& string : string_set) |
| value->AppendString(string); |
| |
| return value; |
| } |
| |
| base::DictionaryValue GetScannerResultsAsDictionary( |
| const safe_browsing::ChromeCleanerScannerResults& scanner_results, |
| Profile* profile) { |
| base::DictionaryValue value; |
| value.SetList("files", |
| GetFilesAsListStorage(scanner_results.files_to_delete())); |
| value.SetList("registryKeys", |
| GetStringSetAsListStorage(scanner_results.registry_keys())); |
| std::set<base::string16> extensions; |
| scanner_results.FetchExtensionNames(profile, &extensions); |
| value.SetList("extensions", GetStringSetAsListStorage(extensions)); |
| return value; |
| } |
| |
| std::string IdleReasonToString( |
| ChromeCleanerController::IdleReason idle_reason) { |
| switch (idle_reason) { |
| case ChromeCleanerController::IdleReason::kInitial: |
| return "initial"; |
| case ChromeCleanerController::IdleReason::kReporterFoundNothing: |
| return "reporter_found_nothing"; |
| case ChromeCleanerController::IdleReason::kReporterFailed: |
| return "reporter_failed"; |
| case ChromeCleanerController::IdleReason::kScanningFoundNothing: |
| return "scanning_found_nothing"; |
| case ChromeCleanerController::IdleReason::kScanningFailed: |
| return "scanning_failed"; |
| case ChromeCleanerController::IdleReason::kConnectionLost: |
| return "connection_lost"; |
| case ChromeCleanerController::IdleReason::kUserDeclinedCleanup: |
| return "user_declined_cleanup"; |
| case ChromeCleanerController::IdleReason::kCleaningFailed: |
| return "cleaning_failed"; |
| case ChromeCleanerController::IdleReason::kCleaningSucceeded: |
| return "cleaning_succeeded"; |
| case ChromeCleanerController::IdleReason::kCleanerDownloadFailed: |
| return "cleaner_download_failed"; |
| } |
| NOTREACHED(); |
| return ""; |
| } |
| |
| } // namespace |
| |
| ChromeCleanupHandler::ChromeCleanupHandler(Profile* profile) |
| : controller_(ChromeCleanerController::GetInstance()), profile_(profile) {} |
| |
| ChromeCleanupHandler::~ChromeCleanupHandler() { |
| controller_->RemoveObserver(this); |
| } |
| |
| void ChromeCleanupHandler::RegisterMessages() { |
| web_ui()->RegisterMessageCallback( |
| "registerChromeCleanerObserver", |
| base::BindRepeating( |
| &ChromeCleanupHandler::HandleRegisterChromeCleanerObserver, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "startScanning", |
| base::BindRepeating(&ChromeCleanupHandler::HandleStartScanning, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "restartComputer", |
| base::BindRepeating(&ChromeCleanupHandler::HandleRestartComputer, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "startCleanup", |
| base::BindRepeating(&ChromeCleanupHandler::HandleStartCleanup, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "notifyShowDetails", |
| base::BindRepeating(&ChromeCleanupHandler::HandleNotifyShowDetails, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "notifyChromeCleanupLearnMoreClicked", |
| base::BindRepeating( |
| &ChromeCleanupHandler::HandleNotifyChromeCleanupLearnMoreClicked, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "getMoreItemsPluralString", |
| base::BindRepeating(&ChromeCleanupHandler::HandleGetMoreItemsPluralString, |
| base::Unretained(this))); |
| web_ui()->RegisterMessageCallback( |
| "getItemsToRemovePluralString", |
| base::BindRepeating( |
| &ChromeCleanupHandler::HandleGetItemsToRemovePluralString, |
| base::Unretained(this))); |
| } |
| |
| void ChromeCleanupHandler::OnJavascriptAllowed() { |
| controller_->AddObserver(this); |
| } |
| |
| void ChromeCleanupHandler::OnJavascriptDisallowed() { |
| controller_->RemoveObserver(this); |
| } |
| |
| void ChromeCleanupHandler::OnIdle( |
| ChromeCleanerController::IdleReason idle_reason) { |
| FireWebUIListener("chrome-cleanup-on-idle", |
| base::Value(IdleReasonToString(idle_reason))); |
| } |
| |
| void ChromeCleanupHandler::OnScanning() { |
| FireWebUIListener("chrome-cleanup-on-scanning"); |
| } |
| |
| void ChromeCleanupHandler::OnReporterRunning() { |
| FireWebUIListener("chrome-cleanup-on-reporter-running"); |
| } |
| |
| void ChromeCleanupHandler::OnInfected( |
| bool is_powered_by_partner, |
| const safe_browsing::ChromeCleanerScannerResults& scanner_results) { |
| FireWebUIListener("chrome-cleanup-on-infected", |
| base::Value(is_powered_by_partner), |
| GetScannerResultsAsDictionary(scanner_results, profile_)); |
| } |
| |
| void ChromeCleanupHandler::OnCleaning( |
| bool is_powered_by_partner, |
| const safe_browsing::ChromeCleanerScannerResults& scanner_results) { |
| FireWebUIListener("chrome-cleanup-on-cleaning", |
| base::Value(is_powered_by_partner), |
| GetScannerResultsAsDictionary(scanner_results, profile_)); |
| } |
| |
| void ChromeCleanupHandler::OnRebootRequired() { |
| FireWebUIListener("chrome-cleanup-on-reboot-required"); |
| } |
| |
| void ChromeCleanupHandler::HandleRegisterChromeCleanerObserver( |
| const base::ListValue* args) { |
| DCHECK_EQ(0U, args->GetSize()); |
| |
| UMA_HISTOGRAM_BOOLEAN("SoftwareReporter.CleanupCard", true); |
| base::RecordAction( |
| base::UserMetricsAction("SoftwareReporter.CleanupWebui_Shown")); |
| AllowJavascript(); |
| |
| FireWebUIListener("chrome-cleanup-enabled-change", |
| base::Value(controller_->IsAllowedByPolicy())); |
| } |
| |
| void ChromeCleanupHandler::HandleStartScanning(const base::ListValue* args) { |
| CHECK_EQ(1U, args->GetSize()); |
| bool allow_logs_upload = false; |
| args->GetBoolean(0, &allow_logs_upload); |
| |
| // If this operation is not allowed the UI should be disabled. |
| CHECK(controller_->IsAllowedByPolicy()); |
| |
| // The state is propagated to all open tabs and should be consistent. |
| DCHECK_EQ(controller_->logs_enabled(profile_), allow_logs_upload); |
| |
| controller_->RequestUserInitiatedScan(profile_); |
| |
| base::RecordAction( |
| base::UserMetricsAction("SoftwareReporter.CleanupWebui_StartScanning")); |
| } |
| |
| void ChromeCleanupHandler::HandleRestartComputer(const base::ListValue* args) { |
| DCHECK_EQ(0U, args->GetSize()); |
| |
| base::RecordAction( |
| base::UserMetricsAction("SoftwareReporter.CleanupWebui_RestartComputer")); |
| |
| controller_->Reboot(); |
| } |
| |
| void ChromeCleanupHandler::HandleStartCleanup(const base::ListValue* args) { |
| CHECK_EQ(1U, args->GetSize()); |
| bool allow_logs_upload = false; |
| args->GetBoolean(0, &allow_logs_upload); |
| |
| // The state is propagated to all open tabs and should be consistent. |
| DCHECK_EQ(controller_->logs_enabled(profile_), allow_logs_upload); |
| |
| safe_browsing::RecordCleanupStartedHistogram( |
| safe_browsing::CLEANUP_STARTED_FROM_PROMPT_IN_SETTINGS); |
| base::RecordAction( |
| base::UserMetricsAction("SoftwareReporter.CleanupWebui_StartCleanup")); |
| |
| extensions::ExtensionService* extension_service = |
| extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| |
| controller_->ReplyWithUserResponse( |
| profile_, extension_service, |
| allow_logs_upload |
| ? ChromeCleanerController::UserResponse::kAcceptedWithLogs |
| : ChromeCleanerController::UserResponse::kAcceptedWithoutLogs); |
| } |
| |
| void ChromeCleanupHandler::HandleNotifyShowDetails( |
| const base::ListValue* args) { |
| CHECK_EQ(1U, args->GetSize()); |
| bool details_section_visible = false; |
| args->GetBoolean(0, &details_section_visible); |
| |
| if (details_section_visible) { |
| base::RecordAction( |
| base::UserMetricsAction("SoftwareReporter.CleanupWebui_ShowDetails")); |
| } else { |
| base::RecordAction( |
| base::UserMetricsAction("SoftwareReporter.CleanupWebui_HideDetails")); |
| } |
| } |
| |
| void ChromeCleanupHandler::HandleNotifyChromeCleanupLearnMoreClicked( |
| const base::ListValue* args) { |
| CHECK_EQ(0U, args->GetSize()); |
| |
| base::RecordAction( |
| base::UserMetricsAction("SoftwareReporter.CleanupWebui_LearnMore")); |
| } |
| |
| void ChromeCleanupHandler::HandleGetMoreItemsPluralString( |
| const base::ListValue* args) { |
| #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) |
| GetPluralString(IDS_SETTINGS_RESET_CLEANUP_DETAILS_MORE, args); |
| #endif // defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) |
| } |
| |
| void ChromeCleanupHandler::HandleGetItemsToRemovePluralString( |
| const base::ListValue* args) { |
| #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) |
| GetPluralString(IDS_SETTINGS_RESET_CLEANUP_DETAILS_ITEMS_TO_BE_REMOVED, args); |
| #endif // defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) |
| } |
| |
| void ChromeCleanupHandler::GetPluralString(int id, |
| const base::ListValue* args) { |
| CHECK_EQ(2U, args->GetSize()); |
| |
| std::string callback_id; |
| CHECK(args->GetString(0, &callback_id)); |
| |
| int num_items = 0; |
| args->GetInteger(1, &num_items); |
| |
| const base::string16 plural_string = |
| num_items > 0 ? l10n_util::GetPluralStringFUTF16(id, num_items) |
| : base::string16(); |
| ResolveJavascriptCallback(base::Value(callback_id), |
| base::Value(plural_string)); |
| } |
| |
| } // namespace settings |