Commit 1cff1c20 authored by Trent Begin's avatar Trent Begin Committed by Commit Bot

network_diagnostics: add network-diagnostics UI to chrome://network

This change creates a new Polymer component network-diagnostics that
runs diagnostic routines and then displays the results.

Bug: chromium:1098405
Change-Id: I245b3378e477f4fae89d9b33201c7359cc9e8e56
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2261189
Commit-Queue: Trent Begin <tbegin@chromium.org>
Reviewed-by: default avatardpapad <dpapad@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789532}
parent 0dd06bcc
......@@ -3450,6 +3450,9 @@
<message name="IDS_NETWORK_UI_NETWORK_HEALTH" desc="Label for network health snapshot. 'Network Health' is a condensend summary of all networking devices on the system and their active networks">
Network Health Snapshot
</message>
<message name="IDS_NETWORK_UI_NETWORK_DIAGNOSTICS" desc="Label for network diagnostics routines">
Network Diagnostic Routines
</message>
<message name="IDS_NETWORK_UI_NETWORK_LISTS" desc="Label for network lists section">
Network (Service) and Device properties
</message>
......@@ -3555,6 +3558,43 @@
<message name="IDS_NETWORK_HEALTH_STATE_ONLINE" desc="Network State - Online. This state is when a network device is connected to a network and can access the internet.">
Online
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_LAN_CONNECTIVITY" desc="Label for Network diagnostics `LAN connectivity` test. This test determines if the device is connected to a Local Area Network (LAN)">
Lan Connectivity
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_SIGNAL_STRENGTH" desc="Label for Network diagnostics `signal strength` test. This test ensures that a WiFi signal is strong enough for a stable connection.">
Signal Strength
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_GATEWAY_CAN_BE_PINGED" desc="Label for Network diagnostics `gateway can be pinged` test. This test ensures that there is a connection to the network gateway.">
Gateway can be Pinged
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_HAS_SECURE_WIFI_CONNECTION" desc="Label for Network diagnostics `has secure WiFi connection` test. This test ensures that the WiFi connection is properly secure.">
Secure WiFi Connection
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_DNS_RESOLVER_PRESENT" desc="Label for Network diagnostics `DNS resolver present` test. This test ensures that the Domain Name Service (DNS) exists.">
DNS Resolver Present
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_DNS_LATENCY" desc="Label for Network diagnostics `DNS latency` test. This test makes sure the latency between the device and the Domain Name Server (DNS) is acceptable.">
DNS Latency
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_DNS_RESOLUTION" desc="Label for Network diagnostics `DNS resolution` test. This test ensures that the Domain Name Server (DNS) can resolve network requests.">
DNS Resolution
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_PASSED" desc="Label shown when a Network diagnostics routine passed">
Passed
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_FAILED" desc="Label shown when a Network diagnostics routine failed">
Failed
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_NOT_RUN" desc="Label shown when a Network diagnostics routine did not run">
Not Run
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_RUN" desc="Label for Network diagnostics run routine button">
Run
</message>
<message name="IDS_NETWORK_DIAGNOSTICS_RUN_ALL" desc="Label for Network diagnostics run all routines button">
Run All Routines
</message>
<!-- Set time/date UI display strings -->
<message name="IDS_SET_TIME_TITLE" desc="Title of the set time/date UI.">
......
8d3e90b224faeaf73f44f7603005fec55751d0f6
\ No newline at end of file
e3f815d34554a89cac6f8ff6495d7cf55d119660
\ No newline at end of file
d6a31bc961c72c6cf7a337b3aac35909bf05a8d4
\ No newline at end of file
a14700c25434eedb5cb5044c7f8d419c55da3761
\ No newline at end of file
d6fffef58f6cadeb2bc619d9b4dade4976b5f3f0
\ No newline at end of file
cf0771fcb7f48c0d1925642d421c5928e79c2470
\ No newline at end of file
e3916d9bc50e0aadba257e9d1497450a9f3fa5d6
\ No newline at end of file
19cb6a747506d33dd08178b2eb3f23e4e7cd8133
\ No newline at end of file
9ae35854439cca9d6352ee1551214f8d03de7891
\ No newline at end of file
af9a303d71a7e6f6990535d9d4621742b249ab19
\ No newline at end of file
52dffb800437a683e215b592e13cbff40655d53c
\ No newline at end of file
fa426ab56d79e3802ef657e7d798375f084b44f2
\ No newline at end of file
8703ff17654615e35ccf9fffb788adfbb66722b7
\ No newline at end of file
......@@ -158,6 +158,7 @@
#include "chromeos/services/multidevice_setup/multidevice_setup_service.h"
#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" // nogncheck
#include "chromeos/services/network_health/public/mojom/network_diagnostics.mojom.h"
#include "chromeos/services/network_health/public/mojom/network_health.mojom.h"
#endif
......@@ -570,6 +571,10 @@ void PopulateChromeWebUIFrameBinders(
RegisterWebUIControllerInterfaceBinder<
chromeos::network_health::mojom::NetworkHealthService,
chromeos::NetworkUI>(map);
RegisterWebUIControllerInterfaceBinder<
chromeos::network_diagnostics::mojom::NetworkDiagnosticsRoutines,
chromeos::NetworkUI>(map);
#endif // defined(OS_CHROMEOS)
#if defined(OS_CHROMEOS) && !defined(OFFICIAL_BUILD)
......
......@@ -14,6 +14,7 @@ namespace network_health {
namespace {
constexpr webui::LocalizedString kLocalizedStrings[] = {
// Network Health Summary Strings
{"NetworkHealthState", IDS_NETWORK_HEALTH_STATE},
{"NetworkHealthStateUninitialized", IDS_NETWORK_HEALTH_STATE_UNINITIALIZED},
{"NetworkHealthStateDisabled", IDS_NETWORK_HEALTH_STATE_DISABLED},
......@@ -23,6 +24,25 @@ constexpr webui::LocalizedString kLocalizedStrings[] = {
{"NetworkHealthStatePortal", IDS_NETWORK_HEALTH_STATE_PORTAL},
{"NetworkHealthStateConnected", IDS_NETWORK_HEALTH_STATE_CONNECTED},
{"NetworkHealthStateOnline", IDS_NETWORK_HEALTH_STATE_ONLINE},
// Network Diagnostics Strings
{"NetworkDiagnosticsLanConnectivity",
IDS_NETWORK_DIAGNOSTICS_LAN_CONNECTIVITY},
{"NetworkDiagnosticsSignalStrength",
IDS_NETWORK_DIAGNOSTICS_SIGNAL_STRENGTH},
{"NetworkDiagnosticsGatewayCanBePinged",
IDS_NETWORK_DIAGNOSTICS_GATEWAY_CAN_BE_PINGED},
{"NetworkDiagnosticsHasSecureWiFiConnection",
IDS_NETWORK_DIAGNOSTICS_HAS_SECURE_WIFI_CONNECTION},
{"NetworkDiagnosticsDnsResolverPresent",
IDS_NETWORK_DIAGNOSTICS_DNS_RESOLVER_PRESENT},
{"NetworkDiagnosticsDnsLatency", IDS_NETWORK_DIAGNOSTICS_DNS_LATENCY},
{"NetworkDiagnosticsDnsResolution", IDS_NETWORK_DIAGNOSTICS_DNS_RESOLUTION},
{"NetworkDiagnosticsPassed", IDS_NETWORK_DIAGNOSTICS_PASSED},
{"NetworkDiagnosticsFailed", IDS_NETWORK_DIAGNOSTICS_FAILED},
{"NetworkDiagnosticsNotRun", IDS_NETWORK_DIAGNOSTICS_NOT_RUN},
{"NetworkDiagnosticsRun", IDS_NETWORK_DIAGNOSTICS_RUN},
{"NetworkDiagnosticsRunAll", IDS_NETWORK_DIAGNOSTICS_RUN_ALL},
};
} // namespace
......
......@@ -2,6 +2,7 @@
<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_select.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/network_health/network_diagnostics.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/network_health/network_health_summary.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_tabs/cr_tabs.html">
......@@ -37,7 +38,7 @@
flex: 1;
position: relative;
}
network-select {
flex: 1;
}
......@@ -86,6 +87,8 @@
<div class="tabpanel" id="health">
<h2>$i18n{networkHealthLabel}</h2>
<network-health-summary></network-health-summary>
<h2>$i18n{networkDiagnosticsLabel}</h2>
<network-diagnostics></network-diagnostics>
</div>
<div class="tabpanel" id="logs">
......
......@@ -33,6 +33,7 @@
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/onc/onc_utils.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
#include "chromeos/services/network_health/public/mojom/network_diagnostics.mojom.h"
#include "chromeos/services/network_health/public/mojom/network_health.mojom.h"
#include "components/device_event_log/device_event_log.h"
#include "content/public/browser/browser_context.h"
......@@ -371,6 +372,9 @@ void NetworkUI::GetLocalizedStrings(base::DictionaryValue* localized_strings) {
localized_strings->SetString(
"networkHealthLabel",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_HEALTH));
localized_strings->SetString(
"networkDiagnosticsLabel",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_DIAGNOSTICS));
localized_strings->SetString(
"visibleNetworksLabel",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_VISIBLE_NETWORKS));
......@@ -500,6 +504,13 @@ void NetworkUI::BindInterface(
std::move(receiver));
}
void NetworkUI::BindInterface(
mojo::PendingReceiver<
network_diagnostics::mojom::NetworkDiagnosticsRoutines> receiver) {
network_health::NetworkHealthService::GetInstance()->BindDiagnosticsRemote(
std::move(receiver));
}
WEB_UI_CONTROLLER_TYPE_IMPL(NetworkUI)
} // namespace chromeos
......@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom-forward.h"
#include "chromeos/services/network_health/public/mojom/network_diagnostics.mojom-forward.h"
#include "chromeos/services/network_health/public/mojom/network_health.mojom-forward.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "ui/webui/mojo_web_ui_controller.h"
......@@ -36,6 +37,12 @@ class NetworkUI : public ui::MojoWebUIController {
mojo::PendingReceiver<network_health::mojom::NetworkHealthService>
receiver);
// Instantiates implementation of the mojom::NetworkDiagnosticsRoutines mojo
// interface passing the pending receiver that will be bound.
void BindInterface(
mojo::PendingReceiver<
network_diagnostics::mojom::NetworkDiagnosticsRoutines> receiver);
private:
WEB_UI_CONTROLLER_TYPE_DECL();
......
......@@ -190,6 +190,12 @@ const std::map<int, std::string> CreateChromeosMojoResourceIdToAliasMap() {
{IDR_NETWORK_HEALTH_MOJOM_LITE_JS,
"mojo/chromeos/services/network_health/public/mojom/"
"network_health.mojom-lite.js"},
{IDR_NETWORK_DIAGNOSTICS_MOJOM_HTML,
"mojo/chromeos/services/network_health/public/mojom/"
"network_diagnostics.mojom.html"},
{IDR_NETWORK_DIAGNOSTICS_MOJOM_LITE_JS,
"mojo/chromeos/services/network_health/public/mojom/"
"network_diagnostics.mojom-lite.js"},
};
}
#endif // !defined(OS_CHROMEOS)
......
......@@ -11,12 +11,18 @@ assert(is_chromeos, "Only ChromeOS components belong here.")
# JS type check for Polymer 2 and 3
js_type_check("closure_compile") {
deps = [ ":network_health_summary" ]
deps = [
":network_diagnostics",
":network_health_summary",
]
}
js_type_check("closure_compile_module") {
is_polymer3 = true
deps = [ ":network_health_summary.m" ]
deps = [
":network_diagnostics.m",
":network_health_summary.m",
]
}
# Sources with Polymer 3 generated modules
......@@ -29,6 +35,13 @@ js_library("network_health_summary") {
]
}
js_library("network_diagnostics") {
deps = [
"//chromeos/services/network_health/public/mojom:mojom_js_library_for_compile",
"//ui/webui/resources/js:i18n_behavior",
]
}
js_library("network_health_summary.m") {
sources = [ "$root_gen_dir/ui/webui/resources/cr_components/chromeos/network_health/network_health_summary.m.js" ]
deps = [
......@@ -40,6 +53,15 @@ js_library("network_health_summary.m") {
extra_deps = [ ":network_health_summary_module" ]
}
js_library("network_diagnostics.m") {
sources = [ "$root_gen_dir/ui/webui/resources/cr_components/chromeos/network_health/network_diagnostics.m.js" ]
deps = [
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:i18n_behavior.m",
]
extra_deps = [ ":network_diagnostics_module" ]
}
# polymer_modulizer for converting Polymer2 to Polymer3
polymer_modulizer("network_health_summary") {
......@@ -48,6 +70,15 @@ polymer_modulizer("network_health_summary") {
html_type = "dom-module"
}
polymer_modulizer("network_diagnostics") {
js_file = "network_diagnostics.js"
html_file = "network_diagnostics.html"
html_type = "dom-module"
}
group("polymer3_elements") {
public_deps = [ ":network_health_summary_module" ]
public_deps = [
":network_diagnostics_module",
":network_health_summary_module",
]
}
<link rel="import" href="../../../html/polymer.html">
<link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html">
<link rel="import" href="chrome://resources/mojo/chromeos/services/network_health/public/mojom/network_diagnostics.mojom.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html">
<link rel="import" href="../../../cr_elements/cr_button/cr_button.html">
<link rel="import" href="../../../html/i18n_behavior.html">
<dom-module id="network-diagnostics">
<template>
<style>
.routine-group {
display: inline-flex;
flex-wrap: wrap;
}
.routine-container {
border: 2px solid rgb(150, 150, 150);
height: 50px;
margin: 10px;
padding: 5px;
width: 400px;
}
.run-btn {
background-color: white;
}
.routine-name {
font-size: 1rem;
font-weight: bold;
}
.routine-content {
display: flex;
}
.routine-result {
flex: 1;
}
.result-passed {
background-color: rgb(217, 234, 211);
}
.result-error {
background-color: rgb(244, 204, 204);
}
.result-not-run {
background-color: rgb(255, 242, 204);
}
</style>
<div>
<cr-button class="action-button" on-click="onRunAllRoutinesClick_">
[[i18n('NetworkDiagnosticsRunAll')]]
</cr-button>
</div>
<div class="routine-group">
<template is="dom-repeat" items="[[routines_]]" as="routine">
<div class="routine-container">
<div class="routine-name">[[i18n(routine.name)]]</div>
<div class="routine-content">
<span class="routine-result">[[routine.resultMsg]]</span>
<template is="dom-if" if="[[routine.running]]">
<paper-spinner-lite active></paper-spinner-lite>
</template>
<cr-button class="run-btn" hidden="[[routine.running]]" on-click="onRunRoutineClick_">
[[i18n('NetworkDiagnosticsRun')]]
</cr-button>
</div>
</div>
</template>
</div>
</template>
<script src="network_diagnostics.js"></script>
</dom-module>
// 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 Polymer element for interacting with Network Diagnostics.
*/
/**
* A network diagnostics routine. Holds descriptive information about the
* routine, and it's transient state.
* @typedef {{
* name: string,
* type: !RoutineType,
* running: boolean,
* resultMsg: string,
* }}
*/
let Routine;
/**
* A routine response from the Network Diagnostics mojo service.
* @typedef {{
* verdict: chromeos.networkDiagnostics.mojom.RoutineVerdict
* }}
*/
let RoutineResponse;
/**
* Definition for all Network diagnostic routine types. This enum is intended
* to be used as an index in an array of routines.
* @enum {number}
*/
const RoutineType = {
LAN_CONNECTIVITY: 0,
SIGNAL_STRENGTH: 1,
GATEWAY_PING: 2,
SECURE_WIFI: 3,
DNS_RESOLVER: 4,
DNS_LATENCY: 5,
DNS_RESOLUTION: 6,
};
/**
* Helper function to create a routine object.
* @param {string} name
* @param {!RoutineType} type
* @return {!Routine} Routine object
*/
function createRoutine(name, type) {
return {name: name, type: type, running: false, resultMsg: ''};
}
Polymer({
is: 'network-diagnostics',
behaviors: [
I18nBehavior,
],
properties: {
/**
* List of Diagnostics Routines
* @private {!Array<!Routine>}
*/
routines_: {
type: Array,
value: function() {
const routines = [];
routines[RoutineType.LAN_CONNECTIVITY] = createRoutine(
'NetworkDiagnosticsLanConnectivity', RoutineType.LAN_CONNECTIVITY);
routines[RoutineType.SIGNAL_STRENGTH] = createRoutine(
'NetworkDiagnosticsSignalStrength', RoutineType.SIGNAL_STRENGTH);
routines[RoutineType.GATEWAY_PING] = createRoutine(
'NetworkDiagnosticsGatewayCanBePinged', RoutineType.GATEWAY_PING);
routines[RoutineType.SECURE_WIFI] = createRoutine(
'NetworkDiagnosticsHasSecureWiFiConnection',
RoutineType.SECURE_WIFI);
routines[RoutineType.DNS_RESOLVER] = createRoutine(
'NetworkDiagnosticsDnsResolverPresent', RoutineType.DNS_RESOLVER);
routines[RoutineType.DNS_LATENCY] = createRoutine(
'NetworkDiagnosticsDnsLatency', RoutineType.DNS_LATENCY);
routines[RoutineType.DNS_RESOLUTION] = createRoutine(
'NetworkDiagnosticsDnsResolution', RoutineType.DNS_RESOLUTION);
return routines;
}
}
},
/**
* Network Diagnostics mojo remote.
* @private {
* ?chromeos.networkDiagnostics.mojom.NetworkDiagnosticsRoutinesRemote}
*/
networkDiagnostics_: null,
/** @override */
created() {
this.networkDiagnostics_ = chromeos.networkDiagnostics.mojom
.NetworkDiagnosticsRoutines.getRemote();
},
/** @private */
onRunAllRoutinesClick_() {
for (const routine of this.routines_) {
this.runRoutine_(routine.type);
}
},
/**
* @param {!Event} event
* @private
*/
onRunRoutineClick_(event) {
this.runRoutine_(event.model.index);
},
/**
* @param {!RoutineType} type
* @private
*/
runRoutine_(type) {
this.set(`routines_.${type}.running`, true);
this.set(`routines_.${type}.resultMsg`, '');
const element =
this.shadowRoot.querySelectorAll('.routine-container')[type];
element.classList.remove('result-passed', 'result-error', 'result-not-run');
switch (type) {
case RoutineType.LAN_CONNECTIVITY:
this.networkDiagnostics_.lanConnectivity().then(
result => this.evaluateRoutine_(type, result));
break;
case RoutineType.SIGNAL_STRENGTH:
this.networkDiagnostics_.signalStrength().then(
result => this.evaluateRoutine_(type, result));
break;
case RoutineType.GATEWAY_PING:
this.networkDiagnostics_.gatewayCanBePinged().then(
result => this.evaluateRoutine_(type, result));
break;
case RoutineType.SECURE_WIFI:
this.networkDiagnostics_.hasSecureWiFiConnection().then(
result => this.evaluateRoutine_(type, result));
break;
case RoutineType.DNS_RESOLVER:
this.networkDiagnostics_.dnsResolverPresent().then(
result => this.evaluateRoutine_(type, result));
break;
case RoutineType.DNS_LATENCY:
this.networkDiagnostics_.dnsLatency().then(
result => this.evaluateRoutine_(type, result));
break;
case RoutineType.DNS_RESOLUTION:
this.networkDiagnostics_.dnsResolution().then(
result => this.evaluateRoutine_(type, result));
break;
}
},
/**
* @param {!RoutineType} type
* @param {!RoutineResponse} result
* @private
*/
evaluateRoutine_(type, result) {
const routine = `routines_.${type}`;
this.set(`${routine}.running`, false);
const element =
this.shadowRoot.querySelectorAll('.routine-container')[type];
let resultMsg = '';
switch (result.verdict) {
case chromeos.networkDiagnostics.mojom.RoutineVerdict.kNoProblem:
resultMsg = this.i18n('NetworkDiagnosticsPassed');
element.classList.add('result-passed');
break;
case chromeos.networkDiagnostics.mojom.RoutineVerdict.kProblem:
resultMsg = this.i18n('NetworkDiagnosticsFailed');
element.classList.add('result-error');
break;
case chromeos.networkDiagnostics.mojom.RoutineVerdict.kNotRun:
resultMsg = this.i18n('NetworkDiagnosticsNotRun');
element.classList.add('result-not-run');
break;
}
this.set(routine + '.resultMsg', resultMsg);
},
});
......@@ -264,6 +264,12 @@
<structure name="IDR_CR_COMPONENTS_CHROMEOS_NETWORK_HEALTH_SUMMARY_JS"
file="cr_components/chromeos/network_health/network_health_summary.js"
type="chrome_html" />
<structure name="IDR_CR_COMPONENTS_CHROMEOS_NETWORK_DIAGNOSTICS_HTML"
file="cr_components/chromeos/network_health/network_diagnostics.html"
type="chrome_html" />
<structure name="IDR_CR_COMPONENTS_CHROMEOS_NETWORK_DIAGNOSTICS_JS"
file="cr_components/chromeos/network_health/network_diagnostics.js"
type="chrome_html" />
<!-- Shared between settings and add new share flow. -->
<structure name="IDR_WEBUI_CHROMEOS_SMB_SHARES_SMB_BROWSER_PROXY_HTML"
......
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