1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/webapprt/Startup.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,155 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* This module is imported at the startup of an application. It takes care of 1.9 + * permissions installation, application url loading, security settings. Put 1.10 + * stuff here that you want to happen once on startup before the webapp is 1.11 + * loaded. */ 1.12 + 1.13 +this.EXPORTED_SYMBOLS = ["startup"]; 1.14 + 1.15 +const Ci = Components.interfaces; 1.16 +const Cu = Components.utils; 1.17 + 1.18 +Cu.import("resource://gre/modules/Services.jsm"); 1.19 +Cu.import("resource://gre/modules/AppsUtils.jsm"); 1.20 +Cu.import("resource://gre/modules/PermissionsInstaller.jsm"); 1.21 +Cu.import('resource://gre/modules/Payment.jsm'); 1.22 +Cu.import('resource://gre/modules/AlarmService.jsm'); 1.23 +Cu.import("resource://gre/modules/Task.jsm"); 1.24 +Cu.import("resource://gre/modules/Promise.jsm"); 1.25 +Cu.import("resource://gre/modules/osfile.jsm"); 1.26 + 1.27 +Cu.import("resource://webapprt/modules/WebappRT.jsm"); 1.28 +Cu.import("resource://webapprt/modules/WebRTCHandler.jsm"); 1.29 + 1.30 +const PROFILE_DIR = OS.Constants.Path.profileDir; 1.31 + 1.32 +function isFirstRunOrUpdate() { 1.33 + let savedBuildID = null; 1.34 + try { 1.35 + savedBuildID = Services.prefs.getCharPref("webapprt.buildID"); 1.36 + } catch (e) {} 1.37 + 1.38 + let ourBuildID = Services.appinfo.platformBuildID; 1.39 + 1.40 + if (ourBuildID != savedBuildID) { 1.41 + Services.prefs.setCharPref("webapprt.buildID", ourBuildID); 1.42 + return true; 1.43 + } 1.44 + 1.45 + return false; 1.46 +} 1.47 + 1.48 +function writeFile(aPath, aData) { 1.49 + return Task.spawn(function() { 1.50 + let data = new TextEncoder().encode(aData); 1.51 + yield OS.File.writeAtomic(aPath, data, { tmpPath: aPath + ".tmp" }); 1.52 + }); 1.53 +} 1.54 + 1.55 +function createBrandingFiles() { 1.56 + return Task.spawn(function() { 1.57 + let manifest = WebappRT.localeManifest; 1.58 + let name = WebappRT.localeManifest.name; 1.59 + let developer = " "; 1.60 + if (WebappRT.localeManifest.developer) { 1.61 + developer = WebappRT.localeManifest.developer.name; 1.62 + } 1.63 + 1.64 + let brandDTDContent = '<!ENTITY brandShortName "' + name + '">\n\ 1.65 + <!ENTITY brandFullName "' + name + '">\n\ 1.66 + <!ENTITY vendorShortName "' + developer + '">\n\ 1.67 + <!ENTITY trademarkInfo.part1 " ">'; 1.68 + 1.69 + yield writeFile(OS.Path.join(PROFILE_DIR, "brand.dtd"), brandDTDContent); 1.70 + 1.71 + let brandPropertiesContent = 'brandShortName=' + name + '\n\ 1.72 + brandFullName=' + name + '\n\ 1.73 + vendorShortName=' + developer; 1.74 + 1.75 + yield writeFile(OS.Path.join(PROFILE_DIR, "brand.properties"), 1.76 + brandPropertiesContent); 1.77 + }); 1.78 +} 1.79 + 1.80 +// Observes all the events needed to actually launch an application. 1.81 +// It waits for XUL window and webapps registry loading. 1.82 +this.startup = function(window) { 1.83 + return Task.spawn(function () { 1.84 + // Observe XUL window loading. 1.85 + // For tests, it could be already loaded. 1.86 + let deferredWindowLoad = Promise.defer(); 1.87 + if (window.document && window.document.getElementById("content")) { 1.88 + deferredWindowLoad.resolve(); 1.89 + } else { 1.90 + window.addEventListener("DOMContentLoaded", function onLoad() { 1.91 + window.removeEventListener("DOMContentLoaded", onLoad, false); 1.92 + deferredWindowLoad.resolve(); 1.93 + }); 1.94 + } 1.95 + 1.96 + let appUpdated = false; 1.97 + let updatePending = yield WebappRT.isUpdatePending(); 1.98 + if (updatePending) { 1.99 + appUpdated = yield WebappRT.applyUpdate(); 1.100 + } 1.101 + 1.102 + yield WebappRT.loadConfig(); 1.103 + 1.104 + let appData = WebappRT.config.app; 1.105 + 1.106 + // Initialize DOMApplicationRegistry by importing Webapps.jsm. 1.107 + Cu.import("resource://gre/modules/Webapps.jsm"); 1.108 + // Initialize window-independent handling of webapps- notifications. 1.109 + Cu.import("resource://webapprt/modules/WebappManager.jsm"); 1.110 + 1.111 + // Wait for webapps registry loading. 1.112 + yield DOMApplicationRegistry.registryStarted; 1.113 + // Add the currently running app to the registry. 1.114 + yield DOMApplicationRegistry.addInstalledApp(appData, appData.manifest, 1.115 + appData.updateManifest); 1.116 + 1.117 + let manifestURL = appData.manifestURL; 1.118 + if (manifestURL) { 1.119 + // On firstrun, set permissions to their default values. 1.120 + // When the webapp runtime is updated, update the permissions. 1.121 + if (isFirstRunOrUpdate(Services.prefs) || appUpdated) { 1.122 + PermissionsInstaller.installPermissions(appData, true); 1.123 + yield createBrandingFiles(); 1.124 + } 1.125 + } 1.126 + 1.127 + // Branding substitution 1.128 + let aliasFile = Components.classes["@mozilla.org/file/local;1"] 1.129 + .createInstance(Ci.nsIFile); 1.130 + aliasFile.initWithPath(PROFILE_DIR); 1.131 + 1.132 + let aliasURI = Services.io.newFileURI(aliasFile); 1.133 + 1.134 + Services.io.getProtocolHandler("resource") 1.135 + .QueryInterface(Ci.nsIResProtocolHandler) 1.136 + .setSubstitution("webappbranding", aliasURI); 1.137 + 1.138 + // Wait for XUL window loading 1.139 + yield deferredWindowLoad.promise; 1.140 + 1.141 + // Get the <browser> element in the webapp.xul window. 1.142 + let appBrowser = window.document.getElementById("content"); 1.143 + 1.144 + // Set the principal to the correct appID and launch the application. 1.145 + appBrowser.docShell.setIsApp(WebappRT.appID); 1.146 + appBrowser.setAttribute("src", WebappRT.launchURI); 1.147 + 1.148 + if (appData.manifest.fullscreen) { 1.149 + appBrowser.addEventListener("load", function onLoad() { 1.150 + appBrowser.removeEventListener("load", onLoad, true); 1.151 + appBrowser.contentDocument. 1.152 + documentElement.mozRequestFullScreen(); 1.153 + }, true); 1.154 + } 1.155 + 1.156 + WebappRT.startUpdateService(); 1.157 + }); 1.158 +}