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

Side by Side Diff: remoting/webapp/crd/js/desktop_connected_view.js

Issue 1001503006: [Webapp Refactor] remoting.ConnectedView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 handling user-facing aspects of the client session. 7 * Class handling user-facing aspects of the client session.
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 * True to enable mouse lock.
17 * This is currently disabled because the current client plugin does not
18 * properly handle mouse lock and delegated large cursors at the same time.
19 * This should be re-enabled (by removing this flag) once a version of
20 * the plugin that supports both has reached Chrome Stable channel.
21 * (crbug.com/429322).
22 *
23 * @type {boolean}
24 */
25 remoting.enableMouseLock = false;
26
27 /**
28 * @param {remoting.ClientPlugin} plugin 16 * @param {remoting.ClientPlugin} plugin
29 * @param {remoting.ClientSession} session
30 * @param {HTMLElement} container 17 * @param {HTMLElement} container
31 * @param {remoting.Host} host 18 * @param {remoting.Host} host
32 * @param {remoting.DesktopConnectedView.Mode} mode The mode of this connection. 19 * @param {remoting.DesktopConnectedView.Mode} mode The mode of this connection.
33 * @param {string} defaultRemapKeys The default set of remap keys, to use 20 * @param {string} defaultRemapKeys The default set of remap keys, to use
34 * when the client doesn't define any. 21 * when the client doesn't define any.
35 * @constructor 22 * @constructor
36 * @extends {base.EventSourceImpl} 23 * @extends {base.EventSourceImpl}
24 * @implements {base.Disposable}
37 */ 25 */
38 remoting.DesktopConnectedView = function(plugin, session, container, host, mode, 26 remoting.DesktopConnectedView = function(plugin, container, host, mode,
39 defaultRemapKeys) { 27 defaultRemapKeys) {
40 this.session_ = session;
41 28
42 /** @private {HTMLElement} */ 29 /** @private {HTMLElement} */
43 this.container_ = container; 30 this.container_ = container;
44 31
45 /** @private {remoting.ClientPlugin} */ 32 /** @private {remoting.ClientPlugin} */
46 this.plugin_ = plugin; 33 this.plugin_ = plugin;
47 34
48 /** @private */ 35 /** @private */
49 this.host_ = host; 36 this.host_ = host;
50 37
51 /** @private */ 38 /** @private */
52 this.mode_ = mode; 39 this.mode_ = mode;
53 40
54 /** @private {string} */ 41 /** @private {string} */
55 this.defaultRemapKeys_ = defaultRemapKeys; 42 this.defaultRemapKeys_ = defaultRemapKeys;
56 43
57 /** @private */
58 this.callPluginLostFocus_ = this.pluginLostFocus_.bind(this);
59 /** @private */
60 this.callPluginGotFocus_ = this.pluginGotFocus_.bind(this);
61 /** @private {Element} */ 44 /** @private {Element} */
62 this.debugRegionContainer_ = 45 this.debugRegionContainer_ =
63 this.container_.querySelector('.debug-region-container'); 46 this.container_.querySelector('.debug-region-container');
64 47
65 /** @private {Element} */
66 this.mouseCursorOverlay_ =
67 this.container_.querySelector('.mouse-cursor-overlay');
68
69 /** @private {remoting.DesktopViewport} */ 48 /** @private {remoting.DesktopViewport} */
70 this.viewport_ = null; 49 this.viewport_ = null;
71 50
72 /** @type {Element} */ 51 /** private {remoting.ConnectedView} */
73 var img = this.mouseCursorOverlay_; 52 this.view_ = null;
74 /**
75 * @param {Event} event
76 * @private
77 */
78 this.updateMouseCursorPosition_ = function(event) {
79 img.style.top = event.offsetY + 'px';
80 img.style.left = event.offsetX + 'px';
81 };
82 53
83 /** @private {remoting.VideoFrameRecorder} */ 54 /** @private {remoting.VideoFrameRecorder} */
84 this.videoFrameRecorder_ = null; 55 this.videoFrameRecorder_ = null;
85 56
86 /** private {base.Disposable} */ 57 /** private {base.Disposable} */
87 this.eventHooks_ = null; 58 this.eventHooks_ = null;
88 59
89 this.setupPlugin_(); 60 this.setupPlugin_();
90 }; 61 };
91 62
63 /** @return {void} Nothing. */
64 remoting.DesktopConnectedView.prototype.dispose = function() {
65 if (remoting.windowFrame) {
66 remoting.windowFrame.setDesktopConnectedView(null);
67 }
68 if (remoting.toolbar) {
69 remoting.toolbar.setDesktopConnectedView(null);
70 }
71 if (remoting.optionsMenu) {
72 remoting.optionsMenu.setDesktopConnectedView(null);
73 }
74
75 document.body.classList.remove('connected');
76
77 base.dispose(this.eventHooks_);
78 this.eventHooks_ = null;
79
80 base.dispose(this.viewport_);
81 this.viewport_ = null;
82 };
83
92 // The mode of this session. 84 // The mode of this session.
93 /** @enum {number} */ 85 /** @enum {number} */
94 remoting.DesktopConnectedView.Mode = { 86 remoting.DesktopConnectedView.Mode = {
95 IT2ME: 0, 87 IT2ME: 0,
96 ME2ME: 1, 88 ME2ME: 1,
97 APP_REMOTING: 2 89 APP_REMOTING: 2
98 }; 90 };
99 91
100 // Keys for per-host settings. 92 // Keys for per-host settings.
101 remoting.DesktopConnectedView.KEY_REMAP_KEYS = 'remapKeys'; 93 remoting.DesktopConnectedView.KEY_REMAP_KEYS = 'remapKeys';
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 } else if (this.mode_ != remoting.DesktopConnectedView.Mode.ME2ME && 155 } else if (this.mode_ != remoting.DesktopConnectedView.Mode.ME2ME &&
164 this.mode_ != remoting.DesktopConnectedView.Mode.APP_REMOTING) { 156 this.mode_ != remoting.DesktopConnectedView.Mode.APP_REMOTING) {
165 var sendCadElement = document.getElementById('send-ctrl-alt-del'); 157 var sendCadElement = document.getElementById('send-ctrl-alt-del');
166 sendCadElement.hidden = true; 158 sendCadElement.hidden = true;
167 } 159 }
168 160
169 // Apply customized key remappings if the plugin supports remapKeys. 161 // Apply customized key remappings if the plugin supports remapKeys.
170 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.REMAP_KEY)) { 162 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.REMAP_KEY)) {
171 this.applyRemapKeys_(true); 163 this.applyRemapKeys_(true);
172 } 164 }
173
174 // TODO(wez): Only allow mouse lock if the app has the pointerLock permission.
175 // Enable automatic mouse-lock.
176 if (remoting.enableMouseLock &&
177 this.plugin_.hasFeature(remoting.ClientPlugin.Feature.ALLOW_MOUSE_LOCK)) {
178 this.plugin_.allowMouseLock();
179 }
180
181 this.plugin_.setMouseCursorHandler(this.updateMouseCursorImage_.bind(this));
182 }; 165 };
183 166
184 /** 167 /**
185 * This is a callback that gets called when the window is resized. 168 * This is a callback that gets called when the window is resized.
186 * 169 *
187 * @return {void} Nothing. 170 * @return {void} Nothing.
188 * @private. 171 * @private.
189 */ 172 */
190 remoting.DesktopConnectedView.prototype.onResize_ = function() { 173 remoting.DesktopConnectedView.prototype.onResize_ = function() {
191 if (this.viewport_) { 174 if (this.viewport_) {
192 this.viewport_.onResize(); 175 this.viewport_.onResize();
193 } 176 }
194 }; 177 };
195 178
196 /** 179 /**
197 * Called when the app window is hidden.
198 * @return {void} Nothing.
199 */
200 remoting.DesktopConnectedView.prototype.onVisibilityChanged_ = function() {
201 this.pauseVideo(document.hidden);
202 };
203
204 /**
205 * Callback that the plugin invokes to indicate when the connection is 180 * Callback that the plugin invokes to indicate when the connection is
206 * ready. 181 * ready.
207 * 182 *
208 * @param {boolean} ready True if the connection is ready. 183 * @param {boolean} ready True if the connection is ready.
209 */ 184 */
210 remoting.DesktopConnectedView.prototype.onConnectionReady = function(ready) { 185 remoting.DesktopConnectedView.prototype.onConnectionReady = function(ready) {
211 if (!ready) { 186 if (this.view_) {
212 this.container_.classList.add('session-client-inactive'); 187 this.view_.onConnectionReady(ready);
213 } else {
214 this.container_.classList.remove('session-client-inactive');
215 } 188 }
216 }; 189 };
217 190
218 /** 191 remoting.DesktopConnectedView.prototype.onConnected = function() {
219 * Deletes the <embed> element from the container, without sending a 192 document.body.classList.add('connected');
220 * session_terminate request. This is to be called when the session was 193
221 * disconnected by the Host. 194 this.view_ = new remoting.ConnectedView(
222 * 195 this.plugin_, this.container_,
223 * @return {void} Nothing. 196 this.container_.querySelector('.mouse-cursor-overlay'));
224 */ 197
225 remoting.DesktopConnectedView.prototype.removePlugin = function() { 198 var scrollerElement = document.getElementById('scroller');
226 if (this.plugin_) { 199 this.viewport_ = new remoting.DesktopViewport(
227 this.plugin_.element().removeEventListener( 200 scrollerElement || document.body,
228 'focus', this.callPluginGotFocus_, false); 201 this.plugin_.hostDesktop(),
229 this.plugin_.element().removeEventListener( 202 this.host_.options);
230 'blur', this.callPluginLostFocus_, false); 203
231 this.plugin_ = null; 204 if (remoting.windowFrame) {
205 remoting.windowFrame.setDesktopConnectedView(this);
206 }
207 if (remoting.toolbar) {
208 remoting.toolbar.setDesktopConnectedView(this);
209 }
210 if (remoting.optionsMenu) {
211 remoting.optionsMenu.setDesktopConnectedView(this);
232 } 212 }
233 213
234 this.updateClientSessionUi_(null); 214 // Activate full-screen related UX.
215 this.eventHooks_ = new base.Disposables(
216 this.view_,
217 new base.DomEventHook(window, 'resize', this.onResize_.bind(this), false),
218 new remoting.Fullscreen.EventHook(this.onFullScreenChanged_.bind(this))
219 );
220 this.onFullScreenChanged_(remoting.fullscreen.isActive());
235 }; 221 };
236 222
237 /** 223 /**
238 * @param {remoting.ClientSession} clientSession The active session, or null if
239 * there is no connection.
240 */
241 remoting.DesktopConnectedView.prototype.updateClientSessionUi_ = function(
242 clientSession) {
243 if (clientSession === null) {
244 if (remoting.windowFrame) {
245 remoting.windowFrame.setDesktopConnectedView(null);
246 }
247 if (remoting.toolbar) {
248 remoting.toolbar.setDesktopConnectedView(null);
249 }
250 if (remoting.optionsMenu) {
251 remoting.optionsMenu.setDesktopConnectedView(null);
252 }
253
254 document.body.classList.remove('connected');
255 this.container_.removeEventListener(
256 'mousemove', this.updateMouseCursorPosition_, true);
257 base.dispose(this.eventHooks_);
258 this.eventHooks_ = null;
259 base.dispose(this.viewport_);
260 this.viewport_ = null;
261 } else {
262 var scrollerElement = document.getElementById('scroller');
263 this.viewport_ = new remoting.DesktopViewport(
264 scrollerElement || document.body,
265 this.plugin_.hostDesktop(),
266 this.host_.options);
267 if (remoting.windowFrame) {
268 remoting.windowFrame.setDesktopConnectedView(this);
269 }
270 if (remoting.toolbar) {
271 remoting.toolbar.setDesktopConnectedView(this);
272 }
273 if (remoting.optionsMenu) {
274 remoting.optionsMenu.setDesktopConnectedView(this);
275 }
276
277 document.body.classList.add('connected');
278 this.container_.addEventListener(
279 'mousemove', this.updateMouseCursorPosition_, true);
280 // Activate full-screen related UX.
281 this.setFocusHandlers_();
282 this.eventHooks_ = new base.Disposables(
283 new base.DomEventHook(window, 'resize', this.onResize_.bind(this), false),
284 new base.DomEventHook(document, 'visibilitychange',
285 this.onVisibilityChanged_.bind(this), false),
286 new remoting.Fullscreen.EventHook(this.onFullScreenChanged_.bind(this))
287 );
288 this.onFullScreenChanged_(remoting.fullscreen.isActive());
289 }
290 };
291
292 /**
293 * Constrains the focus to the plugin element.
294 * @private
295 */
296 remoting.DesktopConnectedView.prototype.setFocusHandlers_ = function() {
297 this.plugin_.element().addEventListener(
298 'focus', this.callPluginGotFocus_, false);
299 this.plugin_.element().addEventListener(
300 'blur', this.callPluginLostFocus_, false);
301 this.plugin_.element().focus();
302 };
303
304 /**
305 * Set the shrink-to-fit and resize-to-client flags and save them if this is 224 * Set the shrink-to-fit and resize-to-client flags and save them if this is
306 * a Me2Me connection. 225 * a Me2Me connection.
307 * 226 *
308 * @param {boolean} shrinkToFit True if the remote desktop should be scaled 227 * @param {boolean} shrinkToFit True if the remote desktop should be scaled
309 * down if it is larger than the client window; false if scroll-bars 228 * down if it is larger than the client window; false if scroll-bars
310 * should be added in this case. 229 * should be added in this case.
311 * @param {boolean} resizeToClient True if window resizes should cause the 230 * @param {boolean} resizeToClient True if window resizes should cause the
312 * host to attempt to resize its desktop to match the client window size; 231 * host to attempt to resize its desktop to match the client window size;
313 * false to disable this behaviour for subsequent window resizes--the 232 * false to disable this behaviour for subsequent window resizes--the
314 * current host desktop size is not restored in this case. 233 * current host desktop size is not restored in this case.
(...skipping 19 matching lines...) Expand all
334 // Fullscreen.isActive call is not guaranteed to return true until the 253 // Fullscreen.isActive call is not guaranteed to return true until the
335 // full-screen event is triggered. In apps v2, the size of the window's 254 // full-screen event is triggered. In apps v2, the size of the window's
336 // client area is calculated differently in full-screen mode, so register 255 // client area is calculated differently in full-screen mode, so register
337 // for both events. 256 // for both events.
338 this.viewport_.onResize(); 257 this.viewport_.onResize();
339 this.viewport_.enableBumpScroll(Boolean(fullscreen)); 258 this.viewport_.enableBumpScroll(Boolean(fullscreen));
340 } 259 }
341 }; 260 };
342 261
343 /** 262 /**
344 * Callback function called when the plugin element gets focus.
345 */
346 remoting.DesktopConnectedView.prototype.pluginGotFocus_ = function() {
347 remoting.clipboard.initiateToHost();
348 };
349
350 /**
351 * Callback function called when the plugin element loses focus.
352 */
353 remoting.DesktopConnectedView.prototype.pluginLostFocus_ = function() {
354 if (this.plugin_) {
355 // Release all keys to prevent them becoming 'stuck down' on the host.
356 this.plugin_.releaseAllKeys();
357 if (this.plugin_.element()) {
358 // Focus should stay on the element, not (for example) the toolbar.
359 // Due to crbug.com/246335, we can't restore the focus immediately,
360 // otherwise the plugin gets confused about whether or not it has focus.
361 window.setTimeout(
362 this.plugin_.element().focus.bind(this.plugin_.element()), 0);
363 }
364 }
365 };
366
367 /**
368 * @param {string} url
369 * @param {number} hotspotX
370 * @param {number} hotspotY
371 */
372 remoting.DesktopConnectedView.prototype.updateMouseCursorImage_ =
373 function(url, hotspotX, hotspotY) {
374 this.mouseCursorOverlay_.hidden = !url;
375 if (url) {
376 this.mouseCursorOverlay_.style.marginLeft = '-' + hotspotX + 'px';
377 this.mouseCursorOverlay_.style.marginTop = '-' + hotspotY + 'px';
378 this.mouseCursorOverlay_.src = url;
379 }
380 };
381
382 /**
383 * Sets and stores the key remapping setting for the current host. 263 * Sets and stores the key remapping setting for the current host.
384 * 264 *
385 * @param {string} remappings Comma separated list of key remappings. 265 * @param {string} remappings Comma separated list of key remappings.
386 */ 266 */
387 remoting.DesktopConnectedView.prototype.setRemapKeys = function(remappings) { 267 remoting.DesktopConnectedView.prototype.setRemapKeys = function(remappings) {
388 // Cancel any existing remappings and apply the new ones. 268 // Cancel any existing remappings and apply the new ones.
389 this.applyRemapKeys_(false); 269 this.applyRemapKeys_(false);
390 this.host_.options.remapKeys = remappings; 270 this.host_.options.remapKeys = remappings;
391 this.applyRemapKeys_(true); 271 this.applyRemapKeys_(true);
392 272
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 /** 342 /**
463 * Sends a Print Screen keypress to the remoting client. 343 * Sends a Print Screen keypress to the remoting client.
464 * 344 *
465 * @return {void} Nothing. 345 * @return {void} Nothing.
466 */ 346 */
467 remoting.DesktopConnectedView.prototype.sendPrintScreen = function() { 347 remoting.DesktopConnectedView.prototype.sendPrintScreen = function() {
468 console.log('Sending Print Screen.'); 348 console.log('Sending Print Screen.');
469 this.sendKeyCombination_([0x070046]); 349 this.sendKeyCombination_([0x070046]);
470 }; 350 };
471 351
472 /**
473 * Requests that the host pause or resume video updates.
474 *
475 * @param {boolean} pause True to pause video, false to resume.
476 * @return {void} Nothing.
477 */
478 remoting.DesktopConnectedView.prototype.pauseVideo = function(pause) {
479 if (this.plugin_) {
480 this.plugin_.pauseVideo(pause);
481 }
482 };
483
484 /**
485 * Requests that the host pause or resume audio.
486 *
487 * @param {boolean} pause True to pause audio, false to resume.
488 * @return {void} Nothing.
489 */
490 remoting.DesktopConnectedView.prototype.pauseAudio = function(pause) {
491 if (this.plugin_) {
492 this.plugin_.pauseAudio(pause)
493 }
494 };
495
496 remoting.DesktopConnectedView.prototype.initVideoFrameRecorder = function() { 352 remoting.DesktopConnectedView.prototype.initVideoFrameRecorder = function() {
497 this.videoFrameRecorder_ = new remoting.VideoFrameRecorder(this.plugin_); 353 this.videoFrameRecorder_ = new remoting.VideoFrameRecorder(this.plugin_);
498 }; 354 };
499 355
500 /** 356 /**
501 * Returns true if the ClientSession can record video frames to a file. 357 * Returns true if the ClientSession can record video frames to a file.
502 * @return {boolean} 358 * @return {boolean}
503 */ 359 */
504 remoting.DesktopConnectedView.prototype.canRecordVideo = function() { 360 remoting.DesktopConnectedView.prototype.canRecordVideo = function() {
505 return !!this.videoFrameRecorder_; 361 return !!this.videoFrameRecorder_;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 var rect = document.createElement('div'); 412 var rect = document.createElement('div');
557 rect.classList.add('debug-region-rect'); 413 rect.classList.add('debug-region-rect');
558 rect.style.left = rects[i][0] + 'px'; 414 rect.style.left = rects[i][0] + 'px';
559 rect.style.top = rects[i][1] +'px'; 415 rect.style.top = rects[i][1] +'px';
560 rect.style.width = rects[i][2] +'px'; 416 rect.style.width = rects[i][2] +'px';
561 rect.style.height = rects[i][3] + 'px'; 417 rect.style.height = rects[i][3] + 'px';
562 this.debugRegionContainer_.appendChild(rect); 418 this.debugRegionContainer_.appendChild(rect);
563 } 419 }
564 } 420 }
565 }; 421 };
OLDNEW
« no previous file with comments | « remoting/webapp/crd/js/connected_view.js ('k') | remoting/webapp/crd/js/session_connector_impl.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698