OLD | NEW |
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 * @param {remoting.ClientPlugin} plugin | |
17 * @param {HTMLElement} container | 16 * @param {HTMLElement} container |
18 * @param {remoting.Host} host | 17 * @param {remoting.ConnectionInfo} connectionInfo |
19 * @param {remoting.DesktopConnectedView.Mode} mode The mode of this connection. | |
20 * @param {string} defaultRemapKeys The default set of remap keys, to use | 18 * @param {string} defaultRemapKeys The default set of remap keys, to use |
21 * when the client doesn't define any. | 19 * when the client doesn't define any. |
22 * @constructor | 20 * @constructor |
23 * @extends {base.EventSourceImpl} | 21 * @extends {base.EventSourceImpl} |
24 * @implements {base.Disposable} | 22 * @implements {base.Disposable} |
25 */ | 23 */ |
26 remoting.DesktopConnectedView = function(plugin, container, host, mode, | 24 remoting.DesktopConnectedView = function(container, connectionInfo, |
27 defaultRemapKeys) { | 25 defaultRemapKeys) { |
28 | 26 |
29 /** @private {HTMLElement} */ | 27 /** @private {HTMLElement} */ |
30 this.container_ = container; | 28 this.container_ = container; |
31 | 29 |
32 /** @private {remoting.ClientPlugin} */ | 30 /** @private {remoting.ClientPlugin} */ |
33 this.plugin_ = plugin; | 31 this.plugin_ = connectionInfo.plugin(); |
| 32 |
| 33 /** @private {remoting.ClientSession} */ |
| 34 this.session_ = connectionInfo.session(); |
34 | 35 |
35 /** @private */ | 36 /** @private */ |
36 this.host_ = host; | 37 this.host_ = connectionInfo.host(); |
37 | 38 |
38 /** @private */ | 39 /** @private */ |
39 this.mode_ = mode; | 40 this.mode_ = connectionInfo.mode(); |
40 | 41 |
41 /** @private {string} */ | 42 /** @private {string} */ |
42 this.defaultRemapKeys_ = defaultRemapKeys; | 43 this.defaultRemapKeys_ = defaultRemapKeys; |
43 | 44 |
44 /** @private {Element} */ | |
45 this.debugRegionContainer_ = | |
46 this.container_.querySelector('.debug-region-container'); | |
47 | |
48 /** @private {remoting.DesktopViewport} */ | 45 /** @private {remoting.DesktopViewport} */ |
49 this.viewport_ = null; | 46 this.viewport_ = null; |
50 | 47 |
51 /** private {remoting.ConnectedView} */ | 48 /** private {remoting.ConnectedView} */ |
52 this.view_ = null; | 49 this.view_ = null; |
53 | 50 |
54 /** @private {remoting.VideoFrameRecorder} */ | 51 /** @private {remoting.VideoFrameRecorder} */ |
55 this.videoFrameRecorder_ = null; | 52 this.videoFrameRecorder_ = null; |
56 | 53 |
57 /** private {base.Disposable} */ | 54 /** private {base.Disposable} */ |
58 this.eventHooks_ = null; | 55 this.eventHooks_ = null; |
59 | 56 |
60 this.setupPlugin_(); | 57 this.initPlugin_(); |
| 58 this.initUI_(); |
61 }; | 59 }; |
62 | 60 |
63 /** @return {void} Nothing. */ | 61 /** @return {void} Nothing. */ |
64 remoting.DesktopConnectedView.prototype.dispose = function() { | 62 remoting.DesktopConnectedView.prototype.dispose = function() { |
65 if (remoting.windowFrame) { | 63 if (remoting.windowFrame) { |
66 remoting.windowFrame.setDesktopConnectedView(null); | 64 remoting.windowFrame.setDesktopConnectedView(null); |
67 } | 65 } |
68 if (remoting.toolbar) { | 66 if (remoting.toolbar) { |
69 remoting.toolbar.setDesktopConnectedView(null); | 67 remoting.toolbar.setDesktopConnectedView(null); |
70 } | 68 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 remoting.DesktopConnectedView.prototype.getPluginContainer_ = function() { | 136 remoting.DesktopConnectedView.prototype.getPluginContainer_ = function() { |
139 return this.container_.querySelector('.client-plugin-container'); | 137 return this.container_.querySelector('.client-plugin-container'); |
140 }; | 138 }; |
141 | 139 |
142 /** @return {remoting.DesktopViewport} */ | 140 /** @return {remoting.DesktopViewport} */ |
143 remoting.DesktopConnectedView.prototype.getViewportForTesting = function() { | 141 remoting.DesktopConnectedView.prototype.getViewportForTesting = function() { |
144 return this.viewport_; | 142 return this.viewport_; |
145 }; | 143 }; |
146 | 144 |
147 /** @private */ | 145 /** @private */ |
148 remoting.DesktopConnectedView.prototype.setupPlugin_ = function() { | 146 remoting.DesktopConnectedView.prototype.initPlugin_ = function() { |
149 // Show the Send Keys menu only if the plugin has the injectKeyEvent feature, | 147 // Show the Send Keys menu only if the plugin has the injectKeyEvent feature, |
150 // and the Ctrl-Alt-Del button only in Me2Me mode. | 148 // and the Ctrl-Alt-Del button only in Me2Me mode. |
151 if (!this.plugin_.hasFeature( | 149 if (!this.plugin_.hasFeature( |
152 remoting.ClientPlugin.Feature.INJECT_KEY_EVENT)) { | 150 remoting.ClientPlugin.Feature.INJECT_KEY_EVENT)) { |
153 var sendKeysElement = document.getElementById('send-keys-menu'); | 151 var sendKeysElement = document.getElementById('send-keys-menu'); |
154 sendKeysElement.hidden = true; | 152 sendKeysElement.hidden = true; |
155 } else if (this.mode_ != remoting.DesktopConnectedView.Mode.ME2ME && | 153 } else if (this.mode_ != remoting.DesktopConnectedView.Mode.ME2ME && |
156 this.mode_ != remoting.DesktopConnectedView.Mode.APP_REMOTING) { | 154 this.mode_ != remoting.DesktopConnectedView.Mode.APP_REMOTING) { |
157 var sendCadElement = document.getElementById('send-ctrl-alt-del'); | 155 var sendCadElement = document.getElementById('send-ctrl-alt-del'); |
158 sendCadElement.hidden = true; | 156 sendCadElement.hidden = true; |
159 } | 157 } |
160 | 158 |
161 // Apply customized key remappings if the plugin supports remapKeys. | 159 // Apply customized key remappings if the plugin supports remapKeys. |
162 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.REMAP_KEY)) { | 160 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.REMAP_KEY)) { |
163 this.applyRemapKeys_(true); | 161 this.applyRemapKeys_(true); |
164 } | 162 } |
| 163 |
| 164 if (this.session_.hasCapability( |
| 165 remoting.ClientSession.Capability.VIDEO_RECORDER)) { |
| 166 this.videoFrameRecorder_ = new remoting.VideoFrameRecorder(this.plugin_); |
| 167 } |
165 }; | 168 }; |
166 | 169 |
167 /** | 170 /** |
168 * This is a callback that gets called when the window is resized. | 171 * This is a callback that gets called when the window is resized. |
169 * | 172 * |
170 * @return {void} Nothing. | 173 * @return {void} Nothing. |
171 * @private. | 174 * @private. |
172 */ | 175 */ |
173 remoting.DesktopConnectedView.prototype.onResize_ = function() { | 176 remoting.DesktopConnectedView.prototype.onResize_ = function() { |
174 if (this.viewport_) { | 177 if (this.viewport_) { |
175 this.viewport_.onResize(); | 178 this.viewport_.onResize(); |
176 } | 179 } |
177 }; | 180 }; |
178 | 181 |
179 /** | 182 /** @private */ |
180 * Callback that the plugin invokes to indicate when the connection is | 183 remoting.DesktopConnectedView.prototype.initUI_ = function() { |
181 * ready. | |
182 * | |
183 * @param {boolean} ready True if the connection is ready. | |
184 */ | |
185 remoting.DesktopConnectedView.prototype.onConnectionReady = function(ready) { | |
186 if (this.view_) { | |
187 this.view_.onConnectionReady(ready); | |
188 } | |
189 }; | |
190 | |
191 remoting.DesktopConnectedView.prototype.onConnected = function() { | |
192 document.body.classList.add('connected'); | 184 document.body.classList.add('connected'); |
193 | 185 |
194 this.view_ = new remoting.ConnectedView( | 186 this.view_ = new remoting.ConnectedView( |
195 this.plugin_, this.container_, | 187 this.plugin_, this.container_, |
196 this.container_.querySelector('.mouse-cursor-overlay')); | 188 this.container_.querySelector('.mouse-cursor-overlay')); |
197 | 189 |
198 var scrollerElement = document.getElementById('scroller'); | 190 var scrollerElement = document.getElementById('scroller'); |
199 this.viewport_ = new remoting.DesktopViewport( | 191 this.viewport_ = new remoting.DesktopViewport( |
200 scrollerElement || document.body, | 192 scrollerElement || document.body, |
201 this.plugin_.hostDesktop(), | 193 this.plugin_.hostDesktop(), |
202 this.host_.options); | 194 this.host_.options); |
203 | 195 |
204 if (remoting.windowFrame) { | 196 if (remoting.windowFrame) { |
205 remoting.windowFrame.setDesktopConnectedView(this); | 197 remoting.windowFrame.setDesktopConnectedView(this); |
206 } | 198 } |
207 if (remoting.toolbar) { | 199 if (remoting.toolbar) { |
208 remoting.toolbar.setDesktopConnectedView(this); | 200 remoting.toolbar.setDesktopConnectedView(this); |
209 } | 201 } |
210 if (remoting.optionsMenu) { | 202 if (remoting.optionsMenu) { |
211 remoting.optionsMenu.setDesktopConnectedView(this); | 203 remoting.optionsMenu.setDesktopConnectedView(this); |
212 } | 204 } |
213 | 205 |
214 // Activate full-screen related UX. | 206 // Activate full-screen related UX. |
215 this.eventHooks_ = new base.Disposables( | 207 this.eventHooks_ = new base.Disposables( |
216 this.view_, | 208 this.view_, |
| 209 new base.EventHook(this.session_, |
| 210 remoting.ClientSession.Events.videoChannelStateChanged, |
| 211 this.view_.onConnectionReady.bind(this.view_)), |
217 new base.DomEventHook(window, 'resize', this.onResize_.bind(this), false), | 212 new base.DomEventHook(window, 'resize', this.onResize_.bind(this), false), |
218 new remoting.Fullscreen.EventHook(this.onFullScreenChanged_.bind(this)) | 213 new remoting.Fullscreen.EventHook(this.onFullScreenChanged_.bind(this))); |
219 ); | |
220 this.onFullScreenChanged_(remoting.fullscreen.isActive()); | 214 this.onFullScreenChanged_(remoting.fullscreen.isActive()); |
221 }; | 215 }; |
222 | 216 |
223 /** | 217 /** |
224 * Set the shrink-to-fit and resize-to-client flags and save them if this is | 218 * Set the shrink-to-fit and resize-to-client flags and save them if this is |
225 * a Me2Me connection. | 219 * a Me2Me connection. |
226 * | 220 * |
227 * @param {boolean} shrinkToFit True if the remote desktop should be scaled | 221 * @param {boolean} shrinkToFit True if the remote desktop should be scaled |
228 * down if it is larger than the client window; false if scroll-bars | 222 * down if it is larger than the client window; false if scroll-bars |
229 * should be added in this case. | 223 * should be added in this case. |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 /** | 336 /** |
343 * Sends a Print Screen keypress to the remoting client. | 337 * Sends a Print Screen keypress to the remoting client. |
344 * | 338 * |
345 * @return {void} Nothing. | 339 * @return {void} Nothing. |
346 */ | 340 */ |
347 remoting.DesktopConnectedView.prototype.sendPrintScreen = function() { | 341 remoting.DesktopConnectedView.prototype.sendPrintScreen = function() { |
348 console.log('Sending Print Screen.'); | 342 console.log('Sending Print Screen.'); |
349 this.sendKeyCombination_([0x070046]); | 343 this.sendKeyCombination_([0x070046]); |
350 }; | 344 }; |
351 | 345 |
352 remoting.DesktopConnectedView.prototype.initVideoFrameRecorder = function() { | |
353 this.videoFrameRecorder_ = new remoting.VideoFrameRecorder(this.plugin_); | |
354 }; | |
355 | |
356 /** | 346 /** |
357 * Returns true if the ClientSession can record video frames to a file. | 347 * Returns true if the ClientSession can record video frames to a file. |
358 * @return {boolean} | 348 * @return {boolean} |
359 */ | 349 */ |
360 remoting.DesktopConnectedView.prototype.canRecordVideo = function() { | 350 remoting.DesktopConnectedView.prototype.canRecordVideo = function() { |
361 return !!this.videoFrameRecorder_; | 351 return !!this.videoFrameRecorder_; |
362 }; | 352 }; |
363 | 353 |
364 /** | 354 /** |
365 * Returns true if the ClientSession is currently recording video frames. | 355 * Returns true if the ClientSession is currently recording video frames. |
(...skipping 21 matching lines...) Expand all Loading... |
387 * @param {Object} message The parsed extension message data. | 377 * @param {Object} message The parsed extension message data. |
388 * @return {boolean} True if the message was recognized, false otherwise. | 378 * @return {boolean} True if the message was recognized, false otherwise. |
389 */ | 379 */ |
390 remoting.DesktopConnectedView.prototype.handleExtensionMessage = | 380 remoting.DesktopConnectedView.prototype.handleExtensionMessage = |
391 function(type, message) { | 381 function(type, message) { |
392 if (this.videoFrameRecorder_) { | 382 if (this.videoFrameRecorder_) { |
393 return this.videoFrameRecorder_.handleMessage(type, message); | 383 return this.videoFrameRecorder_.handleMessage(type, message); |
394 } | 384 } |
395 return false; | 385 return false; |
396 }; | 386 }; |
397 | |
398 /** | |
399 * Handles dirty region debug messages. | |
400 * | |
401 * @param {{rects:Array<Array<number>>}} region Dirty region of the latest | |
402 * frame. | |
403 */ | |
404 remoting.DesktopConnectedView.prototype.handleDebugRegion = function(region) { | |
405 while (this.debugRegionContainer_.firstChild) { | |
406 this.debugRegionContainer_.removeChild( | |
407 this.debugRegionContainer_.firstChild); | |
408 } | |
409 if (region.rects) { | |
410 var rects = region.rects; | |
411 for (var i = 0; i < rects.length; ++i) { | |
412 var rect = document.createElement('div'); | |
413 rect.classList.add('debug-region-rect'); | |
414 rect.style.left = rects[i][0] + 'px'; | |
415 rect.style.top = rects[i][1] +'px'; | |
416 rect.style.width = rects[i][2] +'px'; | |
417 rect.style.height = rects[i][3] + 'px'; | |
418 this.debugRegionContainer_.appendChild(rect); | |
419 } | |
420 } | |
421 }; | |
OLD | NEW |