mobile/android/chrome/content/WebappRT.js

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 let Cc = Components.classes;
michael@0 5 let Ci = Components.interfaces;
michael@0 6 let Cu = Components.utils;
michael@0 7
michael@0 8 Cu.import("resource://gre/modules/Services.jsm");
michael@0 9 Cu.import("resource://gre/modules/FileUtils.jsm");
michael@0 10 Cu.import("resource://gre/modules/NetUtil.jsm");
michael@0 11 Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
michael@0 12 Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
michael@0 13 Cu.import("resource://gre/modules/ContactService.jsm");
michael@0 14 #ifdef MOZ_ANDROID_SYNTHAPKS
michael@0 15 Cu.import("resource://gre/modules/AppsUtils.jsm");
michael@0 16
michael@0 17 XPCOMUtils.defineLazyModuleGetter(this, "Notifications", "resource://gre/modules/Notifications.jsm");
michael@0 18 #endif
michael@0 19
michael@0 20 function pref(name, value) {
michael@0 21 return {
michael@0 22 name: name,
michael@0 23 value: value
michael@0 24 }
michael@0 25 }
michael@0 26
michael@0 27 let WebappRT = {
michael@0 28 DEFAULT_PREFS_FILENAME: "default-prefs.js",
michael@0 29
michael@0 30 prefs: [
michael@0 31 // Disable all add-on locations other than the profile (which can't be disabled this way)
michael@0 32 pref("extensions.enabledScopes", 1),
michael@0 33 // Auto-disable any add-ons that are "dropped in" to the profile
michael@0 34 pref("extensions.autoDisableScopes", 1),
michael@0 35 // Disable add-on installation via the web-exposed APIs
michael@0 36 pref("xpinstall.enabled", false),
michael@0 37 // Set a future policy version to avoid the telemetry prompt.
michael@0 38 pref("toolkit.telemetry.prompted", 999),
michael@0 39 pref("toolkit.telemetry.notifiedOptOut", 999),
michael@0 40 pref("media.useAudioChannelService", true),
michael@0 41 pref("dom.mozTCPSocket.enabled", true),
michael@0 42 // Don't check for updates in webapp processes to avoid duplicate notifications.
michael@0 43 pref("browser.webapps.checkForUpdates", 0),
michael@0 44 ],
michael@0 45
michael@0 46 init: function(aStatus, aUrl, aCallback) {
michael@0 47 this.deck = document.getElementById("browsers");
michael@0 48 this.deck.addEventListener("click", this, false, true);
michael@0 49
michael@0 50 // on first run, update any prefs
michael@0 51 if (aStatus == "new") {
michael@0 52 this.getDefaultPrefs().forEach(this.addPref);
michael@0 53
michael@0 54 // update the blocklist url to use a different app id
michael@0 55 let blocklist = Services.prefs.getCharPref("extensions.blocklist.url");
michael@0 56 blocklist = blocklist.replace(/%APP_ID%/g, "webapprt-mobile@mozilla.org");
michael@0 57 Services.prefs.setCharPref("extensions.blocklist.url", blocklist);
michael@0 58 }
michael@0 59
michael@0 60 // On firstrun, set permissions to their default values.
michael@0 61 // When the webapp runtime is updated, update the permissions.
michael@0 62 if (aStatus == "new" || aStatus == "upgrade") {
michael@0 63 this.getManifestFor(aUrl, function (aManifest, aApp) {
michael@0 64 if (aManifest) {
michael@0 65 PermissionsInstaller.installPermissions(aApp, true);
michael@0 66 }
michael@0 67 });
michael@0 68 }
michael@0 69
michael@0 70 #ifdef MOZ_ANDROID_SYNTHAPKS
michael@0 71 // If the app is in debug mode, configure and enable the remote debugger.
michael@0 72 sendMessageToJava({ type: "NativeApp:IsDebuggable" }, (response) => {
michael@0 73 if (response.isDebuggable) {
michael@0 74 this._enableRemoteDebugger(aUrl);
michael@0 75 }
michael@0 76 });
michael@0 77 #endif
michael@0 78
michael@0 79 this.findManifestUrlFor(aUrl, aCallback);
michael@0 80 },
michael@0 81
michael@0 82 getManifestFor: function (aUrl, aCallback) {
michael@0 83 DOMApplicationRegistry.registryReady.then(() => {
michael@0 84 let request = navigator.mozApps.mgmt.getAll();
michael@0 85 request.onsuccess = function() {
michael@0 86 let apps = request.result;
michael@0 87 for (let i = 0; i < apps.length; i++) {
michael@0 88 let app = apps[i];
michael@0 89 let manifest = new ManifestHelper(app.manifest, app.origin);
michael@0 90
michael@0 91 // if this is a path to the manifest, or the launch path, then we have a hit.
michael@0 92 if (app.manifestURL == aUrl || manifest.fullLaunchPath() == aUrl) {
michael@0 93 aCallback(manifest, app);
michael@0 94 return;
michael@0 95 }
michael@0 96 }
michael@0 97
michael@0 98 // Otherwise, once we loop through all of them, we have a miss.
michael@0 99 aCallback(undefined);
michael@0 100 };
michael@0 101
michael@0 102 request.onerror = function() {
michael@0 103 // Treat an error like a miss. We can't find the manifest.
michael@0 104 aCallback(undefined);
michael@0 105 };
michael@0 106 });
michael@0 107 },
michael@0 108
michael@0 109 findManifestUrlFor: function(aUrl, aCallback) {
michael@0 110 this.getManifestFor(aUrl, function(aManifest, aApp) {
michael@0 111 if (!aManifest) {
michael@0 112 // we can't find the manifest, so open it like a web page
michael@0 113 aCallback(aUrl);
michael@0 114 return;
michael@0 115 }
michael@0 116
michael@0 117 BrowserApp.manifest = aManifest;
michael@0 118 BrowserApp.manifestUrl = aApp.manifestURL;
michael@0 119
michael@0 120 aCallback(aManifest.fullLaunchPath());
michael@0 121 });
michael@0 122 },
michael@0 123
michael@0 124 getDefaultPrefs: function() {
michael@0 125 // read default prefs from the disk
michael@0 126 try {
michael@0 127 let defaultPrefs = [];
michael@0 128 try {
michael@0 129 defaultPrefs = this.readDefaultPrefs(FileUtils.getFile("ProfD", [this.DEFAULT_PREFS_FILENAME]));
michael@0 130 } catch(ex) {
michael@0 131 // this can throw if the defaultprefs.js file doesn't exist
michael@0 132 }
michael@0 133 for (let i = 0; i < defaultPrefs.length; i++) {
michael@0 134 this.prefs.push(defaultPrefs[i]);
michael@0 135 }
michael@0 136 } catch(ex) {
michael@0 137 console.log("Error reading defaultPrefs file: " + ex);
michael@0 138 }
michael@0 139 return this.prefs;
michael@0 140 },
michael@0 141
michael@0 142 readDefaultPrefs: function webapps_readDefaultPrefs(aFile) {
michael@0 143 let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
michael@0 144 fstream.init(aFile, -1, 0, 0);
michael@0 145 let prefsString = NetUtil.readInputStreamToString(fstream, fstream.available(), {});
michael@0 146 return JSON.parse(prefsString);
michael@0 147 },
michael@0 148
michael@0 149 addPref: function(aPref) {
michael@0 150 switch (typeof aPref.value) {
michael@0 151 case "string":
michael@0 152 Services.prefs.setCharPref(aPref.name, aPref.value);
michael@0 153 break;
michael@0 154 case "boolean":
michael@0 155 Services.prefs.setBoolPref(aPref.name, aPref.value);
michael@0 156 break;
michael@0 157 case "number":
michael@0 158 Services.prefs.setIntPref(aPref.name, aPref.value);
michael@0 159 break;
michael@0 160 }
michael@0 161 },
michael@0 162
michael@0 163 #ifdef MOZ_ANDROID_SYNTHAPKS
michael@0 164 _enableRemoteDebugger: function(aUrl) {
michael@0 165 // Skip the connection prompt in favor of notifying the user below.
michael@0 166 Services.prefs.setBoolPref("devtools.debugger.prompt-connection", false);
michael@0 167
michael@0 168 // Automagically find a free port and configure the debugger to use it.
michael@0 169 let serv = Cc['@mozilla.org/network/server-socket;1'].createInstance(Ci.nsIServerSocket);
michael@0 170 serv.init(-1, true, -1);
michael@0 171 let port = serv.port;
michael@0 172 serv.close();
michael@0 173 Services.prefs.setIntPref("devtools.debugger.remote-port", port);
michael@0 174
michael@0 175 Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
michael@0 176
michael@0 177 // Notify the user that we enabled the debugger and which port it's using
michael@0 178 // so they can use the DevTools Connect… dialog to connect the client to it.
michael@0 179 DOMApplicationRegistry.registryReady.then(() => {
michael@0 180 let name;
michael@0 181 let app = DOMApplicationRegistry.getAppByManifestURL(aUrl);
michael@0 182 if (app) {
michael@0 183 name = app.name;
michael@0 184 } else {
michael@0 185 name = Strings.browser.GetStringFromName("remoteNotificationGenericName");
michael@0 186 }
michael@0 187
michael@0 188 Notifications.create({
michael@0 189 title: Strings.browser.formatStringFromName("remoteNotificationTitle", [name], 1),
michael@0 190 message: Strings.browser.formatStringFromName("remoteNotificationMessage", [port], 1),
michael@0 191 icon: "drawable://warning_doorhanger",
michael@0 192 });
michael@0 193 });
michael@0 194 },
michael@0 195 #endif
michael@0 196
michael@0 197 handleEvent: function(event) {
michael@0 198 let target = event.target;
michael@0 199
michael@0 200 // walk up the tree to find the nearest link tag
michael@0 201 while (target && !(target instanceof HTMLAnchorElement)) {
michael@0 202 target = target.parentNode;
michael@0 203 }
michael@0 204
michael@0 205 if (!target || target.getAttribute("target") != "_blank") {
michael@0 206 return;
michael@0 207 }
michael@0 208
michael@0 209 let uri = Services.io.newURI(target.href, target.ownerDocument.characterSet, null);
michael@0 210
michael@0 211 // Direct the URL to the browser.
michael@0 212 Cc["@mozilla.org/uriloader/external-protocol-service;1"].
michael@0 213 getService(Ci.nsIExternalProtocolService).
michael@0 214 getProtocolHandlerInfo(uri.scheme).
michael@0 215 launchWithURI(uri);
michael@0 216
michael@0 217 // Prevent the runtime from loading the URL. We do this after directing it
michael@0 218 // to the browser to give the runtime a shot at handling the URL if we fail
michael@0 219 // to direct it to the browser for some reason.
michael@0 220 event.preventDefault();
michael@0 221 }
michael@0 222 }

mercurial