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.
7 * Class handling user-facing aspects of the client session.
12 /** @suppress {duplicate} */
13 var remoting
= remoting
|| {};
16 * @param {HTMLElement} container
17 * @param {remoting.ConnectionInfo} connectionInfo
19 * @extends {base.EventSourceImpl}
20 * @implements {base.Disposable}
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();
34 this.host_
= connectionInfo
.host();
36 /** @private {remoting.DesktopViewport} */
37 this.viewport_
= null;
39 /** @private {remoting.ConnectedView} */
42 /** @private {remoting.VideoFrameRecorder} */
43 this.videoFrameRecorder_
= null;
45 /** @private {base.Disposable} */
46 this.eventHooks_
= null;
49 this.stats_
= new remoting
.ConnectionStats(
50 document
.getElementById('statistics'), connectionInfo
.plugin());
56 /** @return {void} Nothing. */
57 remoting
.DesktopConnectedView
.prototype.dispose = function() {
58 if (remoting
.windowFrame
) {
59 remoting
.windowFrame
.setDesktopConnectedView(null);
61 if (remoting
.toolbar
) {
62 remoting
.toolbar
.setDesktopConnectedView(null);
64 if (remoting
.optionsMenu
) {
65 remoting
.optionsMenu
.setDesktopConnectedView(null);
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_
);
81 * Get host display name.
85 remoting
.DesktopConnectedView
.prototype.getHostDisplayName = function() {
86 return this.host_
.hostName
;
90 * @return {boolean} True if shrink-to-fit is enabled; false otherwise.
92 remoting
.DesktopConnectedView
.prototype.getShrinkToFit = function() {
94 return this.viewport_
.getShrinkToFit();
100 * @return {boolean} True if resize-to-client is enabled; false otherwise.
102 remoting
.DesktopConnectedView
.prototype.getResizeToClient = function() {
103 if (this.viewport_
) {
104 return this.viewport_
.getResizeToClient();
110 * @return {boolean} True if the right-hand Ctrl key is mapped to the Meta
111 * (Windows, Command) key.
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.
124 remoting
.DesktopConnectedView
.prototype.isStatsVisible = function() {
125 return this.stats_
.isVisible();
129 * @return {Element} The element that should host the plugin.
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
=
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;
162 * This is a callback that gets called when the window is resized.
164 * @return {void} Nothing.
167 remoting
.DesktopConnectedView
.prototype.onResize_ = function() {
168 if (this.viewport_
) {
169 this.viewport_
.onResize();
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(),
187 if (remoting
.windowFrame
) {
188 remoting
.windowFrame
.setDesktopConnectedView(this);
190 if (remoting
.toolbar
) {
191 remoting
.toolbar
.setDesktopConnectedView(this);
193 if (remoting
.optionsMenu
) {
194 remoting
.optionsMenu
.setDesktopConnectedView(this);
197 // Activate full-screen related UX.
198 this.eventHooks_
= new base
.Disposables(
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.
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.
234 remoting
.DesktopConnectedView
.prototype.onFullScreenChanged_ = function (
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
242 this.viewport_
.onResize();
243 this.viewport_
.enableBumpScroll(Boolean(fullscreen
));
248 * Set whether or not the right-hand Ctrl key should send the Meta (Windows,
251 * @param {boolean} enable True to enable the mapping; false to disable.
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.
259 this.host_
.options
.remapKeys
[0x0700e4] = 0x0700e7;
261 delete this.host_
.options
.remapKeys
[0x0700e4]
263 this.setRemapKeys(this.host_
.options
.remapKeys
);
267 * Sends a Ctrl-Alt-Del sequence to the remoting client.
269 * @return {void} Nothing.
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.
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
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
=
303 this.videoFrameRecorder_
= recorder
;
307 * Returns true if the ClientSession can record video frames to a file.
310 remoting
.DesktopConnectedView
.prototype.canRecordVideo = function() {
311 return !!this.videoFrameRecorder_
;
315 * Returns true if the ClientSession is currently recording video frames.
318 remoting
.DesktopConnectedView
.prototype.isRecordingVideo = function() {
319 if (!this.videoFrameRecorder_
) {
322 return this.videoFrameRecorder_
.isRecording();
326 * Starts or stops recording of video frames.
328 remoting
.DesktopConnectedView
.prototype.startStopRecording = function() {
329 if (this.videoFrameRecorder_
) {
330 this.videoFrameRecorder_
.startStopRecording();