| 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 * Class that wraps low-level details of interacting with the client plugin. | 7 * Class that wraps low-level details of interacting with the client plugin. |
| 8 * | 8 * |
| 9 * This abstracts a <embed> element and controls the plugin which does | 9 * This abstracts a <embed> element and controls the plugin which does |
| 10 * the actual remoting work. It also handles differences between | 10 * the actual remoting work. It also handles differences between |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 /** @param {string} message Log message. */ | 34 /** @param {string} message Log message. */ |
| 35 this.onDebugMessageHandler = function (message) {}; | 35 this.onDebugMessageHandler = function (message) {}; |
| 36 /** | 36 /** |
| 37 * @param {number} state The connection state. | 37 * @param {number} state The connection state. |
| 38 * @param {number} error The error code, if any. | 38 * @param {number} error The error code, if any. |
| 39 */ | 39 */ |
| 40 this.onConnectionStatusUpdateHandler = function(state, error) {}; | 40 this.onConnectionStatusUpdateHandler = function(state, error) {}; |
| 41 /** @param {boolean} ready Connection ready state. */ | 41 /** @param {boolean} ready Connection ready state. */ |
| 42 this.onConnectionReadyHandler = function(ready) {}; | 42 this.onConnectionReadyHandler = function(ready) {}; |
| 43 this.onDesktopSizeUpdateHandler = function () {}; | 43 this.onDesktopSizeUpdateHandler = function () {}; |
| 44 /** @param {!Array.<string>} capabilities The negotiated capabilities. */ |
| 45 this.onSetCapabilitiesHandler = function (capabilities) {}; |
| 44 this.fetchPinHandler = function () {}; | 46 this.fetchPinHandler = function () {}; |
| 45 | 47 |
| 46 /** @type {number} */ | 48 /** @type {number} */ |
| 47 this.pluginApiVersion_ = -1; | 49 this.pluginApiVersion_ = -1; |
| 48 /** @type {Array.<string>} */ | 50 /** @type {Array.<string>} */ |
| 49 this.pluginApiFeatures_ = []; | 51 this.pluginApiFeatures_ = []; |
| 50 /** @type {number} */ | 52 /** @type {number} */ |
| 51 this.pluginApiMinVersion_ = -1; | 53 this.pluginApiMinVersion_ = -1; |
| 54 /** @type {!Array.<string>} */ |
| 55 this.capabilities_ = []; |
| 52 /** @type {boolean} */ | 56 /** @type {boolean} */ |
| 53 this.helloReceived_ = false; | 57 this.helloReceived_ = false; |
| 54 /** @type {function(boolean)|null} */ | 58 /** @type {function(boolean)|null} */ |
| 55 this.onInitializedCallback_ = null; | 59 this.onInitializedCallback_ = null; |
| 56 | 60 |
| 57 /** @type {remoting.ClientSession.PerfStats} */ | 61 /** @type {remoting.ClientSession.PerfStats} */ |
| 58 this.perfStats_ = new remoting.ClientSession.PerfStats(); | 62 this.perfStats_ = new remoting.ClientSession.PerfStats(); |
| 59 | 63 |
| 60 /** @type {remoting.ClientPluginAsync} */ | 64 /** @type {remoting.ClientPluginAsync} */ |
| 61 var that = this; | 65 var that = this; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 91 */ | 95 */ |
| 92 remoting.ClientPluginAsync.prototype.handleMessage_ = function(messageStr) { | 96 remoting.ClientPluginAsync.prototype.handleMessage_ = function(messageStr) { |
| 93 var message = /** @type {{method:string, data:Object.<string,string>}} */ | 97 var message = /** @type {{method:string, data:Object.<string,string>}} */ |
| 94 jsonParseSafe(messageStr); | 98 jsonParseSafe(messageStr); |
| 95 | 99 |
| 96 if (!message || !('method' in message) || !('data' in message)) { | 100 if (!message || !('method' in message) || !('data' in message)) { |
| 97 console.error('Received invalid message from the plugin: ' + messageStr); | 101 console.error('Received invalid message from the plugin: ' + messageStr); |
| 98 return; | 102 return; |
| 99 } | 103 } |
| 100 | 104 |
| 105 /** |
| 106 * Splits a string into a list of words delimited by spaces. |
| 107 * @param {string} str String that should be split. |
| 108 * @return {!Array.<string>} List of words. |
| 109 */ |
| 110 var tokenize = function(str) { |
| 111 /** @type {Array.<string>} */ |
| 112 var tokens = str.match(/\S+/g); |
| 113 return tokens ? tokens : []; |
| 114 }; |
| 115 |
| 101 if (message.method == 'hello') { | 116 if (message.method == 'hello') { |
| 102 // Reset the size in case we had to enlarge it to support click-to-play. | 117 // Reset the size in case we had to enlarge it to support click-to-play. |
| 103 this.plugin.width = 0; | 118 this.plugin.width = 0; |
| 104 this.plugin.height = 0; | 119 this.plugin.height = 0; |
| 105 if (typeof message.data['apiVersion'] != 'number' || | 120 if (typeof message.data['apiVersion'] != 'number' || |
| 106 typeof message.data['apiMinVersion'] != 'number') { | 121 typeof message.data['apiMinVersion'] != 'number') { |
| 107 console.error('Received invalid hello message: ' + messageStr); | 122 console.error('Received invalid hello message: ' + messageStr); |
| 108 return; | 123 return; |
| 109 } | 124 } |
| 110 this.pluginApiVersion_ = /** @type {number} */ message.data['apiVersion']; | 125 this.pluginApiVersion_ = /** @type {number} */ message.data['apiVersion']; |
| 126 |
| 111 if (this.pluginApiVersion_ >= 7) { | 127 if (this.pluginApiVersion_ >= 7) { |
| 112 if (typeof message.data['apiFeatures'] != 'string') { | 128 if (typeof message.data['apiFeatures'] != 'string') { |
| 113 console.error('Received invalid hello message: ' + messageStr); | 129 console.error('Received invalid hello message: ' + messageStr); |
| 114 return; | 130 return; |
| 115 } | 131 } |
| 116 this.pluginApiFeatures_ = | 132 this.pluginApiFeatures_ = |
| 117 /** @type {Array.<string>} */ message.data['apiFeatures'].split(' '); | 133 /** @type {Array.<string>} */ tokenize(message.data['apiFeatures']); |
| 134 |
| 135 // Negotiate capabilities. |
| 136 |
| 137 /** @type {!Array.<string>} */ |
| 138 var requestedCapabilities = []; |
| 139 if ('requestedCapabilities' in message.data) { |
| 140 if (typeof message.data['requestedCapabilities'] != 'string') { |
| 141 console.error('Received invalid hello message: ' + messageStr); |
| 142 return; |
| 143 } |
| 144 requestedCapabilities = tokenize(message.data['requestedCapabilities']); |
| 145 } |
| 146 |
| 147 /** @type {!Array.<string>} */ |
| 148 var supportedCapabilities = []; |
| 149 if ('supportedCapabilities' in message.data) { |
| 150 if (typeof message.data['supportedCapabilities'] != 'string') { |
| 151 console.error('Received invalid hello message: ' + messageStr); |
| 152 return; |
| 153 } |
| 154 supportedCapabilities = tokenize(message.data['supportedCapabilities']); |
| 155 } |
| 156 |
| 157 // At the moment the webapp does not recognize any of |
| 158 // 'requestedCapabilities' capabilities (so they all should be disabled) |
| 159 // and do not care about any of 'supportedCapabilities' capabilities (so |
| 160 // they all can be enabled). |
| 161 this.capabilities_ = supportedCapabilities; |
| 162 |
| 163 // Let the host know that the webapp can be requested to always send |
| 164 // the client's dimensions. |
| 165 this.capabilities_.push( |
| 166 remoting.ClientSession.Capability.SEND_INITIAL_RESOLUTION); |
| 118 } else if (this.pluginApiVersion_ >= 6) { | 167 } else if (this.pluginApiVersion_ >= 6) { |
| 119 this.pluginApiFeatures_ = ['highQualityScaling', 'injectKeyEvent']; | 168 this.pluginApiFeatures_ = ['highQualityScaling', 'injectKeyEvent']; |
| 120 } else { | 169 } else { |
| 121 this.pluginApiFeatures_ = ['highQualityScaling']; | 170 this.pluginApiFeatures_ = ['highQualityScaling']; |
| 122 } | 171 } |
| 123 this.pluginApiMinVersion_ = | 172 this.pluginApiMinVersion_ = |
| 124 /** @type {number} */ message.data['apiMinVersion']; | 173 /** @type {number} */ message.data['apiMinVersion']; |
| 125 this.helloReceived_ = true; | 174 this.helloReceived_ = true; |
| 126 if (this.onInitializedCallback_ != null) { | 175 if (this.onInitializedCallback_ != null) { |
| 127 this.onInitializedCallback_(true); | 176 this.onInitializedCallback_(true); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 } | 250 } |
| 202 } else if (message.method == 'onConnectionReady') { | 251 } else if (message.method == 'onConnectionReady') { |
| 203 if (typeof message.data['ready'] != 'boolean') { | 252 if (typeof message.data['ready'] != 'boolean') { |
| 204 console.error('Received incorrect onConnectionReady message.'); | 253 console.error('Received incorrect onConnectionReady message.'); |
| 205 return; | 254 return; |
| 206 } | 255 } |
| 207 var ready = /** @type {boolean} */ message.data['ready']; | 256 var ready = /** @type {boolean} */ message.data['ready']; |
| 208 this.onConnectionReadyHandler(ready); | 257 this.onConnectionReadyHandler(ready); |
| 209 } else if (message.method == 'fetchPin') { | 258 } else if (message.method == 'fetchPin') { |
| 210 this.fetchPinHandler(); | 259 this.fetchPinHandler(); |
| 260 } else if (message.method == 'setCapabilities') { |
| 261 if (typeof message.data['capabilities'] != 'string') { |
| 262 console.error('Received incorrect setCapabilities message.'); |
| 263 return; |
| 264 } |
| 265 |
| 266 /** @type {!Array.<string>} */ |
| 267 var capabilities = tokenize(message.data['capabilities']); |
| 268 this.onSetCapabilitiesHandler(capabilities); |
| 211 } | 269 } |
| 212 }; | 270 }; |
| 213 | 271 |
| 214 /** | 272 /** |
| 215 * Deletes the plugin. | 273 * Deletes the plugin. |
| 216 */ | 274 */ |
| 217 remoting.ClientPluginAsync.prototype.cleanup = function() { | 275 remoting.ClientPluginAsync.prototype.cleanup = function() { |
| 218 this.plugin.parentNode.removeChild(this.plugin); | 276 this.plugin.parentNode.removeChild(this.plugin); |
| 219 }; | 277 }; |
| 220 | 278 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 remoting.ClientPluginAsync.prototype.connect = function( | 357 remoting.ClientPluginAsync.prototype.connect = function( |
| 300 hostJid, hostPublicKey, localJid, sharedSecret, | 358 hostJid, hostPublicKey, localJid, sharedSecret, |
| 301 authenticationMethods, authenticationTag) { | 359 authenticationMethods, authenticationTag) { |
| 302 this.plugin.postMessage(JSON.stringify( | 360 this.plugin.postMessage(JSON.stringify( |
| 303 { method: 'connect', data: { | 361 { method: 'connect', data: { |
| 304 hostJid: hostJid, | 362 hostJid: hostJid, |
| 305 hostPublicKey: hostPublicKey, | 363 hostPublicKey: hostPublicKey, |
| 306 localJid: localJid, | 364 localJid: localJid, |
| 307 sharedSecret: sharedSecret, | 365 sharedSecret: sharedSecret, |
| 308 authenticationMethods: authenticationMethods, | 366 authenticationMethods: authenticationMethods, |
| 309 authenticationTag: authenticationTag | 367 authenticationTag: authenticationTag, |
| 368 capabilities: this.capabilities_.join(" ") |
| 310 } | 369 } |
| 311 })); | 370 })); |
| 312 }; | 371 }; |
| 313 | 372 |
| 314 /** | 373 /** |
| 315 * Release all currently pressed keys. | 374 * Release all currently pressed keys. |
| 316 */ | 375 */ |
| 317 remoting.ClientPluginAsync.prototype.releaseAllKeys = function() { | 376 remoting.ClientPluginAsync.prototype.releaseAllKeys = function() { |
| 318 this.plugin.postMessage(JSON.stringify( | 377 this.plugin.postMessage(JSON.stringify( |
| 319 { method: 'releaseAllKeys', data: {} })); | 378 { method: 'releaseAllKeys', data: {} })); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 this.plugin.width = width; | 535 this.plugin.width = width; |
| 477 this.plugin.height = height; | 536 this.plugin.height = height; |
| 478 // Center the plugin just underneath the "Connnecting..." dialog. | 537 // Center the plugin just underneath the "Connnecting..." dialog. |
| 479 var parentNode = this.plugin.parentNode; | 538 var parentNode = this.plugin.parentNode; |
| 480 var dialog = document.getElementById('client-dialog'); | 539 var dialog = document.getElementById('client-dialog'); |
| 481 var dialogRect = dialog.getBoundingClientRect(); | 540 var dialogRect = dialog.getBoundingClientRect(); |
| 482 parentNode.style.top = (dialogRect.bottom + 16) + 'px'; | 541 parentNode.style.top = (dialogRect.bottom + 16) + 'px'; |
| 483 parentNode.style.left = (window.innerWidth - width) / 2 + 'px'; | 542 parentNode.style.left = (window.innerWidth - width) / 2 + 'px'; |
| 484 } | 543 } |
| 485 }; | 544 }; |
| OLD | NEW |