| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 /** | 5 /** |
| 6 * @fileoverview | 6 * @fileoverview |
| 7 * Functions related to the 'client screen' for Chromoting. | 7 * Functions related to the 'client screen' for Chromoting. |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 'use strict'; | 10 'use strict'; |
| 11 | 11 |
| 12 /** @suppress {duplicate} */ | 12 /** @suppress {duplicate} */ |
| 13 var remoting = remoting || {}; | 13 var remoting = remoting || {}; |
| 14 | 14 |
| 15 /** | 15 /** |
| 16 * @type {remoting.SessionConnector} The connector object, set when a | |
| 17 * connection is initiated. | |
| 18 */ | |
| 19 remoting.connector = null; | |
| 20 | |
| 21 /** | |
| 22 * @type {remoting.ClientSession} The client session object, set once the | 16 * @type {remoting.ClientSession} The client session object, set once the |
| 23 * connector has invoked its onOk callback. | 17 * connector has invoked its onOk callback. |
| 24 */ | 18 */ |
| 25 remoting.clientSession = null; | 19 remoting.clientSession = null; |
| 26 | 20 |
| 27 /** | 21 /** |
| 28 * Initiate an IT2Me connection. | 22 * Initiate an IT2Me connection. |
| 29 */ | 23 */ |
| 30 remoting.connectIT2Me = function() { | 24 remoting.connectIT2Me = function() { |
| 31 remoting.ensureSessionConnector_(); | 25 var connector = remoting.app.getSessionConnector(); |
| 32 var accessCode = document.getElementById('access-code-entry').value; | 26 var accessCode = document.getElementById('access-code-entry').value; |
| 33 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); | 27 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); |
| 34 remoting.connector.connectIT2Me(accessCode); | 28 connector.connectIT2Me(accessCode); |
| 35 }; | 29 }; |
| 36 | 30 |
| 37 /** | 31 /** |
| 38 * Update the remoting client layout in response to a resize event. | 32 * Update the remoting client layout in response to a resize event. |
| 39 * | 33 * |
| 40 * @return {void} Nothing. | 34 * @return {void} Nothing. |
| 41 */ | 35 */ |
| 42 remoting.onResize = function() { | 36 remoting.onResize = function() { |
| 43 if (remoting.clientSession) { | 37 if (remoting.clientSession) { |
| 44 remoting.clientSession.onResize(); | 38 remoting.clientSession.onResize(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_ME2ME); | 90 remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_ME2ME); |
| 97 } | 91 } |
| 98 break; | 92 break; |
| 99 | 93 |
| 100 case remoting.ClientSession.State.FAILED: | 94 case remoting.ClientSession.State.FAILED: |
| 101 var error = remoting.clientSession.getError(); | 95 var error = remoting.clientSession.getError(); |
| 102 console.error('Client plugin reported connection failed: ' + error); | 96 console.error('Client plugin reported connection failed: ' + error); |
| 103 if (error == null) { | 97 if (error == null) { |
| 104 error = remoting.Error.UNEXPECTED; | 98 error = remoting.Error.UNEXPECTED; |
| 105 } | 99 } |
| 106 showConnectError_(error); | 100 remoting.app.onError(error); |
| 107 break; | 101 break; |
| 108 | 102 |
| 109 default: | 103 default: |
| 110 console.error('Unexpected client plugin state: ' + state.current); | 104 console.error('Unexpected client plugin state: ' + state.current); |
| 111 // This should only happen if the web-app and client plugin get out of | 105 // This should only happen if the web-app and client plugin get out of |
| 112 // sync, so MISSING_PLUGIN is a suitable error. | 106 // sync, so MISSING_PLUGIN is a suitable error. |
| 113 showConnectError_(remoting.Error.MISSING_PLUGIN); | 107 remoting.app.onError(remoting.Error.MISSING_PLUGIN); |
| 114 break; | 108 break; |
| 115 } | 109 } |
| 116 | 110 |
| 117 remoting.clientSession.removeEventListener('stateChanged', | 111 remoting.clientSession.removeEventListener('stateChanged', |
| 118 onClientStateChange_); | 112 onClientStateChange_); |
| 119 remoting.clientSession.cleanup(); | 113 remoting.clientSession.cleanup(); |
| 120 remoting.clientSession = null; | 114 remoting.clientSession = null; |
| 121 } | 115 } |
| 122 | 116 |
| 123 /** | 117 /** |
| 124 * Show a client-side error message. | |
| 125 * | |
| 126 * @param {remoting.Error} errorTag The error to be localized and | |
| 127 * displayed. | |
| 128 * @return {void} Nothing. | |
| 129 */ | |
| 130 function showConnectError_(errorTag) { | |
| 131 console.error('Connection failed: ' + errorTag); | |
| 132 var errorDiv = document.getElementById('connect-error-message'); | |
| 133 l10n.localizeElementFromTag(errorDiv, /** @type {string} */ (errorTag)); | |
| 134 remoting.accessCode = ''; | |
| 135 var mode = remoting.clientSession ? remoting.clientSession.getMode() | |
| 136 : remoting.connector.getConnectionMode(); | |
| 137 if (mode == remoting.ClientSession.Mode.IT2ME) { | |
| 138 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_IT2ME); | |
| 139 remoting.hangoutSessionEvents.raiseEvent( | |
| 140 remoting.hangoutSessionEvents.sessionStateChanged, | |
| 141 remoting.ClientSession.State.FAILED | |
| 142 ); | |
| 143 } else { | |
| 144 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_ME2ME); | |
| 145 } | |
| 146 } | |
| 147 | |
| 148 /** | |
| 149 * Set the text on the buttons shown under the error message so that they are | |
| 150 * easy to understand in the case where a successful connection failed, as | |
| 151 * opposed to the case where a connection never succeeded. | |
| 152 */ | |
| 153 function setConnectionInterruptedButtonsText_() { | |
| 154 var button1 = document.getElementById('client-reconnect-button'); | |
| 155 l10n.localizeElementFromTag(button1, /*i18n-content*/'RECONNECT'); | |
| 156 button1.removeAttribute('autofocus'); | |
| 157 var button2 = document.getElementById('client-finished-me2me-button'); | |
| 158 l10n.localizeElementFromTag(button2, /*i18n-content*/'OK'); | |
| 159 button2.setAttribute('autofocus', 'autofocus'); | |
| 160 } | |
| 161 | |
| 162 /** | |
| 163 * Timer callback to update the statistics panel. | 118 * Timer callback to update the statistics panel. |
| 164 */ | 119 */ |
| 165 function updateStatistics_() { | 120 function updateStatistics_() { |
| 166 if (!remoting.clientSession || | 121 if (!remoting.clientSession || |
| 167 remoting.clientSession.getState() != | 122 remoting.clientSession.getState() != |
| 168 remoting.ClientSession.State.CONNECTED) { | 123 remoting.ClientSession.State.CONNECTED) { |
| 169 return; | 124 return; |
| 170 } | 125 } |
| 171 var perfstats = remoting.clientSession.getPerfStats(); | 126 var perfstats = remoting.clientSession.getPerfStats(); |
| 172 remoting.stats.update(perfstats); | 127 remoting.stats.update(perfstats); |
| 173 remoting.clientSession.logStatistics(perfstats); | 128 remoting.clientSession.logStatistics(perfstats); |
| 174 // Update the stats once per second. | 129 // Update the stats once per second. |
| 175 window.setTimeout(updateStatistics_, 1000); | 130 window.setTimeout(updateStatistics_, 1000); |
| 176 } | 131 } |
| 177 | 132 |
| 178 /** | 133 /** |
| 179 * Entry-point for Me2Me connections, handling showing of the host-upgrade nag | 134 * Entry-point for Me2Me connections, handling showing of the host-upgrade nag |
| 180 * dialog if necessary. | 135 * dialog if necessary. |
| 181 * | 136 * |
| 182 * @param {string} hostId The unique id of the host. | 137 * @param {string} hostId The unique id of the host. |
| 183 * @return {void} Nothing. | 138 * @return {void} Nothing. |
| 184 */ | 139 */ |
| 185 remoting.connectMe2Me = function(hostId) { | 140 remoting.connectMe2Me = function(hostId) { |
| 186 var host = remoting.hostList.getHostForId(hostId); | 141 var host = remoting.hostList.getHostForId(hostId); |
| 187 if (!host) { | 142 if (!host) { |
| 188 showConnectError_(remoting.Error.HOST_IS_OFFLINE); | 143 remoting.app.onError(remoting.Error.HOST_IS_OFFLINE); |
| 189 return; | 144 return; |
| 190 } | 145 } |
| 191 var webappVersion = chrome.runtime.getManifest().version; | 146 var webappVersion = chrome.runtime.getManifest().version; |
| 192 if (remoting.Host.needsUpdate(host, webappVersion)) { | 147 if (remoting.Host.needsUpdate(host, webappVersion)) { |
| 193 var needsUpdateMessage = | 148 var needsUpdateMessage = |
| 194 document.getElementById('host-needs-update-message'); | 149 document.getElementById('host-needs-update-message'); |
| 195 l10n.localizeElementFromTag(needsUpdateMessage, | 150 l10n.localizeElementFromTag(needsUpdateMessage, |
| 196 /*i18n-content*/'HOST_NEEDS_UPDATE_TITLE', | 151 /*i18n-content*/'HOST_NEEDS_UPDATE_TITLE', |
| 197 host.hostName); | 152 host.hostName); |
| 198 /** @type {Element} */ | 153 /** @type {Element} */ |
| (...skipping 19 matching lines...) Expand all Loading... |
| 218 }; | 173 }; |
| 219 | 174 |
| 220 /** | 175 /** |
| 221 * Shows PIN entry screen localized to include the host name, and registers | 176 * Shows PIN entry screen localized to include the host name, and registers |
| 222 * a host-specific one-shot event handler for the form submission. | 177 * a host-specific one-shot event handler for the form submission. |
| 223 * | 178 * |
| 224 * @param {remoting.Host} host The Me2Me host to which to connect. | 179 * @param {remoting.Host} host The Me2Me host to which to connect. |
| 225 * @return {void} Nothing. | 180 * @return {void} Nothing. |
| 226 */ | 181 */ |
| 227 remoting.connectMe2MeHostVersionAcknowledged_ = function(host) { | 182 remoting.connectMe2MeHostVersionAcknowledged_ = function(host) { |
| 228 remoting.ensureSessionConnector_(); | 183 /** @type {remoting.SessionConnector} */ |
| 184 var connector = remoting.app.getSessionConnector(); |
| 229 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); | 185 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); |
| 230 | 186 |
| 231 /** | 187 /** |
| 232 * @param {string} tokenUrl Token-issue URL received from the host. | 188 * @param {string} tokenUrl Token-issue URL received from the host. |
| 233 * @param {string} scope OAuth scope to request the token for. | 189 * @param {string} scope OAuth scope to request the token for. |
| 234 * @param {string} hostPublicKey Host public key (DER and Base64 encoded). | 190 * @param {string} hostPublicKey Host public key (DER and Base64 encoded). |
| 235 * @param {function(string, string):void} onThirdPartyTokenFetched Callback. | 191 * @param {function(string, string):void} onThirdPartyTokenFetched Callback. |
| 236 */ | 192 */ |
| 237 var fetchThirdPartyToken = function( | 193 var fetchThirdPartyToken = function( |
| 238 tokenUrl, hostPublicKey, scope, onThirdPartyTokenFetched) { | 194 tokenUrl, hostPublicKey, scope, onThirdPartyTokenFetched) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 var connectMe2MeHostSettingsRetrieved = function(settings) { | 256 var connectMe2MeHostSettingsRetrieved = function(settings) { |
| 301 /** @type {string} */ | 257 /** @type {string} */ |
| 302 var clientId = ''; | 258 var clientId = ''; |
| 303 /** @type {string} */ | 259 /** @type {string} */ |
| 304 var sharedSecret = ''; | 260 var sharedSecret = ''; |
| 305 var pairingInfo = /** @type {Object} */ (settings['pairingInfo']); | 261 var pairingInfo = /** @type {Object} */ (settings['pairingInfo']); |
| 306 if (pairingInfo) { | 262 if (pairingInfo) { |
| 307 clientId = /** @type {string} */ (pairingInfo['clientId']); | 263 clientId = /** @type {string} */ (pairingInfo['clientId']); |
| 308 sharedSecret = /** @type {string} */ (pairingInfo['sharedSecret']); | 264 sharedSecret = /** @type {string} */ (pairingInfo['sharedSecret']); |
| 309 } | 265 } |
| 310 remoting.connector.connectMe2Me(host, requestPin, fetchThirdPartyToken, | 266 connector.connectMe2Me(host, requestPin, fetchThirdPartyToken, |
| 311 clientId, sharedSecret); | 267 clientId, sharedSecret); |
| 312 } | 268 } |
| 313 | 269 |
| 314 remoting.HostSettings.load(host.hostId, connectMe2MeHostSettingsRetrieved); | 270 remoting.HostSettings.load(host.hostId, connectMe2MeHostSettingsRetrieved); |
| 315 }; | 271 }; |
| 316 | |
| 317 /** @param {remoting.ClientSession} clientSession */ | |
| 318 remoting.onConnected = function(clientSession) { | |
| 319 remoting.clientSession = clientSession; | |
| 320 remoting.clientSession.addEventListener('stateChanged', onClientStateChange_); | |
| 321 setConnectionInterruptedButtonsText_(); | |
| 322 document.getElementById('access-code-entry').value = ''; | |
| 323 remoting.setMode(remoting.AppMode.IN_SESSION); | |
| 324 if (!base.isAppsV2()) { | |
| 325 remoting.toolbar.center(); | |
| 326 remoting.toolbar.preview(); | |
| 327 } | |
| 328 remoting.clipboard.startSession(); | |
| 329 updateStatistics_(); | |
| 330 remoting.hangoutSessionEvents.raiseEvent( | |
| 331 remoting.hangoutSessionEvents.sessionStateChanged, | |
| 332 remoting.ClientSession.State.CONNECTED | |
| 333 ); | |
| 334 if (remoting.pairingRequested) { | |
| 335 /** | |
| 336 * @param {string} clientId | |
| 337 * @param {string} sharedSecret | |
| 338 */ | |
| 339 var onPairingComplete = function(clientId, sharedSecret) { | |
| 340 var pairingInfo = { | |
| 341 pairingInfo: { | |
| 342 clientId: clientId, | |
| 343 sharedSecret: sharedSecret | |
| 344 } | |
| 345 }; | |
| 346 remoting.HostSettings.save(remoting.connector.getHostId(), pairingInfo); | |
| 347 remoting.connector.updatePairingInfo(clientId, sharedSecret); | |
| 348 }; | |
| 349 // Use the platform name as a proxy for the local computer name. | |
| 350 // TODO(jamiewalch): Use a descriptive name for the local computer, for | |
| 351 // example, its Chrome Sync name. | |
| 352 var clientName = ''; | |
| 353 if (remoting.platformIsMac()) { | |
| 354 clientName = 'Mac'; | |
| 355 } else if (remoting.platformIsWindows()) { | |
| 356 clientName = 'Windows'; | |
| 357 } else if (remoting.platformIsChromeOS()) { | |
| 358 clientName = 'ChromeOS'; | |
| 359 } else if (remoting.platformIsLinux()) { | |
| 360 clientName = 'Linux'; | |
| 361 } else { | |
| 362 console.log('Unrecognized client platform. Using navigator.platform.'); | |
| 363 clientName = navigator.platform; | |
| 364 } | |
| 365 clientSession.requestPairing(clientName, onPairingComplete); | |
| 366 } | |
| 367 }; | |
| 368 | |
| 369 /** | |
| 370 * Extension message handler. | |
| 371 * | |
| 372 * @param {string} type The type of the extension message. | |
| 373 * @param {string} data The payload of the extension message. | |
| 374 * @return {boolean} Return true if the extension message was recognized. | |
| 375 */ | |
| 376 remoting.onExtensionMessage = function(type, data) { | |
| 377 if (remoting.clientSession) { | |
| 378 return remoting.clientSession.handleExtensionMessage(type, data); | |
| 379 } | |
| 380 return false; | |
| 381 }; | |
| 382 | |
| 383 /** | |
| 384 * Create a session connector if one doesn't already exist. | |
| 385 */ | |
| 386 remoting.ensureSessionConnector_ = function() { | |
| 387 if (!remoting.connector) { | |
| 388 remoting.connector = remoting.SessionConnector.factory.createConnector( | |
| 389 document.getElementById('video-container'), | |
| 390 remoting.onConnected, | |
| 391 showConnectError_, remoting.onExtensionMessage); | |
| 392 } | |
| 393 }; | |
| OLD | NEW |