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

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

Issue 1016373003: [Chromoting] Change Application.Delegate to proper subclass of Application. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update comments; remove desktopDelegateForTesting 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 * This class implements the functionality that is specific to desktop 7 * This class implements the functionality that is specific to desktop
8 * remoting ("Chromoting" or CRD). 8 * remoting ("Chromoting" or CRD).
9 */ 9 */
10 10
11 'use strict'; 11 'use strict';
12 12
13 /** @suppress {duplicate} */ 13 /** @suppress {duplicate} */
14 var remoting = remoting || {}; 14 var remoting = remoting || {};
15 15
16 /** 16 /**
17 * @param {remoting.Application} app The main app that owns this delegate. 17 * @param {Array<string>} appCapabilities Array of application capabilities.
18 * @constructor 18 * @constructor
19 * @implements {remoting.Application.Delegate} 19 * @implements {remoting.ApplicationInterface}
20 * @extends {remoting.Application}
20 */ 21 */
21 remoting.DesktopRemoting = function(app) { 22 remoting.DesktopRemoting = function(appCapabilities) {
22 /** 23 base.inherits(this, remoting.Application, appCapabilities);
23 * TODO(garykac): Remove this reference to the Application. It's only
24 * needed to get the current mode when reporting errors. So we should be
25 * able to refactor and remove this reference cycle.
26 *
27 * @private {remoting.Application}
28 */
29 this.app_ = app;
30 app.setDelegate(this);
31 24
32 /** 25 /**
33 * Whether to refresh the JID and retry the connection if the current JID 26 * Whether to refresh the JID and retry the connection if the current JID
34 * is offline. 27 * is offline.
35 * 28 *
36 * @private {boolean} 29 * @private {boolean}
37 */ 30 */
38 this.refreshHostJidIfOffline_ = true; 31 this.refreshHostJidIfOffline_ = true;
39 32
40 /** @private {remoting.DesktopConnectedView} */ 33 /** @private {remoting.DesktopConnectedView} */
41 this.connectedView_ = null; 34 this.connectedView_ = null;
42 35
43 remoting.desktopDelegateForTesting = this; 36 remoting.desktopDelegateForTesting = this;
44 }; 37 };
45 38
46 /** 39 /**
47 * Initialize the application and register all event handlers. After this 40 * Required for remoting.ApplicationInterface interface.
Jamie 2015/03/25 20:00:39 I don't think you need this annotation on every me
garykac 2015/03/26 01:41:57 @override {type} works, but the type isn't validat
48 * is called, the app is running and waiting for user events.
49 * 41 *
50 * @return {void} Nothing. 42 * @return {string} Application product name to be used in UI.
43 * @override
51 */ 44 */
52 remoting.DesktopRemoting.prototype.init = function() { 45 remoting.DesktopRemoting.prototype.getApplicationName = function() {
46 return chrome.i18n.getMessage(/*i18n-content*/'PRODUCT_NAME');
47 };
48
49 /**
50 * Required for remoting.ApplicationInterface interface.
51 *
52 * @param {!remoting.Error} error The failure reason.
53 * @override
54 */
55 remoting.DesktopRemoting.prototype.signInFailed = function(error) {
56 remoting.showErrorMessage(error);
57 };
58
59 /**
60 * Required for remoting.ApplicationInterface interface.
61 *
62 * @override
63 */
64 remoting.DesktopRemoting.prototype.initApplication = function() {
53 remoting.initElementEventHandlers(); 65 remoting.initElementEventHandlers();
54 66
55 if (base.isAppsV2()) { 67 if (base.isAppsV2()) {
56 remoting.windowFrame = new remoting.WindowFrame( 68 remoting.windowFrame = new remoting.WindowFrame(
57 document.getElementById('title-bar')); 69 document.getElementById('title-bar'));
58 remoting.optionsMenu = remoting.windowFrame.createOptionsMenu(); 70 remoting.optionsMenu = remoting.windowFrame.createOptionsMenu();
59 71
60 var START_FULLSCREEN = 'start-fullscreen'; 72 var START_FULLSCREEN = 'start-fullscreen';
61 remoting.fullscreen = new remoting.FullscreenAppsV2(); 73 remoting.fullscreen = new remoting.FullscreenAppsV2();
62 remoting.fullscreen.addListener(function(isFullscreen) { 74 remoting.fullscreen.addListener(function(isFullscreen) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 document.getElementById('startup-mode-box-it2me').hidden = false; 127 document.getElementById('startup-mode-box-it2me').hidden = false;
116 } 128 }
117 }; 129 };
118 this.isWindowed_(onIsWindowed); 130 this.isWindowed_(onIsWindowed);
119 } 131 }
120 132
121 remoting.ClientPlugin.factory.preloadPlugin(); 133 remoting.ClientPlugin.factory.preloadPlugin();
122 }; 134 };
123 135
124 /** 136 /**
125 * Start the application. Once start() is called, the delegate can assume that 137 * Required for remoting.ApplicationInterface interface.
126 * the user has consented to all permissions specified in the manifest.
127 * 138 *
128 * @param {remoting.SessionConnector} connector 139 * @param {string} token An OAuth access token.
129 * @param {string} token An OAuth access token. The delegate should not cache 140 * @override
130 * this token, but can assume that it will remain valid during application
131 * start-up.
132 */ 141 */
133 remoting.DesktopRemoting.prototype.start = function(connector, token) { 142 remoting.DesktopRemoting.prototype.startApplication = function(token) {
134 remoting.identity.getEmail().then( 143 remoting.identity.getEmail().then(
135 function(/** string */ email) { 144 function(/** string */ email) {
136 document.getElementById('current-email').innerText = email; 145 document.getElementById('current-email').innerText = email;
137 document.getElementById('get-started-it2me').disabled = false; 146 document.getElementById('get-started-it2me').disabled = false;
138 document.getElementById('get-started-me2me').disabled = false; 147 document.getElementById('get-started-me2me').disabled = false;
139 }); 148 });
140 }; 149 };
141 150
142 /** 151 /**
143 * Report an authentication error to the user. This is called in lieu of start()
144 * if the user cannot be authenticated or if they decline the app permissions.
145 *
146 * @param {!remoting.Error} error The failure reason.
147 */
148 remoting.DesktopRemoting.prototype.signInFailed = function(error) {
149 remoting.showErrorMessage(error);
150 };
151
152 /**
153 * @return {string} Application product name to be used in UI.
154 */
155 remoting.DesktopRemoting.prototype.getApplicationName = function() {
garykac 2015/03/23 18:44:22 These were moved earlier in the file so to match t
156 return chrome.i18n.getMessage(/*i18n-content*/'PRODUCT_NAME');
157 };
158
159 /**
160 * Called when a new session has been connected. 152 * Called when a new session has been connected.
161 * 153 *
162 * @param {remoting.ConnectionInfo} connectionInfo 154 * @param {remoting.ConnectionInfo} connectionInfo
163 * @return {void} Nothing. 155 * @return {void} Nothing.
164 */ 156 */
165 remoting.DesktopRemoting.prototype.handleConnected = function(connectionInfo) { 157 remoting.DesktopRemoting.prototype.onConnected = function(connectionInfo) {
158 remoting.Application.prototype.onConnected.call(this, connectionInfo);
159
166 // Set the text on the buttons shown under the error message so that they are 160 // Set the text on the buttons shown under the error message so that they are
167 // easy to understand in the case where a successful connection failed, as 161 // easy to understand in the case where a successful connection failed, as
168 // opposed to the case where a connection never succeeded. 162 // opposed to the case where a connection never succeeded.
169 // TODO(garykac): Investigate to see if these need to be reverted to their 163 // TODO(garykac): Investigate to see if these need to be reverted to their
170 // original values in the onDisconnected method. 164 // original values in the onDisconnected method.
171 var button1 = document.getElementById('client-reconnect-button'); 165 var button1 = document.getElementById('client-reconnect-button');
172 l10n.localizeElementFromTag(button1, /*i18n-content*/'RECONNECT'); 166 l10n.localizeElementFromTag(button1, /*i18n-content*/'RECONNECT');
173 button1.removeAttribute('autofocus'); 167 button1.removeAttribute('autofocus');
174 var button2 = document.getElementById('client-finished-me2me-button'); 168 var button2 = document.getElementById('client-finished-me2me-button');
175 l10n.localizeElementFromTag(button2, /*i18n-content*/'OK'); 169 l10n.localizeElementFromTag(button2, /*i18n-content*/'OK');
(...skipping 12 matching lines...) Expand all
188 this.connectedView_ = new remoting.DesktopConnectedView( 182 this.connectedView_ = new remoting.DesktopConnectedView(
189 document.getElementById('client-container'), connectionInfo); 183 document.getElementById('client-container'), connectionInfo);
190 184
191 // By default, under ChromeOS, remap the right Control key to the right 185 // By default, under ChromeOS, remap the right Control key to the right
192 // Win / Cmd key. 186 // Win / Cmd key.
193 if (remoting.platformIsChromeOS()) { 187 if (remoting.platformIsChromeOS()) {
194 connectionInfo.plugin().setRemapKeys('0x0700e4>0x0700e7'); 188 connectionInfo.plugin().setRemapKeys('0x0700e4>0x0700e7');
195 } 189 }
196 190
197 if (connectionInfo.mode() === remoting.DesktopConnectedView.Mode.ME2ME) { 191 if (connectionInfo.mode() === remoting.DesktopConnectedView.Mode.ME2ME) {
198 var sessionConnector = remoting.app.getSessionConnector();
199 if (remoting.app.hasCapability(remoting.ClientSession.Capability.CAST)) { 192 if (remoting.app.hasCapability(remoting.ClientSession.Capability.CAST)) {
200 sessionConnector.registerProtocolExtension( 193 this.sessionConnector_.registerProtocolExtension(
201 new remoting.CastExtensionHandler()); 194 new remoting.CastExtensionHandler());
202 } 195 }
203 sessionConnector.registerProtocolExtension( 196 this.sessionConnector_.registerProtocolExtension(
204 new remoting.GnubbyAuthHandler()); 197 new remoting.GnubbyAuthHandler());
205 } 198 }
206 199
207 if (remoting.pairingRequested) { 200 if (remoting.pairingRequested) {
201 var that = this;
208 /** 202 /**
209 * @param {string} clientId 203 * @param {string} clientId
210 * @param {string} sharedSecret 204 * @param {string} sharedSecret
211 */ 205 */
212 var onPairingComplete = function(clientId, sharedSecret) { 206 var onPairingComplete = function(clientId, sharedSecret) {
213 var connector = remoting.app.getSessionConnector(); 207 var connector = that.sessionConnector_;
214 var host = remoting.hostList.getHostForId(connector.getHostId()); 208 var host = remoting.hostList.getHostForId(connector.getHostId());
215 host.options.pairingInfo.clientId = clientId; 209 host.options.pairingInfo.clientId = clientId;
216 host.options.pairingInfo.sharedSecret = sharedSecret; 210 host.options.pairingInfo.sharedSecret = sharedSecret;
217 host.options.save(); 211 host.options.save();
218 connector.updatePairingInfo(clientId, sharedSecret); 212 connector.updatePairingInfo(clientId, sharedSecret);
219 }; 213 };
220 // Use the platform name as a proxy for the local computer name. 214 // Use the platform name as a proxy for the local computer name.
221 // TODO(jamiewalch): Use a descriptive name for the local computer, for 215 // TODO(jamiewalch): Use a descriptive name for the local computer, for
222 // example, its Chrome Sync name. 216 // example, its Chrome Sync name.
223 var clientName = ''; 217 var clientName = '';
(...skipping 11 matching lines...) Expand all
235 } 229 }
236 connectionInfo.session().requestPairing(clientName, onPairingComplete); 230 connectionInfo.session().requestPairing(clientName, onPairingComplete);
237 } 231 }
238 }; 232 };
239 233
240 /** 234 /**
241 * Called when the current session has been disconnected. 235 * Called when the current session has been disconnected.
242 * 236 *
243 * @return {void} Nothing. 237 * @return {void} Nothing.
244 */ 238 */
245 remoting.DesktopRemoting.prototype.handleDisconnected = function() { 239 remoting.DesktopRemoting.prototype.onDisconnected = function() {
240 remoting.Application.prototype.onDisconnected.call(this);
241
246 var mode = this.connectedView_.getMode(); 242 var mode = this.connectedView_.getMode();
247 if (mode === remoting.DesktopConnectedView.Mode.IT2ME) { 243 if (mode === remoting.DesktopConnectedView.Mode.IT2ME) {
248 remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_IT2ME); 244 remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_IT2ME);
249 } else { 245 } else {
250 remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_ME2ME); 246 remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_ME2ME);
251 } 247 }
252 base.dispose(this.connectedView_); 248 base.dispose(this.connectedView_);
253 this.connectedView_ = null; 249 this.connectedView_ = null;
254 }; 250 };
255 251
256 /** 252 /**
257 * Called when the current session's connection has failed. 253 * Called when the current session's connection has failed.
258 * 254 *
259 * @param {remoting.SessionConnector} connector
260 * @param {!remoting.Error} error 255 * @param {!remoting.Error} error
261 * @return {void} Nothing. 256 * @return {void} Nothing.
262 */ 257 */
263 remoting.DesktopRemoting.prototype.handleConnectionFailed = function( 258 remoting.DesktopRemoting.prototype.onConnectionFailed = function(error) {
264 connector, error) { 259 remoting.Application.prototype.onConnectionFailed.call(this, error);
260
265 var that = this; 261 var that = this;
266 var onHostListRefresh = function(/** boolean */ success) { 262 var onHostListRefresh = function(/** boolean */ success) {
267 if (success) { 263 if (success) {
264 var connector = that.sessionConnector_;
268 var host = remoting.hostList.getHostForId(connector.getHostId()); 265 var host = remoting.hostList.getHostForId(connector.getHostId());
269 if (host) { 266 if (host) {
270 connector.retryConnectMe2Me(host); 267 connector.retryConnectMe2Me(host);
271 return; 268 return;
272 } 269 }
273 } 270 }
274 that.handleError(error); 271 that.onError(error);
275 }; 272 };
276 273
277 var mode = this.app_.getSessionConnector().getConnectionMode(); 274 var mode = this.sessionConnector_.getConnectionMode();
278 if (error.hasTag(remoting.Error.Tag.HOST_IS_OFFLINE) && 275 if (error.hasTag(remoting.Error.Tag.HOST_IS_OFFLINE) &&
279 mode === remoting.DesktopConnectedView.Mode.ME2ME && 276 mode === remoting.DesktopConnectedView.Mode.ME2ME &&
280 this.refreshHostJidIfOffline_) { 277 this.refreshHostJidIfOffline_) {
281 this.refreshHostJidIfOffline_ = false; 278 this.refreshHostJidIfOffline_ = false;
282 279
283 // The plugin will be re-created when the host finished refreshing 280 // The plugin will be re-created when the host finished refreshing
284 remoting.hostList.refresh(onHostListRefresh); 281 remoting.hostList.refresh(onHostListRefresh);
285 } else { 282 } else {
286 this.handleError(error); 283 this.onError(error);
287 } 284 }
288 }; 285 };
289 286
290 /** 287 /**
291 * Called when an error needs to be displayed to the user. 288 * Called when an error needs to be displayed to the user.
292 * 289 *
293 * @param {!remoting.Error} error The error to be localized and displayed. 290 * @param {!remoting.Error} error The error to be localized and displayed.
294 * @return {void} Nothing. 291 * @return {void} Nothing.
295 */ 292 */
296 remoting.DesktopRemoting.prototype.handleError = function(error) { 293 remoting.DesktopRemoting.prototype.onError = function(error) {
294 remoting.Application.prototype.onError.call(this, error);
295
297 console.error('Connection failed: ' + error.toString()); 296 console.error('Connection failed: ' + error.toString());
298 var mode = this.connectedView_ ? this.connectedView_.getMode() 297 var mode = this.connectedView_ ? this.connectedView_.getMode()
299 : this.app_.getSessionConnector().getConnectionMode(); 298 : this.sessionConnector_.getConnectionMode();
300 base.dispose(this.connectedView_); 299 base.dispose(this.connectedView_);
301 this.connectedView_ = null; 300 this.connectedView_ = null;
302 301
303 if (error.hasTag(remoting.Error.Tag.AUTHENTICATION_FAILED)) { 302 if (error.hasTag(remoting.Error.Tag.AUTHENTICATION_FAILED)) {
304 remoting.setMode(remoting.AppMode.HOME); 303 remoting.setMode(remoting.AppMode.HOME);
305 remoting.handleAuthFailureAndRelaunch(); 304 remoting.handleAuthFailureAndRelaunch();
306 return; 305 return;
307 } 306 }
308 307
309 // Reset the refresh flag so that the next connection will retry if needed. 308 // Reset the refresh flag so that the next connection will retry if needed.
310 this.refreshHostJidIfOffline_ = true; 309 this.refreshHostJidIfOffline_ = true;
311 310
312 var errorDiv = document.getElementById('connect-error-message'); 311 var errorDiv = document.getElementById('connect-error-message');
313 l10n.localizeElementFromTag(errorDiv, error.getTag()); 312 l10n.localizeElementFromTag(errorDiv, error.getTag());
314 313
315 if (mode == remoting.DesktopConnectedView.Mode.IT2ME) { 314 if (mode == remoting.DesktopConnectedView.Mode.IT2ME) {
316 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_IT2ME); 315 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_IT2ME);
317 } else { 316 } else {
318 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_ME2ME); 317 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_ME2ME);
319 } 318 }
320 }; 319 };
321 320
322 /** 321 /**
323 * No cleanup required for desktop remoting.
324 */
325 remoting.DesktopRemoting.prototype.handleExit = function() {
326 };
327
328 /**
329 * Determine whether or not the app is running in a window. 322 * Determine whether or not the app is running in a window.
330 * @param {function(boolean):void} callback Callback to receive whether or not 323 * @param {function(boolean):void} callback Callback to receive whether or not
331 * the current tab is running in windowed mode. 324 * the current tab is running in windowed mode.
332 * @private 325 * @private
333 */ 326 */
334 remoting.DesktopRemoting.prototype.isWindowed_ = function(callback) { 327 remoting.DesktopRemoting.prototype.isWindowed_ = function(callback) {
335 /** @param {chrome.Window} win The current window. */ 328 /** @param {chrome.Window} win The current window. */
336 var windowCallback = function(win) { 329 var windowCallback = function(win) {
337 callback(win.type == 'popup'); 330 callback(win.type == 'popup');
338 }; 331 };
(...skipping 12 matching lines...) Expand all
351 } 344 }
352 } 345 }
353 346
354 /** 347 /**
355 * If an IT2Me client or host is active then prompt the user before closing. 348 * If an IT2Me client or host is active then prompt the user before closing.
356 * If a Me2Me client is active then don't bother, since closing the window is 349 * If a Me2Me client is active then don't bother, since closing the window is
357 * the more intuitive way to end a Me2Me session, and re-connecting is easy. 350 * the more intuitive way to end a Me2Me session, and re-connecting is easy.
358 * @private 351 * @private
359 */ 352 */
360 remoting.DesktopRemoting.prototype.promptClose_ = function() { 353 remoting.DesktopRemoting.prototype.promptClose_ = function() {
361 var sessionConnector = remoting.app.getSessionConnector(); 354 var sessionConnector = this.sessionConnector_;
362 if (sessionConnector && 355 if (sessionConnector &&
363 sessionConnector.getConnectionMode() == 356 sessionConnector.getConnectionMode() ==
364 remoting.DesktopConnectedView.Mode.IT2ME) { 357 remoting.DesktopConnectedView.Mode.IT2ME) {
365 switch (remoting.currentMode) { 358 switch (remoting.currentMode) {
366 case remoting.AppMode.CLIENT_CONNECTING: 359 case remoting.AppMode.CLIENT_CONNECTING:
367 case remoting.AppMode.HOST_WAITING_FOR_CODE: 360 case remoting.AppMode.HOST_WAITING_FOR_CODE:
368 case remoting.AppMode.HOST_WAITING_FOR_CONNECTION: 361 case remoting.AppMode.HOST_WAITING_FOR_CONNECTION:
369 case remoting.AppMode.HOST_SHARED: 362 case remoting.AppMode.HOST_SHARED:
370 case remoting.AppMode.IN_SESSION: 363 case remoting.AppMode.IN_SESSION:
371 return chrome.i18n.getMessage(/*i18n-content*/'CLOSE_PROMPT'); 364 return chrome.i18n.getMessage(/*i18n-content*/'CLOSE_PROMPT');
372 default: 365 default:
373 return null; 366 return null;
374 } 367 }
375 } 368 }
376 }; 369 };
377 370
378 /** @returns {remoting.DesktopConnectedView} */ 371 /** @returns {remoting.DesktopConnectedView} */
379 remoting.DesktopRemoting.prototype.getConnectedViewForTesting = function() { 372 remoting.DesktopRemoting.prototype.getConnectedViewForTesting = function() {
380 return this.connectedView_; 373 return this.connectedView_;
381 }; 374 };
382
383 /**
384 * Global instance of remoting.DesktopRemoting used for testing.
385 * @type {remoting.DesktopRemoting}
386 */
387 remoting.desktopDelegateForTesting = null;
garykac 2015/03/23 18:44:22 No need for this anymore. We can simply use remoti
OLDNEW
« remoting/webapp/base/js/application.js ('K') | « remoting/webapp/crd/js/crd_main.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698