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

Side by Side Diff: remoting/webapp/app_remoting/js/app_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: sync/merge 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
« no previous file with comments | « no previous file | remoting/webapp/app_remoting/js/ar_main.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 application 7 * This class implements the functionality that is specific to application
8 * remoting ("AppRemoting" or AR). 8 * remoting ("AppRemoting" or AR).
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 * @implements {remoting.ProtocolExtension} 20 * @implements {remoting.ProtocolExtension}
21 * @extends {remoting.Application}
21 */ 22 */
22 remoting.AppRemoting = function(app) { 23 remoting.AppRemoting = function(appCapabilities) {
23 app.setDelegate(this); 24 base.inherits(this, remoting.Application, appCapabilities);
24 25
25 /** @private {remoting.ApplicationContextMenu} */ 26 /** @private {remoting.ApplicationContextMenu} */
26 this.contextMenu_ = null; 27 this.contextMenu_ = null;
27 28
28 /** @private {remoting.KeyboardLayoutsMenu} */ 29 /** @private {remoting.KeyboardLayoutsMenu} */
29 this.keyboardLayoutsMenu_ = null; 30 this.keyboardLayoutsMenu_ = null;
30 31
31 /** @private {remoting.WindowActivationMenu} */ 32 /** @private {remoting.WindowActivationMenu} */
32 this.windowActivationMenu_ = null; 33 this.windowActivationMenu_ = null;
33 34
(...skipping 19 matching lines...) Expand all
53 54
54 this.host = { 55 this.host = {
55 /** @type {string} */ 56 /** @type {string} */
56 applicationId: '', 57 applicationId: '',
57 58
58 /** @type {string} */ 59 /** @type {string} */
59 hostId: ''}; 60 hostId: ''};
60 }; 61 };
61 62
62 /** 63 /**
63 * Initialize the application. This is called before an OAuth token is requested 64 * @return {string} Application product name to be used in UI.
64 * and should be used for tasks such as initializing the DOM, registering event 65 * @override {remoting.ApplicationInterface}
65 * handlers, etc.
66 */ 66 */
67 remoting.AppRemoting.prototype.init = function() { 67 remoting.AppRemoting.prototype.getApplicationName = function() {
68 var manifest = chrome.runtime.getManifest();
69 return manifest.name;
70 };
71
72 /**
73 * @param {!remoting.Error} error The failure reason.
74 * @override {remoting.ApplicationInterface}
75 */
76 remoting.AppRemoting.prototype.signInFailed_ = function(error) {
77 this.onError_(error);
78 };
79
80 /**
81 * @override {remoting.ApplicationInterface}
82 */
83 remoting.AppRemoting.prototype.initApplication_ = function() {
68 // TODO(jamiewalch): Remove ClientSession's dependency on remoting.fullscreen 84 // TODO(jamiewalch): Remove ClientSession's dependency on remoting.fullscreen
69 // so that this is no longer required. 85 // so that this is no longer required.
70 remoting.fullscreen = new remoting.FullscreenAppsV2(); 86 remoting.fullscreen = new remoting.FullscreenAppsV2();
71 87
72 var restoreHostWindows = function() { 88 var restoreHostWindows = function() {
73 if (remoting.clientSession) { 89 if (remoting.clientSession) {
74 remoting.clientSession.sendClientMessage('restoreAllWindows', ''); 90 remoting.clientSession.sendClientMessage('restoreAllWindows', '');
75 } 91 }
76 }; 92 };
77 chrome.app.window.current().onRestored.addListener(restoreHostWindows); 93 chrome.app.window.current().onRestored.addListener(restoreHostWindows);
78 94
79 remoting.windowShape.updateClientWindowShape(); 95 remoting.windowShape.updateClientWindowShape();
80 96
81 // Initialize the context menus. 97 // Initialize the context menus.
82 if (remoting.platformIsChromeOS()) { 98 if (remoting.platformIsChromeOS()) {
83 var adapter = new remoting.ContextMenuChrome(); 99 var adapter = new remoting.ContextMenuChrome();
84 } else { 100 } else {
85 var adapter = new remoting.ContextMenuDom( 101 var adapter = new remoting.ContextMenuDom(
86 document.getElementById('context-menu')); 102 document.getElementById('context-menu'));
87 } 103 }
88 this.contextMenu_ = new remoting.ApplicationContextMenu(adapter); 104 this.contextMenu_ = new remoting.ApplicationContextMenu(adapter);
89 this.keyboardLayoutsMenu_ = new remoting.KeyboardLayoutsMenu(adapter); 105 this.keyboardLayoutsMenu_ = new remoting.KeyboardLayoutsMenu(adapter);
90 this.windowActivationMenu_ = new remoting.WindowActivationMenu(adapter); 106 this.windowActivationMenu_ = new remoting.WindowActivationMenu(adapter);
91 }; 107 };
92 108
93 /** 109 /**
94 * Start the application. Once start() is called, the delegate can assume that 110 * @param {string} token An OAuth access token.
95 * the user has consented to all permissions specified in the manifest. 111 * @override {remoting.ApplicationInterface}
96 *
97 * @param {remoting.SessionConnector} connector
98 * @param {string} token An OAuth access token. The delegate should not cache
99 * this token, but can assume that it will remain valid during application
100 * start-up.
101 */ 112 */
102 remoting.AppRemoting.prototype.start = function(connector, token) { 113 remoting.AppRemoting.prototype.startApplication_ = function(token) {
103 remoting.LoadingWindow.show(); 114 remoting.LoadingWindow.show();
104 115
105 /** @type {remoting.AppRemoting} */ 116 /** @type {remoting.AppRemoting} */
106 var that = this; 117 var that = this;
107 118
108 /** @param {!remoting.Xhr.Response} xhrResponse */ 119 /** @param {!remoting.Xhr.Response} xhrResponse */
109 var parseAppHostResponse = function(xhrResponse) { 120 var parseAppHostResponse = function(xhrResponse) {
110 if (xhrResponse.status == 200) { 121 if (xhrResponse.status == 200) {
111 var response = /** @type {remoting.AppRemoting.AppHostResponse} */ 122 var response = /** @type {remoting.AppRemoting.AppHostResponse} */
112 (base.jsonParseSafe(xhrResponse.getText())); 123 (base.jsonParseSafe(xhrResponse.getText()));
(...skipping 27 matching lines...) Expand all
140 * @param {function(string, string):void} onThirdPartyTokenFetched 151 * @param {function(string, string):void} onThirdPartyTokenFetched
141 * Callback. 152 * Callback.
142 */ 153 */
143 var fetchThirdPartyToken = function( 154 var fetchThirdPartyToken = function(
144 tokenUrl, hostPublicKey, scope, onThirdPartyTokenFetched) { 155 tokenUrl, hostPublicKey, scope, onThirdPartyTokenFetched) {
145 // Use the authentication tokens returned by the app-remoting server. 156 // Use the authentication tokens returned by the app-remoting server.
146 onThirdPartyTokenFetched(host['authorizationCode'], 157 onThirdPartyTokenFetched(host['authorizationCode'],
147 host['sharedSecret']); 158 host['sharedSecret']);
148 }; 159 };
149 160
150 connector.connectMe2App(host, fetchThirdPartyToken); 161 that.sessionConnector_.connectMe2App(host, fetchThirdPartyToken);
151 } else if (response && response.status == 'pending') { 162 } else if (response && response.status == 'pending') {
152 that.handleError(new remoting.Error( 163 that.onError_(new remoting.Error(
153 remoting.Error.Tag.SERVICE_UNAVAILABLE)); 164 remoting.Error.Tag.SERVICE_UNAVAILABLE));
154 } 165 }
155 } else { 166 } else {
156 console.error('Invalid "runApplication" response from server.'); 167 console.error('Invalid "runApplication" response from server.');
157 // TODO(garykac) Start using remoting.Error.fromHttpStatus once it has 168 // TODO(garykac) Start using remoting.Error.fromHttpStatus once it has
158 // been updated to properly report 'unknown' errors (rather than 169 // been updated to properly report 'unknown' errors (rather than
159 // reporting them as AUTHENTICATION_FAILED). 170 // reporting them as AUTHENTICATION_FAILED).
160 if (xhrResponse.status == 0) { 171 if (xhrResponse.status == 0) {
161 that.handleError(new remoting.Error( 172 that.onError_(new remoting.Error(
162 remoting.Error.Tag.NETWORK_FAILURE)); 173 remoting.Error.Tag.NETWORK_FAILURE));
163 } else if (xhrResponse.status == 401) { 174 } else if (xhrResponse.status == 401) {
164 that.handleError(new remoting.Error( 175 that.onError_(new remoting.Error(
165 remoting.Error.Tag.AUTHENTICATION_FAILED)); 176 remoting.Error.Tag.AUTHENTICATION_FAILED));
166 } else if (xhrResponse.status == 403) { 177 } else if (xhrResponse.status == 403) {
167 that.handleError(new remoting.Error( 178 that.onError_(new remoting.Error(
168 remoting.Error.Tag.APP_NOT_AUTHORIZED)); 179 remoting.Error.Tag.APP_NOT_AUTHORIZED));
169 } else if (xhrResponse.status == 502 || xhrResponse.status == 503) { 180 } else if (xhrResponse.status == 502 || xhrResponse.status == 503) {
170 that.handleError(new remoting.Error( 181 that.onError_(new remoting.Error(
171 remoting.Error.Tag.SERVICE_UNAVAILABLE)); 182 remoting.Error.Tag.SERVICE_UNAVAILABLE));
172 } else { 183 } else {
173 that.handleError(remoting.Error.unexpected()); 184 that.onError_(remoting.Error.unexpected());
174 } 185 }
175 } 186 }
176 }; 187 };
177 188
178 new remoting.Xhr({ 189 new remoting.Xhr({
179 method: 'POST', 190 method: 'POST',
180 url: that.runApplicationUrl(), 191 url: that.runApplicationUrl_(),
181 oauthToken: token 192 oauthToken: token
182 }).start().then(parseAppHostResponse); 193 }).start().then(parseAppHostResponse);
183 }; 194 };
184 195
185 /** 196 /**
186 * Report an authentication error to the user. This is called in lieu of start() 197 * @override {remoting.ApplicationInterface}
187 * if the user cannot be authenticated or if they decline the app permissions.
188 *
189 * @param {!remoting.Error} error The failure reason.
190 */ 198 */
191 remoting.AppRemoting.prototype.signInFailed = function(error) { 199 remoting.AppRemoting.prototype.exitApplication_ = function() {
192 this.handleError(error); 200 remoting.LoadingWindow.close();
201 this.closeMainWindow_();
193 }; 202 };
194 203
195 /** 204 /**
196 * @return {string} Application product name to be used in UI. 205 * @param {remoting.ConnectionInfo} connectionInfo
206 * @override {remoting.ApplicationInterface}
197 */ 207 */
198 remoting.AppRemoting.prototype.getApplicationName = function() { 208 remoting.AppRemoting.prototype.onConnected_ = function(connectionInfo) {
199 var manifest = chrome.runtime.getManifest(); 209 this.initSession_(connectionInfo);
200 return manifest.name;
201 };
202 210
203 /** @return {string} */
204 remoting.AppRemoting.prototype.runApplicationUrl = function() {
205 return remoting.settings.APP_REMOTING_API_BASE_URL + '/applications/' +
206 remoting.settings.getAppRemotingApplicationId() + '/run';
207 };
208
209 /**
210 * Called when a new session has been connected.
211 *
212 * @param {remoting.ConnectionInfo} connectionInfo
213 * @return {void} Nothing.
214 */
215 remoting.AppRemoting.prototype.handleConnected = function(connectionInfo) {
216 remoting.identity.getUserInfo().then( 211 remoting.identity.getUserInfo().then(
217 function(userInfo) { 212 function(userInfo) {
218 remoting.clientSession.sendClientMessage( 213 remoting.clientSession.sendClientMessage(
219 'setUserDisplayInfo', 214 'setUserDisplayInfo',
220 JSON.stringify({fullName: userInfo.name})); 215 JSON.stringify({fullName: userInfo.name}));
221 }); 216 });
222 217
223 remoting.app.getSessionConnector().registerProtocolExtension(this); 218 this.sessionConnector_.registerProtocolExtension(this);
224 219
225 this.connectedView_ = new remoting.AppConnectedView( 220 this.connectedView_ = new remoting.AppConnectedView(
226 document.getElementById('client-container'), connectionInfo); 221 document.getElementById('client-container'), connectionInfo);
227 222
228 // Map Cmd to Ctrl on Mac since hosts typically use Ctrl for keyboard 223 // Map Cmd to Ctrl on Mac since hosts typically use Ctrl for keyboard
229 // shortcuts, but we want them to act as natively as possible. 224 // shortcuts, but we want them to act as natively as possible.
230 if (remoting.platformIsMac()) { 225 if (remoting.platformIsMac()) {
231 connectionInfo.plugin().setRemapKeys('0x0700e3>0x0700e0,0x0700e7>0x0700e4'); 226 connectionInfo.plugin().setRemapKeys('0x0700e3>0x0700e0,0x0700e7>0x0700e4');
232 } 227 }
233 }; 228 };
234 229
235 /** 230 /**
236 * Called when the current session has been disconnected. 231 * @override {remoting.ApplicationInterface}
237 *
238 * @return {void} Nothing.
239 */ 232 */
240 remoting.AppRemoting.prototype.handleDisconnected = function() { 233 remoting.AppRemoting.prototype.onDisconnected_ = function() {
241 base.dispose(this.connectedView_); 234 base.dispose(this.connectedView_);
242 this.connectedView_ = null; 235 this.connectedView_ = null;
243 236
244 chrome.app.window.current().close(); 237 chrome.app.window.current().close();
245 }; 238 };
246 239
247 /** 240 /**
248 * Called when the current session's connection has failed.
249 *
250 * @param {remoting.SessionConnector} connector
251 * @param {!remoting.Error} error 241 * @param {!remoting.Error} error
252 * @return {void} Nothing. 242 * @override {remoting.ApplicationInterface}
253 */ 243 */
254 remoting.AppRemoting.prototype.handleConnectionFailed = function( 244 remoting.AppRemoting.prototype.onConnectionFailed_ = function(error) {
255 connector, error) { 245 this.onError_(error);
256 this.handleError(error);
257 }; 246 };
258 247
259 /** @return {Array<string>} */ 248 /**
249 * @param {!remoting.Error} error The error to be localized and displayed.
250 * @override {remoting.ApplicationInterface}
251 */
252 remoting.AppRemoting.prototype.onError_ = function(error) {
253 console.error('Connection failed: ' + error.toString());
254 remoting.LoadingWindow.close();
255 remoting.MessageWindow.showErrorMessage(
256 chrome.i18n.getMessage(/*i18n-content*/'CONNECTION_FAILED'),
257 chrome.i18n.getMessage(error.getTag()));
258 };
259
260
261 /**
262 * @return {Array<string>}
263 * @override {remoting.ProtocolExtension}
264 */
260 remoting.AppRemoting.prototype.getExtensionTypes = function() { 265 remoting.AppRemoting.prototype.getExtensionTypes = function() {
261 return ['openURL', 'onWindowRemoved', 'onWindowAdded', 266 return ['openURL', 'onWindowRemoved', 'onWindowAdded',
262 'onAllWindowsMinimized', 'setKeyboardLayouts', 'pingResponse']; 267 'onAllWindowsMinimized', 'setKeyboardLayouts', 'pingResponse'];
263 }; 268 };
264 269
265 /** 270 /**
266 * @param {function(string,string)} sendMessageToHost Callback to send a message 271 * @param {function(string,string)} sendMessageToHost Callback to send a message
267 * to the host. 272 * to the host.
273 * @override {remoting.ProtocolExtension}
268 */ 274 */
269 remoting.AppRemoting.prototype.startExtension = function(sendMessageToHost) { 275 remoting.AppRemoting.prototype.startExtension = function(sendMessageToHost) {
270 }; 276 };
271 277
272 /** 278 /**
273 * @param {string} type The message type. 279 * @param {string} type The message type.
274 * @param {Object} message The parsed extension message data. 280 * @param {Object} message The parsed extension message data.
281 * @override {remoting.ProtocolExtension}
275 */ 282 */
276 remoting.AppRemoting.prototype.onExtensionMessage = function(type, message) { 283 remoting.AppRemoting.prototype.onExtensionMessage = function(type, message) {
277 switch (type) { 284 switch (type) {
278 285
279 case 'openURL': 286 case 'openURL':
280 // URL requests from the hosted app are untrusted, so disallow anything 287 // URL requests from the hosted app are untrusted, so disallow anything
281 // other than HTTP or HTTPS. 288 // other than HTTP or HTTPS.
282 var url = base.getStringAttr(message, 'url'); 289 var url = base.getStringAttr(message, 'url');
283 if (url.indexOf('http:') != 0 && url.indexOf('https:') != 0) { 290 if (url.indexOf('http:') != 0 && url.indexOf('https:') != 0) {
284 console.error('Bad URL: ' + url); 291 console.error('Bad URL: ' + url);
(...skipping 29 matching lines...) Expand all
314 var then = base.getNumberAttr(message, 'timestamp'); 321 var then = base.getNumberAttr(message, 'timestamp');
315 var now = new Date().getTime(); 322 var now = new Date().getTime();
316 this.contextMenu_.updateConnectionRTT(now - then); 323 this.contextMenu_.updateConnectionRTT(now - then);
317 return true; 324 return true;
318 } 325 }
319 326
320 return false; 327 return false;
321 }; 328 };
322 329
323 /** 330 /**
324 * Called when an error needs to be displayed to the user. 331 * @return {string}
325 * 332 * @private
326 * @param {!remoting.Error} error The error to be localized and displayed.
327 * @return {void} Nothing.
328 */ 333 */
329 remoting.AppRemoting.prototype.handleError = function(error) { 334 remoting.AppRemoting.prototype.runApplicationUrl_ = function() {
330 console.error('Connection failed: ' + error.toString()); 335 return remoting.settings.APP_REMOTING_API_BASE_URL + '/applications/' +
331 remoting.LoadingWindow.close(); 336 remoting.settings.getAppRemotingApplicationId() + '/run';
332 remoting.MessageWindow.showErrorMessage(
333 chrome.i18n.getMessage(/*i18n-content*/'CONNECTION_FAILED'),
334 chrome.i18n.getMessage(error.getTag()));
335 }; 337 };
336
337 /**
338 * Close the loading window before exiting.
339 */
340 remoting.AppRemoting.prototype.handleExit = function() {
341 remoting.LoadingWindow.close();
342 };
OLDNEW
« no previous file with comments | « no previous file | remoting/webapp/app_remoting/js/ar_main.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698