Bug 686466 part 3 - Use a pre-generated nsXREAppData struct instead of application.ini. r=ted,bsmedberg
authorMike Hommey <mh+mozilla@glandium.org>
Tue, 22 Nov 2011 08:05:59 +0100
changeset 82268 696df30f6a51064c5f775f5357625c9082e027e0
parent 82267 234baeb36628a24c7602124d229a6fb4451a757c
child 82269 385846d8b780324ad3542052a3aa450d74975ff1
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted, bsmedberg
bugs686466
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 686466 part 3 - Use a pre-generated nsXREAppData struct instead of application.ini. r=ted,bsmedberg
browser/app/Makefile.in
browser/app/nsBrowserApp.cpp
browser/confvars.sh
build/Makefile.in
build/appini_header.py
build/application.ini
build/application.ini.in
config/autoconf.mk.in
configure.in
embedding/android/GeckoApp.java
mobile/xul/app/Makefile.in
mobile/xul/app/nsBrowserApp.cpp
mobile/xul/confvars.sh
toolkit/xre/Makefile.in
toolkit/xre/nsAndroidStartup.cpp
toolkit/xre/nsAppRunner.cpp
xpcom/build/BinaryPath.h
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -68,16 +68,17 @@ else
 
 PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
 
 CPPSRCS = nsBrowserApp.cpp
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
+LOCAL_INCLUDES += -I$(DEPTH)/build
 
 DEFINES += -DXPCOM_GLUE
 STL_FLAGS=
 
 LIBS += \
 	$(EXTRA_DSO_LIBS) \
 	$(XPCOM_STANDALONE_GLUE_LDOPTS) \
 	$(NULL)
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -31,18 +31,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "application.ini.h"
 #include "nsXPCOMGlue.h"
-#include "nsXULAppAPI.h"
 #if defined(XP_WIN)
 #include <windows.h>
 #include <stdlib.h>
 #elif defined(XP_UNIX)
 #include <sys/time.h>
 #include <sys/resource.h>
 #endif
 
@@ -135,30 +135,17 @@ static const nsDynamicFunctionLoad kXULF
     { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
     { "XRE_main", (NSFuncPtr*) &XRE_main },
     { nsnull, nsnull }
 };
 
 static int do_main(const char *exePath, int argc, char* argv[])
 {
   nsCOMPtr<nsILocalFile> appini;
-#ifdef XP_WIN
-  // exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8
-  // encoded path, so it is safe to convert it
-  nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), false,
-                                getter_AddRefs(appini));
-#else
-  nsresult rv = NS_NewNativeLocalFile(nsDependentCString(exePath), false,
-                                      getter_AddRefs(appini));
-#endif
-  if (NS_FAILED(rv)) {
-    return 255;
-  }
-
-  appini->SetNativeLeafName(NS_LITERAL_CSTRING("application.ini"));
+  nsresult rv;
 
   // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
   // Note that -app must be the *first* argument.
   const char *appDataFile = getenv("XUL_APP_FILE");
   if (appDataFile && *appDataFile) {
     rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
     if (NS_FAILED(rv)) {
       Output("Invalid path found: '%s'", appDataFile);
@@ -183,25 +170,42 @@ static int do_main(const char *exePath, 
       Output("Couldn't set %s.\n", appEnv);
       return 255;
     }
     argv[2] = argv[0];
     argv += 2;
     argc -= 2;
   }
 
-  nsXREAppData *appData;
-  rv = XRE_CreateAppData(appini, &appData);
-  if (NS_FAILED(rv)) {
-    Output("Couldn't read application.ini");
-    return 255;
+  int result;
+  if (appini) {
+    nsXREAppData *appData;
+    rv = XRE_CreateAppData(appini, &appData);
+    if (NS_FAILED(rv)) {
+      Output("Couldn't read application.ini");
+      return 255;
+    }
+    result = XRE_main(argc, argv, appData);
+    XRE_FreeAppData(appData);
+  } else {
+#ifdef XP_WIN
+    // exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8
+    // encoded path, so it is safe to convert it
+    rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), PR_FALSE,
+                         getter_AddRefs(appini));
+#else
+    rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_FALSE,
+                               getter_AddRefs(appini));
+#endif
+    if (NS_FAILED(rv)) {
+      return 255;
+    }
+    result = XRE_main(argc, argv, &sAppData);
   }
 
-  int result = XRE_main(argc, argv, appData);
-  XRE_FreeAppData(appData);
   return result;
 }
 
 int main(int argc, char* argv[])
 {
   char exePath[MAXPATHLEN];
 
   nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
@@ -235,16 +239,18 @@ int main(int argc, char* argv[])
   }
 
 
   rv = XPCOMGlueStartup(exePath);
   if (NS_FAILED(rv)) {
     Output("Couldn't load XPCOM.\n");
     return 255;
   }
+  // Reset exePath so that it is the directory name and not the xpcom dll name
+  *lastSlash = 0;
 
   rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
   if (NS_FAILED(rv)) {
     Output("Couldn't load XRE functions.\n");
     return 255;
   }
 
 #ifdef XRE_HAS_DLL_BLOCKLIST
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -49,8 +49,9 @@ MOZ_EXTENSIONS_DEFAULT=" gnomevfs"
 # MOZ_APP_DISPLAYNAME will be set by branding/configure.sh
 # Changing either of these values requires a clobber to ensure correct results,
 # because branding dependencies are broken.
 MOZ_BRANDING_DIRECTORY=browser/branding/nightly
 MOZ_OFFICIAL_BRANDING_DIRECTORY=browser/branding/official
 MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
 MOZ_PROFILE_MIGRATOR=1
 MOZ_EXTENSION_MANAGER=1
+MOZ_APP_STATIC_INI=1
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -66,25 +66,29 @@ ifeq (android,$(MOZ_WIDGET_TOOLKIT))
 endif
 endif
 
 ifdef MOZ_APP_BASENAME
 DIST_FILES = application.ini
 
 ifdef LIBXUL_SDK
 GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
+APP_INI_DEPS = $(LIBXUL_DIST)/bin/platform.ini
 else
 GRE_MILESTONE = $(shell tail -n 1 $(topsrcdir)/config/milestone.txt 2>/dev/null || tail -1 $(topsrcdir)/config/milestone.txt)
+APP_INI_DEPS = $(topsrcdir)/config/milestone.txt
 endif
 
 APP_BUILDID := $(shell cat $(DEPTH)/config/buildid)
+APP_INI_DEPS += $(DEPTH)/config/buildid
 
 DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DAPP_BUILDID=$(APP_BUILDID)
 
 DEFINES += -DMOZ_APP_VERSION="$(MOZ_APP_VERSION)"
+APP_INI_DEPS += $(DEPTH)/config/autoconf.mk
 
 MOZ_SOURCE_STAMP ?= $(firstword $(shell hg -R $(topsrcdir) parent --template="{node|short}\n" 2>/dev/null))
 ifdef MOZ_SOURCE_STAMP
 DEFINES += -DMOZ_SOURCE_STAMP="$(MOZ_SOURCE_STAMP)"
 endif
 
 _dollar=$$
 SOURCE_REPO := $(shell cd $(topsrcdir) && hg showconfig paths.default 2>/dev/null | head -n1 | sed -e "s/^ssh:/http:/" -e "s/\/$(_dollar)//" )
@@ -145,16 +149,29 @@ GARBAGE_DIRS += $(_LEAKTEST_DIR)
 		$(topsrcdir)/build/pgo/blueprint/fancytype-screen.css \
 		$(NULL)
 
 leaktest.py: leaktest.py.in
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $^ > $@
 	chmod +x $@
 GARBAGE += leaktest.py
 
+ifdef MOZ_APP_BASENAME
+application.ini: application.ini.in $(APP_INI_DEPS)
+	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@
+GARBAGE += application.ini
+
+ifdef MOZ_APP_STATIC_INI
+application.ini.h: appini_header.py application.ini 
+	$(PYTHON) $^ > $@
+export:: application.ini.h
+GARBAGE += application.ini.h
+endif
+endif
+
 libs:: $(_LEAKTEST_FILES)
 	$(INSTALL) $^ $(_LEAKTEST_DIR)
 
 ifdef MOZ_VALGRIND
 _VALGRIND_DIR = $(DEPTH)/_valgrind
 GARBAGE_DIRS += $(_VALGRIND_DIR)
 
 _VALGRIND_FILES = \
new file mode 100644
--- /dev/null
+++ b/build/appini_header.py
@@ -0,0 +1,86 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is a build helper for libraries
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mike Hommey <mh@glandium.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+'''Parses a given application.ini file and outputs the corresponding
+   XULAppData structure as a C++ header file'''
+
+import ConfigParser
+import sys
+
+def main(file):
+    config = ConfigParser.RawConfigParser()
+    config.read(file)
+    flags = set()
+    try:
+        if config.getint('XRE', 'EnableExtensionManager') == 1:
+            flags.add('NS_XRE_ENABLE_EXTENSION_MANAGER')
+    except: pass
+    try:
+        if config.getint('XRE', 'EnableProfileMigrator') == 1:
+            flags.add('NS_XRE_ENABLE_PROFILE_MIGRATOR')
+    except: pass
+    try:
+        if config.getint('Crash Reporter', 'Enabled') == 1:
+            flags.add('NS_XRE_ENABLE_CRASH_REPORTER')
+    except: pass
+    appdata = dict(("%s:%s" % (s, o), config.get(s, o)) for s in config.sections() for o in config.options(s))
+    appdata['flags'] = ' | '.join(flags) if flags else '0'
+    appdata['App:profile'] = '"%s"' % appdata['App:profile'] if 'App:profile' in appdata else 'NULL'
+
+    print '''#include "nsXULAppAPI.h"
+             static const nsXREAppData sAppData = {
+                 sizeof(nsXREAppData),
+                 NULL, // directory
+                 "%(App:vendor)s",
+                 "%(App:name)s",
+                 "%(App:version)s",
+                 "%(App:buildid)s",
+                 "%(App:id)s",
+                 NULL, // copyright
+                 %(flags)s,
+                 NULL, // xreDirectory
+                 "%(Gecko:minversion)s",
+                 "%(Gecko:maxversion)s",
+                 "%(Crash Reporter:serverurl)s",
+                 %(App:profile)s
+             };''' % appdata
+
+if __name__ == '__main__':
+    if len(sys.argv) != 1:
+        main(sys.argv[1])
+    else:
+        print >>sys.stderr, "Usage: %s /path/to/application.ini" % sys.argv[0]
rename from build/application.ini
rename to build/application.ini.in
--- a/build/application.ini
+++ b/build/application.ini.in
@@ -1,8 +1,13 @@
+#if MOZ_APP_STATIC_INI
+; This file is not used. If you modify it and want the application to use
+; your modifications, start with the "-app /path/to/application.ini"
+; argument.
+#endif
 #if 0
 ; ***** BEGIN LICENSE BLOCK *****
 ; Version: MPL 1.1/GPL 2.0/LGPL 2.1
 ;
 ; The contents of this file are subject to the Mozilla Public License Version
 ; 1.1 (the "License"); you may not use this file except in compliance with
 ; the License. You may obtain a copy of the License at
 ; http://www.mozilla.org/MPL/
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -53,16 +53,17 @@ MOZ_APP_BASENAME = @MOZ_APP_BASENAME@
 MOZ_APP_VENDOR = @MOZ_APP_VENDOR@
 MOZ_APP_PROFILE = @MOZ_APP_PROFILE@
 MOZ_APP_ID = @MOZ_APP_ID@
 MOZ_PROFILE_MIGRATOR = @MOZ_PROFILE_MIGRATOR@
 MOZ_EXTENSION_MANAGER = @MOZ_EXTENSION_MANAGER@
 MOZ_APP_UA_NAME = @MOZ_APP_UA_NAME@
 MOZ_APP_VERSION = @MOZ_APP_VERSION@
 MOZ_UA_BUILDID = @MOZ_UA_BUILDID@
+MOZ_APP_STATIC_INI = @MOZ_APP_STATIC_INI@
 
 MOZ_PKG_SPECIAL = @MOZ_PKG_SPECIAL@
 
 prefix		= @prefix@
 exec_prefix	= @exec_prefix@
 bindir		= @bindir@
 includedir	= @includedir@/$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)
 libdir		= @libdir@
--- a/configure.in
+++ b/configure.in
@@ -8530,16 +8530,23 @@ AC_SUBST(MOZ_APP_UA_NAME)
 AC_DEFINE_UNQUOTED(MOZ_APP_UA_VERSION, "$MOZ_APP_VERSION")
 AC_SUBST(MOZ_APP_VERSION)
 AC_DEFINE_UNQUOTED(MOZ_UA_FIREFOX_VERSION, "$FIREFOX_VERSION")
 AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIREFOX_VERSION)
 AC_SUBST(FIREFOX_VERSION)
 AC_DEFINE_UNQUOTED(MOZ_UA_BUILDID, "$MOZ_UA_BUILDID")
 AC_SUBST(MOZ_UA_BUILDID)
 
+# We can't use the static application.ini data when building against
+# a libxul SDK.
+if test -n "$LIBXUL_SDK"; then
+    MOZ_APP_STATIC_INI=
+fi
+AC_SUBST(MOZ_APP_STATIC_INI)
+
 AC_SUBST(MOZ_PKG_SPECIAL)
 
 AC_SUBST(MOZILLA_OFFICIAL)
 
 if test "$MOZ_TELEMETRY_REPORTING"; then
     AC_DEFINE(MOZ_TELEMETRY_REPORTING)
 fi
 
--- a/embedding/android/GeckoApp.java
+++ b/embedding/android/GeckoApp.java
@@ -613,17 +613,16 @@ abstract public class GeckoApp
         byte[] buf = new byte[32768];
         try {
             if (unpackFile(zip, buf, null, "removed-files"))
                 removeFiles();
         } catch (Exception ex) {
             // This file may not be there, so just log any errors and move on
             Log.w(LOG_FILE_NAME, "error removing files", ex);
         }
-        unpackFile(zip, buf, null, "application.ini");
         try {
             unpackFile(zip, buf, null, "update.locale");
         } catch (Exception e) {/* this is non-fatal */}
 
         // copy any .xpi file into an extensions/ directory
         Enumeration<? extends ZipEntry> zipEntries = zip.entries();
         while (zipEntries.hasMoreElements()) {
             ZipEntry entry = zipEntries.nextElement();
--- a/mobile/xul/app/Makefile.in
+++ b/mobile/xul/app/Makefile.in
@@ -50,16 +50,17 @@ ifndef LIBXUL_SDK
 ifneq (Android,$(OS_TARGET))
 PROGRAM=$(MOZ_APP_NAME)$(BIN_SUFFIX)
 
 CPPSRCS = nsBrowserApp.cpp
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
+LOCAL_INCLUDES += -I$(DEPTH)/build
 
 DEFINES += -DXPCOM_GLUE
 STL_FLAGS=
 
 LIBS += \
   $(EXTRA_DSO_LIBS) \
   $(XPCOM_STANDALONE_GLUE_LDOPTS) \
   $(NULL)
--- a/mobile/xul/app/nsBrowserApp.cpp
+++ b/mobile/xul/app/nsBrowserApp.cpp
@@ -31,18 +31,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "application.ini.h"
 #include "nsXPCOMGlue.h"
-#include "nsXULAppAPI.h"
 #if defined(XP_WIN)
 #include <windows.h>
 #include <stdlib.h>
 #elif defined(XP_UNIX)
 #include <sys/time.h>
 #include <sys/resource.h>
 #endif
 
@@ -142,30 +142,17 @@ static const nsDynamicFunctionLoad kXULF
     { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
     { "XRE_main", (NSFuncPtr*) &XRE_main },
     { nsnull, nsnull }
 };
 
 static int do_main(const char *exePath, int argc, char* argv[])
 {
   nsCOMPtr<nsILocalFile> appini;
-#ifdef XP_WIN
-  // exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8
-  // encoded path, so it is safe to convert it
-  nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), false,
-                                getter_AddRefs(appini));
-#else
-  nsresult rv = NS_NewNativeLocalFile(nsDependentCString(exePath), false,
-                                      getter_AddRefs(appini));
-#endif
-  if (NS_FAILED(rv)) {
-    return 255;
-  }
-
-  appini->SetNativeLeafName(NS_LITERAL_CSTRING("application.ini"));
+  nsresult rv;
 
   // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
   // Note that -app must be the *first* argument.
   const char *appDataFile = getenv("XUL_APP_FILE");
   if (appDataFile && *appDataFile) {
     rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
     if (NS_FAILED(rv)) {
       Output("Invalid path found: '%s'", appDataFile);
@@ -190,25 +177,42 @@ static int do_main(const char *exePath, 
       Output("Couldn't set %s.\n", appEnv);
       return 255;
     }
     argv[2] = argv[0];
     argv += 2;
     argc -= 2;
   }
 
-  nsXREAppData *appData;
-  rv = XRE_CreateAppData(appini, &appData);
-  if (NS_FAILED(rv)) {
-    Output("Couldn't read application.ini");
-    return 255;
+  int result;
+  if (appini) {
+    nsXREAppData *appData;
+    rv = XRE_CreateAppData(appini, &appData);
+    if (NS_FAILED(rv)) {
+      Output("Couldn't read application.ini");
+      return 255;
+    }
+    result = XRE_main(argc, argv, appData);
+    XRE_FreeAppData(appData);
+  } else {
+#ifdef XP_WIN
+    // exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8
+    // encoded path, so it is safe to convert it
+    rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), PR_FALSE,
+                         getter_AddRefs(appini));
+#else
+    rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_FALSE,
+                               getter_AddRefs(appini));
+#endif
+    if (NS_FAILED(rv)) {
+      return 255;
+    }
+    result = XRE_main(argc, argv, &sAppData);
   }
 
-  int result = XRE_main(argc, argv, appData);
-  XRE_FreeAppData(appData);
   return result;
 }
 
 #if MOZ_PLATFORM_MAEMO == 6
 static bool
 GeckoPreLoader(const char* execPath)
 {
   nsresult rv = XPCOMGlueStartup(execPath);
@@ -264,16 +268,18 @@ int main(int argc, char* argv[])
   nsFastStartup startup;
   startup.CreateFastStartup(argc, argv, exePath, GeckoPreLoader);
 #else
   rv = XPCOMGlueStartup(exePath);
   if (NS_FAILED(rv)) {
     Output("Couldn't load XPCOM.\n");
     return 255;
   }
+  // Reset exePath so that it is the directory name and not the xpcom dll name
+  *lastSlash = 0;
 
   rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
   if (NS_FAILED(rv)) {
     Output("Couldn't load XRE functions.\n");
     return 255;
   }
 #endif
 
--- a/mobile/xul/confvars.sh
+++ b/mobile/xul/confvars.sh
@@ -65,8 +65,9 @@ fi
 MOZ_APP_COMPONENT_LIBS="browsercomps"
 MOZ_APP_COMPONENT_INCLUDE=nsBrowserComponents.h
 
 # use custom widget for html:select
 MOZ_USE_NATIVE_POPUP_WINDOWS=1
 
 MOZ_APP_ID={a23983c0-fd0e-11dc-95ff-0800200c9a66}
 MOZ_EXTENSION_MANAGER=1
+MOZ_APP_STATIC_INI=1
--- a/toolkit/xre/Makefile.in
+++ b/toolkit/xre/Makefile.in
@@ -195,16 +195,21 @@ LOCAL_INCLUDES += \
   $(NULL)
 
 LOCAL_INCLUDES += \
   -I$(srcdir) \
   -I$(srcdir)/../profile \
   -I$(topsrcdir)/config \
   $(NULL)
 
+ifdef MOZ_APP_STATIC_INI
+LOCAL_INCLUDES += -I$(DEPTH)/build
+DEFINES += -DMOZ_APP_STATIC_INI
+endif
+
 CXXFLAGS += $(TK_CFLAGS) $(MOZ_DBUS_CFLAGS) $(MOZ_DBUS_GLIB_CFLAGS)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 CXXFLAGS += $(MOZ_PANGO_CFLAGS)
 endif
 
 DEFINES += \
   -DOS_TARGET=\"$(OS_TARGET)\" \
--- a/toolkit/xre/nsAndroidStartup.cpp
+++ b/toolkit/xre/nsAndroidStartup.cpp
@@ -34,16 +34,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "application.ini.h"
+
 #include <android/log.h>
 
 #include <jni.h>
 
 #include <stdlib.h>
 #include <string.h>
 #include <pthread.h>
 
@@ -85,62 +87,29 @@ GeckoStart(void *data)
     if (!attacher.attached)
         return 0;
 
     if (!data) {
         LOG("Failed to get arguments for GeckoStart\n");
         return 0;
     }
 
-    nsresult rv;
-    nsCOMPtr<nsILocalFile> appini;
-    char* greHome = getenv("GRE_HOME");
-    if (!greHome) {
-        LOG("Failed to get GRE_HOME from the env vars");
-        return 0;
-    }
-    nsCAutoString appini_path(greHome);
-    appini_path.AppendLiteral("/application.ini");
-    rv = NS_NewNativeLocalFile(appini_path, false, getter_AddRefs(appini));
-    if (NS_FAILED(rv)) {
-        LOG("Failed to create nsILocalFile for appdata\n");
-        return 0;
-    }
-
-    nsXREAppData *appData;
-    rv = XRE_CreateAppData(appini, &appData);
-    if (NS_FAILED(rv)) {
-        LOG("Failed to load application.ini from %s\n", appini_path.get());
-        return 0;
-    }
-
-    nsCOMPtr<nsILocalFile> xreDir;
-    rv = NS_NewNativeLocalFile(nsDependentCString(greHome), false, getter_AddRefs(xreDir));
-    if (NS_FAILED(rv)) {
-        LOG("Failed to create nsIFile for xreDirectory");
-        return 0;
-    }
-
-    appData->xreDirectory = xreDir.get();
-
     nsTArray<char *> targs;
     char *arg = strtok(static_cast<char *>(data), " ");
     while (arg) {
         targs.AppendElement(arg);
         arg = strtok(NULL, " ");
     }
     targs.AppendElement(static_cast<char *>(nsnull));
 
-    int result = XRE_main(targs.Length() - 1, targs.Elements(), appData);
+    int result = XRE_main(targs.Length() - 1, targs.Elements(), &sAppData);
 
     if (result)
         LOG("XRE_main returned %d", result);
 
-    XRE_FreeAppData(appData);
-
     mozilla::AndroidBridge::Bridge()->NotifyXreExit();
 
     free(targs[0]);
     nsMemory::Free(data);
     return 0;
 }
 
 extern "C" NS_EXPORT void JNICALL
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -2762,16 +2762,20 @@ XRE_main(int argc, char* argv[], const n
     if (NS_FAILED(rv))
       return 2;
     
     rv = CallQueryInterface(greDir, &appData.xreDirectory);
     if (NS_FAILED(rv))
       return 2;
   }
 
+  if (!appData.directory) {
+    NS_IF_ADDREF(appData.directory = appData.xreDirectory);
+  }
+
   if (appData.size > offsetof(nsXREAppData, minVersion)) {
     if (!appData.minVersion) {
       Output(true, "Error: Gecko:MinVersion not specified in application.ini\n");
       return 1;
     }
 
     if (!appData.maxVersion) {
       // If no maxVersion is specified, we assume the app is only compatible
--- a/xpcom/build/BinaryPath.h
+++ b/xpcom/build/BinaryPath.h
@@ -89,16 +89,30 @@ private:
     if (CFURLGetFileSystemRepresentation(executableURL, false, (UInt8 *)aResult, MAXPATHLEN))
       rv = NS_OK;
     else
       rv = NS_ERROR_FAILURE;
     CFRelease(executableURL);
     return rv;
   }
 
+#elif defined(ANDROID)
+  static nsresult Get(const char *argv0, char aResult[MAXPATHLEN])
+  {
+    // On Android, we use the GRE_HOME variable that is set by the Java
+    // bootstrap code.
+    const char *greHome = getenv("GRE_HOME");
+    if (!greHome)
+      return NS_ERROR_FAILURE;
+
+    snprintf(aResult, MAXPATHLEN, "%s/%s", greHome, "dummy");
+    aResult[MAXPATHLEN] = '\0';
+    return NS_OK;
+  }
+
 #elif defined(XP_UNIX)
   static nsresult Get(const char *argv0, char aResult[MAXPATHLEN])
   {
     struct stat fileStat;
     // on unix, there is no official way to get the path of the current binary.
     // instead of using the MOZILLA_FIVE_HOME hack, which doesn't scale to
     // multiple applications, we will try a series of techniques:
     //