Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** @suppress {duplicate} */ | 5 /** @suppress {duplicate} */ |
| 6 var remoting = remoting || {}; | 6 var remoting = remoting || {}; |
| 7 | 7 |
| 8 (function() { | 8 /** |
| 9 'use strict'; | 9 * Whether or not the plugin should scale itself. |
| 10 * @type {boolean} | |
| 11 */ | |
| 12 remoting.scaleToFit = false; | |
| 10 | 13 |
| 11 window.addEventListener('blur', pluginLostFocus_, false); | 14 /** @type {remoting.ClientSession} */ |
| 15 remoting.session = null; | |
| 12 | 16 |
| 13 function pluginLostFocus_() { | 17 /** @type {string} */ remoting.accessCode = ''; |
| 14 // If the plug loses input focus, release all keys as a precaution against | 18 /** @type {number} */ remoting.accessCodeTimerId = 0; |
| 15 // leaving them 'stuck down' on the host. | 19 /** @type {number} */ remoting.accessCodeExpiresIn = 0; |
| 16 if (remoting.session && remoting.session.plugin) { | 20 /** @type {remoting.AppMode} */ remoting.currentMode; |
| 17 remoting.session.plugin.releaseAllKeys(); | 21 /** @type {string} */ remoting.hostJid = ''; |
| 18 } | 22 /** @type {string} */ remoting.hostPublicKey = ''; |
| 19 } | 23 /** @type {boolean} */ remoting.lastShareWasCancelled = false; |
| 24 /** @type {boolean} */ remoting.timerRunning = false; | |
| 25 /** @type {string} */ remoting.username = ''; | |
|
Jamie
2011/10/18 00:19:27
This while file needs refactoring, but for now jus
| |
| 20 | 26 |
| 21 /** @enum {string} */ | 27 /** @enum {string} */ |
| 22 remoting.AppMode = { | 28 remoting.AppMode = { |
| 23 HOME: 'home', | 29 HOME: 'home', |
| 24 UNAUTHENTICATED: 'auth', | 30 UNAUTHENTICATED: 'auth', |
| 25 CLIENT: 'client', | 31 CLIENT: 'client', |
| 26 CLIENT_UNCONNECTED: 'client.unconnected', | 32 CLIENT_UNCONNECTED: 'client.unconnected', |
| 27 CLIENT_CONNECTING: 'client.connecting', | 33 CLIENT_CONNECTING: 'client.connecting', |
| 28 CLIENT_CONNECT_FAILED: 'client.connect-failed', | 34 CLIENT_CONNECT_FAILED: 'client.connect-failed', |
| 29 CLIENT_SESSION_FINISHED: 'client.session-finished', | 35 CLIENT_SESSION_FINISHED: 'client.session-finished', |
| 30 HOST: 'host', | 36 HOST: 'host', |
| 31 HOST_WAITING_FOR_CODE: 'host.waiting-for-code', | 37 HOST_WAITING_FOR_CODE: 'host.waiting-for-code', |
| 32 HOST_WAITING_FOR_CONNECTION: 'host.waiting-for-connection', | 38 HOST_WAITING_FOR_CONNECTION: 'host.waiting-for-connection', |
| 33 HOST_SHARED: 'host.shared', | 39 HOST_SHARED: 'host.shared', |
| 34 HOST_SHARE_FAILED: 'host.share-failed', | 40 HOST_SHARE_FAILED: 'host.share-failed', |
| 35 HOST_SHARE_FINISHED: 'host.share-finished', | 41 HOST_SHARE_FINISHED: 'host.share-finished', |
| 36 IN_SESSION: 'in-session' | 42 IN_SESSION: 'in-session' |
| 37 }; | 43 }; |
| 38 | 44 |
| 39 remoting.EMAIL = 'email'; | 45 (function() { |
|
Jamie
2011/10/18 00:19:27
This is no longer used.
| |
| 46 'use strict'; | |
|
simonmorris
2011/10/18 00:55:36
Is it better to have 'use strict' at the top of th
Jamie
2011/10/18 01:42:01
It doesn't matter, but yes, probably. Done.
| |
| 47 | |
| 48 window.addEventListener('blur', pluginLostFocus_, false); | |
| 49 | |
| 50 function pluginLostFocus_() { | |
| 51 // If the plug loses input focus, release all keys as a precaution against | |
| 52 // leaving them 'stuck down' on the host. | |
| 53 if (remoting.session && remoting.session.plugin) { | |
| 54 remoting.session.plugin.releaseAllKeys(); | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 /** @type {string} */ | |
| 40 remoting.HOST_PLUGIN_ID = 'host-plugin-id'; | 59 remoting.HOST_PLUGIN_ID = 'host-plugin-id'; |
| 41 | 60 |
| 42 /** @enum {string} */ | 61 /** @enum {string} */ |
| 43 remoting.ClientError = { | 62 remoting.ClientError = { |
| 44 NO_RESPONSE: /*i18n-content*/'ERROR_NO_RESPONSE', | 63 NO_RESPONSE: /*i18n-content*/'ERROR_NO_RESPONSE', |
| 45 INVALID_ACCESS_CODE: /*i18n-content*/'ERROR_INVALID_ACCESS_CODE', | 64 INVALID_ACCESS_CODE: /*i18n-content*/'ERROR_INVALID_ACCESS_CODE', |
| 46 MISSING_PLUGIN: /*i18n-content*/'ERROR_MISSING_PLUGIN', | 65 MISSING_PLUGIN: /*i18n-content*/'ERROR_MISSING_PLUGIN', |
| 47 OAUTH_FETCH_FAILED: /*i18n-content*/'ERROR_AUTHENTICATION_FAILED', | 66 OAUTH_FETCH_FAILED: /*i18n-content*/'ERROR_AUTHENTICATION_FAILED', |
| 48 HOST_IS_OFFLINE: /*i18n-content*/'ERROR_HOST_IS_OFFLINE', | 67 HOST_IS_OFFLINE: /*i18n-content*/'ERROR_HOST_IS_OFFLINE', |
| 49 INCOMPATIBLE_PROTOCOL: /*i18n-content*/'ERROR_INCOMPATIBLE_PROTOCOL', | 68 INCOMPATIBLE_PROTOCOL: /*i18n-content*/'ERROR_INCOMPATIBLE_PROTOCOL', |
| 50 OTHER_ERROR: /*i18n-content*/'ERROR_GENERIC' | 69 OTHER_ERROR: /*i18n-content*/'ERROR_GENERIC' |
| 51 }; | 70 }; |
| 52 | 71 |
| 53 /** | |
| 54 * Whether or not the plugin should scale itself. | |
| 55 * @type {boolean} | |
| 56 */ | |
| 57 remoting.scaleToFit = false; | |
| 58 | |
| 59 // Constants representing keys used for storing persistent application state. | 72 // Constants representing keys used for storing persistent application state. |
| 60 var KEY_APP_MODE_ = 'remoting-app-mode'; | 73 var KEY_APP_MODE_ = 'remoting-app-mode'; |
| 61 var KEY_EMAIL_ = 'remoting-email'; | 74 var KEY_EMAIL_ = 'remoting-email'; |
| 62 var KEY_USE_P2P_API_ = 'remoting-use-p2p-api'; | 75 var KEY_USE_P2P_API_ = 'remoting-use-p2p-api'; |
| 63 | 76 |
| 64 // Some constants for pretty-printing the access code. | 77 // Some constants for pretty-printing the access code. |
| 65 var kSupportIdLen = 7; | 78 /** @type {number} */ var kSupportIdLen = 7; |
| 66 var kHostSecretLen = 5; | 79 /** @type {number} */ var kHostSecretLen = 5; |
| 67 var kAccessCodeLen = kSupportIdLen + kHostSecretLen; | 80 /** @type {number} */ var kAccessCodeLen = kSupportIdLen + kHostSecretLen; |
| 68 var kDigitsPerGroup = 4; | 81 /** @type {number} */ var kDigitsPerGroup = 4; |
| 69 | 82 |
| 83 /** | |
| 84 * @param {string} classes A space-separated list of classes. | |
| 85 * @param {string} cls The class to check for. | |
| 86 * @return {boolean} True if |cls| is found within |classes|. | |
| 87 */ | |
| 70 function hasClass(classes, cls) { | 88 function hasClass(classes, cls) { |
| 71 return classes.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')); | 89 return classes.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) != null; |
| 72 } | 90 } |
| 73 | 91 |
| 92 /** | |
| 93 * @param {Element} element The element to which to add the class. | |
| 94 * @param {string} cls The new class. | |
| 95 * @return {void} Nothing. | |
| 96 */ | |
| 74 function addClass(element, cls) { | 97 function addClass(element, cls) { |
| 75 if (!hasClass(element.className, cls)) { | 98 if (!hasClass(element.className, cls)) { |
| 76 var padded = element.className == '' ? '' : element.className + ' '; | 99 var padded = element.className == '' ? '' : element.className + ' '; |
| 77 element.className = padded + cls; | 100 element.className = padded + cls; |
| 78 } | 101 } |
| 79 } | 102 } |
| 80 | 103 |
| 104 /** | |
| 105 * @param {Element} element The element from which to remove the class. | |
| 106 * @param {string} cls The new class. | |
| 107 * @return {void} Nothing. | |
| 108 */ | |
| 81 function removeClass(element, cls) { | 109 function removeClass(element, cls) { |
| 82 element.className = | 110 element.className = |
| 83 element.className.replace(new RegExp('\\b' + cls + '\\b', 'g'), '') | 111 element.className.replace(new RegExp('\\b' + cls + '\\b', 'g'), '') |
| 84 .replace(' ', ' '); | 112 .replace(' ', ' '); |
| 85 } | 113 } |
| 86 | 114 |
| 87 function retrieveEmail_(access_token) { | 115 function retrieveEmail_(access_token) { |
| 88 var headers = { | 116 var headers = { |
| 89 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken() | 117 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken() |
| 90 }; | 118 }; |
| 91 | 119 |
| 120 /** @param {XMLHttpRequest} xhr The XHR response. */ | |
| 92 var onResponse = function(xhr) { | 121 var onResponse = function(xhr) { |
| 93 if (xhr.status != 200) { | 122 if (xhr.status != 200) { |
| 94 // TODO(ajwong): Have a better way of showing an error. | 123 // TODO(ajwong): Have a better way of showing an error. |
| 95 remoting.debug.log('Unable to get email'); | 124 remoting.debug.log('Unable to get email'); |
| 96 document.getElementById('current-email').innerText = '???'; | 125 document.getElementById('current-email').innerText = '???'; |
| 97 return; | 126 return; |
| 98 } | 127 } |
| 99 | 128 |
| 100 // TODO(ajwong): See if we can't find a JSON endpoint. | 129 // TODO(ajwong): See if we can't find a JSON endpoint. |
| 101 setEmail(xhr.responseText.split('&')[0].split('=')[1]); | 130 setEmail(xhr.responseText.split('&')[0].split('=')[1]); |
| 102 }; | 131 }; |
| 103 | 132 |
| 104 // TODO(ajwong): Update to new v2 API. | 133 // TODO(ajwong): Update to new v2 API. |
| 105 remoting.xhr.get('https://www.googleapis.com/userinfo/email', | 134 remoting.xhr.get('https://www.googleapis.com/userinfo/email', |
| 106 onResponse, '', headers); | 135 onResponse, '', headers); |
| 107 } | 136 } |
| 108 | 137 |
| 109 function refreshEmail_() { | 138 function refreshEmail_() { |
| 110 if (!getEmail() && remoting.oauth2.isAuthenticated()) { | 139 if (!getEmail() && remoting.oauth2.isAuthenticated()) { |
| 111 remoting.oauth2.callWithToken(retrieveEmail_); | 140 remoting.oauth2.callWithToken(retrieveEmail_); |
| 112 } | 141 } |
| 113 } | 142 } |
| 114 | 143 |
| 144 /** | |
| 145 * @param {string} value The email address to place in local storage. | |
| 146 * @return {void} Nothing. | |
| 147 */ | |
| 115 function setEmail(value) { | 148 function setEmail(value) { |
| 116 window.localStorage.setItem(KEY_EMAIL_, value); | 149 window.localStorage.setItem(KEY_EMAIL_, value); |
| 117 document.getElementById('current-email').innerText = value; | 150 document.getElementById('current-email').innerText = value; |
| 118 } | 151 } |
| 119 | 152 |
| 120 /** | 153 /** |
| 121 * @return {?string} The email address associated with the auth credentials. | 154 * @return {?string} The email address associated with the auth credentials. |
| 122 */ | 155 */ |
| 123 function getEmail() { | 156 function getEmail() { |
| 124 var result = window.localStorage.getItem(KEY_EMAIL_); | 157 var result = window.localStorage.getItem(KEY_EMAIL_); |
| 125 return typeof result == 'string' ? result : null; | 158 return typeof result == 'string' ? result : null; |
| 126 } | 159 } |
| 127 | 160 |
| 128 function exchangedCodeForToken_() { | 161 function exchangedCodeForToken_() { |
| 129 if (!remoting.oauth2.isAuthenticated()) { | 162 if (!remoting.oauth2.isAuthenticated()) { |
| 130 alert('Your OAuth2 token was invalid. Please try again.'); | 163 alert('Your OAuth2 token was invalid. Please try again.'); |
| 131 } | 164 } |
| 132 remoting.oauth2.callWithToken(function(token) { | 165 /** @param {string} token The auth token. */ |
| 133 retrieveEmail_(token); | 166 var retrieveEmail = function(token) { retrieveEmail_(token); } |
| 134 }); | 167 remoting.oauth2.callWithToken(retrieveEmail); |
| 135 } | 168 } |
| 136 | 169 |
| 137 remoting.clearOAuth2 = function() { | 170 remoting.clearOAuth2 = function() { |
| 138 remoting.oauth2.clear(); | 171 remoting.oauth2.clear(); |
| 139 window.localStorage.removeItem(KEY_EMAIL_); | 172 window.localStorage.removeItem(KEY_EMAIL_); |
| 140 remoting.setMode(remoting.AppMode.UNAUTHENTICATED); | 173 remoting.setMode(remoting.AppMode.UNAUTHENTICATED); |
| 141 } | 174 } |
| 142 | 175 |
| 143 remoting.toggleDebugLog = function() { | 176 remoting.toggleDebugLog = function() { |
| 144 var debugLog = document.getElementById('debug-log'); | 177 var debugLog = document.getElementById('debug-log'); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 * | 219 * |
| 187 * @param {remoting.AppMode} mode The new modal state, expressed as a dotted | 220 * @param {remoting.AppMode} mode The new modal state, expressed as a dotted |
| 188 * hiearchy. | 221 * hiearchy. |
| 189 */ | 222 */ |
| 190 remoting.setMode = function(mode) { | 223 remoting.setMode = function(mode) { |
| 191 var modes = mode.split('.'); | 224 var modes = mode.split('.'); |
| 192 for (var i = 1; i < modes.length; ++i) | 225 for (var i = 1; i < modes.length; ++i) |
| 193 modes[i] = modes[i - 1] + '.' + modes[i]; | 226 modes[i] = modes[i - 1] + '.' + modes[i]; |
| 194 var elements = document.querySelectorAll('[data-ui-mode]'); | 227 var elements = document.querySelectorAll('[data-ui-mode]'); |
| 195 for (var i = 0; i < elements.length; ++i) { | 228 for (var i = 0; i < elements.length; ++i) { |
| 196 var element = elements[i]; | 229 /** @type {Element} */ var element = elements[i]; |
| 197 var hidden = true; | 230 var hidden = true; |
| 198 for (var m = 0; m < modes.length; ++m) { | 231 for (var m = 0; m < modes.length; ++m) { |
| 199 if (hasClass(element.getAttribute('data-ui-mode'), modes[m])) { | 232 if (hasClass(element.getAttribute('data-ui-mode'), modes[m])) { |
| 200 hidden = false; | 233 hidden = false; |
| 201 break; | 234 break; |
| 202 } | 235 } |
| 203 } | 236 } |
| 204 element.hidden = hidden; | 237 element.hidden = hidden; |
| 205 } | 238 } |
| 206 remoting.debug.log('App mode: ' + mode); | 239 remoting.debug.log('App mode: ' + mode); |
| 207 remoting.currentMode = mode; | 240 remoting.currentMode = mode; |
| 208 if (mode == remoting.AppMode.IN_SESSION) { | 241 if (mode == remoting.AppMode.IN_SESSION) { |
| 209 document.removeEventListener('keydown', remoting.checkHotkeys, false); | 242 document.removeEventListener('keydown', remoting.checkHotkeys, false); |
| 210 } else { | 243 } else { |
| 211 document.addEventListener('keydown', remoting.checkHotkeys, false); | 244 document.addEventListener('keydown', remoting.checkHotkeys, false); |
| 212 } | 245 } |
| 213 } | 246 } |
| 214 | 247 |
| 215 /** | 248 /** |
| 216 * Get the major mode that the app is running in. | 249 * Get the major mode that the app is running in. |
| 217 * @return {remoting.AppMode} The app's current major mode. | 250 * @return {string} The app's current major mode. |
| 218 */ | 251 */ |
| 219 remoting.getMajorMode = function() { | 252 remoting.getMajorMode = function() { |
| 220 return remoting.currentMode.split('.')[0]; | 253 return remoting.currentMode.split('.')[0]; |
| 221 } | 254 } |
| 222 | 255 |
| 223 remoting.tryShare = function() { | 256 remoting.tryShare = function() { |
| 224 remoting.debug.log('Attempting to share...'); | 257 remoting.debug.log('Attempting to share...'); |
| 225 remoting.lastShareWasCancelled = false; | 258 remoting.lastShareWasCancelled = false; |
| 226 if (remoting.oauth2.needsNewAccessToken()) { | 259 if (remoting.oauth2.needsNewAccessToken()) { |
| 227 remoting.debug.log('Refreshing token...'); | 260 remoting.debug.log('Refreshing token...'); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 301 | 334 |
| 302 remoting.updateAccessCodeTimeoutElement_ = function() { | 335 remoting.updateAccessCodeTimeoutElement_ = function() { |
| 303 var pad = (remoting.accessCodeExpiresIn < 10) ? '0:0' : '0:'; | 336 var pad = (remoting.accessCodeExpiresIn < 10) ? '0:0' : '0:'; |
| 304 l10n.localizeElement(document.getElementById('seconds-remaining'), | 337 l10n.localizeElement(document.getElementById('seconds-remaining'), |
| 305 pad + remoting.accessCodeExpiresIn); | 338 pad + remoting.accessCodeExpiresIn); |
| 306 if (!updateTimeoutStyles_()) { | 339 if (!updateTimeoutStyles_()) { |
| 307 disableTimeoutCountdown_(); | 340 disableTimeoutCountdown_(); |
| 308 } | 341 } |
| 309 } | 342 } |
| 310 | 343 |
| 344 /** | |
| 345 * Callback to show or hide the NAT traversal warning when the policy changes. | |
| 346 * @param {boolean} enabled True if NAT traversal is enabled. | |
| 347 * @return {void} Nothing. | |
| 348 */ | |
| 311 function onNatTraversalPolicyChanged_(enabled) { | 349 function onNatTraversalPolicyChanged_(enabled) { |
| 312 var container = document.getElementById('nat-box-container'); | 350 var container = document.getElementById('nat-box-container'); |
| 313 container.hidden = enabled; | 351 container.hidden = enabled; |
| 314 } | 352 } |
| 315 | 353 |
| 316 function onStateChanged_() { | 354 function onStateChanged_() { |
| 317 var plugin = /** @type {remoting.HostPlugin} */ | 355 var plugin = /** @type {remoting.HostPlugin} */ |
| 318 document.getElementById(remoting.HOST_PLUGIN_ID); | 356 document.getElementById(remoting.HOST_PLUGIN_ID); |
| 319 var state = plugin.state; | 357 var state = plugin.state; |
| 320 if (state == plugin.STARTING) { | 358 if (state == plugin.STARTING) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 * @return {void} Nothing. | 445 * @return {void} Nothing. |
| 408 */ | 446 */ |
| 409 remoting.cancelShare = function() { | 447 remoting.cancelShare = function() { |
| 410 remoting.debug.log('Canceling share...'); | 448 remoting.debug.log('Canceling share...'); |
| 411 remoting.lastShareWasCancelled = true; | 449 remoting.lastShareWasCancelled = true; |
| 412 var plugin = /** @type {remoting.HostPlugin} */ | 450 var plugin = /** @type {remoting.HostPlugin} */ |
| 413 document.getElementById(remoting.HOST_PLUGIN_ID); | 451 document.getElementById(remoting.HOST_PLUGIN_ID); |
| 414 try { | 452 try { |
| 415 plugin.disconnect(); | 453 plugin.disconnect(); |
| 416 } catch (error) { | 454 } catch (error) { |
| 417 remoting.debug.log('Error disconnecting: ' + error.description + | 455 var tmp = /** @type {{description: string}} */ error; |
|
Jamie
2011/10/18 00:19:27
This is horrible, but I couldn't find any other wa
simonmorris
2011/10/18 00:55:36
It's OK - maybe rename tmp to errorTyped, to make
Jamie
2011/10/18 01:42:01
Done.
| |
| 456 remoting.debug.log('Error disconnecting: ' + tmp.description + | |
| 418 '. The host plugin probably crashed.'); | 457 '. The host plugin probably crashed.'); |
| 419 // TODO(jamiewalch): Clean this up. We should have a class representing | 458 // TODO(jamiewalch): Clean this up. We should have a class representing |
| 420 // the host plugin, like we do for the client, which should handle crash | 459 // the host plugin, like we do for the client, which should handle crash |
| 421 // reporting and it should use a more detailed error message than the | 460 // reporting and it should use a more detailed error message than the |
| 422 // default 'generic' one. See crbug.com/94624 | 461 // default 'generic' one. See crbug.com/94624 |
| 423 showShareError_(/*i18n-content*/'ERROR_GENERIC'); | 462 showShareError_(/*i18n-content*/'ERROR_GENERIC'); |
| 424 } | 463 } |
| 425 disableTimeoutCountdown_(); | 464 disableTimeoutCountdown_(); |
| 426 } | 465 } |
| 427 | 466 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 476 // Update the stats once per second. | 515 // Update the stats once per second. |
| 477 window.setTimeout(updateStatistics, 1000); | 516 window.setTimeout(updateStatistics, 1000); |
| 478 } | 517 } |
| 479 | 518 |
| 480 function showToolbarPreview_() { | 519 function showToolbarPreview_() { |
| 481 var toolbar = document.getElementById('session-toolbar'); | 520 var toolbar = document.getElementById('session-toolbar'); |
| 482 addClass(toolbar, 'toolbar-preview'); | 521 addClass(toolbar, 'toolbar-preview'); |
| 483 window.setTimeout(removeClass, 3000, toolbar, 'toolbar-preview'); | 522 window.setTimeout(removeClass, 3000, toolbar, 'toolbar-preview'); |
| 484 } | 523 } |
| 485 | 524 |
| 525 /** @param {number} oldState The previous state of the plugin. */ | |
| 486 function onClientStateChange_(oldState) { | 526 function onClientStateChange_(oldState) { |
| 487 if (!remoting.session) { | 527 if (!remoting.session) { |
| 488 // If the connection has been cancelled, then we no longer have a reference | 528 // If the connection has been cancelled, then we no longer have a reference |
| 489 // to the session object and should ignore any state changes. | 529 // to the session object and should ignore any state changes. |
| 490 return; | 530 return; |
| 491 } | 531 } |
| 492 var state = remoting.session.state; | 532 var state = remoting.session.state; |
| 493 if (state == remoting.ClientSession.State.CREATED) { | 533 if (state == remoting.ClientSession.State.CREATED) { |
| 494 remoting.debug.log('Created plugin'); | 534 remoting.debug.log('Created plugin'); |
| 495 } else if (state == remoting.ClientSession.State.BAD_PLUGIN_VERSION) { | 535 } else if (state == remoting.ClientSession.State.BAD_PLUGIN_VERSION) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 function startSession_() { | 585 function startSession_() { |
| 546 remoting.debug.log('Starting session...'); | 586 remoting.debug.log('Starting session...'); |
| 547 var accessCode = document.getElementById('access-code-entry'); | 587 var accessCode = document.getElementById('access-code-entry'); |
| 548 accessCode.value = ''; // The code has been validated and won't work again. | 588 accessCode.value = ''; // The code has been validated and won't work again. |
| 549 remoting.username = | 589 remoting.username = |
| 550 /** @type {string} email must be non-NULL to get here */ getEmail(); | 590 /** @type {string} email must be non-NULL to get here */ getEmail(); |
| 551 remoting.session = | 591 remoting.session = |
| 552 new remoting.ClientSession(remoting.hostJid, remoting.hostPublicKey, | 592 new remoting.ClientSession(remoting.hostJid, remoting.hostPublicKey, |
| 553 remoting.accessCode, remoting.username, | 593 remoting.accessCode, remoting.username, |
| 554 onClientStateChange_); | 594 onClientStateChange_); |
| 555 remoting.oauth2.callWithToken(function(token) { | 595 /** @param {string} token The auth token. */ |
| 596 var createPluginAndConnect = function(token) { | |
| 556 remoting.session.createPluginAndConnect( | 597 remoting.session.createPluginAndConnect( |
| 557 document.getElementById('session-mode'), | 598 document.getElementById('session-mode'), |
| 558 token); | 599 token); |
| 559 }); | 600 }; |
| 601 remoting.oauth2.callWithToken(createPluginAndConnect); | |
| 560 } | 602 } |
| 561 | 603 |
| 562 /** | 604 /** |
| 563 * Show a client-side error message. | 605 * Show a client-side error message. |
| 564 * | 606 * |
| 565 * @param {remoting.ClientError} errorTag The error to be localized and | 607 * @param {remoting.ClientError} errorTag The error to be localized and |
| 566 * displayed. | 608 * displayed. |
| 567 * @return {void} Nothing. | 609 * @return {void} Nothing. |
| 568 */ | 610 */ |
| 569 function showConnectError_(errorTag) { | 611 function showConnectError_(errorTag) { |
| 570 remoting.debug.log('Connection failed: ' + errorTag); | 612 remoting.debug.log('Connection failed: ' + errorTag); |
| 571 var errorDiv = document.getElementById('connect-error-message'); | 613 var errorDiv = document.getElementById('connect-error-message'); |
| 572 l10n.localizeElementFromTag(errorDiv, /** @type {string} */ (errorTag)); | 614 l10n.localizeElementFromTag(errorDiv, /** @type {string} */ (errorTag)); |
| 573 remoting.accessCode = ''; | 615 remoting.accessCode = ''; |
| 574 if (remoting.session) { | 616 if (remoting.session) { |
| 575 remoting.session.disconnect(); | 617 remoting.session.disconnect(); |
| 576 remoting.session = null; | 618 remoting.session = null; |
| 577 } | 619 } |
| 578 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED); | 620 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED); |
| 579 } | 621 } |
| 580 | 622 |
| 581 /** | 623 /** |
| 582 * @param {XMLHttpRequest} xhr The XMLHttpRequest object. | 624 * @param {XMLHttpRequest} xhr The XMLHttpRequest object. |
| 583 * @return {void} Nothing. | 625 * @return {void} Nothing. |
| 584 */ | 626 */ |
| 585 function parseServerResponse_(xhr) { | 627 function parseServerResponse_(xhr) { |
| 586 remoting.supportHostsXhr = null; | 628 remoting.supportHostsXhr = null; |
| 587 remoting.debug.log('parseServerResponse: status = ' + xhr.status); | 629 remoting.debug.log('parseServerResponse: status = ' + xhr.status); |
| 588 if (xhr.status == 200) { | 630 if (xhr.status == 200) { |
| 589 var host = JSON.parse(xhr.responseText); | 631 var host = /** @type {{data: {jabberId: string, publicKey: string}}} */ |
| 590 if (host.data && host.data.jabberId) { | 632 JSON.parse(xhr.responseText); |
| 633 if (host.data && host.data.jabberId && host.data.publicKey) { | |
|
Jamie
2011/10/18 00:19:27
I've updated the test to match the type cast above
simonmorris
2011/10/18 00:55:36
OK.
| |
| 591 remoting.hostJid = host.data.jabberId; | 634 remoting.hostJid = host.data.jabberId; |
| 592 remoting.hostPublicKey = host.data.publicKey; | 635 remoting.hostPublicKey = host.data.publicKey; |
| 593 var split = remoting.hostJid.split('/'); | 636 var split = remoting.hostJid.split('/'); |
| 594 document.getElementById('connected-to').innerText = split[0]; | 637 document.getElementById('connected-to').innerText = split[0]; |
| 595 startSession_(); | 638 startSession_(); |
| 596 return; | 639 return; |
| 597 } | 640 } |
| 598 } | 641 } |
| 599 var errorMsg = remoting.ClientError.OTHER_ERROR; | 642 var errorMsg = remoting.ClientError.OTHER_ERROR; |
| 600 if (xhr.status == 404) { | 643 if (xhr.status == 404) { |
| 601 errorMsg = remoting.ClientError.INVALID_ACCESS_CODE; | 644 errorMsg = remoting.ClientError.INVALID_ACCESS_CODE; |
| 602 } else if (xhr.status == 0) { | 645 } else if (xhr.status == 0) { |
| 603 errorMsg = remoting.ClientError.NO_RESPONSE; | 646 errorMsg = remoting.ClientError.NO_RESPONSE; |
| 604 } else { | 647 } else { |
| 605 remoting.debug.log('The server responded: ' + xhr.responseText); | 648 remoting.debug.log('The server responded: ' + xhr.responseText); |
| 606 } | 649 } |
| 607 showConnectError_(errorMsg); | 650 showConnectError_(errorMsg); |
| 608 } | 651 } |
| 609 | 652 |
| 653 /** @param {string} accessCode The access code, as entered by the user. | |
| 654 * @return {string} The normalized form of the code (whitespace removed). */ | |
| 610 function normalizeAccessCode_(accessCode) { | 655 function normalizeAccessCode_(accessCode) { |
| 611 // Trim whitespace. | 656 // Trim whitespace. |
| 612 // TODO(sergeyu): Do we need to do any other normalization here? | 657 // TODO(sergeyu): Do we need to do any other normalization here? |
| 613 return accessCode.replace(/\s/g, ''); | 658 return accessCode.replace(/\s/g, ''); |
| 614 } | 659 } |
| 615 | 660 |
| 661 /** @param {string} supportId The canonicalized support ID. */ | |
| 616 function resolveSupportId(supportId) { | 662 function resolveSupportId(supportId) { |
| 617 var headers = { | 663 var headers = { |
| 618 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken() | 664 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken() |
| 619 }; | 665 }; |
| 620 | 666 |
| 621 remoting.supportHostsXhr = remoting.xhr.get( | 667 remoting.supportHostsXhr = remoting.xhr.get( |
| 622 'https://www.googleapis.com/chromoting/v1/support-hosts/' + | 668 'https://www.googleapis.com/chromoting/v1/support-hosts/' + |
| 623 encodeURIComponent(supportId), | 669 encodeURIComponent(supportId), |
| 624 parseServerResponse_, | 670 parseServerResponse_, |
| 625 '', | 671 '', |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 640 }); | 686 }); |
| 641 } else { | 687 } else { |
| 642 remoting.tryConnectWithAccessToken(); | 688 remoting.tryConnectWithAccessToken(); |
| 643 } | 689 } |
| 644 } | 690 } |
| 645 | 691 |
| 646 remoting.tryConnectWithAccessToken = function() { | 692 remoting.tryConnectWithAccessToken = function() { |
| 647 if (!remoting.wcsLoader) { | 693 if (!remoting.wcsLoader) { |
| 648 remoting.wcsLoader = new remoting.WcsLoader(); | 694 remoting.wcsLoader = new remoting.WcsLoader(); |
| 649 } | 695 } |
| 696 /** @param {function(string):void} setToken The callback function. */ | |
| 697 var callWithToken = function(setToken) { | |
| 698 remoting.oauth2.callWithToken(setToken); | |
| 699 }; | |
| 650 remoting.wcsLoader.start( | 700 remoting.wcsLoader.start( |
| 651 remoting.oauth2.getAccessToken(), | 701 remoting.oauth2.getAccessToken(), |
| 652 function(setToken) { | 702 callWithToken, |
| 653 remoting.oauth2.callWithToken(setToken); | |
| 654 }, | |
| 655 remoting.tryConnectWithWcs); | 703 remoting.tryConnectWithWcs); |
| 656 } | 704 } |
| 657 | 705 |
| 658 remoting.tryConnectWithWcs = function() { | 706 remoting.tryConnectWithWcs = function() { |
| 659 var accessCode = document.getElementById('access-code-entry').value; | 707 var accessCode = document.getElementById('access-code-entry').value; |
| 660 remoting.accessCode = normalizeAccessCode_(accessCode); | 708 remoting.accessCode = normalizeAccessCode_(accessCode); |
| 661 // At present, only 12-digit access codes are supported, of which the first | 709 // At present, only 12-digit access codes are supported, of which the first |
| 662 // 7 characters are the supportId. | 710 // 7 characters are the supportId. |
| 663 if (remoting.accessCode.length != kAccessCodeLen) { | 711 if (remoting.accessCode.length != kAccessCodeLen) { |
| 664 remoting.debug.log('Bad access code length'); | 712 remoting.debug.log('Bad access code length'); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 762 case remoting.AppMode.HOST_WAITING_FOR_CONNECTION: | 810 case remoting.AppMode.HOST_WAITING_FOR_CONNECTION: |
| 763 case remoting.AppMode.HOST_SHARED: | 811 case remoting.AppMode.HOST_SHARED: |
| 764 case remoting.AppMode.IN_SESSION: | 812 case remoting.AppMode.IN_SESSION: |
| 765 var result = chrome.i18n.getMessage(/*i18n-content*/'CLOSE_PROMPT'); | 813 var result = chrome.i18n.getMessage(/*i18n-content*/'CLOSE_PROMPT'); |
| 766 return result; | 814 return result; |
| 767 default: | 815 default: |
| 768 return null; | 816 return null; |
| 769 } | 817 } |
| 770 } | 818 } |
| 771 | 819 |
| 820 /** | |
| 821 * @param {Event} event The keyboard event. | |
| 822 * @return {void} Nothing. | |
| 823 */ | |
| 772 remoting.checkHotkeys = function(event) { | 824 remoting.checkHotkeys = function(event) { |
| 773 if (String.fromCharCode(event.which) == 'D') { | 825 if (String.fromCharCode(event.which) == 'D') { |
| 774 remoting.toggleDebugLog(); | 826 remoting.toggleDebugLog(); |
| 775 } | 827 } |
| 776 } | 828 } |
| 777 | 829 |
| 778 function recenterToolbar_() { | 830 function recenterToolbar_() { |
| 779 var toolbar = document.getElementById('session-toolbar'); | 831 var toolbar = document.getElementById('session-toolbar'); |
| 780 var toolbarX = (window.innerWidth - toolbar.clientWidth) / 2; | 832 var toolbarX = (window.innerWidth - toolbar.clientWidth) / 2; |
| 781 toolbar.style['left'] = toolbarX + 'px'; | 833 toolbar.style['left'] = toolbarX + 'px'; |
| 782 } | 834 } |
| 783 | 835 |
| 784 }()); | 836 }()); |
| OLD | NEW |