Rewrite AndroidSyncSettings to be significantly simpler.
[chromium-blink-merge.git] / remoting / webapp / crd / js / app_launcher.js
blob4bf03c74f8e8f16f1af22a11a626f25142752644
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.
5 /**
6  * @fileoverview
7  * AppLauncher is an interface that allows the client code to launch and close
8  * the app without knowing the implementation difference between a v1 app and
9  * a v2 app.
10  *
11  * To launch an app:
12  *   var appLauncher = new remoting.V1AppLauncher();
13  *   var appId = "";
14  *   appLauncher.launch({arg1:'someValue'}).then(function(id){
15  *    appId = id;
16  *   });
17  *
18  * To close an app:
19  *   appLauncher.close(appId);
20  */
22 /** @suppress {duplicate} */
23 var remoting = remoting || {};
25 (function() {
27 'use strict';
29 /** @interface */
30 remoting.AppLauncher = function() {};
32 /**
33  * @param {Object=} opt_launchArgs
34  * @return {Promise} The promise will resolve when the app is launched.  It will
35  * provide the caller with the appId (which is either the id of the hosting tab
36  * or window). The caller can use the appId to close the app.
37  */
38 remoting.AppLauncher.prototype.launch = function(opt_launchArgs) { };
40 /**
41  * @param {string} id  The id of the app to close.
42  * @return {Promise} The promise will resolve when the app is closed.
43  */
44 remoting.AppLauncher.prototype.close = function(id) {};
46 /**
47  * @constructor
48  * @implements {remoting.AppLauncher}
49  */
50 remoting.V1AppLauncher = function() {};
52 remoting.V1AppLauncher.prototype.launch = function(opt_launchArgs) {
53   var url = base.urlJoin('main.html', opt_launchArgs);
55   /**
56    * @param {function(*=):void} resolve
57    * @param {function(*=):void} reject
58    */
59   return new Promise(function(resolve, reject) {
60       chrome.tabs.create({ url: url, selected: true },
61         /** @param {chrome.Tab} tab The created tab. */
62         function(tab) {
63           if (!tab) {
64             reject(new Error(chrome.runtime.lastError.message));
65           } else {
66             resolve(String(tab.id));
67           }
68       });
69   });
72 remoting.V1AppLauncher.prototype.close = function(id) {
73   /**
74    * @param {function(*=):void} resolve
75    * @param {function(*=):void} reject
76    */
77   return new Promise(function(resolve, reject) {
78     /** @param {chrome.Tab} tab The retrieved tab. */
79     chrome.tabs.get(id, function(tab) {
80       if (!tab) {
81         reject(new Error(chrome.runtime.lastError.message));
82       } else {
83         chrome.tabs.remove(tab.id, /** @type {function(*=):void} */ (resolve));
84       }
85     });
86   });
90 /**
91  * @constructor
92  * @implements {remoting.AppLauncher}
93  */
94 remoting.V2AppLauncher = function() {};
96 var APP_MAIN_URL = 'main.html';
98 /**
99  * @param {string} id
100  */
101 remoting.V2AppLauncher.prototype.restart = function(id) {
102   this.close(id).then(function() {
103     // Not using the launch() method because we want to launch a new window with
104     // the same id, such that the size and positioning of the original window
105     // can be preserved.
106     return chrome.app.window.create(APP_MAIN_URL, {'id' : id, 'frame': 'none'});
107   });
110 remoting.V2AppLauncher.prototype.launch = function(opt_launchArgs) {
111   var url = base.urlJoin(APP_MAIN_URL, opt_launchArgs);
113   /**
114    * @param {function(*=):void} resolve
115    * @param {function(*=):void} reject
116    */
117   return new Promise(function(resolve, reject) {
118     var START_FULLSCREEN = 'start-fullscreen';
119     /** @param {Object} values */
120     var onValues = function(values) {
121       /** @type {string} */
122       var state = values[START_FULLSCREEN] ? 'fullscreen' : 'normal';
123       chrome.app.window.create(url, {
124           'width': 800,
125           'height': 600,
126           'frame': 'none',
127           'id': String(getNextWindowId()),
128           'state': state
129         },
130         /** @param {AppWindow=} appWindow */
131         function(appWindow) {
132           if (!appWindow) {
133             reject(new Error(chrome.runtime.lastError.message));
134           } else {
135             resolve(appWindow.id);
136           }
137         });
138     };
139     chrome.storage.local.get(START_FULLSCREEN, onValues);
140   });
143 remoting.V2AppLauncher.prototype.close = function(id) {
144   /**
145    * @param {function(*=):void} resolve
146    * @param {function(*=):void} reject
147    */
148   return new Promise(function(resolve, reject) {
149     var appWindow = chrome.app.window.get(id);
150     if (!appWindow) {
151       return Promise.reject(new Error(chrome.runtime.lastError.message));
152     }
153     appWindow.onClosed.addListener(resolve);
154     appWindow.close();
155   });
159  * @return {number} the next available window id.
160  */
161 function getNextWindowId() {
162   var appWindows = chrome.app.window.getAll();
163   var lastId = /** @type(number) */ (0);
164   appWindows.forEach(function(appWindow) {
165     base.debug.assert(Number.isInteger(appWindow.id),
166                       "Window Id should be an integer");
167     var id = parseInt(appWindow.id, 10);
168     if (lastId <= id) {
169       lastId = id;
170     }
171   });
172   return ++lastId;
175 })();