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