Bumping manifests a=b2g-bump
[gecko.git] / webapprt / Startup.jsm
blob13284ab978f60faf1df78302b5a30835538e1515
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     // Override Toolkit's nsITransfer implementation with the one from the
146     // JavaScript API for downloads. This will eventually be removed when
147     // nsIDownloadManager will not be available anymore (bug 851471).
148     Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
149               .registerFactory(Components.ID("{1b4c85df-cbdd-4bb6-b04e-613caece083c}"),
150                                "", "@mozilla.org/transfer;1", null);
152     // Load these modules here because they aren't needed right at startup,
153     // but they need to be loaded to perform some initialization steps.
154     Cu.import("resource://gre/modules/Payment.jsm");
155     Cu.import("resource://gre/modules/AlarmService.jsm");
156     Cu.import("resource://webapprt/modules/WebRTCHandler.jsm");
157     Cu.import("resource://webapprt/modules/DownloadView.jsm");
159     // Get the <browser> element in the webapp.xul window.
160     let appBrowser = window.document.getElementById("content");
162     // Set the principal to the correct appID and launch the application.
163     appBrowser.docShell.setIsApp(WebappRT.appID);
164     appBrowser.setAttribute("src", WebappRT.launchURI);
166     if (appData.manifest.fullscreen) {
167       appBrowser.addEventListener("load", function onLoad() {
168         appBrowser.removeEventListener("load", onLoad, true);
169         appBrowser.contentDocument.
170           documentElement.mozRequestFullScreen();
171       }, true);
172     }
174     WebappRT.startUpdateService();
175   });