| 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 * True to enable mouse lock. | 16 * True to enable mouse lock. |
| 17 * This is currently disabled because the current client plugin does not | 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. | 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 | 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. | 20 * the plugin that supports both has reached Chrome Stable channel. |
| 21 * (crbug.com/429322). | 21 * (crbug.com/429322). |
| 22 * | 22 * |
| 23 * @type {boolean} | 23 * @type {boolean} |
| 24 */ | 24 */ |
| 25 remoting.enableMouseLock = false; | 25 remoting.enableMouseLock = false; |
| 26 | 26 |
| 27 /** | 27 /** |
| 28 * @param {remoting.ClientPlugin} plugin |
| 28 * @param {remoting.ClientSession} session | 29 * @param {remoting.ClientSession} session |
| 29 * @param {HTMLElement} container | 30 * @param {HTMLElement} container |
| 30 * @param {remoting.Host} host | 31 * @param {remoting.Host} host |
| 31 * @param {remoting.DesktopConnectedView.Mode} mode The mode of this connection. | 32 * @param {remoting.DesktopConnectedView.Mode} mode The mode of this connection. |
| 32 * @param {string} defaultRemapKeys The default set of remap keys, to use | 33 * @param {string} defaultRemapKeys The default set of remap keys, to use |
| 33 * when the client doesn't define any. | 34 * when the client doesn't define any. |
| 34 * @param {function(remoting.Error, remoting.ClientPlugin): void} onInitialized | |
| 35 * @constructor | 35 * @constructor |
| 36 * @extends {base.EventSourceImpl} | 36 * @extends {base.EventSourceImpl} |
| 37 */ | 37 */ |
| 38 remoting.DesktopConnectedView = function(session, container, host, mode, | 38 remoting.DesktopConnectedView = function(plugin, session, container, host, mode, |
| 39 defaultRemapKeys, onInitialized) { | 39 defaultRemapKeys) { |
| 40 this.session_ = session; | 40 this.session_ = session; |
| 41 | 41 |
| 42 /** @type {HTMLElement} @private */ | 42 /** @type {HTMLElement} @private */ |
| 43 this.container_ = container; | 43 this.container_ = container; |
| 44 | 44 |
| 45 /** @type {remoting.ClientPlugin} @private */ | 45 /** @type {remoting.ClientPlugin} @private */ |
| 46 this.plugin_ = null; | 46 this.plugin_ = plugin; |
| 47 | 47 |
| 48 /** @private */ | 48 /** @private */ |
| 49 this.host_ = host; | 49 this.host_ = host; |
| 50 | 50 |
| 51 /** @private */ | 51 /** @private */ |
| 52 this.mode_ = mode; | 52 this.mode_ = mode; |
| 53 | 53 |
| 54 /** @type {string} @private */ | 54 /** @type {string} @private */ |
| 55 this.defaultRemapKeys_ = defaultRemapKeys; | 55 this.defaultRemapKeys_ = defaultRemapKeys; |
| 56 | 56 |
| 57 /** | |
| 58 * Called when the UI is finished initializing. | |
| 59 * @type {function(remoting.Error, remoting.ClientPlugin):void} | |
| 60 */ | |
| 61 this.onInitialized_ = onInitialized; | |
| 62 | |
| 63 /** @private */ | 57 /** @private */ |
| 64 this.callPluginLostFocus_ = this.pluginLostFocus_.bind(this); | 58 this.callPluginLostFocus_ = this.pluginLostFocus_.bind(this); |
| 65 /** @private */ | 59 /** @private */ |
| 66 this.callPluginGotFocus_ = this.pluginGotFocus_.bind(this); | 60 this.callPluginGotFocus_ = this.pluginGotFocus_.bind(this); |
| 67 /** @type {Element} @private */ | 61 /** @type {Element} @private */ |
| 68 this.debugRegionContainer_ = | 62 this.debugRegionContainer_ = |
| 69 this.container_.querySelector('.debug-region-container'); | 63 this.container_.querySelector('.debug-region-container'); |
| 70 | 64 |
| 71 /** @type {Element} @private */ | 65 /** @type {Element} @private */ |
| 72 this.mouseCursorOverlay_ = | 66 this.mouseCursorOverlay_ = |
| 73 this.container_.querySelector('.mouse-cursor-overlay'); | 67 this.container_.querySelector('.mouse-cursor-overlay'); |
| 74 | 68 |
| 75 /** @private {remoting.DesktopViewport} */ | 69 /** @private {remoting.DesktopViewport} */ |
| 76 this.viewport_ = null; | 70 this.viewport_ = null; |
| 77 | 71 |
| 78 /** @type {Element} */ | 72 /** @type {Element} */ |
| 79 var img = this.mouseCursorOverlay_; | 73 var img = this.mouseCursorOverlay_; |
| 80 /** @param {Event} event @private */ | 74 /** @param {Event} event @private */ |
| 81 this.updateMouseCursorPosition_ = function(event) { | 75 this.updateMouseCursorPosition_ = function(event) { |
| 82 img.style.top = event.offsetY + 'px'; | 76 img.style.top = event.offsetY + 'px'; |
| 83 img.style.left = event.offsetX + 'px'; | 77 img.style.left = event.offsetX + 'px'; |
| 84 }; | 78 }; |
| 85 | 79 |
| 86 /** @type {remoting.VideoFrameRecorder} @private */ | 80 /** @type {remoting.VideoFrameRecorder} @private */ |
| 87 this.videoFrameRecorder_ = null; | 81 this.videoFrameRecorder_ = null; |
| 88 | 82 |
| 89 /** private {base.Disposable} */ | 83 /** private {base.Disposable} */ |
| 90 this.eventHooks_ = null; | 84 this.eventHooks_ = null; |
| 85 |
| 86 this.setupPlugin_(); |
| 91 }; | 87 }; |
| 92 | 88 |
| 93 // The mode of this session. | 89 // The mode of this session. |
| 94 /** @enum {number} */ | 90 /** @enum {number} */ |
| 95 remoting.DesktopConnectedView.Mode = { | 91 remoting.DesktopConnectedView.Mode = { |
| 96 IT2ME: 0, | 92 IT2ME: 0, |
| 97 ME2ME: 1, | 93 ME2ME: 1, |
| 98 APP_REMOTING: 2 | 94 APP_REMOTING: 2 |
| 99 }; | 95 }; |
| 100 | 96 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 */ | 142 */ |
| 147 remoting.DesktopConnectedView.prototype.getPluginContainer_ = function() { | 143 remoting.DesktopConnectedView.prototype.getPluginContainer_ = function() { |
| 148 return this.container_.querySelector('.client-plugin-container'); | 144 return this.container_.querySelector('.client-plugin-container'); |
| 149 }; | 145 }; |
| 150 | 146 |
| 151 /** @return {remoting.DesktopViewport} */ | 147 /** @return {remoting.DesktopViewport} */ |
| 152 remoting.DesktopConnectedView.prototype.getViewportForTesting = function() { | 148 remoting.DesktopConnectedView.prototype.getViewportForTesting = function() { |
| 153 return this.viewport_; | 149 return this.viewport_; |
| 154 }; | 150 }; |
| 155 | 151 |
| 156 /** | 152 /** @private */ |
| 157 * Adds <embed> element to the UI container and readies the session object. | 153 remoting.DesktopConnectedView.prototype.setupPlugin_ = function() { |
| 158 * | |
| 159 * @param {function(string, string):boolean} onExtensionMessage The handler for | |
| 160 * protocol extension messages. Returns true if a message is recognized; | |
| 161 * false otherwise. | |
| 162 * @param {Array<string>} requiredCapabilities A list of capabilities | |
| 163 * required by this application. | |
| 164 */ | |
| 165 remoting.DesktopConnectedView.prototype.createPluginAndConnect = | |
| 166 function(onExtensionMessage, requiredCapabilities) { | |
| 167 this.plugin_ = remoting.ClientPlugin.factory.createPlugin( | |
| 168 this.getPluginContainer_(), | |
| 169 onExtensionMessage, requiredCapabilities); | |
| 170 var that = this; | |
| 171 this.host_.options.load().then(function(){ | |
| 172 that.plugin_.initialize(that.onPluginInitialized_.bind(that)); | |
| 173 }); | |
| 174 }; | |
| 175 | |
| 176 /** | |
| 177 * @param {boolean} initialized | |
| 178 */ | |
| 179 remoting.DesktopConnectedView.prototype.onPluginInitialized_ = function( | |
| 180 initialized) { | |
| 181 if (!initialized) { | |
| 182 console.error('ERROR: remoting plugin not loaded'); | |
| 183 this.onInitialized_(remoting.Error.MISSING_PLUGIN, this.plugin_); | |
| 184 return; | |
| 185 } | |
| 186 | |
| 187 if (!this.plugin_.isSupportedVersion()) { | |
| 188 this.onInitialized_(remoting.Error.BAD_PLUGIN_VERSION, this.plugin_); | |
| 189 return; | |
| 190 } | |
| 191 | |
| 192 // Show the Send Keys menu only if the plugin has the injectKeyEvent feature, | 154 // Show the Send Keys menu only if the plugin has the injectKeyEvent feature, |
| 193 // and the Ctrl-Alt-Del button only in Me2Me mode. | 155 // and the Ctrl-Alt-Del button only in Me2Me mode. |
| 194 if (!this.plugin_.hasFeature( | 156 if (!this.plugin_.hasFeature( |
| 195 remoting.ClientPlugin.Feature.INJECT_KEY_EVENT)) { | 157 remoting.ClientPlugin.Feature.INJECT_KEY_EVENT)) { |
| 196 var sendKeysElement = document.getElementById('send-keys-menu'); | 158 var sendKeysElement = document.getElementById('send-keys-menu'); |
| 197 sendKeysElement.hidden = true; | 159 sendKeysElement.hidden = true; |
| 198 } else if (this.mode_ != remoting.DesktopConnectedView.Mode.ME2ME && | 160 } else if (this.mode_ != remoting.DesktopConnectedView.Mode.ME2ME && |
| 199 this.mode_ != remoting.DesktopConnectedView.Mode.APP_REMOTING) { | 161 this.mode_ != remoting.DesktopConnectedView.Mode.APP_REMOTING) { |
| 200 var sendCadElement = document.getElementById('send-ctrl-alt-del'); | 162 var sendCadElement = document.getElementById('send-ctrl-alt-del'); |
| 201 sendCadElement.hidden = true; | 163 sendCadElement.hidden = true; |
| 202 } | 164 } |
| 203 | 165 |
| 204 // Apply customized key remappings if the plugin supports remapKeys. | 166 // Apply customized key remappings if the plugin supports remapKeys. |
| 205 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.REMAP_KEY)) { | 167 if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.REMAP_KEY)) { |
| 206 this.applyRemapKeys_(true); | 168 this.applyRemapKeys_(true); |
| 207 } | 169 } |
| 208 | 170 |
| 209 // TODO(wez): Only allow mouse lock if the app has the pointerLock permission. | 171 // TODO(wez): Only allow mouse lock if the app has the pointerLock permission. |
| 210 // Enable automatic mouse-lock. | 172 // Enable automatic mouse-lock. |
| 211 if (remoting.enableMouseLock && | 173 if (remoting.enableMouseLock && |
| 212 this.plugin_.hasFeature(remoting.ClientPlugin.Feature.ALLOW_MOUSE_LOCK)) { | 174 this.plugin_.hasFeature(remoting.ClientPlugin.Feature.ALLOW_MOUSE_LOCK)) { |
| 213 this.plugin_.allowMouseLock(); | 175 this.plugin_.allowMouseLock(); |
| 214 } | 176 } |
| 215 | 177 |
| 216 this.plugin_.setMouseCursorHandler(this.updateMouseCursorImage_.bind(this)); | 178 this.plugin_.setMouseCursorHandler(this.updateMouseCursorImage_.bind(this)); |
| 217 | |
| 218 this.onInitialized_(remoting.Error.NONE, this.plugin_); | |
| 219 }; | 179 }; |
| 220 | 180 |
| 221 /** | 181 /** |
| 222 * This is a callback that gets called when the window is resized. | 182 * This is a callback that gets called when the window is resized. |
| 223 * | 183 * |
| 224 * @return {void} Nothing. | 184 * @return {void} Nothing. |
| 225 * @private. | 185 * @private. |
| 226 */ | 186 */ |
| 227 remoting.DesktopConnectedView.prototype.onResize_ = function() { | 187 remoting.DesktopConnectedView.prototype.onResize_ = function() { |
| 228 if (this.viewport_) { | 188 if (this.viewport_) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 258 * disconnected by the Host. | 218 * disconnected by the Host. |
| 259 * | 219 * |
| 260 * @return {void} Nothing. | 220 * @return {void} Nothing. |
| 261 */ | 221 */ |
| 262 remoting.DesktopConnectedView.prototype.removePlugin = function() { | 222 remoting.DesktopConnectedView.prototype.removePlugin = function() { |
| 263 if (this.plugin_) { | 223 if (this.plugin_) { |
| 264 this.plugin_.element().removeEventListener( | 224 this.plugin_.element().removeEventListener( |
| 265 'focus', this.callPluginGotFocus_, false); | 225 'focus', this.callPluginGotFocus_, false); |
| 266 this.plugin_.element().removeEventListener( | 226 this.plugin_.element().removeEventListener( |
| 267 'blur', this.callPluginLostFocus_, false); | 227 'blur', this.callPluginLostFocus_, false); |
| 268 this.plugin_.dispose(); | |
| 269 this.plugin_ = null; | 228 this.plugin_ = null; |
| 270 } | 229 } |
| 271 | 230 |
| 272 this.updateClientSessionUi_(null); | 231 this.updateClientSessionUi_(null); |
| 273 }; | 232 }; |
| 274 | 233 |
| 275 /** | 234 /** |
| 276 * @param {remoting.ClientSession} clientSession The active session, or null if | 235 * @param {remoting.ClientSession} clientSession The active session, or null if |
| 277 * there is no connection. | 236 * there is no connection. |
| 278 */ | 237 */ |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 var rect = document.createElement('div'); | 553 var rect = document.createElement('div'); |
| 595 rect.classList.add('debug-region-rect'); | 554 rect.classList.add('debug-region-rect'); |
| 596 rect.style.left = rects[i][0] + 'px'; | 555 rect.style.left = rects[i][0] + 'px'; |
| 597 rect.style.top = rects[i][1] +'px'; | 556 rect.style.top = rects[i][1] +'px'; |
| 598 rect.style.width = rects[i][2] +'px'; | 557 rect.style.width = rects[i][2] +'px'; |
| 599 rect.style.height = rects[i][3] + 'px'; | 558 rect.style.height = rects[i][3] + 'px'; |
| 600 this.debugRegionContainer_.appendChild(rect); | 559 this.debugRegionContainer_.appendChild(rect); |
| 601 } | 560 } |
| 602 } | 561 } |
| 603 }; | 562 }; |
| OLD | NEW |