Commit 2b1664a9 authored by Rainhard Findling's avatar Rainhard Findling Committed by Commit Bot

Safety check browser proxy

* Adds the JS side of the safety check browser proxy.
* Introduces the same API on JS side as used on the C++ side
  (https://crrev.com/c/2049982).
* Adds states for the safety check children elements in the form of
  Polymer properties, which will be used by the safety check children
  elements in the future.

Bug: 1015841
Change-Id: I4bd95e2970a018b0d3c8e63114582c1f4e2cb60b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2059375
Commit-Queue: Rainhard Findling <rainhard@chromium.org>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#744217}
parent c018b81a
...@@ -5,12 +5,22 @@ ...@@ -5,12 +5,22 @@
import("//third_party/closure_compiler/compile_js.gni") import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") { js_type_check("closure_compile") {
deps = [ ":safety_check_page" ] deps = [
":safety_check_browser_proxy",
":safety_check_page",
]
} }
js_library("safety_check_page") { js_library("safety_check_page") {
deps = [ deps = [
":safety_check_browser_proxy",
"//ui/webui/resources/js:assert", "//ui/webui/resources/js:assert",
"//ui/webui/resources/js:i18n_behavior", "//ui/webui/resources/js:i18n_behavior",
"//ui/webui/resources/js:web_ui_listener_behavior",
] ]
externs_list = [ "$externs_path/chrome_send.js" ]
}
js_library("safety_check_browser_proxy") {
deps = [ "//ui/webui/resources/js:cr" ]
} }
<link rel="import" href="chrome://resources/html/cr.html">
<script src="safety_check_browser_proxy.js"></script>
// Copyright 2020 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.
/**
* @fileoverview A helper object used by the "SafetyCheck" to interact with
* the browser.
*/
cr.define('settings', function() {
/**
* States of the safety check updates element.
* Needs to be kept in sync with UpdatesStatus in
* chrome/browser/ui/webui/settings/safety_check_handler.h
* @enum {number}
*/
const SafetyCheckUpdatesStatus = {
CHECKING: 0,
UPDATED: 1,
UPDATING: 2,
RELAUNCH: 3,
DISABLED_BY_ADMIN: 4,
FAILED_OFFLINE: 5,
FAILED: 6,
};
/**
* States of the safety check passwords element.
* Needs to be kept in sync with PasswordsStatus in
* chrome/browser/ui/webui/settings/safety_check_handler.h
* @enum {number}
*/
const SafetyCheckPasswordsStatus = {
CHECKING: 0,
SAFE: 1,
COMPROMISED: 2,
OFFLINE: 3,
NO_PASSWORDS: 4,
SIGNED_OUT: 5,
QUOTA_LIMIT: 6,
TOO_MANY_PASSWORDS: 7,
ERROR: 8,
};
/**
* States of the safety check safe browsing element.
* Needs to be kept in sync with SafeBrowsingStatus in
* chrome/browser/ui/webui/settings/safety_check_handler.h
* @enum {number}
*/
const SafetyCheckSafeBrowsingStatus = {
CHECKING: 0,
ENABLED: 1,
DISABLED: 2,
DISABLED_BY_ADMIN: 3,
DISABLED_BY_EXTENSION: 4,
};
/**
* States of the safety check extensions element.
* Needs to be kept in sync with ExtensionsStatus in
* chrome/browser/ui/webui/settings/safety_check_handler.h
* @enum {number}
*/
const SafetyCheckExtensionsStatus = {
CHECKING: 0,
ERROR: 1,
SAFE: 2,
BAD_EXTENSIONS_ON: 3,
BAD_EXTENSIONS_OFF: 4,
MANAGED_BY_ADMIN: 5,
};
/** @interface */
class SafetyCheckBrowserProxy {
/** Run the safety check. */
runSafetyCheck() {}
}
/** @implements {settings.SafetyCheckBrowserProxy} */
class SafetyCheckBrowserProxyImpl {
/** @override */
runSafetyCheck() {
chrome.send('performSafetyCheck');
}
}
cr.addSingletonGetter(SafetyCheckBrowserProxyImpl);
return {
SafetyCheckUpdatesStatus,
SafetyCheckPasswordsStatus,
SafetyCheckSafeBrowsingStatus,
SafetyCheckExtensionsStatus,
SafetyCheckBrowserProxy,
SafetyCheckBrowserProxyImpl,
};
});
...@@ -4,11 +4,14 @@ ...@@ -4,11 +4,14 @@
<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
<link rel="import" href="../i18n_setup.html"> <link rel="import" href="../i18n_setup.html">
<link rel="import" href="../prefs/prefs_behavior.html"> <link rel="import" href="../prefs/prefs_behavior.html">
<link rel="import" href="../settings_shared_css.html"> <link rel="import" href="../settings_shared_css.html">
<link rel="import" href="safety_check_browser_proxy.html">
<dom-module id="settings-safety-check-page"> <dom-module id="settings-safety-check-page">
<template> <template>
<!-- // TODO(crbug.com/1010001): Release block M82 beta: <!-- // TODO(crbug.com/1010001): Release block M82 beta:
......
...@@ -19,10 +19,34 @@ const ParentStatus = { ...@@ -19,10 +19,34 @@ const ParentStatus = {
AFTER: 2, AFTER: 2,
}; };
/**
* Values used to identify safety check components in the callback dictionary.
* Needs to be kept in sync with SafetyCheckComponent in
* chrome/browser/ui/webui/settings/safety_check_handler.h
* @enum {number}
*/
const SafetyCheckComponent = {
UPDATES: 0,
PASSWORDS: 1,
SAFE_BROWSING: 2,
EXTENSIONS: 3,
};
/**
* @typedef {{
* safetyCheckComponent: SafetyCheckComponent,
* newState: number,
* passwordsCompromised: (number|undefined),
* badExtensions: (number|undefined),
* }}
*/
/* #export */ let SafetyCheckStatusChangedEvent;
Polymer({ Polymer({
is: 'settings-safety-check-page', is: 'settings-safety-check-page',
behaviors: [ behaviors: [
WebUIListenerBehavior,
I18nBehavior, I18nBehavior,
], ],
...@@ -35,6 +59,72 @@ Polymer({ ...@@ -35,6 +59,72 @@ Polymer({
type: Number, type: Number,
value: ParentStatus.BEFORE, value: ParentStatus.BEFORE,
}, },
/**
* Current state of the safety check updates element.
* @private {!settings.SafetyCheckUpdatesStatus}
*/
updatesStatus_: {
type: Number,
value: settings.SafetyCheckUpdatesStatus.CHECKING,
},
/**
* Current state of the safety check passwords element.
* @private {!settings.SafetyCheckPasswordsStatus}
*/
passwordsStatus_: {
type: Number,
value: settings.SafetyCheckPasswordsStatus.CHECKING,
},
/**
* Number of password compromises.
* @private {number}
*/
passwordsCompromisedCount_: {
type: Number,
},
/**
* Current state of the safety check safe browsing element.
* @private {!settings.SafetyCheckSafeBrowsingStatus}
*/
safeBrowsingStatus_: {
type: Number,
value: settings.SafetyCheckSafeBrowsingStatus.CHECKING,
},
/**
* Current state of the safety check extensions element.
* @private {!settings.SafetyCheckExtensionsStatus}
*/
extensionsStatus_: {
type: Number,
value: settings.SafetyCheckExtensionsStatus.CHECKING,
},
/**
* Number of bad extensions.
* @private {number}
*/
badExtensionsCount_: {
type: Number,
},
},
/** @private {settings.SafetyCheckBrowserProxy} */
safetyCheckBrowserProxy_: null,
/** @override */
attached: function() {
this.safetyCheckBrowserProxy_ =
settings.SafetyCheckBrowserProxyImpl.getInstance();
// Register for safety check status updates.
this.addWebUIListener(
'safety-check-status-changed',
this.onSafetyCheckStatusUpdate_.bind(this));
}, },
/** /**
...@@ -42,8 +132,52 @@ Polymer({ ...@@ -42,8 +132,52 @@ Polymer({
* @private * @private
*/ */
onRunSafetyCheckClick_: function() { onRunSafetyCheckClick_: function() {
// TODO(crbug.com/1010001) Trigger backend safety check here. // Update UI.
this.parentStatus_ = ParentStatus.CHECKING; this.parentStatus_ = ParentStatus.CHECKING;
// Reset all children states.
this.updatesStatus_ = settings.SafetyCheckUpdatesStatus.CHECKING;
this.passwordsStatus_ = settings.SafetyCheckPasswordsStatus.CHECKING;
this.safeBrowsingStatus_ = settings.SafetyCheckSafeBrowsingStatus.CHECKING;
this.extensionsStatus_ = settings.SafetyCheckExtensionsStatus.CHECKING;
// Trigger safety check.
this.safetyCheckBrowserProxy_.runSafetyCheck();
},
/**
* Safety check callback to update UI from safety check result.
* @param {SafetyCheckStatusChangedEvent} event
* @private
*/
onSafetyCheckStatusUpdate_: function(event) {
const status = event['newState'];
switch (event.safetyCheckComponent) {
case SafetyCheckComponent.UPDATES:
this.updatesStatus_ = status;
break;
case SafetyCheckComponent.PASSWORDS:
this.passwordsStatus_ = status;
this.passwordsCompromisedCount_ = event['passwordsCompromised'];
break;
case SafetyCheckComponent.SAFE_BROWSING:
this.safeBrowsingStatus_ = status;
break;
case SafetyCheckComponent.EXTENSIONS:
this.extensionsStatus_ = status;
this.badExtensionsCount_ = event['badExtensions'];
break;
default:
assertNotReached();
}
// If all children elements received updates: update parent element.
if (this.updatesStatus_ != settings.SafetyCheckUpdatesStatus.CHECKING &&
this.passwordsStatus_ != settings.SafetyCheckPasswordsStatus.CHECKING &&
this.safeBrowsingStatus_ !=
settings.SafetyCheckSafeBrowsingStatus.CHECKING &&
this.extensionsStatus_ !=
settings.SafetyCheckExtensionsStatus.CHECKING) {
this.parentStatus_ = ParentStatus.AFTER;
}
}, },
/** /**
......
...@@ -883,6 +883,12 @@ ...@@ -883,6 +883,12 @@
<structure name="IDR_SETTINGS_SAFETY_CHECK_PAGE_JS" <structure name="IDR_SETTINGS_SAFETY_CHECK_PAGE_JS"
file="safety_check_page/safety_check_page.js" file="safety_check_page/safety_check_page.js"
type="chrome_html" /> type="chrome_html" />
<structure name="IDR_SETTINGS_SAFETY_CHECK_BROWSER_PROXY_HTML"
file="safety_check_page/safety_check_browser_proxy.html"
type="chrome_html" />
<structure name="IDR_SETTINGS_SAFETY_CHECK_BROWSER_PROXY_JS"
file="safety_check_page/safety_check_browser_proxy.js"
type="chrome_html" />
<structure name="IDR_SETTINGS_PROTOCOL_HANDLERS_HTML" <structure name="IDR_SETTINGS_PROTOCOL_HANDLERS_HTML"
file="site_settings/protocol_handlers.html" file="site_settings/protocol_handlers.html"
preprocess="true" preprocess="true"
......
...@@ -14,7 +14,6 @@ namespace { ...@@ -14,7 +14,6 @@ namespace {
// Constants for communication with JS. // Constants for communication with JS.
static constexpr char kStatusChanged[] = "safety-check-status-changed"; static constexpr char kStatusChanged[] = "safety-check-status-changed";
static constexpr char kInitialize[] = "initializeSafetyCheck";
static constexpr char kPerformSafetyCheck[] = "performSafetyCheck"; static constexpr char kPerformSafetyCheck[] = "performSafetyCheck";
static constexpr char kSafetyCheckComponent[] = "safetyCheckComponent"; static constexpr char kSafetyCheckComponent[] = "safetyCheckComponent";
static constexpr char kNewState[] = "newState"; static constexpr char kNewState[] = "newState";
...@@ -54,6 +53,7 @@ SafetyCheckHandler::SafetyCheckHandler() ...@@ -54,6 +53,7 @@ SafetyCheckHandler::SafetyCheckHandler()
SafetyCheckHandler::~SafetyCheckHandler() = default; SafetyCheckHandler::~SafetyCheckHandler() = default;
void SafetyCheckHandler::PerformSafetyCheck() { void SafetyCheckHandler::PerformSafetyCheck() {
AllowJavascript();
if (!version_updater_) { if (!version_updater_) {
version_updater_.reset(VersionUpdater::Create(web_ui()->GetWebContents())); version_updater_.reset(VersionUpdater::Create(web_ui()->GetWebContents()));
} }
...@@ -66,10 +66,6 @@ SafetyCheckHandler::SafetyCheckHandler( ...@@ -66,10 +66,6 @@ SafetyCheckHandler::SafetyCheckHandler(
SafetyCheckHandlerObserver* observer) SafetyCheckHandlerObserver* observer)
: version_updater_(std::move(version_updater)), observer_(observer) {} : version_updater_(std::move(version_updater)), observer_(observer) {}
void SafetyCheckHandler::HandleInitialize(const base::ListValue* /*args*/) {
AllowJavascript();
}
void SafetyCheckHandler::HandlePerformSafetyCheck( void SafetyCheckHandler::HandlePerformSafetyCheck(
const base::ListValue* /*args*/) { const base::ListValue* /*args*/) {
PerformSafetyCheck(); PerformSafetyCheck();
...@@ -140,9 +136,6 @@ void SafetyCheckHandler::OnJavascriptAllowed() {} ...@@ -140,9 +136,6 @@ void SafetyCheckHandler::OnJavascriptAllowed() {}
void SafetyCheckHandler::OnJavascriptDisallowed() {} void SafetyCheckHandler::OnJavascriptDisallowed() {}
void SafetyCheckHandler::RegisterMessages() { void SafetyCheckHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
kInitialize, base::BindRepeating(&SafetyCheckHandler::HandleInitialize,
base::Unretained(this)));
web_ui()->RegisterMessageCallback( web_ui()->RegisterMessageCallback(
kPerformSafetyCheck, kPerformSafetyCheck,
base::BindRepeating(&SafetyCheckHandler::HandlePerformSafetyCheck, base::BindRepeating(&SafetyCheckHandler::HandlePerformSafetyCheck,
......
...@@ -61,9 +61,6 @@ class SafetyCheckHandler : public settings::SettingsPageUIHandler { ...@@ -61,9 +61,6 @@ class SafetyCheckHandler : public settings::SettingsPageUIHandler {
SafetyCheckHandlerObserver* observer); SafetyCheckHandlerObserver* observer);
private: private:
// Handles page initialization. Should be called when page is loaded.
void HandleInitialize(const base::ListValue* args);
// Handles triggering the safety check from the frontend (by user pressing a // Handles triggering the safety check from the frontend (by user pressing a
// button). // button).
void HandlePerformSafetyCheck(const base::ListValue* args); void HandlePerformSafetyCheck(const base::ListValue* args);
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "chrome/browser/ui/webui/settings/profile_info_handler.h" #include "chrome/browser/ui/webui/settings/profile_info_handler.h"
#include "chrome/browser/ui/webui/settings/protocol_handlers_handler.h" #include "chrome/browser/ui/webui/settings/protocol_handlers_handler.h"
#include "chrome/browser/ui/webui/settings/reset_settings_handler.h" #include "chrome/browser/ui/webui/settings/reset_settings_handler.h"
#include "chrome/browser/ui/webui/settings/safety_check_handler.h"
#include "chrome/browser/ui/webui/settings/search_engines_handler.h" #include "chrome/browser/ui/webui/settings/search_engines_handler.h"
#include "chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h" #include "chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h"
#include "chrome/browser/ui/webui/settings/settings_cookies_view_handler.h" #include "chrome/browser/ui/webui/settings/settings_cookies_view_handler.h"
...@@ -187,6 +188,7 @@ SettingsUI::SettingsUI(content::WebUI* web_ui) ...@@ -187,6 +188,7 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
AddSettingsPageUIHandler(std::make_unique<BrowserLifetimeHandler>()); AddSettingsPageUIHandler(std::make_unique<BrowserLifetimeHandler>());
AddSettingsPageUIHandler( AddSettingsPageUIHandler(
std::make_unique<ClearBrowsingDataHandler>(web_ui, profile)); std::make_unique<ClearBrowsingDataHandler>(web_ui, profile));
AddSettingsPageUIHandler(std::make_unique<SafetyCheckHandler>());
AddSettingsPageUIHandler(std::make_unique<CookiesViewHandler>()); AddSettingsPageUIHandler(std::make_unique<CookiesViewHandler>());
AddSettingsPageUIHandler(std::make_unique<DownloadsHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<DownloadsHandler>(profile));
AddSettingsPageUIHandler(std::make_unique<ExtensionControlHandler>()); AddSettingsPageUIHandler(std::make_unique<ExtensionControlHandler>());
......
...@@ -18,16 +18,47 @@ suite('SafetyCheckUiTests', function() { ...@@ -18,16 +18,47 @@ suite('SafetyCheckUiTests', function() {
}); });
test('parentBeforeCheckUiTest', function() { test('parentBeforeCheckUiTest', function() {
// Only the text button is present.
assertTrue(!!page.$$('#safetyCheckParentButton')); assertTrue(!!page.$$('#safetyCheckParentButton'));
assertFalse(!!page.$$('#safetyCheckParentIconButton')); assertFalse(!!page.$$('#safetyCheckParentIconButton'));
}); });
test('parentDuringCheckUiTest', function() { test('parentDuringCheckUiTest', function() {
// User starts check.
page.$$('#safetyCheckParentButton').click(); page.$$('#safetyCheckParentButton').click();
Polymer.dom.flush(); Polymer.dom.flush();
// No button is present.
assertFalse(!!page.$$('#safetyCheckParentButton')); assertFalse(!!page.$$('#safetyCheckParentButton'));
assertFalse(!!page.$$('#safetyCheckParentIconButton')); assertFalse(!!page.$$('#safetyCheckParentIconButton'));
}); });
test('parentAfterCheckUiTest', function() {
// User starts check.
page.$$('#safetyCheckParentButton').click();
// Mock all incoming messages that indicate safety check completion.
cr.webUIListenerCallback('safety-check-status-changed', {
safetyCheckComponent: 0, /* UPDATES */
newState: settings.SafetyCheckUpdatesStatus.UPDATED,
});
cr.webUIListenerCallback('safety-check-status-changed', {
safetyCheckComponent: 1, /* PASSWORDS */
newState: settings.SafetyCheckPasswordsStatus.SAFE,
});
cr.webUIListenerCallback('safety-check-status-changed', {
safetyCheckComponent: 2, /* SAFE_BROWSING */
newState: settings.SafetyCheckSafeBrowsingStatus.ENABLED,
});
cr.webUIListenerCallback('safety-check-status-changed', {
safetyCheckComponent: 3, /* EXTENSIONS */
newState: settings.SafetyCheckExtensionsStatus.SAFE,
});
Polymer.dom.flush();
// Only the icon button is present.
assertFalse(!!page.$$('#safetyCheckParentButton'));
assertTrue(!!page.$$('#safetyCheckParentIconButton'));
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment