Roll src/third_party/WebKit 3529d49:06e8485 (svn 202554:202555)
[chromium-blink-merge.git] / remoting / webapp / crd / js / desktop_connected_view.js
blob1f528d36909c8a7c9ad8140dfe45d9fbcf3baf47
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
3 // found in the LICENSE file.
5 /**
6  * @fileoverview
7  * Class handling user-facing aspects of the client session.
8  */
10 'use strict';
12 /** @suppress {duplicate} */
13 var remoting = remoting || {};
15 /**
16  * @param {HTMLElement} container
17  * @param {remoting.ConnectionInfo} connectionInfo
18  * @constructor
19  * @extends {base.EventSourceImpl}
20  * @implements {base.Disposable}
21  */
22 remoting.DesktopConnectedView = function(container, connectionInfo) {
24   /** @private {HTMLElement} */
25   this.container_ = container;
27   /** @private {remoting.ClientPlugin} */
28   this.plugin_ = connectionInfo.plugin();
30   /** @private {remoting.ClientSession} */
31   this.session_ = connectionInfo.session();
33   /** @private */
34   this.host_ = connectionInfo.host();
36   /** @private {remoting.DesktopViewport} */
37   this.viewport_ = null;
39   /** @private {remoting.ConnectedView} */
40   this.view_ = null;
42   /** @private {remoting.VideoFrameRecorder} */
43   this.videoFrameRecorder_ = null;
45   /** @private {base.Disposable} */
46   this.eventHooks_ = null;
48   /** @private */
49   this.stats_ = new remoting.ConnectionStats(
50       document.getElementById('statistics'), connectionInfo.plugin());
52   this.initPlugin_();
53   this.initUI_();
56 /** @return {void} Nothing. */
57 remoting.DesktopConnectedView.prototype.dispose = function() {
58   if (remoting.windowFrame) {
59     remoting.windowFrame.setDesktopConnectedView(null);
60   }
61   if (remoting.toolbar) {
62     remoting.toolbar.setDesktopConnectedView(null);
63   }
64   if (remoting.optionsMenu) {
65     remoting.optionsMenu.setDesktopConnectedView(null);
66   }
68   document.body.classList.remove('connected');
70   base.dispose(this.eventHooks_);
71   this.eventHooks_ = null;
73   base.dispose(this.viewport_);
74   this.viewport_ = null;
76   base.dispose(this.stats_);
77   this.stats = null;
80 /**
81  * Get host display name.
82  *
83  * @return {string}
84  */
85 remoting.DesktopConnectedView.prototype.getHostDisplayName = function() {
86   return this.host_.hostName;
89 /**
90  * @return {boolean} True if shrink-to-fit is enabled; false otherwise.
91  */
92 remoting.DesktopConnectedView.prototype.getShrinkToFit = function() {
93   if (this.viewport_) {
94     return this.viewport_.getShrinkToFit();
95   }
96   return false;
99 /**
100  * @return {boolean} True if resize-to-client is enabled; false otherwise.
101  */
102 remoting.DesktopConnectedView.prototype.getResizeToClient = function() {
103   if (this.viewport_) {
104     return this.viewport_.getResizeToClient();
105   }
106   return false;
110  * @return {boolean} True if the right-hand Ctrl key is mapped to the Meta
111  *     (Windows, Command) key.
112  */
113 remoting.DesktopConnectedView.prototype.getMapRightCtrl = function() {
114   return this.host_.options.remapKeys[0x0700e4] === 0x0700e7;
117 remoting.DesktopConnectedView.prototype.toggleStats = function() {
118   this.stats_.toggle();
122  * @return {boolean} True if the connection stats is visible; false otherwise.
123  */
124 remoting.DesktopConnectedView.prototype.isStatsVisible = function() {
125   return this.stats_.isVisible();
129  * @return {Element} The element that should host the plugin.
130  * @private
131  */
132 remoting.DesktopConnectedView.prototype.getPluginContainer_ = function() {
133   return this.container_.querySelector('.client-plugin-container');
136 /** @return {remoting.DesktopViewport} */
137 remoting.DesktopConnectedView.prototype.getViewportForTesting = function() {
138   return this.viewport_;
141 /** @return {remoting.ConnectedView} */
142 remoting.DesktopConnectedView.prototype.getConnectedViewForTesting =
143     function() {
144   return this.view_;
147 /** @private */
148 remoting.DesktopConnectedView.prototype.initPlugin_ = function() {
149   console.assert(remoting.app instanceof remoting.DesktopRemoting,
150                 '|remoting.app| is not an instance of DesktopRemoting.');
151   var drApp = /** @type {remoting.DesktopRemoting} */ (remoting.app);
152   var mode = drApp.getConnectionMode();
154   // Show the Ctrl-Alt-Del button only in Me2Me mode.
155   if (mode == remoting.DesktopRemoting.Mode.IT2ME) {
156     var sendCadElement = document.getElementById('send-ctrl-alt-del');
157     sendCadElement.hidden = true;
158   }
162  * This is a callback that gets called when the window is resized.
164  * @return {void} Nothing.
165  * @private.
166  */
167 remoting.DesktopConnectedView.prototype.onResize_ = function() {
168   if (this.viewport_) {
169     this.viewport_.onResize();
170   }
173 /** @private */
174 remoting.DesktopConnectedView.prototype.initUI_ = function() {
175   document.body.classList.add('connected');
177   this.view_ = new remoting.ConnectedView(
178       this.plugin_, this.container_,
179       this.container_.querySelector('.mouse-cursor-overlay'));
181   var scrollerElement = document.getElementById('scroller');
182   this.viewport_ = new remoting.DesktopViewport(
183       scrollerElement || document.body,
184       this.plugin_.hostDesktop(),
185       this.host_.options);
187   if (remoting.windowFrame) {
188     remoting.windowFrame.setDesktopConnectedView(this);
189   }
190   if (remoting.toolbar) {
191     remoting.toolbar.setDesktopConnectedView(this);
192   }
193   if (remoting.optionsMenu) {
194     remoting.optionsMenu.setDesktopConnectedView(this);
195   }
197   // Activate full-screen related UX.
198   this.eventHooks_ = new base.Disposables(
199     this.view_,
200     new base.EventHook(this.session_,
201                        remoting.ClientSession.Events.videoChannelStateChanged,
202                        this.view_.onConnectionReady.bind(this.view_)),
203     new base.DomEventHook(window, 'resize', this.onResize_.bind(this), false),
204     new remoting.Fullscreen.EventHook(this.onFullScreenChanged_.bind(this)));
205   this.onFullScreenChanged_(remoting.fullscreen.isActive());
209  * Set the shrink-to-fit and resize-to-client flags and save them if this is
210  * a Me2Me connection.
212  * @param {boolean} shrinkToFit True if the remote desktop should be scaled
213  *     down if it is larger than the client window; false if scroll-bars
214  *     should be added in this case.
215  * @param {boolean} resizeToClient True if window resizes should cause the
216  *     host to attempt to resize its desktop to match the client window size;
217  *     false to disable this behaviour for subsequent window resizes--the
218  *     current host desktop size is not restored in this case.
219  * @return {void} Nothing.
220  */
221 remoting.DesktopConnectedView.prototype.setScreenMode =
222     function(shrinkToFit, resizeToClient) {
223   this.viewport_.setScreenMode(shrinkToFit, resizeToClient);
227  * Called when the full-screen status has changed, either via the
228  * remoting.Fullscreen class, or via a system event such as the Escape key
230  * @param {boolean=} fullscreen True if the app is entering full-screen mode;
231  *     false if it is leaving it.
232  * @private
233  */
234 remoting.DesktopConnectedView.prototype.onFullScreenChanged_ = function (
235     fullscreen) {
236   if (this.viewport_) {
237     // When a window goes full-screen, a resize event is triggered, but the
238     // Fullscreen.isActive call is not guaranteed to return true until the
239     // full-screen event is triggered. In apps v2, the size of the window's
240     // client area is calculated differently in full-screen mode, so register
241     // for both events.
242     this.viewport_.onResize();
243     this.viewport_.enableBumpScroll(Boolean(fullscreen));
244   }
248  * Set whether or not the right-hand Ctrl key should send the Meta (Windows,
249  * Command) key-code.
251  * @param {boolean} enable True to enable the mapping; false to disable.
252  */
253 remoting.DesktopConnectedView.prototype.setMapRightCtrl = function(enable) {
254   if (enable === this.getMapRightCtrl()) {
255     return;  // In case right Ctrl is mapped, but not to right Meta.
256   }
258   if (enable) {
259     this.host_.options.remapKeys[0x0700e4] = 0x0700e7;
260   } else {
261     delete this.host_.options.remapKeys[0x0700e4]
262   }
263   this.setRemapKeys(this.host_.options.remapKeys);
267  * Sends a Ctrl-Alt-Del sequence to the remoting client.
269  * @return {void} Nothing.
270  */
271 remoting.DesktopConnectedView.prototype.sendCtrlAltDel = function() {
272   console.log('Sending Ctrl-Alt-Del.');
273   this.plugin_.injectKeyCombination([0x0700e0, 0x0700e2, 0x07004c]);
277  * Sends a Print Screen keypress to the remoting client.
279  * @return {void} Nothing.
280  */
281 remoting.DesktopConnectedView.prototype.sendPrintScreen = function() {
282   console.log('Sending Print Screen.');
283   this.plugin_.injectKeyCombination([0x070046]);
287  * Sets and stores the key remapping setting for the current host. If set,
288  * these mappings override the defaults for the client platform.
290  * @param {!Object} remappings
291  */
292 remoting.DesktopConnectedView.prototype.setRemapKeys = function(remappings) {
293   this.plugin_.setRemapKeys(remappings);
294   // Save the new remapping setting.
295   this.host_.options.remapKeys =
296       /** @type {!Object} */ (base.deepCopy(remappings));
297   this.host_.options.save();
300 /** @param {remoting.VideoFrameRecorder} recorder */
301 remoting.DesktopConnectedView.prototype.setVideoFrameRecorder =
302     function(recorder) {
303   this.videoFrameRecorder_ = recorder;
307  * Returns true if the ClientSession can record video frames to a file.
308  * @return {boolean}
309  */
310 remoting.DesktopConnectedView.prototype.canRecordVideo = function() {
311   return !!this.videoFrameRecorder_;
315  * Returns true if the ClientSession is currently recording video frames.
316  * @return {boolean}
317  */
318 remoting.DesktopConnectedView.prototype.isRecordingVideo = function() {
319   if (!this.videoFrameRecorder_) {
320     return false;
321   }
322   return this.videoFrameRecorder_.isRecording();
326  * Starts or stops recording of video frames.
327  */
328 remoting.DesktopConnectedView.prototype.startStopRecording = function() {
329   if (this.videoFrameRecorder_) {
330     this.videoFrameRecorder_.startStopRecording();
331   }
335  * Factory function so that it can be overwritten in unit test to avoid
336  * UI dependencies.
338  * @param {HTMLElement} container
339  * @param {remoting.ConnectionInfo} connectionInfo
340  * @return  {remoting.DesktopConnectedView}
341  */
342 remoting.DesktopConnectedView.create = function(container, connectionInfo) {
343   return new remoting.DesktopConnectedView(container, connectionInfo);