summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorgarykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-08 19:46:14 +0000
committergarykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-08 19:46:14 +0000
commitcc1a4ca35f3095776c98f84f476b098037967c6d (patch)
treefc5200df1ba83530973a23ec988beba3173bdb15 /remoting
parent63f01e39ac59725da8d30fa7570f6d85b6ed1f67 (diff)
downloadchromium_src-cc1a4ca35f3095776c98f84f476b098037967c6d.zip
chromium_src-cc1a4ca35f3095776c98f84f476b098037967c6d.tar.gz
chromium_src-cc1a4ca35f3095776c98f84f476b098037967c6d.tar.bz2
Improve UI of Chromoting client UI to select available hosts.
BUG=53988 TEST=none Review URL: http://codereview.chromium.org/3338014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58862 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/client/extension/chromoticon.pngbin0 -> 332 bytes
-rw-r--r--remoting/client/extension/client.js308
-rw-r--r--remoting/client/extension/icon.pngbin3789 -> 0 bytes
-rw-r--r--remoting/client/extension/login.html41
-rw-r--r--remoting/client/extension/machine.pngbin0 -> 4992 bytes
-rw-r--r--remoting/client/extension/main.css98
-rw-r--r--remoting/client/extension/manifest.json2
-rw-r--r--remoting/client/extension/popup.html38
-rwxr-xr-xremoting/tools/gethosts.sh7
9 files changed, 355 insertions, 139 deletions
diff --git a/remoting/client/extension/chromoticon.png b/remoting/client/extension/chromoticon.png
new file mode 100644
index 0000000..a5cb2b2
--- /dev/null
+++ b/remoting/client/extension/chromoticon.png
Binary files differ
diff --git a/remoting/client/extension/client.js b/remoting/client/extension/client.js
index dd53cf3..138d014 100644
--- a/remoting/client/extension/client.js
+++ b/remoting/client/extension/client.js
@@ -2,65 +2,100 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-function initParams() {
- var hash;
- var hashes = window.location.href.slice(
- window.location.href.indexOf('?') + 1).split('&');
-
- // Prepopulate via cookies first.
- document.getElementById('xmpp_auth').value = getCookie('xmpp_auth');
- document.getElementById('chromoting_auth').value =
- getCookie('chromoting_auth');
- document.getElementById('username').value = getCookie('username');
-
- for(var i = 0; i < hashes.length; i++)
- {
- hash = hashes[i].split('=');
- if (hash[0] == 'xmpp_auth') {
- document.getElementById('xmpp_auth').value = hash[1];
- setCookie('xmpp_auth', hash[1]);
-
- } else if (hash[0] == "chromoting_auth") {
- document.getElementById('chromoting_auth').value = hash[1];
- setCookie('chromoting_auth', hash[1]);
-
- } else if (hash[0] == 'username') {
- document.getElementById('username').value = hash[1];
- setCookie('username', hash[1]);
-
- } else if (hash[0] == 'password') {
- document.getElementById('password').value = hash[1];
-
- } else if (hash[0] == 'host_jid') {
- document.getElementById('host_jid').value = hash[1];
- }
- }
+var BAD_AUTH_TOKEN = 'bad_token';
+
+function init() {
+ updateLoginStatus();
+
+ // Defer getting the host list for a little bit so that we don't
+ // block the display of the extension popup.
+ window.setTimeout(listHosts, 100);
}
-function findHosts(form) {
- // If either cookie is missing, login first.
- if (getCookie('chromoting_auth') == null ||
- getCookie('xmpp_auth') == null) {
- doLogin(form.username.value, form.username.password, doListHosts);
+// Update the login status region (at the bottom of the popup) with the
+// current account and links to sign in/out.
+function updateLoginStatus() {
+ var username = getCookie('username');
+
+ var loginDiv = document.getElementById('login_div');
+ clear(loginDiv);
+
+ if (!username) {
+ var signinLink = document.createElement('a');
+ signinLink.setAttribute('href',
+ "javascript:window.open('login.html', 'Sign In', " +
+ "'width=400,height=200,scrollbars=no'); return false;");
+ signinLink.appendChild(document.createTextNode('Sign In'));
+ loginDiv.appendChild(signinLink);
} else {
- doListHosts();
+ var email = document.createElement('span');
+ email.setAttribute('class', 'login_email');
+ email.appendChild(document.createTextNode(username));
+ loginDiv.appendChild(email);
+
+ loginDiv.appendChild(document.createTextNode(' | '));
+
+ var signoutLink = document.createElement('a');
+ signoutLink.setAttribute('href', 'javascript:logout(this.form);');
+ signoutLink.appendChild(document.createTextNode('Sign Out'));
+ loginDiv.appendChild(signoutLink);
}
}
+// Sign out the current user by erasing the auth cookies.
+function logout(form) {
+ setCookie('username', '', 100);
+ setCookie('chromoting_auth', '', 100);
+ setCookie('xmpp_auth', '', 100);
+
+ updateLoginStatus();
+ listHosts();
+}
+
function login(form) {
- doLogin(form.username.value, form.password.value);
+ var status = document.getElementById('login_status');
+ clear(status);
+ doLogin(form.username.value, form.password.value, checkLogin);
}
-function extractAuthToken(message) {
- var lines = message.split('\n');
- for (var i = 0; i < lines.length; i++) {
- if (lines[i].match('^Auth=.*')) {
- return lines[i].split('=')[1];
+// Check to see if the login was successful.
+function checkLogin() {
+ var username = getCookie('username');
+ var cauth = getCookie('chromoting_auth');
+ var xauth = getCookie('xmpp_auth');
+
+ // Verify login and show login status.
+ var status = document.getElementById('login_status');
+ if (cauth == BAD_AUTH_TOKEN || xauth == BAD_AUTH_TOKEN) {
+ appendMessage(status, '', 'Sign in failed!');
+ if (username) {
+ setCookie('username', '', 100);
}
+ } else {
+ appendMessage(status, '', 'Successfully signed in as ' + username);
}
+}
- console.log('Could not parse auth token in : "' + message + '"');
- return 'bad_token';
+function doLogin(username, password, done) {
+ // Don't call |done| callback until both login requests have completed.
+ var count = 2;
+ var barrier = function() {
+ count--;
+ if (done && count == 0) {
+ done();
+ }
+ }
+ setCookie('username', username, 100);
+ doGaiaLogin(username, password, 'chromoting',
+ function(cAuthToken) {
+ setCookie('chromoting_auth', cAuthToken, 100);
+ barrier();
+ });
+ doGaiaLogin(username, password, 'chromiumsync',
+ function(xAuthToken) {
+ setCookie('xmpp_auth', xAuthToken, 100);
+ barrier();
+ });
}
function doGaiaLogin(username, password, service, done) {
@@ -82,54 +117,90 @@ function doGaiaLogin(username, password, service, done) {
password + '&service=' + service + '&source=chromoclient');
}
-function doLogin(username, password, done) {
- var count = 2;
- var barrier = function() {
- count--;
- if (done && count == 0) {
- done();
+function extractAuthToken(message) {
+ var lines = message.split('\n');
+ for (var i = 0; i < lines.length; i++) {
+ if (lines[i].match('^Auth=.*')) {
+ return lines[i].split('=')[1];
}
}
- setCookie('username', username, 100);
- doGaiaLogin(username, password, 'chromoting',
- function(token1) {
- setCookie('chromoting_auth', token1, 100);
- document.getElementById('chromoting_auth').value = token1;
- barrier();
- });
- doGaiaLogin(username, password, 'chromiumsync',
- function(token) {
- setCookie('xmpp_auth', token, 100);
- document.getElementById('xmpp_auth').value = token;
- barrier();
- });
+
+ console.log('Could not parse auth token in : "' + message + '"');
+ return BAD_AUTH_TOKEN;
+}
+
+// Open a chromoting connection in a new tab.
+function openChromotingTab(host_jid) {
+ var background = chrome.extension.getBackgroundPage();
+ background.openChromotingTab(host_jid);
+}
+
+// Erase the content of the specified element.
+function clear(e) {
+ e.innerHTML = '';
+}
+
+// Clear out the specified element and show the message to the user.
+function displayMessage(e, classname, message) {
+ clear(e);
+ appendMessage(e, classname, message);
}
-function doListHosts() {
+// Append the message text to the specified element.
+function appendMessage(e, classname, message) {
+ var p = document.createElement('p');
+ if (classname.length != 0) {
+ p.setAttribute('class', classname);
+ }
+
+ p.appendChild(document.createTextNode(message));
+
+ e.appendChild(p);
+}
+
+function listHosts() {
+ var username = getCookie('username');
+
+ var hostlistDiv = document.getElementById('hostlist_div');
+ if (!username) {
+ displayMessage(hostlistDiv, 'message',
+ 'Please sign in to see a list of available hosts.');
+ return;
+ }
+
var xhr = new XMLHttpRequest();
var token = getCookie('chromoting_auth');
// Unhide host list.
- var hostlist_div = document.getElementById('hostlist_div');
- hostlist_div.style.display = "block";
+ hostlistDiv.style.display = "block";
xhr.onreadystatechange = function() {
if (xhr.readyState == 1) {
- hostlist_div.appendChild(document.createTextNode('Finding..'));
- hostlist_div.appendChild(document.createElement('br'));
+ displayMessage(hostlistDiv, 'message', 'Loading host list for ' +
+ username);
}
if (xhr.readyState != 4) {
return;
}
if (xhr.status == 200) {
- parsed_response = JSON.parse(xhr.responseText);
- hostlist_div.appendChild(document.createTextNode('--Found Hosts--'));
- hostlist_div.appendChild(document.createElement('br'));
+ var parsed_response = JSON.parse(xhr.responseText);
appendHostLinks(parsed_response.data.items);
} else {
- console.log('bad status on host list query: "' + xhr.status + ' ' +
- xhr.statusText);
- hostlist_div.appendChild(document.createTextNode('!! Failed !!. :\'('));
+ var errorResponse = JSON.parse(xhr.responseText);
+
+ console.log('Error: Bad status on host list query: "' +
+ xhr.status + ' ' + xhr.statusText);
+ console.log('Error code ' + errorResponse.error.code);
+ console.log('Error message ' + errorResponse.error.message);
+
+ clear(hostlistDiv);
+ appendMessage(hostlistDiv, 'message',
+ 'Unable to load host list for ' + username + '. ' +
+ 'Please try again later.');
+ appendMessage(hostlistDiv, 'message',
+ 'Error code: ' + errorResponse.error.code);
+ appendMessage(hostlistDiv, 'message',
+ 'Message: ' + errorResponse.error.message);
}
};
@@ -139,47 +210,64 @@ function doListHosts() {
xhr.send(null);
}
+// Populate the 'hostlist_div' element with the list of hosts for this user.
function appendHostLinks(hostlist) {
- // A host link entry should look like:
- // - Host: <a onclick="openChromotingTab(host_jid); return false;">
- // NAME (JID) </a> <br />
- var host;
- var host_link;
- var hostlist_div = document.getElementById('hostlist_div');
+ var hostlistDiv = document.getElementById('hostlist_div');
- // Cleanup the div
- hostlist_div.innerHTML = "";
+ // Clear the div before adding the host info.
+ clear(hostlistDiv);
// Add the hosts.
- for(var i = 0; i < hostlist.length; ++i) {
- hostlist_div.appendChild(document.createTextNode('-*- Host: '));
- host = hostlist[i];
- host_link = document.createElement('a');
- // TODO(ajwong): Reenable once we figure out how to control a new tab.
- host_link.setAttribute('onclick', 'openChromotingTab(\'' + host.jabberId +
- '\'); return false;');
- host_link.setAttribute('href', 'javascript:void(0)');
- host_link.appendChild(
- document.createTextNode(host.hostName + ' (' + host.hostId + ', ' +
- host.jabberId + ')'));
- hostlist_div.appendChild(host_link);
- hostlist_div.appendChild(document.createElement('br'));
+ // TODO(garykac): We should have some sort of MRU list here.
+ // First, add all of the connected hosts.
+ for (var i = 0; i < hostlist.length; ++i) {
+ if (hostlist[i].status == "ONLINE") {
+ hostlistDiv.appendChild(addHostInfo(hostlist[i]));
+ }
+ }
+ // Add non-online hosts at the end.
+ for (var i = 0; i < hostlist.length; ++i) {
+ if (hostlist[i].status != "ONLINE") {
+ hostlistDiv.appendChild(addHostInfo(hostlist[i]));
+ }
}
}
-function connect(form) {
- openChromotingTab(form.host_jid);
-}
+// Create a single host description element.
+function addHostInfo(host) {
+ var hostEntry = document.createElement('div');
+ hostEntry.setAttribute('class', 'hostentry');
-function openChromotingTab(host_jid) {
- var background = chrome.extension.getBackgroundPage();
- background.openChromotingTab(host_jid);
-}
+ var hostIcon = document.createElement('img');
+ hostIcon.setAttribute('src', 'machine.png');
+ hostIcon.setAttribute('class', 'hosticon');
+ hostEntry.appendChild(hostIcon);
+
+ var span = document.createElement('span');
+ span.setAttribute('class', 'connect');
+ var connect = document.createElement('input');
+ connect.setAttribute('type', 'button');
+ connect.setAttribute('value', 'Connect');
+ connect.setAttribute('onclick', 'openChromotingTab(\'' + host.jabberId +
+ '\'); return false;');
+ span.appendChild(connect);
+ hostEntry.appendChild(span);
+
+ var hostName = document.createElement('p');
+ hostName.setAttribute('class', 'hostname');
+ hostName.appendChild(document.createTextNode(host.hostName));
+ hostEntry.appendChild(hostName);
+
+ var hostStatus = document.createElement('p');
+ hostStatus.setAttribute('class', 'hostinfo hoststatus_' +
+ ((host.status == 'ONLINE') ? 'good' : 'bad'));
+ hostStatus.appendChild(document.createTextNode(host.status));
+ hostEntry.appendChild(hostStatus);
-function setAuthCookies(form) {
- var now = new Date();
- now.setTime(now.getTime() + 1000 * 60 * 60 * 24 * 365)
+ var hostInfo = document.createElement('p');
+ hostInfo.setAttribute('class', 'hostinfo');
+ hostInfo.appendChild(document.createTextNode(host.jabberId));
+ hostEntry.appendChild(hostInfo);
- setCookie('xmpp_auth', form.xmpp_auth.value, 100);
- setCookie('chromoting_auth', form.chromoting_auth.value, 100);
+ return hostEntry;
}
diff --git a/remoting/client/extension/icon.png b/remoting/client/extension/icon.png
deleted file mode 100644
index 103ff36..0000000
--- a/remoting/client/extension/icon.png
+++ /dev/null
Binary files differ
diff --git a/remoting/client/extension/login.html b/remoting/client/extension/login.html
new file mode 100644
index 0000000..23998ac
--- /dev/null
+++ b/remoting/client/extension/login.html
@@ -0,0 +1,41 @@
+<!--
+Copyright (c) 2010 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.
+-->
+
+<html>
+ <head>
+ <script type="text/javascript" src="base.js"></script>
+ <script type="text/javascript" src="client.js"></script>
+ <link rel="stylesheet" type="text/css" href="main.css" />
+ <title>Sign in</title>
+ </head>
+ <body>
+
+ <form name="loginform" action="" method="GET">
+ <table>
+ <tr>
+ <td align="right">Email:</td>
+ <td align="left">
+ <input type="text" name="username" id="username" value="" />
+ </td>
+ </tr><tr>
+ <td align="right">Password:</td>
+ <td align="left">
+ <input type="password" name="password" id="password" value="" />
+ </td>
+ </tr><tr>
+ <td></td>
+ <td>
+ <input type="button" name="login_button" value="Log In"
+ onclick="login(this.form)" />
+ <td>
+ </table>
+ </form>
+
+ <div id="login_status">
+ </div>
+
+ </body>
+</html>
diff --git a/remoting/client/extension/machine.png b/remoting/client/extension/machine.png
new file mode 100644
index 0000000..635a9bb
--- /dev/null
+++ b/remoting/client/extension/machine.png
Binary files differ
diff --git a/remoting/client/extension/main.css b/remoting/client/extension/main.css
new file mode 100644
index 0000000..d375107
--- /dev/null
+++ b/remoting/client/extension/main.css
@@ -0,0 +1,98 @@
+body {
+ width: 500px;
+ overflow: hidden;
+ scrollbars: no;
+}
+
+p {
+ color: black;
+}
+
+h1 {
+ font-family: sans-serif;
+ font-size: 2em;
+ font-weight: bold;
+ margin: 2px 5px 5px 5px
+}
+
+.message {
+ font-family: sans-serif;
+ font-size: 1.2em;
+ padding: 0px 4px 0px 4px;
+}
+
+.hostlist {
+ width: 100%;
+ height: 400px;
+ margin: 0px;
+ overflow: auto;
+ border: black 1px solid;
+}
+
+.hostentry {
+ margin: 0;
+ padding: 3px;
+ border-top: blue 1px solid;
+ min-height: 70px;
+}
+
+.hostentry:first-child {
+ border-top-style: none;
+}
+
+a.hostentry { text-decoration: none; }
+
+.hosticon {
+ float: left;
+ margin: 2px;
+}
+
+.hostname {
+ font-family: sans-serif;
+ font-size: 1.2em;
+ font-weight: bold;
+ line-height: 1.2em;
+ margin: 2px 4px 2px 75px;
+}
+
+.hoststatus_good {
+ font-weight: bold;
+ color: green;
+}
+
+.hoststatus_bad {
+ font-weight: bold;
+ color: red;
+}
+
+.hostinfo {
+ font-family: sans-serif;
+ font-size: 0.8em;
+ line-height: 1em;
+ margin: 2px 4px 2px 75px;
+}
+
+.connect {
+ float: right;
+}
+
+.reload {
+ font-family: sans-serif;
+ font-size: 0.8em;
+ font-style: italic;
+ text-align: right;
+ margin: 0.25em 0 0.5em 0;
+ line-height: 1em;
+}
+
+.login {
+ font-family: sans-serif;
+ font-size: 0.9em;
+ position: absolute;
+ bottom: 0;
+ margin-bottom: 3px;
+}
+
+.login_email {
+ font-weight: bold;
+}
diff --git a/remoting/client/extension/manifest.json b/remoting/client/extension/manifest.json
index 15f22a5..6d5f0d6 100644
--- a/remoting/client/extension/manifest.json
+++ b/remoting/client/extension/manifest.json
@@ -3,7 +3,7 @@
"version": "1.0",
"description": "Lists the hosts that the user can access.",
"browser_action": {
- "default_icon": "icon.png",
+ "default_icon": "chromoticon.png",
"popup": "popup.html"
},
"background_page": "background.html",
diff --git a/remoting/client/extension/popup.html b/remoting/client/extension/popup.html
index a4162c5..d582cba 100644
--- a/remoting/client/extension/popup.html
+++ b/remoting/client/extension/popup.html
@@ -8,40 +8,22 @@ found in the LICENSE file.
<head>
<script type="text/javascript" src="base.js"></script>
<script type="text/javascript" src="client.js"></script>
- <title>Get hosts</title>
+ <link rel="stylesheet" type="text/css" href="main.css" />
+ <title>Remote Access</title>
</head>
- <body onload="initParams();" style="width:250;">
+ <body onload="init();">
- <div style="border: blue 1px dotted;">
- <form name="hostqueryform" action="" method="GET">
- Fill-in to reauthenticate. <br />
- U: <input type="text" name="username" id="username" value="" /> <br />
- P: <input type="password" name="password" id="password" value="" /> <br />
- <input type="button" name="login_button" value="Log In" onclick="login(this.form)" />
- </form>
- </div>
-
- <div style="border: blue 1px dotted;">
- Use to manually override the cookies. <br />
- <form name="connectparamsform" action="" method="GET">
- chromoting: <input type="text" name="chromoting_auth" id="chromoting_auth" value="" /> <br />
- xmpp: <input type="text" name="xmpp_auth" id="xmpp_auth" value="" />
- <input type="button" name="set_cookie_button" value="Set Auth Cookies" onclick="setAuthCookies(this.form)" />
- </form>
- </div>
+ <h1>Remote Access</h1>
- <div style="border: blue 1px dotted;">
- <form name="connectform" action="" method="GET">
- Conenct directly to host using auth cookies. Find Hosts doesn't require the host_jid to be filled out. <br />
- host_jid: <input type="text" name="host_jid" id="host_jid" value="" /> <br />
- <input type="button" name="connect_button" value="Connect" onclick="connect(this.form)" />
- <input type="button" name="find_host_button" value="Find Hosts" onclick="findHosts(this.form)" />
- </form>
+ <div id="hostlist_div" class="hostlist">
+ <p class='message'>Initializing...</p>
</div>
- <br />
+ <p class="reload">
+ <a href="javascript:listHosts()">Reload host list</a>
+ </p>
- <div id="hostlist_div" style="border: blue 1px solid; display: none;">
+ <div id="login_div" class="login">
</div>
<br />
diff --git a/remoting/tools/gethosts.sh b/remoting/tools/gethosts.sh
new file mode 100755
index 0000000..dc31202
--- /dev/null
+++ b/remoting/tools/gethosts.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+# Simple shell script to get list of available hosts from the Chromoting
+# Directory API using the saved AuthToken.
+authToken=`sed -n 2p ~/.chromotingDirectoryAuthToken`
+url="https://www.googleapis.com/chromoting/v1/@me/hosts"
+curl --header "Content-Type: application/json" --header "Authorization: GoogleLogin Auth=$authToken" -L "$url"
+echo