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
3 // found in the LICENSE file.
7 * This class implements the functionality that is specific to desktop
8 * remoting ("Chromoting" or CRD).
13 /** @suppress {duplicate} */
14 var remoting = remoting || {};
18 * @implements {remoting.ApplicationInterface}
19 * @extends {remoting.Application}
21 remoting.DesktopRemoting = function() {
22 base.inherits(this, remoting.Application);
24 /** @protected {remoting.DesktopRemoting.Mode} */
25 this.connectionMode_ = remoting.DesktopRemoting.Mode.ME2ME;
27 /** @private {remoting.Activity} */
28 this.activity_ = null;
32 * The current desktop remoting mode (IT2Me or Me2Me).
36 remoting.DesktopRemoting.Mode = {
42 * Get the connection mode (Me2Me or IT2Me).
44 * @return {remoting.DesktopRemoting.Mode}
46 remoting.DesktopRemoting.prototype.getConnectionMode = function() {
47 return this.connectionMode_;
51 * @return {string} Application Id.
52 * @override {remoting.ApplicationInterface}
54 remoting.DesktopRemoting.prototype.getApplicationId = function() {
55 // Application IDs are not used in desktop remoting.
60 * @return {string} Application product name to be used in UI.
61 * @override {remoting.ApplicationInterface}
63 remoting.DesktopRemoting.prototype.getApplicationName = function() {
64 return chrome.i18n.getMessage(/*i18n-content*/'PRODUCT_NAME');
68 * @param {!remoting.Error} error The failure reason.
69 * @override {remoting.ApplicationInterface}
71 remoting.DesktopRemoting.prototype.signInFailed_ = function(error) {
72 remoting.showErrorMessage(error);
76 * @override {remoting.ApplicationInterface}
78 remoting.DesktopRemoting.prototype.initApplication_ = function() {
79 remoting.initElementEventHandlers();
81 if (remoting.platformIsWindows()) {
82 document.body.classList.add('os-windows');
83 } else if (remoting.platformIsMac()) {
84 document.body.classList.add('os-mac');
85 } else if (remoting.platformIsChromeOS()) {
86 document.body.classList.add('os-chromeos');
87 } else if (remoting.platformIsLinux()) {
88 document.body.classList.add('os-linux');
91 if (base.isAppsV2()) {
92 remoting.windowFrame = new remoting.WindowFrame(
93 document.getElementById('title-bar'), this.disconnect_.bind(this));
94 remoting.optionsMenu = remoting.windowFrame.createOptionsMenu();
96 var START_FULLSCREEN = 'start-fullscreen';
97 remoting.fullscreen = new remoting.FullscreenAppsV2();
98 remoting.fullscreen.addListener(function(isFullscreen) {
99 chrome.storage.local.set({START_FULLSCREEN: isFullscreen});
101 // TODO(jamiewalch): This should be handled by the background page when the
102 // window is created, but due to crbug.com/51587 it needs to be done here.
103 // Remove this hack once that bug is fixed.
104 chrome.storage.local.get(
106 /** @param {Object} values */
108 if (values[START_FULLSCREEN]) {
109 remoting.fullscreen.activate(true);
115 remoting.fullscreen = new remoting.FullscreenAppsV1();
116 remoting.toolbar = new remoting.Toolbar(
117 document.getElementById('session-toolbar'),
118 this.disconnect_.bind(this));
119 remoting.optionsMenu = remoting.toolbar.createOptionsMenu();
121 window.addEventListener('beforeunload',
122 this.promptClose_.bind(this), false);
123 window.addEventListener('unload', this.disconnect_.bind(this), false);
126 remoting.initHostlist_(this.connectMe2Me_.bind(this));
127 document.getElementById('access-mode-button').addEventListener(
128 'click', this.connectIt2Me_.bind(this), false);
130 remoting.manageHelpAndFeedback(
131 document.getElementById('title-bar'));
133 remoting.showOrHideIT2MeUi();
134 remoting.showOrHideMe2MeUi();
136 // For Apps v1, check the tab type to warn the user if they are not getting
137 // the best keyboard experience.
138 if (!base.isAppsV2() && !remoting.platformIsMac()) {
139 /** @param {boolean} isWindowed */
140 var onIsWindowed = function(isWindowed) {
142 document.getElementById('startup-mode-box-me2me').hidden = false;
143 document.getElementById('startup-mode-box-it2me').hidden = false;
146 this.isWindowed_(onIsWindowed);
149 remoting.ClientPlugin.factory.preloadPlugin();
153 * @param {string} token An OAuth access token.
154 * @override {remoting.ApplicationInterface}
156 remoting.DesktopRemoting.prototype.startApplication_ = function(token) {
157 remoting.identity.getEmail().then(
158 function(/** string */ email) {
159 document.getElementById('current-email').innerText = email;
160 document.getElementById('get-started-it2me').disabled = false;
161 document.getElementById('get-started-me2me').disabled = false;
165 /** @override {remoting.ApplicationInterface} */
166 remoting.DesktopRemoting.prototype.exitApplication_ = function() {
168 this.closeMainWindow_();
172 * Determine whether or not the app is running in a window.
173 * @param {function(boolean):void} callback Callback to receive whether or not
174 * the current tab is running in windowed mode.
177 remoting.DesktopRemoting.prototype.isWindowed_ = function(callback) {
178 var windowCallback = function(/** ChromeWindow */ win) {
179 callback(win.type == 'popup');
181 /** @param {Tab=} tab */
182 var tabCallback = function(tab) {
186 chrome.windows.get(tab.windowId, null, windowCallback);
190 chrome.tabs.getCurrent(tabCallback);
192 console.error('chome.tabs is not available.');
197 * If an IT2Me client or host is active then prompt the user before closing.
198 * If a Me2Me client is active then don't bother, since closing the window is
199 * the more intuitive way to end a Me2Me session, and re-connecting is easy.
202 remoting.DesktopRemoting.prototype.promptClose_ = function() {
203 if (this.getConnectionMode() === remoting.DesktopRemoting.Mode.IT2ME) {
204 switch (remoting.currentMode) {
205 case remoting.AppMode.CLIENT_CONNECTING:
206 case remoting.AppMode.HOST_WAITING_FOR_CODE:
207 case remoting.AppMode.HOST_WAITING_FOR_CONNECTION:
208 case remoting.AppMode.HOST_SHARED:
209 case remoting.AppMode.IN_SESSION:
210 return chrome.i18n.getMessage(/*i18n-content*/'CLOSE_PROMPT');
217 /** @returns {remoting.DesktopConnectedView} */
218 remoting.DesktopRemoting.prototype.getConnectedViewForTesting = function() {
219 var activity = /** @type {remoting.Me2MeActivity} */ (this.activity_);
220 return activity.getDesktopActivity().getConnectedView();
223 remoting.DesktopRemoting.prototype.getActivity = function() {
224 return this.activity_;
227 remoting.DesktopRemoting.prototype.disconnect_ = function() {
228 if (this.activity_) {
229 this.activity_.stop();
234 * Entry-point for Me2Me connections.
236 * @param {string} hostId The unique id of the host.
237 * @return {void} Nothing.
240 remoting.DesktopRemoting.prototype.connectMe2Me_ = function(hostId) {
241 var host = remoting.hostList.getHostForId(hostId);
242 base.dispose(this.activity_);
243 this.activity_ = new remoting.Me2MeActivity(host, remoting.hostList);
244 this.activity_.start();
245 this.connectionMode_ = remoting.DesktopRemoting.Mode.ME2ME;
249 * Entry-point for It2Me connections.
253 remoting.DesktopRemoting.prototype.connectIt2Me_ = function() {
254 base.dispose(this.activity_);
255 this.activity_ = new remoting.It2MeActivity();
256 this.activity_.start();
257 this.connectionMode_ = remoting.DesktopRemoting.Mode.IT2ME;