Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / remoting / webapp / crd / js / app_launcher.js
blob7441cc6716c9f378f1d9208344bc9db3ebfeea8c
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   return new Promise(function(resolve, reject) {
56     chrome.tabs.create({ url: url, selected: true }, function(/**Tab*/ tab){
57       if (!tab) {
58         reject(new Error(chrome.runtime.lastError.message));
59       } else {
60         resolve(String(tab.id));
61       }
62     });
63   });
66 remoting.V1AppLauncher.prototype.close = function(id) {
67   return new Promise(function(resolve, reject) {
68     chrome.tabs.get(parseInt(id, 10), function(/** Tab */ tab) {
69       if (!tab) {
70         reject(new Error(chrome.runtime.lastError.message));
71       } else {
72         chrome.tabs.remove(tab.id, resolve);
73       }
74     });
75   });
79 /**
80  * @constructor
81  * @implements {remoting.AppLauncher}
82  */
83 remoting.V2AppLauncher = function() {};
85 var APP_MAIN_URL = 'main.html';
87 /**
88  * @param {string} id
89  * @return {Promise<string>}  A promise that resolves with the id of the created
90  *     window, which is guaranteed to be the same as the current window id.
91  */
92 remoting.V2AppLauncher.prototype.restart = function(id) {
93   return this.close(id).then(function() {
94     return createWindow_({'id' : id, 'frame': 'none'});
95   }).then(function (/** string */ newId) {
96     console.assert(newId === id, 'restart() should preserve the window id.');
97     return newId;
98   });
102  * @param {!chrome.app.window.CreateWindowOptions=} opt_options
103  * @param {Object=} opt_launchArgs
104  * @return {Promise<string>} A promise that resolves with the id of the created
105  *     window.
106  */
107 function createWindow_(opt_options, opt_launchArgs) {
108   var url = base.urlJoin(APP_MAIN_URL, opt_launchArgs);
109   var deferred = new base.Deferred();
111   chrome.app.window.create(url, opt_options,
112     function(/** chrome.app.window.AppWindow= */ appWindow) {
113       if (!appWindow) {
114         deferred.reject(new Error(chrome.runtime.lastError.message));
115       } else {
116         deferred.resolve(appWindow.id);
117       }
118     });
119   return deferred.promise();
122 remoting.V2AppLauncher.prototype.launch = function(opt_launchArgs) {
123   var deferred = new base.Deferred();
124   var START_FULLSCREEN = 'start-fullscreen';
126   /** @param {Object} values */
127   var onValues = function(values) {
128     /** @type {string} */
129     var state = values[START_FULLSCREEN] ? 'fullscreen' : 'normal';
130     createWindow_({
131         'width': 800,
132         'height': 634,
133         'frame': 'none',
134         'id': String(getNextWindowId()),
135         'state': state
136     }, opt_launchArgs).then(
137       deferred.resolve.bind(deferred),
138       deferred.reject.bind(deferred)
139     );
140   };
141   chrome.storage.local.get(START_FULLSCREEN, onValues);
142   return deferred.promise();
145 remoting.V2AppLauncher.prototype.close = function(id) {
146   return new Promise(
147       /**
148        * @param {function(*=):void} resolve
149        * @param {function(*=):void} reject
150        */
151       function(resolve, reject) {
152         var appWindow = chrome.app.window.get(id);
153         if (!appWindow) {
154           return Promise.reject(new Error(chrome.runtime.lastError.message));
155         }
156         appWindow.onClosed.addListener(resolve);
157         appWindow.close();
158       });
162  * @return {number} The first available window id. Since Chrome remembers
163  *     properties such as size and position for app windows, it is better
164  *     to reuse window ids rather than allocating new ones.
165  */
166 function getNextWindowId() {
167   var appWindows = chrome.app.window.getAll();
168   var result = 1;
169   for (; result <= appWindows.length; ++result) {
170     if (!chrome.app.window.get(String(result))) {
171       break;
172     }
173   }
174   return result;
177 })();