Bug 1039883 - release Tiled layer's gralloc when an application is background r=nical
[gecko.git] / webapprt / Startup.jsm
blobc4a16a6a4327f1e2c907863c9897c4b4719f4491
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /* This module is imported at the startup of an application.  It takes care of
6  * permissions installation, application url loading, security settings.  Put
7  * stuff here that you want to happen once on startup before the webapp is
8  * loaded.  */
10 this.EXPORTED_SYMBOLS = ["startup"];
12 const Ci = Components.interfaces;
13 const Cu = Components.utils;
15 /* We load here modules that are needed to perform the application startup.
16  * We lazily load modules that aren't needed on every startup.
17  * We load modules that aren't used here but that need to perform some
18  * initialization steps later in the startup function. */
20 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
21 Cu.import("resource://gre/modules/Services.jsm");
22 Cu.import("resource://gre/modules/Task.jsm");
23 Cu.import("resource://gre/modules/Promise.jsm");
24 Cu.import("resource://gre/modules/osfile.jsm");
26 Cu.import("resource://webapprt/modules/WebappRT.jsm");
28 // Lazily load these modules because we don't need them at every
29 // startup, but only during first run or runtime update.
31 XPCOMUtils.defineLazyModuleGetter(this, "PermissionsInstaller",
32   "resource://gre/modules/PermissionsInstaller.jsm");
34 const PROFILE_DIR = OS.Constants.Path.profileDir;
36 function isFirstRunOrUpdate() {
37   let savedBuildID = null;
38   try {
39     savedBuildID = Services.prefs.getCharPref("webapprt.buildID");
40   } catch (e) {}
42   let ourBuildID = Services.appinfo.platformBuildID;
44   if (ourBuildID != savedBuildID) {
45     Services.prefs.setCharPref("webapprt.buildID", ourBuildID);
46     return true;
47   }
49   return false;
52 function writeFile(aPath, aData) {
53   return Task.spawn(function() {
54     let data = new TextEncoder().encode(aData);
55     yield OS.File.writeAtomic(aPath, data, { tmpPath: aPath + ".tmp" });
56   });
59 function createBrandingFiles() {
60   return Task.spawn(function() {
61     let manifest = WebappRT.localeManifest;
62     let name = WebappRT.localeManifest.name;
63     let developer = " ";
64     if (WebappRT.localeManifest.developer) {
65       developer = WebappRT.localeManifest.developer.name;
66     }
68     let brandDTDContent = '<!ENTITY brandShortName "' + name + '">\n\
69   <!ENTITY brandFullName "' + name + '">\n\
70   <!ENTITY vendorShortName "' + developer + '">\n\
71   <!ENTITY trademarkInfo.part1 " ">';
73     yield writeFile(OS.Path.join(PROFILE_DIR, "brand.dtd"), brandDTDContent);
75     let brandPropertiesContent = 'brandShortName=' + name + '\n\
76   brandFullName=' + name + '\n\
77   vendorShortName=' + developer;
79     yield writeFile(OS.Path.join(PROFILE_DIR, "brand.properties"),
80                     brandPropertiesContent);
81   });
84 // Observes all the events needed to actually launch an application.
85 // It waits for XUL window and webapps registry loading.
86 this.startup = function(window) {
87   return Task.spawn(function () {
88     // Observe XUL window loading.
89     // For tests, it could be already loaded.
90     let deferredWindowLoad = Promise.defer();
91     if (window.document && window.document.getElementById("content")) {
92       deferredWindowLoad.resolve();
93     } else {
94       window.addEventListener("DOMContentLoaded", function onLoad() {
95         window.removeEventListener("DOMContentLoaded", onLoad, false);
96         deferredWindowLoad.resolve();
97       });
98     }
100     let appUpdated = false;
101     let updatePending = yield WebappRT.isUpdatePending();
102     if (updatePending) {
103       appUpdated = yield WebappRT.applyUpdate();
104     }
106     yield WebappRT.configPromise;
108     let appData = WebappRT.config.app;
110     // Initialize DOMApplicationRegistry by importing Webapps.jsm.
111     Cu.import("resource://gre/modules/Webapps.jsm");
112     // Initialize window-independent handling of webapps- notifications.
113     Cu.import("resource://webapprt/modules/WebappManager.jsm");
115     // Wait for webapps registry loading.
116     yield DOMApplicationRegistry.registryStarted;
117     // Add the currently running app to the registry.
118     yield DOMApplicationRegistry.addInstalledApp(appData, appData.manifest,
119                                                  appData.updateManifest);
121     let manifestURL = appData.manifestURL;
122     if (manifestURL) {
123       // On firstrun, set permissions to their default values.
124       // When the webapp runtime is updated, update the permissions.
125       if (isFirstRunOrUpdate(Services.prefs) || appUpdated) {
126         PermissionsInstaller.installPermissions(appData, true);
127         yield createBrandingFiles();
128       }
129     }
131     // Branding substitution
132     let aliasFile = Components.classes["@mozilla.org/file/local;1"]
133                               .createInstance(Ci.nsIFile);
134     aliasFile.initWithPath(PROFILE_DIR);
136     let aliasURI = Services.io.newFileURI(aliasFile);
138     Services.io.getProtocolHandler("resource")
139                .QueryInterface(Ci.nsIResProtocolHandler)
140                .setSubstitution("webappbranding", aliasURI);
142     // Wait for XUL window loading
143     yield deferredWindowLoad.promise;
145     // Load these modules here because they aren't needed right at startup,
146     // but they need to be loaded to perform some initialization steps.
147     Cu.import("resource://gre/modules/Payment.jsm");
148     Cu.import("resource://gre/modules/AlarmService.jsm");
149     Cu.import("resource://webapprt/modules/WebRTCHandler.jsm");
151     // Get the <browser> element in the webapp.xul window.
152     let appBrowser = window.document.getElementById("content");
154     // Set the principal to the correct appID and launch the application.
155     appBrowser.docShell.setIsApp(WebappRT.appID);
156     appBrowser.setAttribute("src", WebappRT.launchURI);
158     if (appData.manifest.fullscreen) {
159       appBrowser.addEventListener("load", function onLoad() {
160         appBrowser.removeEventListener("load", onLoad, true);
161         appBrowser.contentDocument.
162           documentElement.mozRequestFullScreen();
163       }, true);
164     }
166     WebappRT.startUpdateService();
167   });