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 |