Bug 1287107 - Move gaia to chrome:// URLs r?
MozReview-Commit-ID: HguO5sUeZx5
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -419,20 +419,17 @@ var shell = {
this.contentBrowser.addEventListener('mozbrowserloadstart', this, true);
this.contentBrowser.addEventListener('mozbrowserscrollviewchange', this, true);
this.contentBrowser.addEventListener('mozbrowsercaretstatechanged', this);
CustomEventManager.init();
UserAgentOverrides.init();
CaptivePortalLoginHelper.init();
- Cu.import("resource://gre/modules/AppPermissions.jsm");
- PermissionsInstaller.setAllPermissions().then(() => {
- this.contentBrowser.src = homeURL;
- });
+ this.contentBrowser.src = homeURL;
this._isEventListenerReady = false;
window.performance.mark('gecko-shell-system-frame-set');
ppmm.addMessageListener("content-handler", this);
ppmm.addMessageListener("dial-handler", this);
ppmm.addMessageListener("sms-handler", this);
deleted file mode 100644
--- a/b2g/components/AppPermissions.jsm
+++ /dev/null
@@ -1,257 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cc = Components.classes;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/PermissionSettings.jsm");
-Cu.import("resource://gre/modules/PermissionsTable.jsm");
-
-this.EXPORTED_SYMBOLS = ["PermissionsInstaller"];
-const UNKNOWN_ACTION = Ci.nsIPermissionManager.UNKNOWN_ACTION;
-const ALLOW_ACTION = Ci.nsIPermissionManager.ALLOW_ACTION;
-const DENY_ACTION = Ci.nsIPermissionManager.DENY_ACTION;
-const PROMPT_ACTION = Ci.nsIPermissionManager.PROMPT_ACTION;
-
-// Permission access flags
-const READONLY = "readonly";
-const CREATEONLY = "createonly";
-const READCREATE = "readcreate";
-const READWRITE = "readwrite";
-
-const PERM_TO_STRING = ["unknown", "allow", "deny", "prompt"];
-
-function debug(aMsg) {
- //dump("-*-*- AppPermissions.jsm : " + aMsg + "\n");
-}
-
- /**
- * Resolves to a json file.
- */
-function loadJSON(url) {
- return new Promise((aResolve, aReject) => {
- debug("Loading resource " + url);
-
- let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
- .createInstance(Ci.nsIXMLHttpRequest);
- xhr.mozBackgroundRequest = true;
- xhr.open("GET", url);
- xhr.responseType = "json";
- xhr.addEventListener("load", () => {
- if (xhr.status >= 200 && xhr.status < 400) {
- debug("Success loading " + url);
- aResolve(xhr.response);
- } else {
- aReject("Error loading " + url);
- }
- });
- xhr.addEventListener("error", () => {
- aReject("Error loading " + url);
- });
- xhr.send(null);
- });
-}
-
-this.PermissionsInstaller = {
- /**
- * Install permissisions or remove deprecated permissions upon re-install.
- * @param object aApp
- * The just-installed app configuration.
- * The properties used are manifestURL, origin and manifest.
- * @param boolean aIsReinstall
- * Indicates the app was just re-installed
- * @returns bool indicating whether an error occured or not.
- **/
- installPermissions: function installPermissions(aApp, aIsReinstall) {
- try {
- let newManifest = aApp.manifest;
- if (!newManifest.permissions && !aIsReinstall) {
- return;
- }
-
- if (aIsReinstall) {
- // Compare the original permissions against the new permissions
- // Remove any deprecated Permissions
-
- if (newManifest.permissions) {
- // Expand permission names.
- let newPermNames = [];
- for (let permName in newManifest.permissions) {
- let expandedPermNames =
- expandPermissions(permName,
- newManifest.permissions[permName].access);
- newPermNames = newPermNames.concat(expandedPermNames);
- }
-
- newPermNames.push("indexedDB");
-
- // Add the appcache related permissions.
- if (newManifest.appcache_path) {
- newPermNames = newPermNames.concat(["offline-app", "pin-app"]);
- }
-
- for (let idx in AllPossiblePermissions) {
- let permName = AllPossiblePermissions[idx];
- let index = newPermNames.indexOf(permName);
- if (index == -1) {
- // See if the permission was installed previously.
- let permValue =
- PermissionSettingsModule.getPermission(permName,
- aApp.manifestURL,
- aApp.origin,
- false);
- if (permValue == "unknown" || permValue == "deny") {
- // All 'deny' permissions should be preserved
- continue;
- }
- // Remove the deprecated permission
- PermissionSettingsModule.removePermission(permName,
- aApp.manifestURL,
- aApp.origin,
- false);
- }
- }
- }
- }
-
- // Check to see if the 'webapp' is app/privileged/certified.
- let appStatus = newManifest.type;
-
- this._setPermission("indexedDB", "allow", aApp);
-
- // Add the appcache related permissions. We allow it for all kinds of
- // apps.
- if (newManifest.appcache_path) {
- this._setPermission("offline-app", "allow", aApp);
- this._setPermission("pin-app", "allow", aApp);
- }
-
- for (let permName in newManifest.permissions) {
- if (!PermissionsTable[permName]) {
- Cu.reportError("PermissionsInstaller.jsm: '" + permName + "'" +
- " is not a valid Webapps permission name.");
- dump("PermissionsInstaller.jsm: '" + permName + "'" +
- " is not a valid Webapps permission name. " + aApp.origin);
- continue;
- }
-
- let expandedPermNames =
- expandPermissions(permName,
- newManifest.permissions[permName].access);
- for (let idx in expandedPermNames) {
-
- let isPromptPermission =
- PermissionsTable[permName][appStatus] === PROMPT_ACTION;
-
- // We silently upgrade the permission to whatever the permission
- // is for certified apps (ALLOW or PROMPT) only if the
- // following holds true:
- // * The app is preinstalled
- // * The permission that would be granted is PROMPT
- // * The app is privileged
- let permission =
- aApp.isPreinstalled && isPromptPermission &&
- appStatus === "privileged"
- ? PermissionsTable[permName]["certified"]
- : PermissionsTable[permName][appStatus];
-
- let permValue = PERM_TO_STRING[permission];
- if (isPromptPermission) {
- // If the permission is prompt, keep the current value. This will
- // work even on a system update, with the caveat that if a
- // ALLOW/DENY permission is changed to PROMPT then the system should
- // inform the user that he can now change a permission that he could
- // not change before.
- permValue =
- PermissionSettingsModule.getPermission(expandedPermNames[idx],
- aApp.manifestURL,
- aApp.origin,
- false,
- aApp.isCachedPackage);
- if (permValue === "unknown") {
- permValue = PERM_TO_STRING[permission];
- }
- }
-
- this._setPermission(expandedPermNames[idx], permValue, aApp);
- }
- }
- }
- catch (ex) {
- dump("Caught webapps install permissions error for " + aApp.origin +
- " : " + ex + "\n");
- Cu.reportError(ex);
- return false;
- }
- return true;
- },
-
- /**
- * Set a permission value.
- * @param string aPermName
- * The permission name.
- * @param string aPermValue
- * The permission value.
- * @param object aApp
- * The just-installed app configuration.
- * The properties used are manifestURL, origin, appId, isCachedPackage.
- * @returns void
- **/
- _setPermission: function setPermission(aPermName, aPermValue, aApp) {
- debug(`setPermission ${aPermName} -> ${aPermValue} for ${aApp.origin}`);
- PermissionSettingsModule.addPermission({
- type: aPermName,
- origin: aApp.origin,
- manifestURL: aApp.manifestURL,
- value: aPermValue,
- browserFlag: false,
- localId: aApp.localId,
- isCachedPackage: aApp.isCachedPackage,
- });
- },
-
- processApp: function(aApp) {
- return new Promise((aResolve, aReject) => {
- debug(`Processing ${aApp}`);
- loadJSON(`http://localhost/${aApp}/manifest.webapp`)
- .then(aManifest => {
- debug(`Got manifest for ${aApp}`);
- let data = {
- isCachedPackage: true,
- origin: "http://localhost/^inBrowser=1", // welcome to hack-land.
- manifest: aManifest
- }
- if (this.installPermissions(data, false)) {
- aResolve();
- } else {
- aReject();
- }
- })
- .catch(err => {
- aReject(err);
- })
- });
- },
-
- setAllPermissions(aRootURL) {
- debug("setAllPermissions");
- return loadJSON("file:///system/b2g/apps/webapps.json")
- .then(apps => {
- let promises = [];
- for (let app in apps) {
- // For each app, load the webapps.manifest file and process the
- // permissions.
- promises.push(this.processApp(app));
- }
- return Promise.all(promises);
- })
- .catch(err => {
- debug(`Error loading webapps.json : ${err}`);
- });
- }
-};
new file mode 100644
--- /dev/null
+++ b/b2g/components/GaiaChrome.cpp
@@ -0,0 +1,188 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GaiaChrome.h"
+
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsChromeRegistry.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsLocalFile.h"
+#include "nsXULAppAPI.h"
+
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/ModuleUtils.h"
+#include "mozilla/Services.h"
+#include "mozilla/FileLocation.h"
+
+#define NS_GAIACHROME_CID \
+ { 0x83f8f999, 0x6b87, 0x4dd8, { 0xa0, 0x93, 0x72, 0x0b, 0xfb, 0x67, 0x4d, 0x38 } }
+
+using namespace mozilla;
+
+StaticRefPtr<GaiaChrome> gGaiaChrome;
+
+NS_IMPL_ISUPPORTS(GaiaChrome, nsIGaiaChrome)
+
+GaiaChrome::GaiaChrome()
+ : mPackageName(NS_LITERAL_CSTRING("gaia"))
+ , mAppsDir(NS_LITERAL_STRING("apps"))
+ , mDataRoot(NS_LITERAL_STRING("/data/local"))
+ , mSystemRoot(NS_LITERAL_STRING("/system/b2g"))
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ GetProfileDir();
+ Register();
+}
+
+//virtual
+GaiaChrome::~GaiaChrome()
+{
+}
+
+nsresult
+GaiaChrome::GetProfileDir()
+{
+ nsCOMPtr<nsIFile> profDir;
+ nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+ getter_AddRefs(profDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = profDir->Clone(getter_AddRefs(mProfDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+}
+
+nsresult
+GaiaChrome::ComputeAppsPath(nsIFile* aPath)
+{
+#if defined(MOZ_MULET)
+ aPath->InitWithFile(mProfDir);
+#elif defined(MOZ_WIDGET_GONK)
+ nsCOMPtr<nsIFile> locationDetection = new nsLocalFile();
+ locationDetection->InitWithPath(mSystemRoot);
+ locationDetection->Append(mAppsDir);
+ bool appsInSystem = EnsureIsDirectory(locationDetection);
+ locationDetection->InitWithPath(mDataRoot);
+ locationDetection->Append(mAppsDir);
+ bool appsInData = EnsureIsDirectory(locationDetection);
+
+ if (!appsInData && !appsInSystem) {
+ printf_stderr("!!! NO root directory with apps found\n");
+ MOZ_ASSERT(false);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ aPath->InitWithPath(appsInData ? mDataRoot : mSystemRoot);
+#else
+ return NS_ERROR_UNEXPECTED;
+#endif
+
+ aPath->Append(mAppsDir);
+ aPath->Append(NS_LITERAL_STRING("."));
+
+ nsresult rv = EnsureValidPath(aPath);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+}
+
+bool
+GaiaChrome::EnsureIsDirectory(nsIFile* aPath)
+{
+ bool isDir = false;
+ aPath->IsDirectory(&isDir);
+ return isDir;
+}
+
+nsresult
+GaiaChrome::EnsureValidPath(nsIFile* appsDir)
+{
+ // Ensure there is a valid "apps/system" directory
+ nsCOMPtr<nsIFile> systemAppDir = new nsLocalFile();
+ systemAppDir->InitWithFile(appsDir);
+ systemAppDir->Append(NS_LITERAL_STRING("system"));
+
+ bool hasSystemAppDir = EnsureIsDirectory(systemAppDir);
+ if (!hasSystemAppDir) {
+ nsCString path; appsDir->GetNativePath(path);
+ // We don't want to continue if the apps path does not exists ...
+ printf_stderr("!!! Gaia chrome package is not a directory: %s\n", path.get());
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+GaiaChrome::Register()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(nsChromeRegistry::gChromeRegistry != nullptr);
+
+ nsCOMPtr<nsIFile> aPath = new nsLocalFile();
+ nsresult rv = ComputeAppsPath(aPath);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ FileLocation appsLocation(aPath);
+ nsCString uri;
+ appsLocation.GetURIString(uri);
+
+ char* argv[2];
+ argv[0] = (char*)mPackageName.get();
+ argv[1] = (char*)uri.get();
+
+ nsChromeRegistry::ManifestProcessingContext cx(NS_APP_LOCATION, appsLocation);
+ nsChromeRegistry::gChromeRegistry->ManifestContent(cx, 0, argv, 0);
+
+ return NS_OK;
+}
+
+already_AddRefed<GaiaChrome>
+GaiaChrome::FactoryCreate()
+{
+ if (!XRE_IsParentProcess()) {
+ return nullptr;
+ }
+
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!gGaiaChrome) {
+ gGaiaChrome = new GaiaChrome();
+ ClearOnShutdown(&gGaiaChrome);
+ }
+
+ RefPtr<GaiaChrome> service = gGaiaChrome.get();
+ return service.forget();
+}
+
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(GaiaChrome,
+ GaiaChrome::FactoryCreate)
+
+NS_DEFINE_NAMED_CID(NS_GAIACHROME_CID);
+
+static const mozilla::Module::CIDEntry kGaiaChromeCIDs[] = {
+ { &kNS_GAIACHROME_CID, false, nullptr, GaiaChromeConstructor },
+ { nullptr }
+};
+
+static const mozilla::Module::ContractIDEntry kGaiaChromeContracts[] = {
+ { "@mozilla.org/b2g/gaia-chrome;1", &kNS_GAIACHROME_CID },
+ { nullptr }
+};
+
+static const mozilla::Module::CategoryEntry kGaiaChromeCategories[] = {
+ { "profile-after-change", "Gaia Chrome Registration", GAIACHROME_CONTRACTID },
+ { nullptr }
+};
+
+static const mozilla::Module kGaiaChromeModule = {
+ mozilla::Module::kVersion,
+ kGaiaChromeCIDs,
+ kGaiaChromeContracts,
+ kGaiaChromeCategories
+};
+
+NSMODULE_DEFN(GaiaChromeModule) = &kGaiaChromeModule;
new file mode 100644
--- /dev/null
+++ b/b2g/components/GaiaChrome.h
@@ -0,0 +1,44 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef __GAIACHROME_H__
+#define __GAIACHROME_H__
+
+#include "nsIGaiaChrome.h"
+
+#include "nsIFile.h"
+
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+using namespace mozilla;
+
+class GaiaChrome final : public nsIGaiaChrome
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIGAIACHROME
+
+ static already_AddRefed<GaiaChrome>
+ FactoryCreate();
+
+private:
+ nsCString mPackageName;
+
+ nsAutoString mAppsDir;
+ nsAutoString mDataRoot;
+ nsAutoString mSystemRoot;
+
+ nsCOMPtr<nsIFile> mProfDir;
+
+ GaiaChrome();
+ ~GaiaChrome();
+
+ nsresult ComputeAppsPath(nsIFile*);
+ bool EnsureIsDirectory(nsIFile*);
+ nsresult EnsureValidPath(nsIFile*);
+ nsresult GetProfileDir();
+};
+
+#endif // __GAIACHROME_H__
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -50,17 +50,16 @@ if CONFIG['MOZ_UPDATER']:
EXTRA_COMPONENTS += [
'UpdatePrompt.js',
]
EXTRA_JS_MODULES += [
'AboutServiceWorkers.jsm',
'ActivityChannel.jsm',
'AlertsHelper.jsm',
- 'AppPermissions.jsm',
'Bootstraper.jsm',
'ContentRequestHelper.jsm',
'DebuggerActors.js',
'ErrorPage.jsm',
'Frames.jsm',
'FxAccountsMgmtService.jsm',
'LogCapture.jsm',
'LogParser.jsm',
@@ -75,12 +74,23 @@ EXTRA_JS_MODULES += [
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
EXTRA_JS_MODULES += [
'GlobalSimulatorScreen.jsm'
]
XPIDL_SOURCES += [
+ 'nsIGaiaChrome.idl',
'nsISystemMessagesInternal.idl'
]
XPIDL_MODULE = 'gaia_chrome'
+
+UNIFIED_SOURCES += [
+ 'GaiaChrome.cpp'
+]
+
+LOCAL_INCLUDES += [
+ '/chrome'
+]
+
+FINAL_LIBRARY = 'xul'
new file mode 100644
--- /dev/null
+++ b/b2g/components/nsIGaiaChrome.idl
@@ -0,0 +1,15 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(92a18a98-ab5d-4d02-a024-bdbb3bc89ce1)]
+interface nsIGaiaChrome : nsISupports
+{
+ void register();
+};
+
+%{ C++
+#define GAIACHROME_CONTRACTID "@mozilla.org/b2g/gaia-chrome;1"
+%}
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -226,16 +226,17 @@
@RESPATH@/components/exthelper.xpt
@RESPATH@/components/fastfind.xpt
@RESPATH@/components/feeds.xpt
#ifdef MOZ_GTK
@RESPATH@/components/filepicker.xpt
#endif
@RESPATH@/components/find.xpt
@RESPATH@/components/gfx.xpt
+@RESPATH@/components/gaia_chrome.xpt
@RESPATH@/components/hal.xpt
@RESPATH@/components/html5.xpt
@RESPATH@/components/htmlparser.xpt
@RESPATH@/components/identity.xpt
@RESPATH@/components/imglib2.xpt
@RESPATH@/components/inspector.xpt
@RESPATH@/components/intl.xpt
@RESPATH@/components/jar.xpt