Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: remoting/webapp/client_plugin_impl.js

Issue 552403004: Interfaceify ClientPlugin in preparation for mocking it. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Renamed interfaces. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
Sergey Ulanov 2014/09/20 00:35:25 2014 - this is a new file
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
11 * client plugins versions when it is necessary. 11 * client plugins versions when it is necessary.
12 */ 12 */
13 13
14 'use strict'; 14 'use strict';
15 15
16 /** @suppress {duplicate} */ 16 /** @suppress {duplicate} */
17 var remoting = remoting || {}; 17 var remoting = remoting || {};
18 18
19 /** 19 /**
20 * @param {Element} container The container for the embed element. 20 * @param {Element} container The container for the embed element.
21 * @param {function(string, string):boolean} onExtensionMessage The handler for 21 * @param {function(string, string):boolean} onExtensionMessage The handler for
22 * protocol extension messages. Returns true if a message is recognized; 22 * protocol extension messages. Returns true if a message is recognized;
23 * false otherwise. 23 * false otherwise.
24 * @constructor 24 * @constructor
25 * @implements {remoting.ClientPlugin}
25 */ 26 */
26 remoting.ClientPlugin = function(container, onExtensionMessage) { 27 remoting.ClientPluginImpl = function(container, onExtensionMessage) {
27 this.plugin_ = remoting.ClientPlugin.createPluginElement_(); 28 this.plugin_ = remoting.ClientPluginImpl.createPluginElement_();
28 this.plugin_.id = 'session-client-plugin'; 29 this.plugin_.id = 'session-client-plugin';
29 container.appendChild(this.plugin_); 30 container.appendChild(this.plugin_);
30 31
31 this.onExtensionMessage_ = onExtensionMessage; 32 this.onExtensionMessage_ = onExtensionMessage;
32 33
33 this.desktopWidth = 0; 34 /** @private */
34 this.desktopHeight = 0; 35 this.desktopWidth_ = 0;
35 this.desktopXDpi = 96; 36 /** @private */
36 this.desktopYDpi = 96; 37 this.desktopHeight_ = 0;
38 /** @private */
39 this.desktopXDpi_ = 96;
40 /** @private */
41 this.desktopYDpi_ = 96;
37 42
38 /** @param {string} iq The Iq stanza received from the host. */ 43 /**
39 this.onOutgoingIqHandler = function (iq) {}; 44 * @param {string} iq The Iq stanza received from the host.
40 /** @param {string} message Log message. */ 45 * @private
41 this.onDebugMessageHandler = function (message) {}; 46 */
47 this.onOutgoingIqHandler_ = function (iq) {};
48 /**
49 * @param {string} message Log message.
50 * @private
51 */
52 this.onDebugMessageHandler_ = function (message) {};
42 /** 53 /**
43 * @param {number} state The connection state. 54 * @param {number} state The connection state.
44 * @param {number} error The error code, if any. 55 * @param {number} error The error code, if any.
56 * @private
45 */ 57 */
46 this.onConnectionStatusUpdateHandler = function(state, error) {}; 58 this.onConnectionStatusUpdateHandler_ = function(state, error) {};
47 /** @param {boolean} ready Connection ready state. */ 59 /**
48 this.onConnectionReadyHandler = function(ready) {}; 60 * @param {boolean} ready Connection ready state.
61 * @private
62 */
63 this.onConnectionReadyHandler_ = function(ready) {};
49 64
50 /** 65 /**
51 * @param {string} tokenUrl Token-request URL, received from the host. 66 * @param {string} tokenUrl Token-request URL, received from the host.
52 * @param {string} hostPublicKey Public key for the host. 67 * @param {string} hostPublicKey Public key for the host.
53 * @param {string} scope OAuth scope to request the token for. 68 * @param {string} scope OAuth scope to request the token for.
69 * @private
54 */ 70 */
55 this.fetchThirdPartyTokenHandler = function( 71 this.fetchThirdPartyTokenHandler_ = function(
56 tokenUrl, hostPublicKey, scope) {}; 72 tokenUrl, hostPublicKey, scope) {};
57 this.onDesktopSizeUpdateHandler = function () {}; 73 /** @private */
58 /** @param {!Array.<string>} capabilities The negotiated capabilities. */ 74 this.onDesktopSizeUpdateHandler_ = function () {};
59 this.onSetCapabilitiesHandler = function (capabilities) {}; 75 /**
60 this.fetchPinHandler = function (supportsPairing) {}; 76 * @param {!Array.<string>} capabilities The negotiated capabilities.
61 /** @param {string} data Remote gnubbyd data. */ 77 * @private
62 this.onGnubbyAuthHandler = function(data) {}; 78 */
79 this.onSetCapabilitiesHandler_ = function (capabilities) {};
80 /** @private */
81 this.fetchPinHandler_ = function (supportsPairing) {};
82 /**
83 * @param {string} data Remote gnubbyd data.
84 * @private
85 */
86 this.onGnubbyAuthHandler_ = function(data) {};
63 /** 87 /**
64 * @param {string} url 88 * @param {string} url
65 * @param {number} hotspotX 89 * @param {number} hotspotX
66 * @param {number} hotspotY 90 * @param {number} hotspotY
91 * @private
67 */ 92 */
68 this.updateMouseCursorImage = function(url, hotspotX, hotspotY) {}; 93 this.updateMouseCursorImage_ = function(url, hotspotX, hotspotY) {};
69 94
70 /** @param {string} data Remote cast extension message. */ 95 /**
71 this.onCastExtensionHandler = function(data) {}; 96 * @param {string} data Remote cast extension message.
97 * @private
98 */
99 this.onCastExtensionHandler_ = function(data) {};
72 100
73 /** @type {remoting.MediaSourceRenderer} */ 101 /**
102 * @type {remoting.MediaSourceRenderer}
103 * @private
104 */
74 this.mediaSourceRenderer_ = null; 105 this.mediaSourceRenderer_ = null;
75 106
76 /** @type {number} */ 107 /**
108 * @type {number}
109 * @private
110 */
77 this.pluginApiVersion_ = -1; 111 this.pluginApiVersion_ = -1;
78 /** @type {Array.<string>} */ 112 /**
113 * @type {Array.<string>}
114 * @private
115 */
79 this.pluginApiFeatures_ = []; 116 this.pluginApiFeatures_ = [];
80 /** @type {number} */ 117 /**
118 * @type {number}
119 * @private
120 */
81 this.pluginApiMinVersion_ = -1; 121 this.pluginApiMinVersion_ = -1;
82 /** @type {!Array.<string>} */ 122 /**
123 * @type {!Array.<string>}
124 * @private
125 */
83 this.capabilities_ = []; 126 this.capabilities_ = [];
84 /** @type {boolean} */ 127 /**
128 * @type {boolean}
129 * @private
130 */
85 this.helloReceived_ = false; 131 this.helloReceived_ = false;
86 /** @type {function(boolean)|null} */ 132 /**
133 * @type {function(boolean)|null}
134 * @private
135 */
87 this.onInitializedCallback_ = null; 136 this.onInitializedCallback_ = null;
88 /** @type {function(string, string):void} */ 137 /**
138 * @type {function(string, string):void}
139 * @private
140 */
89 this.onPairingComplete_ = function(clientId, sharedSecret) {}; 141 this.onPairingComplete_ = function(clientId, sharedSecret) {};
90 /** @type {remoting.ClientSession.PerfStats} */ 142 /**
143 * @type {remoting.ClientSession.PerfStats}
144 * @private
145 */
91 this.perfStats_ = new remoting.ClientSession.PerfStats(); 146 this.perfStats_ = new remoting.ClientSession.PerfStats();
92 147
93 /** @type {remoting.ClientPlugin} */ 148 /** @type {remoting.ClientPluginImpl} */
94 var that = this; 149 var that = this;
95 /** @param {Event} event Message event from the plugin. */ 150 /** @param {Event} event Message event from the plugin. */
96 this.plugin_.addEventListener('message', function(event) { 151 this.plugin_.addEventListener('message', function(event) {
97 that.handleMessage_(event.data); 152 that.handleMessage_(event.data);
98 }, false); 153 }, false);
99 154
100 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'native') { 155 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'native') {
101 window.setTimeout(this.showPluginForClickToPlay_.bind(this), 500); 156 window.setTimeout(this.showPluginForClickToPlay_.bind(this), 500);
102 } 157 }
103 }; 158 };
104 159
105 /** 160 /**
106 * Creates plugin element without adding it to a container. 161 * Creates plugin element without adding it to a container.
107 * 162 *
108 * @return {remoting.ViewerPlugin} Plugin element 163 * @return {remoting.ViewerPlugin} Plugin element
109 */ 164 */
110 remoting.ClientPlugin.createPluginElement_ = function() { 165 remoting.ClientPluginImpl.createPluginElement_ = function() {
111 var plugin = /** @type {remoting.ViewerPlugin} */ 166 var plugin = /** @type {remoting.ViewerPlugin} */
112 document.createElement('embed'); 167 document.createElement('embed');
113 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'pnacl') { 168 if (remoting.settings.CLIENT_PLUGIN_TYPE == 'pnacl') {
114 plugin.src = 'remoting_client_pnacl.nmf'; 169 plugin.src = 'remoting_client_pnacl.nmf';
115 plugin.type = 'application/x-pnacl'; 170 plugin.type = 'application/x-pnacl';
116 } else if (remoting.settings.CLIENT_PLUGIN_TYPE == 'nacl') { 171 } else if (remoting.settings.CLIENT_PLUGIN_TYPE == 'nacl') {
117 plugin.src = 'remoting_client_nacl.nmf'; 172 plugin.src = 'remoting_client_nacl.nmf';
118 plugin.type = 'application/x-nacl'; 173 plugin.type = 'application/x-nacl';
119 } else { 174 } else {
120 plugin.src = 'about://none'; 175 plugin.src = 'about://none';
121 plugin.type = 'application/vnd.chromium.remoting-viewer'; 176 plugin.type = 'application/vnd.chromium.remoting-viewer';
122 } 177 }
123 plugin.width = 0; 178 plugin.width = 0;
124 plugin.height = 0; 179 plugin.height = 0;
125 plugin.tabIndex = 0; // Required, otherwise focus() doesn't work. 180 plugin.tabIndex = 0; // Required, otherwise focus() doesn't work.
126 return plugin; 181 return plugin;
127 } 182 }
128 183
129 /** 184 /**
130 * Preloads the plugin to make instantiation faster when the user tries
131 * to connect.
132 */
133 remoting.ClientPlugin.preload = function() {
134 if (remoting.settings.CLIENT_PLUGIN_TYPE != 'pnacl') {
135 return;
136 }
137
138 var plugin = remoting.ClientPlugin.createPluginElement_();
139 plugin.addEventListener(
140 'loadend', function() { document.body.removeChild(plugin); }, false);
141 document.body.appendChild(plugin);
142 }
143
144 /**
145 * Set of features for which hasFeature() can be used to test.
146 *
147 * @enum {string}
148 */
149 remoting.ClientPlugin.Feature = {
150 INJECT_KEY_EVENT: 'injectKeyEvent',
151 NOTIFY_CLIENT_RESOLUTION: 'notifyClientResolution',
152 ASYNC_PIN: 'asyncPin',
153 PAUSE_VIDEO: 'pauseVideo',
154 PAUSE_AUDIO: 'pauseAudio',
155 REMAP_KEY: 'remapKey',
156 SEND_CLIPBOARD_ITEM: 'sendClipboardItem',
157 THIRD_PARTY_AUTH: 'thirdPartyAuth',
158 TRAP_KEY: 'trapKey',
159 PINLESS_AUTH: 'pinlessAuth',
160 EXTENSION_MESSAGE: 'extensionMessage',
161 MEDIA_SOURCE_RENDERING: 'mediaSourceRendering',
162 VIDEO_CONTROL: 'videoControl'
163 };
164
165 /**
166 * Chromoting session API version (for this javascript). 185 * Chromoting session API version (for this javascript).
167 * This is compared with the plugin API version to verify that they are 186 * This is compared with the plugin API version to verify that they are
168 * compatible. 187 * compatible.
169 * 188 *
170 * @const 189 * @const
171 * @private 190 * @private
172 */ 191 */
173 remoting.ClientPlugin.prototype.API_VERSION_ = 6; 192 remoting.ClientPluginImpl.prototype.API_VERSION_ = 6;
174 193
175 /** 194 /**
176 * The oldest API version that we support. 195 * The oldest API version that we support.
177 * This will differ from the |API_VERSION_| if we maintain backward 196 * This will differ from the |API_VERSION_| if we maintain backward
178 * compatibility with older API versions. 197 * compatibility with older API versions.
179 * 198 *
180 * @const 199 * @const
181 * @private 200 * @private
182 */ 201 */
183 remoting.ClientPlugin.prototype.API_MIN_VERSION_ = 5; 202 remoting.ClientPluginImpl.prototype.API_MIN_VERSION_ = 5;
203
204 /**
205 * @param {function(string):void} handler
206 */
207 remoting.ClientPluginImpl.prototype.setOnOutgoingIqHandler = function(handler) {
208 this.onOutgoingIqHandler_ = handler;
209 };
210
211 /**
212 * @param {function(string):void} handler
213 */
214 remoting.ClientPluginImpl.prototype.setOnDebugMessageHandler =
215 function(handler) {
216 this.onDebugMessageHandler_ = handler;
217 };
218
219 /**
220 * @param {function(number, number):void} handler
221 */
222 remoting.ClientPluginImpl.prototype.setConnectionStatusUpdateHandler =
223 function(handler) {
224 this.onConnectionStatusUpdateHandler_ = handler;
225 };
226
227 /**
228 * @param {function(boolean):void} handler
229 */
230 remoting.ClientPluginImpl.prototype.setConnectionReadyHandler =
231 function(handler) {
232 this.onConnectionReadyHandler_ = handler;
233 };
234
235 /**
236 * @param {function():void} handler
237 */
238 remoting.ClientPluginImpl.prototype.setDesktopSizeUpdateHandler =
239 function(handler) {
240 this.onDesktopSizeUpdateHandler_ = handler;
241 };
242
243 /**
244 * @param {function(!Array.<string>):void} handler
245 */
246 remoting.ClientPluginImpl.prototype.setCapabilitiesHandler = function(handler) {
247 this.onSetCapabilitiesHandler_ = handler;
248 };
249
250 /**
251 * @param {function(string):void} handler
252 */
253 remoting.ClientPluginImpl.prototype.setGnubbyAuthHandler = function(handler) {
254 this.onGnubbyAuthHandler_ = handler;
255 };
256
257 /**
258 * @param {function(string):void} handler
259 */
260 remoting.ClientPluginImpl.prototype.setCastExtensionHandler =
261 function(handler) {
262 this.onCastExtensionHandler_ = handler;
263 };
264
265 /**
266 * @param {function(string, number, number):void} handler
267 */
268 remoting.ClientPluginImpl.prototype.setMouseCursorHandler = function(handler) {
269 this.updateMouseCursorImage_ = handler;
270 };
271
272 /**
273 * @param {function(string, string, string):void} handler
274 */
275 remoting.ClientPluginImpl.prototype.setFetchThirdPartyTokenHandler =
276 function(handler) {
277 this.fetchThirdPartyTokenHandler_ = handler;
278 };
279
280 /**
281 * @param {function(boolean):void} handler
282 */
283 remoting.ClientPluginImpl.prototype.setFetchPinHandler = function(handler) {
284 this.fetchPinHandler_ = handler;
285 };
184 286
185 /** 287 /**
186 * @param {string|{method:string, data:Object.<string,*>}} 288 * @param {string|{method:string, data:Object.<string,*>}}
187 * rawMessage Message from the plugin. 289 * rawMessage Message from the plugin.
188 * @private 290 * @private
189 */ 291 */
190 remoting.ClientPlugin.prototype.handleMessage_ = function(rawMessage) { 292 remoting.ClientPluginImpl.prototype.handleMessage_ = function(rawMessage) {
191 var message = 293 var message =
192 /** @type {{method:string, data:Object.<string,*>}} */ 294 /** @type {{method:string, data:Object.<string,*>}} */
193 ((typeof(rawMessage) == 'string') ? jsonParseSafe(rawMessage) 295 ((typeof(rawMessage) == 'string') ? jsonParseSafe(rawMessage)
194 : rawMessage); 296 : rawMessage);
195 if (!message || !('method' in message) || !('data' in message)) { 297 if (!message || !('method' in message) || !('data' in message)) {
196 console.error('Received invalid message from the plugin:', rawMessage); 298 console.error('Received invalid message from the plugin:', rawMessage);
197 return; 299 return;
198 } 300 }
199 301
200 try { 302 try {
201 this.handleMessageMethod_(message); 303 this.handleMessageMethod_(message);
202 } catch(e) { 304 } catch(e) {
203 console.error(/** @type {*} */ (e)); 305 console.error(/** @type {*} */ (e));
204 } 306 }
205 } 307 }
206 308
207 /** 309 /**
208 * @param {{method:string, data:Object.<string,*>}} 310 * @param {{method:string, data:Object.<string,*>}}
209 * message Parsed message from the plugin. 311 * message Parsed message from the plugin.
210 * @private 312 * @private
211 */ 313 */
212 remoting.ClientPlugin.prototype.handleMessageMethod_ = function(message) { 314 remoting.ClientPluginImpl.prototype.handleMessageMethod_ = function(message) {
213 /** 315 /**
214 * Splits a string into a list of words delimited by spaces. 316 * Splits a string into a list of words delimited by spaces.
215 * @param {string} str String that should be split. 317 * @param {string} str String that should be split.
216 * @return {!Array.<string>} List of words. 318 * @return {!Array.<string>} List of words.
217 */ 319 */
218 var tokenize = function(str) { 320 var tokenize = function(str) {
219 /** @type {Array.<string>} */ 321 /** @type {Array.<string>} */
220 var tokens = str.match(/\S+/g); 322 var tokens = str.match(/\S+/g);
221 return tokens ? tokens : []; 323 return tokens ? tokens : [];
222 }; 324 };
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 } else { 380 } else {
279 this.pluginApiFeatures_ = ['highQualityScaling']; 381 this.pluginApiFeatures_ = ['highQualityScaling'];
280 } 382 }
281 this.helloReceived_ = true; 383 this.helloReceived_ = true;
282 if (this.onInitializedCallback_ != null) { 384 if (this.onInitializedCallback_ != null) {
283 this.onInitializedCallback_(true); 385 this.onInitializedCallback_(true);
284 this.onInitializedCallback_ = null; 386 this.onInitializedCallback_ = null;
285 } 387 }
286 388
287 } else if (message.method == 'sendOutgoingIq') { 389 } else if (message.method == 'sendOutgoingIq') {
288 this.onOutgoingIqHandler(getStringAttr(message.data, 'iq')); 390 this.onOutgoingIqHandler_(getStringAttr(message.data, 'iq'));
289 391
290 } else if (message.method == 'logDebugMessage') { 392 } else if (message.method == 'logDebugMessage') {
291 this.onDebugMessageHandler(getStringAttr(message.data, 'message')); 393 this.onDebugMessageHandler_(getStringAttr(message.data, 'message'));
292 394
293 } else if (message.method == 'onConnectionStatus') { 395 } else if (message.method == 'onConnectionStatus') {
294 var state = remoting.ClientSession.State.fromString( 396 var state = remoting.ClientSession.State.fromString(
295 getStringAttr(message.data, 'state')) 397 getStringAttr(message.data, 'state'))
296 var error = remoting.ClientSession.ConnectionError.fromString( 398 var error = remoting.ClientSession.ConnectionError.fromString(
297 getStringAttr(message.data, 'error')); 399 getStringAttr(message.data, 'error'));
298 this.onConnectionStatusUpdateHandler(state, error); 400 this.onConnectionStatusUpdateHandler_(state, error);
299 401
300 } else if (message.method == 'onDesktopSize') { 402 } else if (message.method == 'onDesktopSize') {
301 this.desktopWidth = getNumberAttr(message.data, 'width'); 403 this.desktopWidth_ = getNumberAttr(message.data, 'width');
302 this.desktopHeight = getNumberAttr(message.data, 'height'); 404 this.desktopHeight_ = getNumberAttr(message.data, 'height');
303 this.desktopXDpi = getNumberAttr(message.data, 'x_dpi', 96); 405 this.desktopXDpi_ = getNumberAttr(message.data, 'x_dpi', 96);
304 this.desktopYDpi = getNumberAttr(message.data, 'y_dpi', 96); 406 this.desktopYDpi_ = getNumberAttr(message.data, 'y_dpi', 96);
305 this.onDesktopSizeUpdateHandler(); 407 this.onDesktopSizeUpdateHandler_();
306 408
307 } else if (message.method == 'onPerfStats') { 409 } else if (message.method == 'onPerfStats') {
308 // Return value is ignored. These calls will throw an error if the value 410 // Return value is ignored. These calls will throw an error if the value
309 // is not a number. 411 // is not a number.
310 getNumberAttr(message.data, 'videoBandwidth'); 412 getNumberAttr(message.data, 'videoBandwidth');
311 getNumberAttr(message.data, 'videoFrameRate'); 413 getNumberAttr(message.data, 'videoFrameRate');
312 getNumberAttr(message.data, 'captureLatency'); 414 getNumberAttr(message.data, 'captureLatency');
313 getNumberAttr(message.data, 'encodeLatency'); 415 getNumberAttr(message.data, 'encodeLatency');
314 getNumberAttr(message.data, 'decodeLatency'); 416 getNumberAttr(message.data, 'decodeLatency');
315 getNumberAttr(message.data, 'renderLatency'); 417 getNumberAttr(message.data, 'renderLatency');
316 getNumberAttr(message.data, 'roundtripLatency'); 418 getNumberAttr(message.data, 'roundtripLatency');
317 this.perfStats_ = 419 this.perfStats_ =
318 /** @type {remoting.ClientSession.PerfStats} */ message.data; 420 /** @type {remoting.ClientSession.PerfStats} */ message.data;
319 421
320 } else if (message.method == 'injectClipboardItem') { 422 } else if (message.method == 'injectClipboardItem') {
321 var mimetype = getStringAttr(message.data, 'mimeType'); 423 var mimetype = getStringAttr(message.data, 'mimeType');
322 var item = getStringAttr(message.data, 'item'); 424 var item = getStringAttr(message.data, 'item');
323 if (remoting.clipboard) { 425 if (remoting.clipboard) {
324 remoting.clipboard.fromHost(mimetype, item); 426 remoting.clipboard.fromHost(mimetype, item);
325 } 427 }
326 428
327 } else if (message.method == 'onFirstFrameReceived') { 429 } else if (message.method == 'onFirstFrameReceived') {
328 if (remoting.clientSession) { 430 if (remoting.clientSession) {
329 remoting.clientSession.onFirstFrameReceived(); 431 remoting.clientSession.onFirstFrameReceived();
330 } 432 }
331 433
332 } else if (message.method == 'onConnectionReady') { 434 } else if (message.method == 'onConnectionReady') {
333 var ready = getBooleanAttr(message.data, 'ready'); 435 var ready = getBooleanAttr(message.data, 'ready');
334 this.onConnectionReadyHandler(ready); 436 this.onConnectionReadyHandler_(ready);
335 437
336 } else if (message.method == 'fetchPin') { 438 } else if (message.method == 'fetchPin') {
337 // The pairingSupported value in the dictionary indicates whether both 439 // The pairingSupported value in the dictionary indicates whether both
338 // client and host support pairing. If the client doesn't support pairing, 440 // client and host support pairing. If the client doesn't support pairing,
339 // then the value won't be there at all, so give it a default of false. 441 // then the value won't be there at all, so give it a default of false.
340 var pairingSupported = getBooleanAttr(message.data, 'pairingSupported', 442 var pairingSupported = getBooleanAttr(message.data, 'pairingSupported',
341 false) 443 false)
342 this.fetchPinHandler(pairingSupported); 444 this.fetchPinHandler_(pairingSupported);
343 445
344 } else if (message.method == 'setCapabilities') { 446 } else if (message.method == 'setCapabilities') {
345 /** @type {!Array.<string>} */ 447 /** @type {!Array.<string>} */
346 var capabilities = tokenize(getStringAttr(message.data, 'capabilities')); 448 var capabilities = tokenize(getStringAttr(message.data, 'capabilities'));
347 this.onSetCapabilitiesHandler(capabilities); 449 this.onSetCapabilitiesHandler_(capabilities);
348 450
349 } else if (message.method == 'fetchThirdPartyToken') { 451 } else if (message.method == 'fetchThirdPartyToken') {
350 var tokenUrl = getStringAttr(message.data, 'tokenUrl'); 452 var tokenUrl = getStringAttr(message.data, 'tokenUrl');
351 var hostPublicKey = getStringAttr(message.data, 'hostPublicKey'); 453 var hostPublicKey = getStringAttr(message.data, 'hostPublicKey');
352 var scope = getStringAttr(message.data, 'scope'); 454 var scope = getStringAttr(message.data, 'scope');
353 this.fetchThirdPartyTokenHandler(tokenUrl, hostPublicKey, scope); 455 this.fetchThirdPartyTokenHandler_(tokenUrl, hostPublicKey, scope);
354 456
355 } else if (message.method == 'pairingResponse') { 457 } else if (message.method == 'pairingResponse') {
356 var clientId = getStringAttr(message.data, 'clientId'); 458 var clientId = getStringAttr(message.data, 'clientId');
357 var sharedSecret = getStringAttr(message.data, 'sharedSecret'); 459 var sharedSecret = getStringAttr(message.data, 'sharedSecret');
358 this.onPairingComplete_(clientId, sharedSecret); 460 this.onPairingComplete_(clientId, sharedSecret);
359 461
360 } else if (message.method == 'extensionMessage') { 462 } else if (message.method == 'extensionMessage') {
361 var extMsgType = getStringAttr(message.data, 'type'); 463 var extMsgType = getStringAttr(message.data, 'type');
362 var extMsgData = getStringAttr(message.data, 'data'); 464 var extMsgData = getStringAttr(message.data, 'data');
363 switch (extMsgType) { 465 switch (extMsgType) {
364 case 'gnubby-auth': 466 case 'gnubby-auth':
365 this.onGnubbyAuthHandler(extMsgData); 467 this.onGnubbyAuthHandler_(extMsgData);
366 break; 468 break;
367 case 'test-echo-reply': 469 case 'test-echo-reply':
368 console.log('Got echo reply: ' + extMsgData); 470 console.log('Got echo reply: ' + extMsgData);
369 break; 471 break;
370 case 'cast_message': 472 case 'cast_message':
371 this.onCastExtensionHandler(extMsgData); 473 this.onCastExtensionHandler_(extMsgData);
372 break; 474 break;
373 default: 475 default:
374 this.onExtensionMessage_(extMsgType, extMsgData); 476 this.onExtensionMessage_(extMsgType, extMsgData);
375 break; 477 break;
376 } 478 }
377 479
378 } else if (message.method == 'mediaSourceReset') { 480 } else if (message.method == 'mediaSourceReset') {
379 if (!this.mediaSourceRenderer_) { 481 if (!this.mediaSourceRenderer_) {
380 console.error('Unexpected mediaSourceReset.'); 482 console.error('Unexpected mediaSourceReset.');
381 return; 483 return;
382 } 484 }
383 this.mediaSourceRenderer_.reset(getStringAttr(message.data, 'format')) 485 this.mediaSourceRenderer_.reset(getStringAttr(message.data, 'format'))
384 486
385 } else if (message.method == 'mediaSourceData') { 487 } else if (message.method == 'mediaSourceData') {
386 if (!(message.data['buffer'] instanceof ArrayBuffer)) { 488 if (!(message.data['buffer'] instanceof ArrayBuffer)) {
387 console.error('Invalid mediaSourceData message:', message.data); 489 console.error('Invalid mediaSourceData message:', message.data);
388 return; 490 return;
389 } 491 }
390 if (!this.mediaSourceRenderer_) { 492 if (!this.mediaSourceRenderer_) {
391 console.error('Unexpected mediaSourceData.'); 493 console.error('Unexpected mediaSourceData.');
392 return; 494 return;
393 } 495 }
394 // keyframe flag may be absent from the message. 496 // keyframe flag may be absent from the message.
395 var keyframe = !!message.data['keyframe']; 497 var keyframe = !!message.data['keyframe'];
396 this.mediaSourceRenderer_.onIncomingData( 498 this.mediaSourceRenderer_.onIncomingData(
397 (/** @type {ArrayBuffer} */ message.data['buffer']), keyframe); 499 (/** @type {ArrayBuffer} */ message.data['buffer']), keyframe);
398 500
399 } else if (message.method == 'unsetCursorShape') { 501 } else if (message.method == 'unsetCursorShape') {
400 this.updateMouseCursorImage('', 0, 0); 502 this.updateMouseCursorImage_('', 0, 0);
401 503
402 } else if (message.method == 'setCursorShape') { 504 } else if (message.method == 'setCursorShape') {
403 var width = getNumberAttr(message.data, 'width'); 505 var width = getNumberAttr(message.data, 'width');
404 var height = getNumberAttr(message.data, 'height'); 506 var height = getNumberAttr(message.data, 'height');
405 var hotspotX = getNumberAttr(message.data, 'hotspotX'); 507 var hotspotX = getNumberAttr(message.data, 'hotspotX');
406 var hotspotY = getNumberAttr(message.data, 'hotspotY'); 508 var hotspotY = getNumberAttr(message.data, 'hotspotY');
407 var srcArrayBuffer = getObjectAttr(message.data, 'data'); 509 var srcArrayBuffer = getObjectAttr(message.data, 'data');
408 510
409 var canvas = 511 var canvas =
410 /** @type {HTMLCanvasElement} */ (document.createElement('canvas')); 512 /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
411 canvas.width = width; 513 canvas.width = width;
412 canvas.height = height; 514 canvas.height = height;
413 515
414 var context = 516 var context =
415 /** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d')); 517 /** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d'));
416 var imageData = context.getImageData(0, 0, width, height); 518 var imageData = context.getImageData(0, 0, width, height);
417 base.debug.assert(srcArrayBuffer instanceof ArrayBuffer); 519 base.debug.assert(srcArrayBuffer instanceof ArrayBuffer);
418 var src = new Uint8Array(/** @type {ArrayBuffer} */(srcArrayBuffer)); 520 var src = new Uint8Array(/** @type {ArrayBuffer} */(srcArrayBuffer));
419 var dest = imageData.data; 521 var dest = imageData.data;
420 for (var i = 0; i < /** @type {number} */(dest.length); i += 4) { 522 for (var i = 0; i < /** @type {number} */(dest.length); i += 4) {
421 dest[i] = src[i + 2]; 523 dest[i] = src[i + 2];
422 dest[i + 1] = src[i + 1]; 524 dest[i + 1] = src[i + 1];
423 dest[i + 2] = src[i]; 525 dest[i + 2] = src[i];
424 dest[i + 3] = src[i + 3]; 526 dest[i + 3] = src[i + 3];
425 } 527 }
426 528
427 context.putImageData(imageData, 0, 0); 529 context.putImageData(imageData, 0, 0);
428 this.updateMouseCursorImage(canvas.toDataURL(), hotspotX, hotspotY); 530 this.updateMouseCursorImage_(canvas.toDataURL(), hotspotX, hotspotY);
429 } 531 }
430 }; 532 };
431 533
432 /** 534 /**
433 * Deletes the plugin. 535 * Deletes the plugin.
434 */ 536 */
435 remoting.ClientPlugin.prototype.cleanup = function() { 537 remoting.ClientPluginImpl.prototype.dispose = function() {
436 if (this.plugin_) { 538 if (this.plugin_) {
437 this.plugin_.parentNode.removeChild(this.plugin_); 539 this.plugin_.parentNode.removeChild(this.plugin_);
438 this.plugin_ = null; 540 this.plugin_ = null;
439 } 541 }
440 }; 542 };
441 543
442 /** 544 /**
443 * @return {HTMLEmbedElement} HTML element that corresponds to the plugin. 545 * @return {HTMLEmbedElement} HTML element that corresponds to the plugin.
444 */ 546 */
445 remoting.ClientPlugin.prototype.element = function() { 547 remoting.ClientPluginImpl.prototype.element = function() {
446 return this.plugin_; 548 return this.plugin_;
447 }; 549 };
448 550
449 /** 551 /**
450 * @param {function(boolean): void} onDone 552 * @param {function(boolean): void} onDone
451 */ 553 */
452 remoting.ClientPlugin.prototype.initialize = function(onDone) { 554 remoting.ClientPluginImpl.prototype.initialize = function(onDone) {
453 if (this.helloReceived_) { 555 if (this.helloReceived_) {
454 onDone(true); 556 onDone(true);
455 } else { 557 } else {
456 this.onInitializedCallback_ = onDone; 558 this.onInitializedCallback_ = onDone;
457 } 559 }
458 }; 560 };
459 561
460 /** 562 /**
461 * @return {boolean} True if the plugin and web-app versions are compatible. 563 * @return {boolean} True if the plugin and web-app versions are compatible.
462 */ 564 */
463 remoting.ClientPlugin.prototype.isSupportedVersion = function() { 565 remoting.ClientPluginImpl.prototype.isSupportedVersion = function() {
464 if (!this.helloReceived_) { 566 if (!this.helloReceived_) {
465 console.error( 567 console.error(
466 "isSupportedVersion() is called before the plugin is initialized."); 568 "isSupportedVersion() is called before the plugin is initialized.");
467 return false; 569 return false;
468 } 570 }
469 return this.API_VERSION_ >= this.pluginApiMinVersion_ && 571 return this.API_VERSION_ >= this.pluginApiMinVersion_ &&
470 this.pluginApiVersion_ >= this.API_MIN_VERSION_; 572 this.pluginApiVersion_ >= this.API_MIN_VERSION_;
471 }; 573 };
472 574
473 /** 575 /**
474 * @param {remoting.ClientPlugin.Feature} feature The feature to test for. 576 * @param {remoting.ClientPlugin.Feature} feature The feature to test for.
475 * @return {boolean} True if the plugin supports the named feature. 577 * @return {boolean} True if the plugin supports the named feature.
476 */ 578 */
477 remoting.ClientPlugin.prototype.hasFeature = function(feature) { 579 remoting.ClientPluginImpl.prototype.hasFeature = function(feature) {
478 if (!this.helloReceived_) { 580 if (!this.helloReceived_) {
479 console.error( 581 console.error(
480 "hasFeature() is called before the plugin is initialized."); 582 "hasFeature() is called before the plugin is initialized.");
481 return false; 583 return false;
482 } 584 }
483 return this.pluginApiFeatures_.indexOf(feature) > -1; 585 return this.pluginApiFeatures_.indexOf(feature) > -1;
484 }; 586 };
485 587
486 /** 588 /**
487 * @return {boolean} True if the plugin supports the injectKeyEvent API. 589 * @return {boolean} True if the plugin supports the injectKeyEvent API.
488 */ 590 */
489 remoting.ClientPlugin.prototype.isInjectKeyEventSupported = function() { 591 remoting.ClientPluginImpl.prototype.isInjectKeyEventSupported = function() {
490 return this.pluginApiVersion_ >= 6; 592 return this.pluginApiVersion_ >= 6;
491 }; 593 };
492 594
493 /** 595 /**
494 * @param {string} iq Incoming IQ stanza. 596 * @param {string} iq Incoming IQ stanza.
495 */ 597 */
496 remoting.ClientPlugin.prototype.onIncomingIq = function(iq) { 598 remoting.ClientPluginImpl.prototype.onIncomingIq = function(iq) {
497 if (this.plugin_ && this.plugin_.postMessage) { 599 if (this.plugin_ && this.plugin_.postMessage) {
498 this.plugin_.postMessage(JSON.stringify( 600 this.plugin_.postMessage(JSON.stringify(
499 { method: 'incomingIq', data: { iq: iq } })); 601 { method: 'incomingIq', data: { iq: iq } }));
500 } else { 602 } else {
501 // plugin.onIq may not be set after the plugin has been shut 603 // plugin.onIq may not be set after the plugin has been shut
502 // down. Particularly this happens when we receive response to 604 // down. Particularly this happens when we receive response to
503 // session-terminate stanza. 605 // session-terminate stanza.
504 console.warn('plugin.onIq is not set so dropping incoming message.'); 606 console.warn('plugin.onIq is not set so dropping incoming message.');
505 } 607 }
506 }; 608 };
507 609
508 /** 610 /**
509 * @param {string} hostJid The jid of the host to connect to. 611 * @param {string} hostJid The jid of the host to connect to.
510 * @param {string} hostPublicKey The base64 encoded version of the host's 612 * @param {string} hostPublicKey The base64 encoded version of the host's
511 * public key. 613 * public key.
512 * @param {string} localJid Local jid. 614 * @param {string} localJid Local jid.
513 * @param {string} sharedSecret The access code for IT2Me or the PIN 615 * @param {string} sharedSecret The access code for IT2Me or the PIN
514 * for Me2Me. 616 * for Me2Me.
515 * @param {string} authenticationMethods Comma-separated list of 617 * @param {string} authenticationMethods Comma-separated list of
516 * authentication methods the client should attempt to use. 618 * authentication methods the client should attempt to use.
517 * @param {string} authenticationTag A host-specific tag to mix into 619 * @param {string} authenticationTag A host-specific tag to mix into
518 * authentication hashes. 620 * authentication hashes.
519 * @param {string} clientPairingId For paired Me2Me connections, the 621 * @param {string} clientPairingId For paired Me2Me connections, the
520 * pairing id for this client, as issued by the host. 622 * pairing id for this client, as issued by the host.
521 * @param {string} clientPairedSecret For paired Me2Me connections, the 623 * @param {string} clientPairedSecret For paired Me2Me connections, the
522 * paired secret for this client, as issued by the host. 624 * paired secret for this client, as issued by the host.
523 */ 625 */
524 remoting.ClientPlugin.prototype.connect = function( 626 remoting.ClientPluginImpl.prototype.connect = function(
525 hostJid, hostPublicKey, localJid, sharedSecret, 627 hostJid, hostPublicKey, localJid, sharedSecret,
526 authenticationMethods, authenticationTag, 628 authenticationMethods, authenticationTag,
527 clientPairingId, clientPairedSecret) { 629 clientPairingId, clientPairedSecret) {
528 var keyFilter = ''; 630 var keyFilter = '';
529 if (remoting.platformIsMac()) { 631 if (remoting.platformIsMac()) {
530 keyFilter = 'mac'; 632 keyFilter = 'mac';
531 } else if (remoting.platformIsChromeOS()) { 633 } else if (remoting.platformIsChromeOS()) {
532 keyFilter = 'cros'; 634 keyFilter = 'cros';
533 } 635 }
534 this.plugin_.postMessage(JSON.stringify( 636 this.plugin_.postMessage(JSON.stringify(
(...skipping 10 matching lines...) Expand all
545 clientPairingId: clientPairingId, 647 clientPairingId: clientPairingId,
546 clientPairedSecret: clientPairedSecret, 648 clientPairedSecret: clientPairedSecret,
547 keyFilter: keyFilter 649 keyFilter: keyFilter
548 } 650 }
549 })); 651 }));
550 }; 652 };
551 653
552 /** 654 /**
553 * Release all currently pressed keys. 655 * Release all currently pressed keys.
554 */ 656 */
555 remoting.ClientPlugin.prototype.releaseAllKeys = function() { 657 remoting.ClientPluginImpl.prototype.releaseAllKeys = function() {
556 this.plugin_.postMessage(JSON.stringify( 658 this.plugin_.postMessage(JSON.stringify(
557 { method: 'releaseAllKeys', data: {} })); 659 { method: 'releaseAllKeys', data: {} }));
558 }; 660 };
559 661
560 /** 662 /**
561 * Send a key event to the host. 663 * Send a key event to the host.
562 * 664 *
563 * @param {number} usbKeycode The USB-style code of the key to inject. 665 * @param {number} usbKeycode The USB-style code of the key to inject.
564 * @param {boolean} pressed True to inject a key press, False for a release. 666 * @param {boolean} pressed True to inject a key press, False for a release.
565 */ 667 */
566 remoting.ClientPlugin.prototype.injectKeyEvent = 668 remoting.ClientPluginImpl.prototype.injectKeyEvent =
567 function(usbKeycode, pressed) { 669 function(usbKeycode, pressed) {
568 this.plugin_.postMessage(JSON.stringify( 670 this.plugin_.postMessage(JSON.stringify(
569 { method: 'injectKeyEvent', data: { 671 { method: 'injectKeyEvent', data: {
570 'usbKeycode': usbKeycode, 672 'usbKeycode': usbKeycode,
571 'pressed': pressed} 673 'pressed': pressed}
572 })); 674 }));
573 }; 675 };
574 676
575 /** 677 /**
576 * Remap one USB keycode to another in all subsequent key events. 678 * Remap one USB keycode to another in all subsequent key events.
577 * 679 *
578 * @param {number} fromKeycode The USB-style code of the key to remap. 680 * @param {number} fromKeycode The USB-style code of the key to remap.
579 * @param {number} toKeycode The USB-style code to remap the key to. 681 * @param {number} toKeycode The USB-style code to remap the key to.
580 */ 682 */
581 remoting.ClientPlugin.prototype.remapKey = 683 remoting.ClientPluginImpl.prototype.remapKey =
582 function(fromKeycode, toKeycode) { 684 function(fromKeycode, toKeycode) {
583 this.plugin_.postMessage(JSON.stringify( 685 this.plugin_.postMessage(JSON.stringify(
584 { method: 'remapKey', data: { 686 { method: 'remapKey', data: {
585 'fromKeycode': fromKeycode, 687 'fromKeycode': fromKeycode,
586 'toKeycode': toKeycode} 688 'toKeycode': toKeycode}
587 })); 689 }));
588 }; 690 };
589 691
590 /** 692 /**
591 * Enable/disable redirection of the specified key to the web-app. 693 * Enable/disable redirection of the specified key to the web-app.
592 * 694 *
593 * @param {number} keycode The USB-style code of the key. 695 * @param {number} keycode The USB-style code of the key.
594 * @param {Boolean} trap True to enable trapping, False to disable. 696 * @param {Boolean} trap True to enable trapping, False to disable.
595 */ 697 */
596 remoting.ClientPlugin.prototype.trapKey = function(keycode, trap) { 698 remoting.ClientPluginImpl.prototype.trapKey = function(keycode, trap) {
597 this.plugin_.postMessage(JSON.stringify( 699 this.plugin_.postMessage(JSON.stringify(
598 { method: 'trapKey', data: { 700 { method: 'trapKey', data: {
599 'keycode': keycode, 701 'keycode': keycode,
600 'trap': trap} 702 'trap': trap}
601 })); 703 }));
602 }; 704 };
603 705
604 /** 706 /**
605 * Returns an associative array with a set of stats for this connecton. 707 * Returns an associative array with a set of stats for this connecton.
606 * 708 *
607 * @return {remoting.ClientSession.PerfStats} The connection statistics. 709 * @return {remoting.ClientSession.PerfStats} The connection statistics.
608 */ 710 */
609 remoting.ClientPlugin.prototype.getPerfStats = function() { 711 remoting.ClientPluginImpl.prototype.getPerfStats = function() {
610 return this.perfStats_; 712 return this.perfStats_;
611 }; 713 };
612 714
613 /** 715 /**
614 * Sends a clipboard item to the host. 716 * Sends a clipboard item to the host.
615 * 717 *
616 * @param {string} mimeType The MIME type of the clipboard item. 718 * @param {string} mimeType The MIME type of the clipboard item.
617 * @param {string} item The clipboard item. 719 * @param {string} item The clipboard item.
618 */ 720 */
619 remoting.ClientPlugin.prototype.sendClipboardItem = 721 remoting.ClientPluginImpl.prototype.sendClipboardItem =
620 function(mimeType, item) { 722 function(mimeType, item) {
621 if (!this.hasFeature(remoting.ClientPlugin.Feature.SEND_CLIPBOARD_ITEM)) 723 if (!this.hasFeature(remoting.ClientPlugin.Feature.SEND_CLIPBOARD_ITEM))
622 return; 724 return;
623 this.plugin_.postMessage(JSON.stringify( 725 this.plugin_.postMessage(JSON.stringify(
624 { method: 'sendClipboardItem', 726 { method: 'sendClipboardItem',
625 data: { mimeType: mimeType, item: item }})); 727 data: { mimeType: mimeType, item: item }}));
626 }; 728 };
627 729
628 /** 730 /**
629 * Notifies the host that the client has the specified size and pixel density. 731 * Notifies the host that the client has the specified size and pixel density.
630 * 732 *
631 * @param {number} width The available client width in DIPs. 733 * @param {number} width The available client width in DIPs.
632 * @param {number} height The available client height in DIPs. 734 * @param {number} height The available client height in DIPs.
633 * @param {number} device_scale The number of device pixels per DIP. 735 * @param {number} device_scale The number of device pixels per DIP.
634 */ 736 */
635 remoting.ClientPlugin.prototype.notifyClientResolution = 737 remoting.ClientPluginImpl.prototype.notifyClientResolution =
636 function(width, height, device_scale) { 738 function(width, height, device_scale) {
637 if (this.hasFeature(remoting.ClientPlugin.Feature.NOTIFY_CLIENT_RESOLUTION)) { 739 if (this.hasFeature(remoting.ClientPlugin.Feature.NOTIFY_CLIENT_RESOLUTION)) {
638 var dpi = Math.floor(device_scale * 96); 740 var dpi = Math.floor(device_scale * 96);
639 this.plugin_.postMessage(JSON.stringify( 741 this.plugin_.postMessage(JSON.stringify(
640 { method: 'notifyClientResolution', 742 { method: 'notifyClientResolution',
641 data: { width: Math.floor(width * device_scale), 743 data: { width: Math.floor(width * device_scale),
642 height: Math.floor(height * device_scale), 744 height: Math.floor(height * device_scale),
643 x_dpi: dpi, y_dpi: dpi }})); 745 x_dpi: dpi, y_dpi: dpi }}));
644 } 746 }
645 }; 747 };
646 748
647 /** 749 /**
648 * Requests that the host pause or resume sending video updates. 750 * Requests that the host pause or resume sending video updates.
649 * 751 *
650 * @param {boolean} pause True to suspend video updates, false otherwise. 752 * @param {boolean} pause True to suspend video updates, false otherwise.
651 */ 753 */
652 remoting.ClientPlugin.prototype.pauseVideo = 754 remoting.ClientPluginImpl.prototype.pauseVideo =
653 function(pause) { 755 function(pause) {
654 if (this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) { 756 if (this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) {
655 this.plugin_.postMessage(JSON.stringify( 757 this.plugin_.postMessage(JSON.stringify(
656 { method: 'videoControl', data: { pause: pause }})); 758 { method: 'videoControl', data: { pause: pause }}));
657 } else if (this.hasFeature(remoting.ClientPlugin.Feature.PAUSE_VIDEO)) { 759 } else if (this.hasFeature(remoting.ClientPlugin.Feature.PAUSE_VIDEO)) {
658 this.plugin_.postMessage(JSON.stringify( 760 this.plugin_.postMessage(JSON.stringify(
659 { method: 'pauseVideo', data: { pause: pause }})); 761 { method: 'pauseVideo', data: { pause: pause }}));
660 } 762 }
661 }; 763 };
662 764
663 /** 765 /**
664 * Requests that the host pause or resume sending audio updates. 766 * Requests that the host pause or resume sending audio updates.
665 * 767 *
666 * @param {boolean} pause True to suspend audio updates, false otherwise. 768 * @param {boolean} pause True to suspend audio updates, false otherwise.
667 */ 769 */
668 remoting.ClientPlugin.prototype.pauseAudio = 770 remoting.ClientPluginImpl.prototype.pauseAudio =
669 function(pause) { 771 function(pause) {
670 if (!this.hasFeature(remoting.ClientPlugin.Feature.PAUSE_AUDIO)) { 772 if (!this.hasFeature(remoting.ClientPlugin.Feature.PAUSE_AUDIO)) {
671 return; 773 return;
672 } 774 }
673 this.plugin_.postMessage(JSON.stringify( 775 this.plugin_.postMessage(JSON.stringify(
674 { method: 'pauseAudio', data: { pause: pause }})); 776 { method: 'pauseAudio', data: { pause: pause }}));
675 }; 777 };
676 778
677 /** 779 /**
678 * Requests that the host configure the video codec for lossless encode. 780 * Requests that the host configure the video codec for lossless encode.
679 * 781 *
680 * @param {boolean} wantLossless True to request lossless encoding. 782 * @param {boolean} wantLossless True to request lossless encoding.
681 */ 783 */
682 remoting.ClientPlugin.prototype.setLosslessEncode = 784 remoting.ClientPluginImpl.prototype.setLosslessEncode =
683 function(wantLossless) { 785 function(wantLossless) {
684 if (!this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) { 786 if (!this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) {
685 return; 787 return;
686 } 788 }
687 this.plugin_.postMessage(JSON.stringify( 789 this.plugin_.postMessage(JSON.stringify(
688 { method: 'videoControl', data: { losslessEncode: wantLossless }})); 790 { method: 'videoControl', data: { losslessEncode: wantLossless }}));
689 }; 791 };
690 792
691 /** 793 /**
692 * Requests that the host configure the video codec for lossless color. 794 * Requests that the host configure the video codec for lossless color.
693 * 795 *
694 * @param {boolean} wantLossless True to request lossless color. 796 * @param {boolean} wantLossless True to request lossless color.
695 */ 797 */
696 remoting.ClientPlugin.prototype.setLosslessColor = 798 remoting.ClientPluginImpl.prototype.setLosslessColor =
697 function(wantLossless) { 799 function(wantLossless) {
698 if (!this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) { 800 if (!this.hasFeature(remoting.ClientPlugin.Feature.VIDEO_CONTROL)) {
699 return; 801 return;
700 } 802 }
701 this.plugin_.postMessage(JSON.stringify( 803 this.plugin_.postMessage(JSON.stringify(
702 { method: 'videoControl', data: { losslessColor: wantLossless }})); 804 { method: 'videoControl', data: { losslessColor: wantLossless }}));
703 }; 805 };
704 806
705 /** 807 /**
706 * Called when a PIN is obtained from the user. 808 * Called when a PIN is obtained from the user.
707 * 809 *
708 * @param {string} pin The PIN. 810 * @param {string} pin The PIN.
709 */ 811 */
710 remoting.ClientPlugin.prototype.onPinFetched = 812 remoting.ClientPluginImpl.prototype.onPinFetched =
711 function(pin) { 813 function(pin) {
712 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { 814 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) {
713 return; 815 return;
714 } 816 }
715 this.plugin_.postMessage(JSON.stringify( 817 this.plugin_.postMessage(JSON.stringify(
716 { method: 'onPinFetched', data: { pin: pin }})); 818 { method: 'onPinFetched', data: { pin: pin }}));
717 }; 819 };
718 820
719 /** 821 /**
720 * Tells the plugin to ask for the PIN asynchronously. 822 * Tells the plugin to ask for the PIN asynchronously.
721 */ 823 */
722 remoting.ClientPlugin.prototype.useAsyncPinDialog = 824 remoting.ClientPluginImpl.prototype.useAsyncPinDialog =
723 function() { 825 function() {
724 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) { 826 if (!this.hasFeature(remoting.ClientPlugin.Feature.ASYNC_PIN)) {
725 return; 827 return;
726 } 828 }
727 this.plugin_.postMessage(JSON.stringify( 829 this.plugin_.postMessage(JSON.stringify(
728 { method: 'useAsyncPinDialog', data: {} })); 830 { method: 'useAsyncPinDialog', data: {} }));
729 }; 831 };
730 832
731 /** 833 /**
732 * Sets the third party authentication token and shared secret. 834 * Sets the third party authentication token and shared secret.
733 * 835 *
734 * @param {string} token The token received from the token URL. 836 * @param {string} token The token received from the token URL.
735 * @param {string} sharedSecret Shared secret received from the token URL. 837 * @param {string} sharedSecret Shared secret received from the token URL.
736 */ 838 */
737 remoting.ClientPlugin.prototype.onThirdPartyTokenFetched = function( 839 remoting.ClientPluginImpl.prototype.onThirdPartyTokenFetched = function(
738 token, sharedSecret) { 840 token, sharedSecret) {
739 this.plugin_.postMessage(JSON.stringify( 841 this.plugin_.postMessage(JSON.stringify(
740 { method: 'onThirdPartyTokenFetched', 842 { method: 'onThirdPartyTokenFetched',
741 data: { token: token, sharedSecret: sharedSecret}})); 843 data: { token: token, sharedSecret: sharedSecret}}));
742 }; 844 };
743 845
744 /** 846 /**
745 * Request pairing with the host for PIN-less authentication. 847 * Request pairing with the host for PIN-less authentication.
746 * 848 *
747 * @param {string} clientName The human-readable name of the client. 849 * @param {string} clientName The human-readable name of the client.
748 * @param {function(string, string):void} onDone, Callback to receive the 850 * @param {function(string, string):void} onDone, Callback to receive the
749 * client id and shared secret when they are available. 851 * client id and shared secret when they are available.
750 */ 852 */
751 remoting.ClientPlugin.prototype.requestPairing = 853 remoting.ClientPluginImpl.prototype.requestPairing =
752 function(clientName, onDone) { 854 function(clientName, onDone) {
753 if (!this.hasFeature(remoting.ClientPlugin.Feature.PINLESS_AUTH)) { 855 if (!this.hasFeature(remoting.ClientPlugin.Feature.PINLESS_AUTH)) {
754 return; 856 return;
755 } 857 }
756 this.onPairingComplete_ = onDone; 858 this.onPairingComplete_ = onDone;
757 this.plugin_.postMessage(JSON.stringify( 859 this.plugin_.postMessage(JSON.stringify(
758 { method: 'requestPairing', data: { clientName: clientName } })); 860 { method: 'requestPairing', data: { clientName: clientName } }));
759 }; 861 };
760 862
761 /** 863 /**
762 * Send an extension message to the host. 864 * Send an extension message to the host.
763 * 865 *
764 * @param {string} type The message type. 866 * @param {string} type The message type.
765 * @param {string} message The message payload. 867 * @param {string} message The message payload.
766 */ 868 */
767 remoting.ClientPlugin.prototype.sendClientMessage = 869 remoting.ClientPluginImpl.prototype.sendClientMessage =
768 function(type, message) { 870 function(type, message) {
769 if (!this.hasFeature(remoting.ClientPlugin.Feature.EXTENSION_MESSAGE)) { 871 if (!this.hasFeature(remoting.ClientPlugin.Feature.EXTENSION_MESSAGE)) {
770 return; 872 return;
771 } 873 }
772 this.plugin_.postMessage(JSON.stringify( 874 this.plugin_.postMessage(JSON.stringify(
773 { method: 'extensionMessage', 875 { method: 'extensionMessage',
774 data: { type: type, data: message } })); 876 data: { type: type, data: message } }));
775 877
776 }; 878 };
777 879
778 /** 880 /**
779 * Request MediaStream-based rendering. 881 * Request MediaStream-based rendering.
780 * 882 *
781 * @param {remoting.MediaSourceRenderer} mediaSourceRenderer 883 * @param {remoting.MediaSourceRenderer} mediaSourceRenderer
782 */ 884 */
783 remoting.ClientPlugin.prototype.enableMediaSourceRendering = 885 remoting.ClientPluginImpl.prototype.enableMediaSourceRendering =
784 function(mediaSourceRenderer) { 886 function(mediaSourceRenderer) {
785 if (!this.hasFeature(remoting.ClientPlugin.Feature.MEDIA_SOURCE_RENDERING)) { 887 if (!this.hasFeature(remoting.ClientPlugin.Feature.MEDIA_SOURCE_RENDERING)) {
786 return; 888 return;
787 } 889 }
788 this.mediaSourceRenderer_ = mediaSourceRenderer; 890 this.mediaSourceRenderer_ = mediaSourceRenderer;
789 this.plugin_.postMessage(JSON.stringify( 891 this.plugin_.postMessage(JSON.stringify(
790 { method: 'enableMediaSourceRendering', data: {} })); 892 { method: 'enableMediaSourceRendering', data: {} }));
791 }; 893 };
792 894
895 remoting.ClientPluginImpl.prototype.getDesktopWidth = function() {
896 return this.desktopWidth_;
897 }
898
899 remoting.ClientPluginImpl.prototype.getDesktopHeight = function() {
900 return this.desktopHeight_;
901 }
902
903 remoting.ClientPluginImpl.prototype.getDesktopXDpi = function() {
904 return this.desktopXDpi_;
905 }
906
907 remoting.ClientPluginImpl.prototype.getDesktopYDpi = function() {
908 return this.desktopYDpi_;
909 }
910
793 /** 911 /**
794 * If we haven't yet received a "hello" message from the plugin, change its 912 * If we haven't yet received a "hello" message from the plugin, change its
795 * size so that the user can confirm it if click-to-play is enabled, or can 913 * size so that the user can confirm it if click-to-play is enabled, or can
796 * see the "this plugin is disabled" message if it is actually disabled. 914 * see the "this plugin is disabled" message if it is actually disabled.
797 * @private 915 * @private
798 */ 916 */
799 remoting.ClientPlugin.prototype.showPluginForClickToPlay_ = function() { 917 remoting.ClientPluginImpl.prototype.showPluginForClickToPlay_ = function() {
800 if (!this.helloReceived_) { 918 if (!this.helloReceived_) {
801 var width = 200; 919 var width = 200;
802 var height = 200; 920 var height = 200;
803 this.plugin_.style.width = width + 'px'; 921 this.plugin_.style.width = width + 'px';
804 this.plugin_.style.height = height + 'px'; 922 this.plugin_.style.height = height + 'px';
805 // Center the plugin just underneath the "Connnecting..." dialog. 923 // Center the plugin just underneath the "Connnecting..." dialog.
806 var dialog = document.getElementById('client-dialog'); 924 var dialog = document.getElementById('client-dialog');
807 var dialogRect = dialog.getBoundingClientRect(); 925 var dialogRect = dialog.getBoundingClientRect();
808 this.plugin_.style.top = (dialogRect.bottom + 16) + 'px'; 926 this.plugin_.style.top = (dialogRect.bottom + 16) + 'px';
809 this.plugin_.style.left = (window.innerWidth - width) / 2 + 'px'; 927 this.plugin_.style.left = (window.innerWidth - width) / 2 + 'px';
810 this.plugin_.style.position = 'fixed'; 928 this.plugin_.style.position = 'fixed';
811 } 929 }
812 }; 930 };
813 931
814 /** 932 /**
815 * Undo the CSS rules needed to make the plugin clickable for click-to-play. 933 * Undo the CSS rules needed to make the plugin clickable for click-to-play.
816 * @private 934 * @private
817 */ 935 */
818 remoting.ClientPlugin.prototype.hidePluginForClickToPlay_ = function() { 936 remoting.ClientPluginImpl.prototype.hidePluginForClickToPlay_ = function() {
819 this.plugin_.style.width = ''; 937 this.plugin_.style.width = '';
820 this.plugin_.style.height = ''; 938 this.plugin_.style.height = '';
821 this.plugin_.style.top = ''; 939 this.plugin_.style.top = '';
822 this.plugin_.style.left = ''; 940 this.plugin_.style.left = '';
823 this.plugin_.style.position = ''; 941 this.plugin_.style.position = '';
824 }; 942 };
943
944
945 /**
946 * @constructor
947 * @implements {remoting.ClientPluginFactory}
948 */
949 remoting.DefaultClientPluginFactory = function() {};
950
951 /**
952 * @param {Element} container
953 * @param {function(string, string):boolean} onExtensionMessage
954 * @return {remoting.ClientPlugin}
955 */
956 remoting.DefaultClientPluginFactory.prototype.createPlugin =
957 function(container, onExtensionMessage) {
958 return new remoting.ClientPluginImpl(container, onExtensionMessage);
959 };
960
961 remoting.DefaultClientPluginFactory.prototype.preloadPlugin = function() {
962 if (remoting.settings.CLIENT_PLUGIN_TYPE != 'pnacl') {
963 return;
964 }
965
966 var plugin = remoting.ClientPluginImpl.createPluginElement_();
967 plugin.addEventListener(
968 'loadend', function() { document.body.removeChild(plugin); }, false);
969 document.body.appendChild(plugin);
970 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698