Commit 6c98b035 authored by hshi@chromium.org's avatar hshi@chromium.org

Diagnostics UI: more UI implementation.

Implement encapsulated JS handling of the diagnostics page.

Adjust the page layout and element styles to match the Chrome OS Diagnostics Implementation Plan V1 document.

Handle i18n for all strings.

BUG=139442
TEST=lumpy device.

Review URL: https://chromiumcodereview.appspot.com/10825291

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152044 0039d316-1c4b-4281-b951-d872f2087c98
parent b6f2de33
......@@ -17396,6 +17396,52 @@ Battery full
Add Media Gallery by Directory
</message>
<!-- chrome://diagnostics strings -->
<if expr="pp_ifdef('chromeos')">
<message name="IDS_DIAGNOSTICS_DIAGNOSTICS_TITLE" desc="Title for the diagnostics page.">
Diagnostics
</message>
<message name="IDS_DIAGNOSTICS_CONNECTIVITY_TITLE" desc="Title for the connectivity tab.">
Connectivity
</message>
<message name="IDS_DIAGNOSTICS_LOADING" desc="Shown while loading the diagnostics page.">
Loading...
</message>
<message name="IDS_DIAGNOSTICS_ADAPTER_WLAN0" desc="Adapter name for wlan0 interface.">
Wi-Fi
</message>
<message name="IDS_DIAGNOSTICS_ADAPTER_ETH0" desc="Adapter name for eth0 interface.">
Ethernet 1
</message>
<message name="IDS_DIAGNOSTICS_ADAPTER_ETH1" desc="Adapter name for eth1 interface.">
Ethernet 2
</message>
<message name="IDS_DIAGNOSTICS_ADAPTER_WWAN0" desc="Adapter name for wwan0 interface.">
3G
</message>
<message name="IDS_DIAGNOSTICS_TESTING_HARDWARE" desc="Indicates testing network hardware.">
<ph name="BEGIN_BOLD">&lt;b&gt;</ph>1. <ph name="END_BOLD">&lt;/b&gt;</ph>Testing <ph name="ADAPTER_NAME">$2<ex>Wi-Fi</ex></ph> hardware...
</message>
<message name="IDS_DIAGNOSTICS_TESTING_CONNECTION_TO_ROUTER" desc="Indicates testing connection to router.">
<ph name="BEGIN_BOLD">&lt;b&gt;</ph>2. <ph name="END_BOLD">&lt;/b&gt;</ph>Testing connection to router...
</message>
<message name="IDS_DIAGNOSTICS_TESTING_CONNECTION_TO_INTERNET" desc="Indicates testing connection to internet.">
<ph name="BEGIN_BOLD">&lt;b&gt;</ph>3. <ph name="END_BOLD">&lt;/b&gt;</ph>Testing connection to internet...
</message>
<message name="IDS_DIAGNOSTICS_ADAPTER_DISABLED" desc="Indicates adapter is disabled.">
The <ph name="ADAPTER_NAME">$1<ex>Wi-Fi</ex></ph> adapter was not enabled.
</message>
<message name="IDS_DIAGNOSTICS_ADAPTER_NO_IP" desc="Indicates adapter does not have an IP address.">
The <ph name="ADAPTER_NAME">$1<ex>Wi-Fi</ex></ph> adapter does not have an IP address and cannot connect to the internet.
</message>
<message name="IDS_DIAGNOSTICS_ENABLE_ADAPTER" desc="Recommendation for enabling adapter.">
<ph name="BEGIN_BOLD">&lt;b&gt;</ph>Recommendation: <ph name="END_BOLD">&lt;/b&gt;</ph>Enable the <ph name="ADAPTER_NAME">$1<ex>Wi-Fi</ex></ph> adapter.
</message>
<message name="IDS_DIAGNOSTICS_FIX_CONNECTION_TO_ROUTER" desc="Recommendation for fixing connection to the router.">
<ph name="BEGIN_BOLD">&lt;b&gt;</ph>Recommendation: <ph name="END_BOLD">&lt;/b&gt;</ph><ph name="BEGIN_ITALIC">&lt;i&gt;</ph>Please ensure that<ph name="END_ITALIC">&lt;/i&gt;</ph><ph name="BR">&lt;br /&gt;</ph>1) you are trying to connect to the right network<ph name="BR2">&lt;br /&gt;</ph>2) you are using the right authentication method<ph name="BR3">&lt;br /&gt;</ph>3) your router is configured correctly<ph name="BR4">&lt;br /&gt;</ph><ph name="BEGIN2_ITALIC">&lt;i&gt;</ph>Try to<ph name="END2_ITALIC">&lt;/i&gt;</ph><ph name="BR5">&lt;br /&gt;</ph>1) connect to a different netowrk<ph name="BR6">&lt;br /&gt;</ph>2) reboot your router
</message>
</if>
</messages>
<structures fallback_to_english="true">
......@@ -222,6 +222,9 @@
<include name="IDR_DIAGNOSTICS_MAIN_CSS" file="resources\chromeos\diagnostics\main.css" type="BINDATA" />
<include name="IDR_DIAGNOSTICS_MAIN_HTML" file="resources\chromeos\diagnostics\main.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_DIAGNOSTICS_MAIN_JS" file="resources\chromeos\diagnostics\main.js" type="BINDATA" />
<include name="IDR_DIAGNOSTICS_IMAGES_FAIL" file="resources\chromeos\diagnostics\fail.png" type="BINDATA" />
<include name="IDR_DIAGNOSTICS_IMAGES_TICK" file="resources\chromeos\diagnostics\tick.png" type="BINDATA" />
<include name="IDR_DIAGNOSTICS_IMAGES_WARNING" file="resources\chromeos\diagnostics\warning.png" type="BINDATA" />
<include name="IDR_DRIVE_INTERNALS_CSS" file="resources\chromeos\drive_internals.css" type="BINDATA" />
<include name="IDR_DRIVE_INTERNALS_HTML" file="resources\chromeos\drive_internals.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_DRIVE_INTERNALS_JS" file="resources\chromeos\drive_internals.js" type="BINDATA" />
......
......@@ -4,8 +4,6 @@
*/
body {
font-family: 'Chrome Droid Sans', 'Droid Sans Fallback', sans-serif;
font-size: 75%;
padding: 0;
}
......@@ -52,10 +50,41 @@ body {
* to the end of the header, such as the managed prefs banner). */
.page header > h1::after {
-webkit-margin-end: 20px;
background-color: #eee;
background-color: rgb(238, 238, 238);
content: '';
display: block;
height: 1px;
position: relative;
top: 13px;
}
.page div {
line-height: 29px;
}
#connectivity-status div {
clear: both;
float: left;
position: relative;
}
.test-performed {
color: rgb(70, 78, 90);
}
.test-pending {
color: rgb(153, 153, 153);
}
.test-error {
color: rgb(206, 57, 38);
}
div.recommendation {
background: -webkit-gradient(linear, left top, left bottom,
from(rgb(171, 253, 182)),
to(rgb(94, 191, 107)));
border: 1px solid rgb(17, 102, 27);
line-height: 16px;
padding: 2px;
}
<!DOCTYPE HTML>
<html>
<head>
<title>diagnostics</title>
<title i18n-content="diagnostics"></title>
<meta charset="utf-8">
<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
<link rel="stylesheet" href="main.css">
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/local_strings.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome://diagnostics/strings.js"></script>
<script src="chrome://diagnostics/main.js"></script>
</head>
<body>
<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
<div class="navigation">
<h1>Diagnostics</h1>
<h1 i18n-content="diagnostics"></h1>
<ul>
<li class="selected">Connectivity</li>
<li class="selected" i18n-content="connectivity"></li>
</ul>
</div>
<div class="page">
<header>
<h1>Connectivity</h1>
<h1 i18n-content="connectivity"></h1>
</header>
<div id='connectivity-status'></div>
<div id="loading" i18n-content="loading"></div>
<div id="adapter-selection"></div>
<div id="connectivity-status"></div>
</div>
</body>
<script src="chrome://resources/js/i18n_template.js"></script>
<script src="chrome://resources/js/i18n_process.js"></script>
</html>
......@@ -2,38 +2,239 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Updates the Connectivity Status section.
* @param {String} connStatus Dictionary containing connectivity status.
*/
function updateConnectivityStatus(connStatus) {
var deviceTypes = ['wlan0', 'wwan0', 'eth0', 'eth1'];
var deviceNames = ['Wi-Fi', '3G', 'Ethernet0', 'Ethernet1'];
for (var i = 0; i < deviceTypes.length; i++) {
var deviceName = deviceNames[i];
var nameElement = document.createElement('h2');
nameElement.appendChild(document.createTextNode(deviceName));
$('connectivity-status').appendChild(nameElement);
var deviceType = deviceTypes[i];
var deviceStatus = connStatus[deviceType];
var statusMessage;
if (!deviceStatus) {
statusMessage = 'Device not found.';
} else if (!deviceStatus.flags ||
deviceStatus.flags.indexOf('up') == -1) {
statusMessage = 'Device disabled.';
} else if (!deviceStatus.ipv4) {
statusMessage = 'IPv4 address unavailable.';
} else {
statusMessage = 'IPv4 address: ' + deviceStatus.ipv4.addrs;
var localStrings = new LocalStrings();
cr.define('diag', function() {
/**
* Encapsulated handling of the diagnostics page.
*/
function DiagPage() {}
cr.addSingletonGetter(DiagPage);
/*
* Remove all children nodes for an element.
* @param {element} parent of the elements to be removed.
*/
function removeChildren(element) {
element.textContent = '';
}
/**
* List of network adapter types.
*/
DiagPage.AdapterType = [
{adapter: 'wlan0', name: localStrings.getString('wlan0')},
{adapter: 'eth0', name: localStrings.getString('eth0')},
{adapter: 'eth1', name: localStrings.getString('eth1')},
{adapter: 'wwan0', name: localStrings.getString('wwan0')},
];
/**
* List of network adapter status.
* The numeric value assigned to each status reflects how healthy the network
* adapter is.
*
* @enum {int}
*/
DiagPage.AdapterStatus = {
NOT_FOUND: 0,
DISABLED: 1,
NO_IP: 2,
VALID_IP: 3
};
/**
* Image elements for icons.
*/
DiagPage.FailIconElement = document.createElement('img');
DiagPage.TickIconElement = document.createElement('img');
DiagPage.FailIconElement.setAttribute('src', 'fail.png');
DiagPage.TickIconElement.setAttribute('src', 'tick.png');
DiagPage.prototype = {
/**
* Perform initial setup.
*/
initialize: function() {
// Initialize member variables.
this.activeAdapter_ = -1;
this.adapterStatus_ = new Array();
// Attempt to update.
chrome.send('pageLoaded');
},
/**
* Updates the connectivity status with netif information.
* @param {String} netifStatus Dictionary of network adapter status.
*/
setNetifStatus_: function(netifStatus) {
// Hide the "loading" message.
$('loading').hidden = true;
// Update netif state.
for (var i = 0; i < DiagPage.AdapterType.length; i++) {
var adapterType = DiagPage.AdapterType[i];
var status = netifStatus[adapterType.adapter];
if (!status)
this.adapterStatus_[i] = DiagPage.AdapterStatus.NOT_FOUND;
else if (!status.flags || status.flags.indexOf('up') == -1)
this.adapterStatus_[i] = DiagPage.AdapterStatus.DISABLED;
else if (!status.ipv4)
this.adapterStatus_[i] = DiagPage.AdapterStatus.NO_IP;
else
this.adapterStatus_[i] = DiagPage.AdapterStatus.VALID_IP;
}
// Update UI
this.updateAdapterSelection_();
this.updateConnectivityStatus_();
},
/**
* Gets the HTML radio input element id for a network adapter.
* @private
*/
getAdapterElementId_: function(adapter) {
return 'adapter-' + DiagPage.AdapterType[adapter].adapter;
},
/**
* Gets the most active adapter based on their status.
* @private
*/
getActiveAdapter_: function() {
var activeAdapter = -1;
var activeAdapterStatus = DiagPage.AdapterStatus.NOT_FOUND;
for (var i = 0; i < DiagPage.AdapterType.length; i++) {
var status = this.adapterStatus_[i];
if (status == DiagPage.AdapterStatus.NOT_FOUND)
continue;
if (activeAdapter == -1 || status > activeAdapterStatus) {
activeAdapter = i;
activeAdapterStatus = status;
}
}
return activeAdapter;
},
/**
* Update the adapter selection section.
* @private
*/
updateAdapterSelection_: function() {
// Determine active adapter.
if (this.activeAdapter_ == -1)
this.activeAdapter_ = this.getActiveAdapter_();
// Create HTML radio input elements.
var adapterSelectionElement = $('adapter-selection');
removeChildren(adapterSelectionElement);
for (var i = 0; i < DiagPage.AdapterType.length; i++) {
if (this.adapterStatus_[i] == DiagPage.AdapterStatus.NOT_FOUND)
continue;
var radioElement = document.createElement('input');
var elementId = this.getAdapterElementId_(i);
radioElement.setAttribute('type', 'radio');
radioElement.setAttribute('name', 'adapter');
radioElement.setAttribute('id', elementId);
if (i == this.activeAdapter_)
radioElement.setAttribute('checked', 'true');
radioElement.onclick = function(adapter) {
this.activeAdapter_ = adapter;
this.updateConnectivityStatus_();
}.bind(this, i);
var labelElement = document.createElement('label');
labelElement.setAttribute('for', elementId);
labelElement.appendChild(radioElement);
labelElement.appendChild(
document.createTextNode(DiagPage.AdapterType[i].name));
adapterSelectionElement.appendChild(labelElement);
adapterSelectionElement.appendChild(document.createElement('br'));
}
},
/**
* Update the connectivity status for the specified network interface.
* @private
*/
updateConnectivityStatus_: function() {
var adapter = this.activeAdapter_;
var status = this.adapterStatus_[adapter];
var name = DiagPage.AdapterType[adapter].name;
// Status messages for individual tests.
var connectivityStatusElement = $('connectivity-status');
var testStatusElements = new Array();
removeChildren(connectivityStatusElement);
for (var i = 0; i < 3; i++) {
testStatusElements[i] = document.createElement('div');
connectivityStatusElement.appendChild(testStatusElements[i]);
}
testStatusElements[0].innerHTML =
localStrings.getStringF('testing-hardware', name);
testStatusElements[1].innerHTML =
localStrings.getString('testing-connection-to-router');
testStatusElements[2].innerHTML =
localStrings.getString('testing-connection-to-internet');
// Error and recommendation messages may be inserted in test status
// elements.
var errorElement = document.createElement('div');
var recommendationElement = document.createElement('div');
errorElement.className = 'test-error';
recommendationElement.className = 'recommendation';
testStatusElements[0].className = 'test-performed';
if (status == DiagPage.AdapterStatus.DISABLED) {
errorElement.appendChild(DiagPage.FailIconElement.cloneNode());
errorElement.appendChild(document.createTextNode(
localStrings.getStringF('adapter-disabled', name)));
recommendationElement.innerHTML =
localStrings.getStringF('enable-adapter', name);
connectivityStatusElement.insertBefore(errorElement,
testStatusElements[1]);
connectivityStatusElement.insertBefore(recommendationElement,
testStatusElements[1]);
testStatusElements[1].className = 'test-pending';
testStatusElements[2].className = 'test-pending';
} else {
testStatusElements[0].appendChild(DiagPage.TickIconElement.cloneNode());
testStatusElements[1].className = 'test-performed';
if (status == DiagPage.AdapterStatus.NO_IP) {
errorElement.appendChild(DiagPage.FailIconElement.cloneNode());
errorElement.appendChild(document.createTextNode(
localStrings.getStringF('adapter-no-ip', name)));
recommendationElement.innerHTML =
localStrings.getStringF('fix-connection-to-router');
connectivityStatusElement.insertBefore(errorElement,
testStatusElements[2]);
connectivityStatusElement.insertBefore(recommendationElement,
testStatusElements[2]);
testStatusElements[2].className = 'test-pending';
} else {
testStatusElements[1].appendChild(
DiagPage.TickIconElement.cloneNode());
testStatusElements[2].className = 'test-performed';
testStatusElements[2].appendChild(
DiagPage.TickIconElement.cloneNode());
}
}
}
var statusElement = document.createElement('p');
statusElement.appendChild(document.createTextNode(statusMessage));
$('connectivity-status').appendChild(statusElement);
};
DiagPage.setNetifStatus = function(netifStatus) {
DiagPage.getInstance().setNetifStatus_(netifStatus);
}
}
// Export
return {
DiagPage: DiagPage
};
});
/**
* Initialize the DiagPage upon DOM content loaded.
*/
document.addEventListener('DOMContentLoaded', function() {
chrome.send('pageLoaded');
diag.DiagPage.getInstance().initialize();
});
......@@ -16,13 +16,14 @@
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
namespace chromeos {
namespace {
// JS API callback names.
const char kJsApiUpdateConnStatus[] = "updateConnectivityStatus";
const char kJsApiSetNetifStatus[] = "diag.DiagPage.setNetifStatus";
////////////////////////////////////////////////////////////////////////////////
// DiagnosticsHandler
......@@ -77,7 +78,7 @@ void DiagnosticsWebUIHandler::OnGetNetworkInterfaces(
if (parsed_value.get() && parsed_value->IsType(Value::TYPE_DICTIONARY)) {
base::DictionaryValue* result =
static_cast<DictionaryValue*>(parsed_value.get());
web_ui()->CallJavascriptFunction(kJsApiUpdateConnStatus, *result);
web_ui()->CallJavascriptFunction(kJsApiSetNetifStatus, *result);
}
}
......@@ -92,8 +93,34 @@ DiagnosticsUI::DiagnosticsUI(content::WebUI* web_ui)
ChromeWebUIDataSource* source =
new ChromeWebUIDataSource(chrome::kChromeUIDiagnosticsHost);
source->set_json_path("strings.js");
source->add_resource_path("main.css", IDR_DIAGNOSTICS_MAIN_CSS);
source->add_resource_path("main.js", IDR_DIAGNOSTICS_MAIN_JS);
source->add_resource_path("fail.png", IDR_DIAGNOSTICS_IMAGES_FAIL);
source->add_resource_path("tick.png", IDR_DIAGNOSTICS_IMAGES_TICK);
source->add_resource_path("warning.png", IDR_DIAGNOSTICS_IMAGES_WARNING);
source->AddLocalizedString("diagnostics", IDS_DIAGNOSTICS_DIAGNOSTICS_TITLE);
source->AddLocalizedString("connectivity",
IDS_DIAGNOSTICS_CONNECTIVITY_TITLE);
source->AddLocalizedString("loading", IDS_DIAGNOSTICS_LOADING);
source->AddLocalizedString("wlan0", IDS_DIAGNOSTICS_ADAPTER_WLAN0);
source->AddLocalizedString("eth0", IDS_DIAGNOSTICS_ADAPTER_ETH0);
source->AddLocalizedString("eth1", IDS_DIAGNOSTICS_ADAPTER_ETH1);
source->AddLocalizedString("wwan0", IDS_DIAGNOSTICS_ADAPTER_WWAN0);
source->AddLocalizedString("testing-hardware",
IDS_DIAGNOSTICS_TESTING_HARDWARE);
source->AddLocalizedString("testing-connection-to-router",
IDS_DIAGNOSTICS_TESTING_CONNECTION_TO_ROUTER);
source->AddLocalizedString("testing-connection-to-internet",
IDS_DIAGNOSTICS_TESTING_CONNECTION_TO_INTERNET);
source->AddLocalizedString("adapter-disabled",
IDS_DIAGNOSTICS_ADAPTER_DISABLED);
source->AddLocalizedString("adapter-no-ip",
IDS_DIAGNOSTICS_ADAPTER_NO_IP);
source->AddLocalizedString("enable-adapter",
IDS_DIAGNOSTICS_ENABLE_ADAPTER);
source->AddLocalizedString("fix-connection-to-router",
IDS_DIAGNOSTICS_FIX_CONNECTION_TO_ROUTER);
source->set_default_resource(IDR_DIAGNOSTICS_MAIN_HTML);
Profile* profile = Profile::FromWebUI(web_ui);
......
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