Back out parts 3-7 of bug 620931 which caused bug 656172, r=killer
authorMichael Wu <mwu@mozilla.com>
Tue, 10 May 2011 18:27:51 -0700
changeset 69551 f442ce8fb412e0a10542c4b77463a53120476916
parent 69494 83ca7e97185766903c9a57b09789f12840691b06
child 69552 2ab5c696884ee561c32b653a74bc7ddf3286c31e
push idunknown
push userunknown
push dateunknown
reviewerskiller
bugs620931, 656172
milestone6.0a1
Back out parts 3-7 of bug 620931 which caused bug 656172, r=killer
browser/installer/Makefile.in
browser/installer/precompile_cache.js
embedding/android/GeckoAppShell.java
ipc/glue/GeckoChildProcessHost.cpp
js/src/xpconnect/loader/mozJSComponentLoader.cpp
js/src/xpconnect/shell/xpcshell.cpp
modules/libjar/nsJAR.cpp
modules/libpref/src/nsPrefService.cpp
netwerk/protocol/res/nsResProtocolHandler.cpp
other-licenses/android/APKOpen.cpp
startupcache/StartupCache.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsEmbedFunctions.cpp
toolkit/xre/nsXREDirProvider.cpp
xpcom/build/Makefile.in
xpcom/build/Omnijar.cpp
xpcom/build/Omnijar.h
xpcom/build/nsXPComInit.cpp
xpcom/components/nsComponentManager.cpp
xulrunner/confvars.sh
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -118,17 +118,17 @@ INSTALL_SDK = 1
 endif
 
 ifneq (1_,$(if $(CROSS_COMPILE),1,0)_$(UNIVERSAL_BINARY))
 ifdef RUN_TEST_PROGRAM
 _ABS_RUN_TEST_PROGRAM = $(call core_abspath,$(RUN_TEST_PROGRAM))
 endif
 
 GENERATE_CACHE = \
-  $(_ABS_RUN_TEST_PROGRAM) $(_ABS_DIST)/bin/xpcshell$(BIN_SUFFIX) -g "$$PWD" -a "$$PWD" -f $(topsrcdir)/browser/installer/precompile_cache.js -e 'populate_startupcache("omni.jar", "startupCache.zip");' && \
+  $(_ABS_RUN_TEST_PROGRAM) $(_ABS_DIST)/bin/xpcshell$(BIN_SUFFIX) -g "$$PWD" -f $(topsrcdir)/browser/installer/precompile_cache.js -e 'populate_startupcache("omni.jar", "startupCache.zip");' && \
   rm -rf jsloader && \
   $(UNZIP) startupCache.zip && \
   rm startupCache.zip && \
   find jsloader | xargs touch -t 201001010000 && \
   $(ZIP) -r9mX omni.jar jsloader
 endif
 
 include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
--- a/browser/installer/precompile_cache.js
+++ b/browser/installer/precompile_cache.js
@@ -60,20 +60,33 @@ function load(url) {
   } catch(e) {
     dump("Failed to import " + url + ":" + e + "\n");
   }
 }
 
 function load_entries(entries, prefix) {
   while (entries.hasMore()) {
     var c = entries.getNext();
+    // Required to ensure sync js is only loaded in load_custom_entries.
+    // That function loads the sync js with the right URIs.
+    if (c.indexOf("services-sync") >= 0)
+      continue;
+    if (c.indexOf("services-crypto") >= 0)
+      continue;
     load(prefix + c);
   }
 }
 
+function load_custom_entries(entries, subst) {
+  while (entries.hasMore()) {
+    var c = entries.getNext();
+    load("resource://" + subst + "/" + c.replace("modules/" + subst + "/", ""));
+  }
+}
+
 function getGreDir() {
   return Cc["@mozilla.org/file/directory_service;1"].
     getService(Ci.nsIProperties).get("GreD", Ci.nsIFile);
 }
 
 function openJar(file) {
   var zipreader = Cc["@mozilla.org/libjar/zip-reader;1"].
     createInstance(Ci.nsIZipReader);
@@ -85,15 +98,32 @@ function populate_startupcache(omnijarNa
   var file = getGreDir();
   file.append(omnijarName);
   zipreader = openJar(file);
 
   var scFile = getGreDir();
   scFile.append(startupcacheName);
   setenv("MOZ_STARTUP_CACHE", scFile.path);
 
-  let prefix = "resource:///";
+  // the sync part below doesn't work as smoothly
+  let ioService = Cc["@mozilla.org/network/io-service;1"].
+    getService(Ci.nsIIOService);
+  let uri = ioService.newURI("resource:///modules/services-sync/",
+                             null, null);
+  let resProt = ioService.getProtocolHandler("resource")
+    .QueryInterface(Ci.nsIResProtocolHandler);
+  resProt.setSubstitution("services-sync", uri);
 
-  load_entries(zipreader.findEntries("components/*js"), prefix);
-  load_entries(zipreader.findEntries("modules/*js"), prefix);
-  load_entries(zipreader.findEntries("modules/*jsm"), prefix);
+  uri = ioService.newURI("resource:///modules/services-crypto/",
+                         null, null);
+  resProt.setSubstitution("services-crypto", uri);
+
+  load_entries(zipreader.findEntries("components/*js"), "resource://gre/");
+
+  load_custom_entries(zipreader.findEntries("modules/services-sync/*js"),
+                      "services-sync");
+  load_custom_entries(zipreader.findEntries("modules/services-crypto/*js"),
+                      "services-crypto");
+
+  load_entries(zipreader.findEntries("modules/*js"), "resource://gre/");
+  load_entries(zipreader.findEntries("modules/*jsm"), "resource://gre/");
   zipreader.close();
 }
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -372,17 +372,17 @@ public class GeckoAppShell
     public static void runGecko(String apkPath, String args, String url) {
         // run gecko -- it will spawn its own thread
         GeckoAppShell.nativeInit();
 
         // Tell Gecko where the target surface view is for rendering
         GeckoAppShell.setSurfaceView(GeckoApp.surfaceView);
 
         // First argument is the .apk path
-        String combinedArgs = apkPath + " -greomni " + apkPath;
+        String combinedArgs = apkPath + " -omnijar " + apkPath;
         if (args != null)
             combinedArgs += " " + args;
         if (url != null)
             combinedArgs += " " + url;
         // and go
         GeckoAppShell.nativeRun(combinedArgs);
     }
 
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -487,29 +487,26 @@ GeckoChildProcessHost::PerformAsyncLaunc
   // other end of the socketpair() from us
 
   std::vector<std::string> childArgv;
 
   childArgv.push_back(exePath.value());
 
   childArgv.insert(childArgv.end(), aExtraOpts.begin(), aExtraOpts.end());
 
+#ifdef MOZ_OMNIJAR
   // Make sure the child process can find the omnijar
   // See XRE_InitCommandLine in nsAppRunner.cpp
-  nsCAutoString path;
-  nsCOMPtr<nsIFile> file = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE);
-  if (file && NS_SUCCEEDED(file->GetNativePath(path))) {
-    childArgv.push_back("-greomni");
-    childArgv.push_back(path.get());
+  nsCAutoString omnijarPath;
+  if (mozilla::OmnijarPath()) {
+    mozilla::OmnijarPath()->GetNativePath(omnijarPath);
+    childArgv.push_back("-omnijar");
+    childArgv.push_back(omnijarPath.get());
   }
-  file = mozilla::Omnijar::GetPath(mozilla::Omnijar::APP);
-  if (file && NS_SUCCEEDED(file->GetNativePath(path))) {
-    childArgv.push_back("-appomni");
-    childArgv.push_back(path.get());
-  }
+#endif
 
   childArgv.push_back(pidstring);
 
 #if defined(MOZ_CRASHREPORTER)
 #  if defined(OS_LINUX)
   int childCrashFd, childCrashRemapFd;
   if (!CrashReporter::CreateNotificationPipeForChild(
         &childCrashFd, &childCrashRemapFd))
@@ -602,29 +599,26 @@ GeckoChildProcessHost::PerformAsyncLaunc
   for (std::vector<std::string>::iterator it = aExtraOpts.begin();
        it != aExtraOpts.end();
        ++it) {
       cmdLine.AppendLooseValue(UTF8ToWide(*it));
   }
 
   cmdLine.AppendLooseValue(std::wstring(mGroupId.get()));
 
+#ifdef MOZ_OMNIJAR
   // Make sure the child process can find the omnijar
   // See XRE_InitCommandLine in nsAppRunner.cpp
-  nsAutoString path;
-  nsCOMPtr<nsIFile> file = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE);
-  if (file && NS_SUCCEEDED(file->GetPath(path))) {
-    cmdLine.AppendLooseValue(UTF8ToWide("-greomni"));
-    cmdLine.AppendLooseValue(path.get());
+  nsAutoString omnijarPath;
+  if (mozilla::OmnijarPath()) {
+    mozilla::OmnijarPath()->GetPath(omnijarPath);
+    cmdLine.AppendLooseValue(UTF8ToWide("-omnijar"));
+    cmdLine.AppendLooseValue(omnijarPath.get());
   }
-  file = mozilla::Omnijar::GetPath(mozilla::Omnijar::APP);
-  if (file && NS_SUCCEEDED(file->GetPath(path))) {
-    cmdLine.AppendLooseValue(UTF8ToWide("-appomni"));
-    cmdLine.AppendLooseValue(path.get());
-  }
+#endif
 
   cmdLine.AppendLooseValue(UTF8ToWide(pidstring));
 
 #if defined(MOZ_CRASHREPORTER)
   cmdLine.AppendLooseValue(
     UTF8ToWide(CrashReporter::GetChildNotificationPipe()));
 #endif
 
--- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
@@ -79,17 +79,16 @@
 #include "nsIConsoleService.h"
 #include "nsIStorageStream.h"
 #include "nsIStringStream.h"
 #include "prmem.h"
 #if defined(XP_WIN)
 #include "nsILocalFileWin.h"
 #endif
 #include "xpcprivate.h"
-#include "nsIResProtocolHandler.h"
 
 #ifdef MOZ_ENABLE_LIBXUL
 #include "mozilla/scache/StartupCache.h"
 #include "mozilla/scache/StartupCacheUtils.h"
 #endif
 #include "mozilla/Omnijar.h"
 
 #include "jsdbgapi.h"
@@ -617,21 +616,34 @@ mozJSComponentLoader::LoadModule(nsILoca
 }
 
 const mozilla::Module*
 mozJSComponentLoader::LoadModuleFromJAR(nsILocalFile *aJarFile,
                                         const nsACString &aComponentPath)
 {
     nsresult rv;
 
-    nsCAutoString fullSpec, fileSpec;
-    NS_GetURLSpecFromActualFile(aJarFile, fileSpec);
-    fullSpec = "jar:";
-    fullSpec += fileSpec;
-    fullSpec += "!/";
+    nsCAutoString fullSpec;
+
+#ifdef MOZ_OMNIJAR
+    PRBool equal;
+    rv = aJarFile->Equals(mozilla::OmnijarPath(), &equal);
+    if (NS_SUCCEEDED(rv) && equal) {
+        fullSpec = "resource://gre/";
+    } else {
+#endif
+        nsCAutoString fileSpec;
+        NS_GetURLSpecFromActualFile(aJarFile, fileSpec);
+        fullSpec = "jar:";
+        fullSpec += fileSpec;
+        fullSpec += "!/";
+#ifdef MOZ_OMNIJAR
+    }
+#endif
+
     fullSpec += aComponentPath;
 
     nsCOMPtr<nsIURI> uri;
     rv = NS_NewURI(getter_AddRefs(uri), fullSpec);
     if (NS_FAILED(rv))
         return NULL;
 
     nsAutoString hashstring;
@@ -802,138 +814,57 @@ class JSPrincipalsHolder
     JSPrincipalsHolder(JSContext *cx, JSPrincipals *principals)
         : mCx(cx), mPrincipals(principals) {}
     ~JSPrincipalsHolder() { JSPRINCIPALS_DROP(mCx, mPrincipals); }
  private:
     JSContext *mCx;
     JSPrincipals *mPrincipals;
 };
 
-static const char baseName[2][5] = { "gre/", "app/" };
-
-static inline PRBool
-canonicalizeBase(nsCAutoString &spec, nsACString &out, mozilla::Omnijar::Type aType)
-{
-    nsCAutoString base;
-    nsresult rv = mozilla::Omnijar::GetURIString(aType, base);
-
-    if (NS_FAILED(rv) || !base.Length())
-        return PR_FALSE;
-
-    if (base.Compare(spec.get(), PR_FALSE, base.Length()))
-        return PR_FALSE;
-
-    out.Append("/resource/");
-    out.Append(baseName[aType]);
-    out.Append(Substring(spec, base.Length()));
-    return PR_TRUE;
-}
 /**
  * PathifyURI transforms mozilla .js uris into useful zip paths
  * to make it makes it easier to manipulate startup cache entries
  * using standard zip tools.
  * Transformations applied:
- *  * jsloader/ prefix is used to group mozJSComponentLoader cache entries in
+ *  * jsloader/<scheme> prefix is used to group mozJSComponentLoader cache entries in
  *    a top-level zip directory.
- *  * resource:// URIs are resolved to their corresponding file/jar URI to
- *    canonicalize resources URIs other than gre and app.
- *  * Paths under GRE or APP directory have their base path replaced with
- *    resource/gre or resource/app to avoid depending on install location.
- *  * jar:file:///path/to/file.jar!/sub/path urls are replaced with
- *    /path/to/file.jar/sub/path
+ *  * In MOZ_OMNIJAR case resource:/// and resource://gre/ URIs refer to the same path
+ *    so treat both of them as resource://gre/
  *  * .bin suffix is added to the end of the path to indicate that jsloader/ entries
  *     are binary representations of JS source.
  * For example:
- *  resource://gre/modules/XPCOMUtils.jsm or
- *  file://$GRE_DIR/modules/XPCOMUtils.jsm or
- *  jar:file://$GRE_DIR/omni.jar!/modules/XPCOMUtils.jsm become
- *     jsloader/resource/gre/modules/XPCOMUtils.jsm.bin
- *  file://$PROFILE_DIR/extensions/{uuid}/components/component.js becomes
- *     jsloader/$PROFILE_DIR/extensions/%7Buuid%7D/components/component.js.bin
- *  jar:file://$PROFILE_DIR/extensions/some.xpi!/components/component.js becomes
- *     jsloader/$PROFILE_DIR/extensions/some.xpi/components/component.js.bin
+ *  resource://gre/modules/XPCOMUtils.jsm becomes
+ *  jsloader/resource/gre/modules/XPCOMUtils.jsm.bin
  */
 static nsresult
 PathifyURI(nsIURI *in, nsACString &out)
 { 
-    PRBool equals;
-    nsresult rv;
-    nsCOMPtr<nsIURI> uri = in;
-    nsCAutoString spec;
-
-    out = "jsloader";
-
-    // Resolve resource:// URIs. At the end of this if/else block, we
-    // have both spec and uri variables identifying the same URI.
-    if (NS_SUCCEEDED(in->SchemeIs("resource", &equals)) && equals) {
-        nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        nsCOMPtr<nsIProtocolHandler> ph;
-        rv = ioService->GetProtocolHandler("resource", getter_AddRefs(ph));
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        nsCOMPtr<nsIResProtocolHandler> irph(do_QueryInterface(ph, &rv));
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        rv = irph->ResolveURI(in, spec);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        rv = ioService->NewURI(spec, nsnull, nsnull, getter_AddRefs(uri));
-        NS_ENSURE_SUCCESS(rv, rv);
-    } else {
-        rv = in->GetSpec(spec);
-        NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    if (!canonicalizeBase(spec, out, mozilla::Omnijar::GRE) &&
-        !canonicalizeBase(spec, out, mozilla::Omnijar::APP)) {
-        if (NS_SUCCEEDED(uri->SchemeIs("file", &equals)) && equals) {
-            nsCOMPtr<nsIFileURL> baseFileURL;
-            baseFileURL = do_QueryInterface(uri, &rv);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            nsCAutoString path;
-            rv = baseFileURL->GetPath(path);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            out.Append(path);
-        } else if (NS_SUCCEEDED(uri->SchemeIs("jar", &equals)) && equals) {
-            nsCOMPtr<nsIJARURI> jarURI = do_QueryInterface(uri, &rv);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            nsCOMPtr<nsIURI> jarFileURI;
-            rv = jarURI->GetJARFile(getter_AddRefs(jarFileURI));
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            nsCOMPtr<nsIFileURL> jarFileURL;
-            jarFileURL = do_QueryInterface(jarFileURI, &rv);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            nsCAutoString path;
-            rv = jarFileURL->GetPath(path);
-            NS_ENSURE_SUCCESS(rv, rv);
-            out.Append(path);
-
-            rv = jarURI->GetJAREntry(path);
-            NS_ENSURE_SUCCESS(rv, rv);
-            out.Append("/");
-            out.Append(path);
-        } else { // Very unlikely
-            nsCAutoString spec;
-            rv = uri->GetSpec(spec);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            out.Append("/");
-            out.Append(spec);
-        }
-    }
-
-    out.Append(".bin");
-    return NS_OK;
+   out = "jsloader/";
+   nsCAutoString scheme;
+   nsresult rv = in->GetScheme(scheme);
+   NS_ENSURE_SUCCESS(rv, rv);
+   out.Append(scheme);
+   nsCAutoString host;
+   // OK for GetHost to fail since it's not implemented sometimes
+   in->GetHost(host);
+#ifdef MOZ_OMNIJAR
+   if (scheme.Equals("resource") && host.Length() == 0){
+       host = "gre";
+   }
+#endif
+   if (host.Length()) {
+       out.Append("/");
+       out.Append(host);
+   }
+   nsCAutoString path;
+   rv = in->GetPath(path);
+   NS_ENSURE_SUCCESS(rv, rv);
+   out.Append(path);
+   out.Append(".bin");
+   return NS_OK;
 }
 
 /* static */
 #ifdef MOZ_ENABLE_LIBXUL
 nsresult
 mozJSComponentLoader::ReadScript(StartupCache* cache, nsIURI *uri,
                                  JSContext *cx, JSObject **scriptObj)
 {
--- a/js/src/xpconnect/shell/xpcshell.cpp
+++ b/js/src/xpconnect/shell/xpcshell.cpp
@@ -1145,17 +1145,17 @@ Process(JSContext *cx, JSObject *obj, co
     if (file != stdin)
         fclose(file);
 }
 
 static int
 usage(void)
 {
     fprintf(gErrFile, "%s\n", JS_GetImplementationVersion());
-    fprintf(gErrFile, "usage: xpcshell [-g gredir] [-a appdir] [-r manifest]... [-PsSwWxCij] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
+    fprintf(gErrFile, "usage: xpcshell [-g gredir] [-r manifest]... [-PsSwWxCij] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
     return 2;
 }
 
 extern JSClass global_class;
 
 static int
 ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
 {
@@ -1799,33 +1799,16 @@ main(int argc, char **argv, char **envp)
         if (!dirprovider.SetGREDir(argv[2])) {
             printf("SetGREDir failed.\n");
             return 1;
         }
         argc -= 2;
         argv += 2;
     }
 
-    if (argc > 1 && !strcmp(argv[1], "-a")) {
-        if (argc < 3)
-            return usage();
-
-        nsCOMPtr<nsILocalFile> dir;
-        rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(dir));
-        if (NS_SUCCEEDED(rv)) {
-            appDir = do_QueryInterface(dir, &rv);
-        }
-        if (NS_FAILED(rv)) {
-            printf("Couldn't use given appdir.\n");
-            return 1;
-        }
-        argc -= 2;
-        argv += 2;
-    }
-
     while (argc > 1 && !strcmp(argv[1], "-r")) {
         if (argc < 3)
             return usage();
 
         nsCOMPtr<nsILocalFile> lf;
         rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(lf));
         if (NS_FAILED(rv)) {
             printf("Couldn't get manifest file.\n");
--- a/modules/libjar/nsJAR.cpp
+++ b/modules/libjar/nsJAR.cpp
@@ -172,23 +172,26 @@ nsJAR::Open(nsIFile* zipFile)
 {
   NS_ENSURE_ARG_POINTER(zipFile);
   if (mOpened) return NS_ERROR_FAILURE; // Already open!
 
   mZipFile = zipFile;
   mOuterZipEntry.Truncate();
   mOpened = PR_TRUE;
   
+#ifdef MOZ_OMNIJAR
   // The omnijar is special, it is opened early on and closed late
   // this avoids reopening it
-  nsZipArchive *zip = mozilla::Omnijar::GetReader(zipFile);
-  if (zip) {
-    mZip = zip;
+  PRBool equals;
+  nsresult rv = zipFile->Equals(mozilla::OmnijarPath(), &equals);
+  if (NS_SUCCEEDED(rv) && equals) {
+    mZip = mozilla::OmnijarReader();
     return NS_OK;
   }
+#endif
   return mZip->OpenArchive(zipFile);
 }
 
 NS_IMETHODIMP
 nsJAR::OpenInner(nsIZipReader *aZipReader, const char *aZipEntry)
 {
   NS_ENSURE_ARG_POINTER(aZipReader);
   NS_ENSURE_ARG_POINTER(aZipEntry);
@@ -227,22 +230,23 @@ NS_IMETHODIMP
 nsJAR::Close()
 {
   mOpened = PR_FALSE;
   mParsedManifest = PR_FALSE;
   mManifestData.Reset();
   mGlobalStatus = JAR_MANIFEST_NOT_PARSED;
   mTotalItemsInManifest = 0;
 
-  if ((mZip == mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE)) ||
-      (mZip == mozilla::Omnijar::GetReader(mozilla::Omnijar::APP))) {
+#ifdef MOZ_OMNIJAR
+  if (mZip == mozilla::OmnijarReader()) {
     mZip.forget();
     mZip = new nsZipArchive();
     return NS_OK;
   }
+#endif
   return mZip->CloseArchive();
 }
 
 NS_IMETHODIMP
 nsJAR::Test(const char *aEntryName)
 {
   return mZip->Test(aEntryName);
 }
@@ -383,21 +387,22 @@ nsJAR::GetInputStreamWithSpec(const nsAC
 NS_IMETHODIMP
 nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal)
 {
   //-- Parameter check
   if (!aPrincipal)
     return NS_ERROR_NULL_POINTER;
   *aPrincipal = nsnull;
 
+#ifdef MOZ_OMNIJAR
   // Don't check signatures in the omnijar - this is only
   // interesting for extensions/XPIs.
-  if ((mZip == mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE)) ||
-      (mZip == mozilla::Omnijar::GetReader(mozilla::Omnijar::APP)))
+  if (mZip == mozilla::OmnijarReader())
     return NS_OK;
+#endif
 
   //-- Parse the manifest
   nsresult rv = ParseManifest();
   if (NS_FAILED(rv)) return rv;
   if (mGlobalStatus == JAR_NO_MANIFEST)
     return NS_OK;
 
   PRInt16 requestedStatus;
--- a/modules/libpref/src/nsPrefService.cpp
+++ b/modules/libpref/src/nsPrefService.cpp
@@ -65,18 +65,20 @@
 
 #include "prefapi.h"
 #include "prefread.h"
 #include "prefapi_private_data.h"
 #include "PrefTuple.h"
 
 #include "nsITimelineService.h"
 
+#ifdef MOZ_OMNIJAR
 #include "mozilla/Omnijar.h"
 #include "nsZipArchive.h"
+#endif
 
 // Definitions
 #define INITIAL_PREF_FILES 10
 static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
 
 // Prototypes
 static nsresult openPrefFile(nsIFile* aFile);
 static nsresult pref_InitInitialObjects(void);
@@ -777,144 +779,124 @@ static nsresult pref_LoadPrefsInDirList(
           pref_LoadPrefsInDir(dir, nsnull, 0); 
         }
       }
     }
   }
   return NS_OK;
 }
 
+//----------------------------------------------------------------------------------------
+// Initialize default preference JavaScript buffers from
+// appropriate TEXT resources
+//----------------------------------------------------------------------------------------
+static nsresult pref_InitDefaults()
+{
+  nsCOMPtr<nsIFile> greprefsFile;
+  nsresult          rv;
+
+  rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(greprefsFile));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = greprefsFile->AppendNative(NS_LITERAL_CSTRING("greprefs.js"));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = openPrefFile(greprefsFile);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Error parsing GRE default preferences. Is this an old-style embedding app?");
+  }
+
+  return NS_OK;
+}
+
+#ifdef MOZ_OMNIJAR
 static nsresult pref_ReadPrefFromJar(nsZipArchive* jarReader, const char *name)
 {
   nsZipItemPtr<char> manifest(jarReader, name, true);
   NS_ENSURE_TRUE(manifest.Buffer(), NS_ERROR_NOT_AVAILABLE);
 
   PrefParseState ps;
   PREF_InitParseState(&ps, PREF_ReaderCallback, NULL);
   nsresult rv = PREF_ParseBuf(&ps, manifest, manifest.Length());
   PREF_FinalizeParseState(&ps);
 
   return rv;
 }
 
-//----------------------------------------------------------------------------------------
-// Initialize default preference JavaScript buffers from
-// appropriate TEXT resources
-//----------------------------------------------------------------------------------------
+static nsresult pref_InitAppDefaultsFromOmnijar()
+{
+  nsresult rv;
+
+  nsZipArchive* jarReader = mozilla::OmnijarReader();
+  if (!jarReader)
+    return pref_InitDefaults();
+
+  rv = pref_ReadPrefFromJar(jarReader, "greprefs.js");
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsZipFind *findPtr;
+  rv = jarReader->FindInit("defaults/pref/*.js$", &findPtr);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoPtr<nsZipFind> find(findPtr);
+
+  nsTArray<nsCString> prefEntries;
+  const char *entryName;
+  PRUint16 entryNameLen;
+  while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) {
+    prefEntries.AppendElement(Substring(entryName, entryName + entryNameLen));
+  }
+
+  prefEntries.Sort();
+  for (PRUint32 i = prefEntries.Length(); i--; ) {
+    rv = pref_ReadPrefFromJar(jarReader, prefEntries[i].get());
+    if (NS_FAILED(rv))
+      NS_WARNING("Error parsing preferences.");
+  }
+
+  return NS_OK;
+}
+#endif
+
 static nsresult pref_InitInitialObjects()
 {
   nsresult rv;
 
-  // In omni.jar case, we load the following prefs:
-  // - jar:$gre/omni.jar!/greprefs.js
-  // - jar:$gre/omni.jar!/defaults/pref/*.js
-  // In non omni.jar case, we load:
-  // - $gre/greprefs.js
-  //
-  // When $app == $gre, we additionally load, in all cases:
-  // - $gre/defaults/pref/*.js
-  // This is kept for bug 591866 (channel-prefs.js should not be in omni.jar).
-  // We load all files instead of channel-prefs.js only to have the same
-  // behaviour as $app != $gre.
-  //
-  // When $app != $gre, we additionally load, in omni.jar case:
-  // - jar:$app/omni.jar!/defaults/preferences/*.js
-  // - $app/defaults/preferences/*.js
-  // and in non omni.jar case:
-  // - $app/defaults/preferences/*.js
-
-  nsZipFind *findPtr;
-  nsAutoPtr<nsZipFind> find;
-  nsTArray<nsCString> prefEntries;
-  const char *entryName;
-  PRUint16 entryNameLen;
-
-  nsZipArchive* jarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
-  if (jarReader) {
-    // Load jar:$gre/omni.jar!/greprefs.js
-    rv = pref_ReadPrefFromJar(jarReader, "greprefs.js");
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // Load jar:$gre/omni.jar!/defaults/pref/*.js
-    rv = jarReader->FindInit("defaults/pref/*.js$", &findPtr);
-    NS_ENSURE_SUCCESS(rv, rv);
+  // first we parse the GRE default prefs. This also works if we're not using a GRE, 
+#ifdef MOZ_OMNIJAR
+  rv = pref_InitAppDefaultsFromOmnijar();
+#else
+  rv = pref_InitDefaults();
+#endif
+  NS_ENSURE_SUCCESS(rv, rv);
 
-    find = findPtr;
-    while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) {
-      prefEntries.AppendElement(Substring(entryName, entryName + entryNameLen));
-    }
-
-    prefEntries.Sort();
-    for (PRUint32 i = prefEntries.Length(); i--; ) {
-      rv = pref_ReadPrefFromJar(jarReader, prefEntries[i].get());
-      if (NS_FAILED(rv))
-        NS_WARNING("Error parsing preferences.");
-    }
-  } else {
-    // Load $gre/greprefs.js
-    nsCOMPtr<nsIFile> greprefsFile;
-    rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(greprefsFile));
-    NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIFile> defaultPrefDir;
+  // now parse the "application" default preferences
+  rv = NS_GetSpecialDirectory(NS_APP_PREF_DEFAULTS_50_DIR, getter_AddRefs(defaultPrefDir));
+  NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = greprefsFile->AppendNative(NS_LITERAL_CSTRING("greprefs.js"));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = openPrefFile(greprefsFile);
-    if (NS_FAILED(rv))
-      NS_WARNING("Error parsing GRE default preferences. Is this an old-style embedding app?");
-  }
-
-  if (!mozilla::Omnijar::HasOmnijar(mozilla::Omnijar::APP)) {
-    // Load $gre/defaults/pref/*.js
-    nsCOMPtr<nsIFile> defaultPrefDir;
-
-    rv = NS_GetSpecialDirectory(NS_APP_PREF_DEFAULTS_50_DIR, getter_AddRefs(defaultPrefDir));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    /* these pref file names should not be used: we process them after all other application pref files for backwards compatibility */
-    static const char* specialFiles[] = {
+  /* these pref file names should not be used: we process them after all other application pref files for backwards compatibility */
+  static const char* specialFiles[] = {
 #if defined(XP_MAC) || defined(XP_MACOSX)
       "macprefs.js"
 #elif defined(XP_WIN)
       "winpref.js"
 #elif defined(XP_UNIX)
       "unix.js"
-#if defined(VMS)
-      , "openvms.js"
-#elif defined(_AIX)
+#if defined(_AIX)
       , "aix.js"
 #endif
 #elif defined(XP_OS2)
       "os2pref.js"
-#elif defined(XP_BEOS)
-      "beos.js"
 #endif
-    };
-
-    rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, NS_ARRAY_LENGTH(specialFiles));
-    if (NS_FAILED(rv))
-      NS_WARNING("Error parsing application default preferences.");
-  }
+  };
 
-  // Load jar:$app/omni.jar!/defaults/preferences/*.js
-  nsZipArchive *appJarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP);
-  if (appJarReader) {
-    rv = appJarReader->FindInit("defaults/preferences/*.js$", &findPtr);
-    NS_ENSURE_SUCCESS(rv, rv);
-    find = findPtr;
-    prefEntries.Clear();
-    while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) {
-      prefEntries.AppendElement(Substring(entryName, entryName + entryNameLen));
-    }
-    prefEntries.Sort();
-    for (PRUint32 i = prefEntries.Length(); i--; ) {
-      rv = pref_ReadPrefFromJar(appJarReader, prefEntries[i].get());
-      if (NS_FAILED(rv))
-        NS_WARNING("Error parsing preferences.");
-    }
+  rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, NS_ARRAY_LENGTH(specialFiles));
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Error parsing application default preferences.");
   }
 
   rv = pref_LoadPrefsInDirList(NS_APP_PREFS_DEFAULTS_DIR_LIST);
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_CreateServicesFromCategory(NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID,
                                 nsnull, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID);
 
--- a/netwerk/protocol/res/nsResProtocolHandler.cpp
+++ b/netwerk/protocol/res/nsResProtocolHandler.cpp
@@ -71,17 +71,16 @@ static nsResProtocolHandler *gResHandler
 //    set NSPR_LOG_FILE=log.txt
 //
 // this enables PR_LOG_ALWAYS level information and places all output in
 // the file log.txt
 //
 static PRLogModuleInfo *gResLog;
 #endif
 
-#define kAPP           NS_LITERAL_CSTRING("app")
 #define kGRE           NS_LITERAL_CSTRING("gre")
 
 //----------------------------------------------------------------------------
 // nsResURL : overrides nsStandardURL::GetFile to provide nsIFile resolution
 //----------------------------------------------------------------------------
 
 nsresult
 nsResURL::EnsureFile()
@@ -150,68 +149,97 @@ nsResProtocolHandler::nsResProtocolHandl
 }
 
 nsResProtocolHandler::~nsResProtocolHandler()
 {
     gResHandler = nsnull;
 }
 
 nsresult
+nsResProtocolHandler::AddSpecialDir(const char* aSpecialDir, const nsACString& aSubstitution)
+{
+    nsCOMPtr<nsIFile> file;
+    nsresult rv = NS_GetSpecialDirectory(aSpecialDir, getter_AddRefs(file));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<nsIURI> uri;
+    rv = mIOService->NewFileURI(file, getter_AddRefs(uri));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    return SetSubstitution(aSubstitution, uri);
+}
+
+nsresult
 nsResProtocolHandler::Init()
 {
     if (!mSubstitutions.Init(32))
         return NS_ERROR_UNEXPECTED;
 
     nsresult rv;
 
     mIOService = do_GetIOService(&rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCAutoString appURI, greURI;
-    rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::APP, appURI);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::GRE, greURI);
-    NS_ENSURE_SUCCESS(rv, rv);
+#ifdef MOZ_OMNIJAR
+    nsCOMPtr<nsIFile> omniJar(mozilla::OmnijarPath());
+    if (omniJar)
+        return Init(omniJar);
+#endif
+
+    // these entries should be kept in sync with the omnijar Init function
 
     //
-    // make resource:/// point to the application directory or omnijar
+    // make resource:/// point to the application directory
     //
-    nsCOMPtr<nsIURI> uri;
-    rv = NS_NewURI(getter_AddRefs(uri), appURI.Length() ? appURI : greURI);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = SetSubstitution(EmptyCString(), uri);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    //
-    // make resource://app/ point to the application directory or omnijar
-    //
-    rv = SetSubstitution(kAPP, uri);
+    rv = AddSpecialDir(NS_OS_CURRENT_PROCESS_DIR, EmptyCString());
     NS_ENSURE_SUCCESS(rv, rv);
 
     //
     // make resource://gre/ point to the GRE directory
     //
-    if (appURI.Length()) { // We already have greURI in uri if appURI.Length() is 0.
-        rv = NS_NewURI(getter_AddRefs(uri), greURI);
-        NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    rv = SetSubstitution(kGRE, uri);
+    rv = AddSpecialDir(NS_GRE_DIR, kGRE);
     NS_ENSURE_SUCCESS(rv, rv);
 
     //XXXbsmedberg Neil wants a resource://pchrome/ for the profile chrome dir...
     // but once I finish multiple chrome registration I'm not sure that it is needed
 
     // XXX dveditz: resource://pchrome/ defeats profile directory salting
     // if web content can load it. Tread carefully.
 
     return rv;
 }
 
+#ifdef MOZ_OMNIJAR
+nsresult
+nsResProtocolHandler::Init(nsIFile *aOmniJar)
+{
+    nsresult rv;
+    nsCOMPtr<nsIURI> uri;
+    nsCAutoString omniJarSpec;
+    NS_GetURLSpecFromActualFile(aOmniJar, omniJarSpec, mIOService);
+
+    nsCAutoString urlStr("jar:");
+    urlStr += omniJarSpec;
+    urlStr += "!/";
+
+    rv = mIOService->NewURI(urlStr, nsnull, nsnull, getter_AddRefs(uri));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // these entries should be kept in sync with the normal Init function
+
+    // resource:/// points to jar:omni.jar!/
+    SetSubstitution(EmptyCString(), uri);
+
+    // resource://gre/ points to jar:omni.jar!/
+    SetSubstitution(kGRE, uri);
+
+    return NS_OK;
+}
+#endif
+
 static PLDHashOperator
 EnumerateSubstitution(const nsACString& aKey,
                       nsIURI* aURI,
                       void* aArg)
 {
     nsTArray<ResourceMapping>* resources =
             static_cast<nsTArray<ResourceMapping>*>(aArg);
     SerializedURI uri;
--- a/other-licenses/android/APKOpen.cpp
+++ b/other-licenses/android/APKOpen.cpp
@@ -762,17 +762,17 @@ Java_org_mozilla_gecko_GeckoAppShell_loa
 typedef int GeckoProcessType;
 typedef int nsresult;
 
 extern "C" NS_EXPORT int
 ChildProcessInit(int argc, char* argv[])
 {
   int i;
   for (i = 0; i < (argc - 1); i++) {
-    if (strcmp(argv[i], "-greomni"))
+    if (strcmp(argv[i], "-omnijar"))
       continue;
 
     i = i + 1;
     break;
   }
 
   fillLibCache(argv[argc - 1]);
   loadLibs(argv[i]);
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -245,36 +245,27 @@ StartupCache::GetBuffer(const char* id, 
     nsZipItemPtr<char> zipItem(mArchive, id, true);
     if (zipItem) {
       *outbuf = zipItem.Forget();
       *length = zipItem.Length();
       return NS_OK;
     } 
   }
 
-  if (mozilla::Omnijar::GetReader(mozilla::Omnijar::APP)) {
+#ifdef MOZ_OMNIJAR
+  if (mozilla::OmnijarReader()) {
     // no need to checksum omnijarred entries
-    nsZipItemPtr<char> zipItem(mozilla::Omnijar::GetReader(mozilla::Omnijar::APP), id);
+    nsZipItemPtr<char> zipItem(mozilla::OmnijarReader(), id);
     if (zipItem) {
       *outbuf = zipItem.Forget();
       *length = zipItem.Length();
       return NS_OK;
     } 
   }
-
-  if (mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE)) {
-    // no need to checksum omnijarred entries
-    nsZipItemPtr<char> zipItem(mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE), id);
-    if (zipItem) {
-      *outbuf = zipItem.Forget();
-      *length = zipItem.Length();
-      return NS_OK;
-    } 
-  }
-
+#endif
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 // Makes a copy of the buffer, client retains ownership of inbuf.
 nsresult
 StartupCache::PutBuffer(const char* id, const char* inbuf, PRUint32 len) 
 {
   NS_ASSERTION(NS_IsMainThread(), "Startup cache only available on main thread");
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -3821,49 +3821,34 @@ XRE_InitCommandLine(int aArgc, char* aAr
   NS_ASSERTION(!CommandLine::IsInitialized(), "Bad news!");
   CommandLine::Init(aArgc, canonArgs);
 
   for (int i = 0; i < aArgc; ++i)
       free(canonArgs[i]);
   delete[] canonArgs;
 #endif
 
-  const char *path = nsnull;
-  ArgResult ar = CheckArg("greomni", PR_FALSE, &path);
+#ifdef MOZ_OMNIJAR
+  const char *omnijarPath = nsnull;
+  ArgResult ar = CheckArg("omnijar", PR_FALSE, &omnijarPath);
   if (ar == ARG_BAD) {
-    PR_fprintf(PR_STDERR, "Error: argument -greomni requires a path argument\n");
+    PR_fprintf(PR_STDERR, "Error: argument -omnijar requires an omnijar path\n");
     return NS_ERROR_FAILURE;
   }
 
-  if (!path)
-    return rv;
-
-  nsCOMPtr<nsILocalFile> greOmni;
-  rv = XRE_GetFileFromPath(path, getter_AddRefs(greOmni));
-  if (NS_FAILED(rv)) {
-    PR_fprintf(PR_STDERR, "Error: argument -greomni requires a valid path\n");
+  if (!omnijarPath)
     return rv;
-  }
-
-  ar = CheckArg("appomni", PR_FALSE, &path);
-  if (ar == ARG_BAD) {
-    PR_fprintf(PR_STDERR, "Error: argument -appomni requires a path argument\n");
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<nsILocalFile> appOmni;
-  if (path) {
-      rv = XRE_GetFileFromPath(path, getter_AddRefs(appOmni));
-      if (NS_FAILED(rv)) {
-        PR_fprintf(PR_STDERR, "Error: argument -appomni requires a valid path\n");
-        return rv;
-      }
-  }
-
-  mozilla::Omnijar::Init(greOmni, appOmni);
+
+  nsCOMPtr<nsILocalFile> omnijar;
+  rv = NS_NewNativeLocalFile(nsDependentCString(omnijarPath), PR_TRUE,
+                             getter_AddRefs(omnijar));
+  if (NS_SUCCEEDED(rv))
+    mozilla::SetOmnijar(omnijar);
+#endif
+
   return rv;
 }
 
 nsresult
 XRE_DeinitCommandLine()
 {
   nsresult rv = NS_OK;
 
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -507,17 +507,19 @@ XRE_InitChildProcess(int aArgc,
       }
 
       // Run the UI event loop on the main thread.
       uiMessageLoop.MessageLoop::Run();
 
       // Allow ProcessChild to clean up after itself before going out of
       // scope and being deleted
       process->CleanUp();
-      mozilla::Omnijar::CleanUp();
+#ifdef MOZ_OMNIJAR
+      mozilla::SetOmnijar(nsnull);
+#endif
     }
   }
 
   NS_LogTerm();
   return XRE_DeinitCommandLine();
 }
 
 MessageLoop*
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -296,16 +296,19 @@ nsXREDirProvider::GetFile(const char* aP
     }
   }
   else if (!strcmp(aProperty, XRE_EXECUTABLE_FILE) && gArgv[0]) {
     nsCOMPtr<nsILocalFile> lf;
     rv = XRE_GetBinaryPath(gArgv[0], getter_AddRefs(lf));
     if (NS_SUCCEEDED(rv))
       file = lf;
   }
+  else if (!strcmp(aProperty, "resource:app")) {
+    rv = GetAppDir()->Clone(getter_AddRefs(file));
+  }
 
   else if (!strcmp(aProperty, NS_APP_PROFILE_DIR_STARTUP) && mProfileDir) {
     return mProfileDir->Clone(aFile);
   }
   else if (!strcmp(aProperty, NS_APP_PROFILE_LOCAL_DIR_STARTUP)) {
     if (mProfileLocalDir)
       return mProfileLocalDir->Clone(aFile);
 
--- a/xpcom/build/Makefile.in
+++ b/xpcom/build/Makefile.in
@@ -64,25 +64,28 @@ CSRCS		= \
 		$(NULL)
 
 CPPSRCS		= \
 		$(XPCOM_GLUE_SRC_LCPPSRCS) \
 		$(XPCOM_GLUENS_SRC_LCPPSRCS) \
 		nsXPComInit.cpp \
 		nsXPCOMStrings.cpp \
 		Services.cpp \
-		Omnijar.cpp \
 		$(NULL)
 
 ifndef MOZ_ENABLE_LIBXUL
 ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
 CPPSRCS += dlldeps.cpp
 endif
 endif
 
+ifdef MOZ_OMNIJAR
+CPPSRCS += Omnijar.cpp
+endif
+
 SHARED_LIBRARY_LIBS = \
 		$(DEPTH)/chrome/src/$(LIB_PREFIX)chrome_s.$(LIB_SUFFIX) \
 		../ds/$(LIB_PREFIX)xpcomds_s.$(LIB_SUFFIX) \
 		../io/$(LIB_PREFIX)xpcomio_s.$(LIB_SUFFIX) \
 		../components/$(LIB_PREFIX)xpcomcomponents_s.$(LIB_SUFFIX) \
 		../threads/$(LIB_PREFIX)xpcomthreads_s.$(LIB_SUFFIX) \
 		../proxy/src/$(LIB_PREFIX)xpcomproxy_s.$(LIB_SUFFIX) \
 		../base/$(LIB_PREFIX)xpcombase_s.$(LIB_SUFFIX) \
--- a/xpcom/build/Omnijar.cpp
+++ b/xpcom/build/Omnijar.cpp
@@ -16,17 +16,16 @@
  *
  * The Initial Developer of the Original Code is
  * Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2010
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Michael Wu <mwu@mozilla.com>
- *   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
@@ -34,157 +33,69 @@
  * 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 "Omnijar.h"
 
-#include "nsDirectoryService.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsIFile.h"
+#include "nsILocalFile.h"
+#include "nsXULAppAPI.h"
 #include "nsZipArchive.h"
-#include "nsNetUtil.h"
-
-namespace mozilla {
-
-nsIFile *Omnijar::sPath[2] = { nsnull, nsnull };
-nsZipArchive *Omnijar::sReader[2] = { nsnull, nsnull };
-PRPackedBool Omnijar::sInitialized = PR_FALSE;
-static PRPackedBool sIsUnified = PR_FALSE;
-
-static const char *sProp[2] =
-    { NS_GRE_DIR, NS_XPCOM_CURRENT_PROCESS_DIR };
 
-#define SPROP(Type) ((Type == mozilla::Omnijar::GRE) ? sProp[GRE] : sProp[APP])
+static nsILocalFile* sOmnijarPath = nsnull;
+static nsZipArchive* sOmnijarReader = nsnull;
 
-void
-Omnijar::CleanUpOne(Type aType)
-{
-    if (sReader[aType]) {
-        sReader[aType]->CloseArchive();
-        delete sReader[aType];
-    }
-    sReader[aType] = nsnull;
-    NS_IF_RELEASE(sPath[aType]);
-}
-
-void
-Omnijar::InitOne(nsIFile *aPath, Type aType)
+static void
+SetupReader()
 {
-    nsCOMPtr<nsIFile> file;
-    if (aPath) {
-        file = aPath;
-    } else {
-        nsCOMPtr<nsIFile> dir;
-        nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile), getter_AddRefs(dir));
-        if (NS_FAILED(dir->Clone(getter_AddRefs(file))) ||
-            NS_FAILED(file->AppendNative(NS_LITERAL_CSTRING("omni.jar"))))
-            return;
-    }
-    PRBool isFile;
-    if (NS_FAILED(file->IsFile(&isFile)) || !isFile) {
-        // If we're not using an omni.jar for GRE, and we don't have an
-        // omni.jar for APP, check if both directories are the same.
-        if ((aType == APP) && (!sPath[GRE])) {
-            nsCOMPtr<nsIFile> greDir, appDir;
-            PRBool equals;
-            nsDirectoryService::gService->Get(SPROP(GRE), NS_GET_IID(nsIFile), getter_AddRefs(greDir));
-            nsDirectoryService::gService->Get(SPROP(APP), NS_GET_IID(nsIFile), getter_AddRefs(appDir));
-            if (NS_SUCCEEDED(greDir->Equals(appDir, &equals)) && equals)
-                sIsUnified = PR_TRUE;
-        }
-        return;
-    }
-
-    PRBool equals;
-    if ((aType == APP) && (sPath[GRE]) &&
-        NS_SUCCEEDED(sPath[GRE]->Equals(file, &equals)) && equals) {
-        // If we're using omni.jar on both GRE and APP and their path
-        // is the same, we're in the unified case.
-        sIsUnified = PR_TRUE;
+    if (!sOmnijarPath) {
         return;
     }
 
     nsZipArchive* zipReader = new nsZipArchive();
-    if (!zipReader)
+    if (!zipReader) {
+        NS_IF_RELEASE(sOmnijarPath);
         return;
+    }
 
-    if (NS_FAILED(zipReader->OpenArchive(file))) {
+    if (NS_FAILED(zipReader->OpenArchive(sOmnijarPath))) {
         delete zipReader;
+        NS_IF_RELEASE(sOmnijarPath);
         return;
     }
 
-    CleanUpOne(aType);
-    sReader[aType] = zipReader;
-    sPath[aType] = file;
-    NS_IF_ADDREF(file);
+    sOmnijarReader = zipReader;
 }
 
-void
-Omnijar::Init(nsIFile *aGrePath, nsIFile *aAppPath)
+nsILocalFile*
+mozilla::OmnijarPath()
 {
-    InitOne(aGrePath, GRE);
-    InitOne(aAppPath, APP);
-    sInitialized = PR_TRUE;
+    if (!sOmnijarReader)
+        SetupReader();
+
+    return sOmnijarPath;
+}
+
+nsZipArchive*
+mozilla::OmnijarReader()
+{
+    if (!sOmnijarReader)
+        SetupReader();
+
+    return sOmnijarReader;
 }
 
 void
-Omnijar::CleanUp()
+mozilla::SetOmnijar(nsILocalFile* aPath)
 {
-    CleanUpOne(GRE);
-    CleanUpOne(APP);
-    sInitialized = PR_FALSE;
-}
-
-nsZipArchive *
-Omnijar::GetReader(nsIFile *aPath)
-{
-    NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
+    NS_IF_RELEASE(sOmnijarPath);
+    if (sOmnijarReader) {
+        sOmnijarReader->CloseArchive();
+        delete sOmnijarReader;
+        sOmnijarReader = nsnull;
+    }
 
-    PRBool equals;
-    nsresult rv;
-
-    if (sPath[GRE]) {
-        rv = sPath[GRE]->Equals(aPath, &equals);
-        if (NS_SUCCEEDED(rv) && equals)
-            return sReader[GRE];
-    }
-    if (sPath[APP]) {
-        rv = sPath[APP]->Equals(aPath, &equals);
-        if (NS_SUCCEEDED(rv) && equals)
-            return sReader[APP];
-    }
-    return nsnull;
+    sOmnijarPath = aPath;
+    NS_IF_ADDREF(sOmnijarPath);
 }
 
-nsresult
-Omnijar::GetURIString(Type aType, nsACString &result)
-{
-    NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
-
-    result.Truncate();
-
-    // Return an empty string for APP in the unified case.
-    if ((aType == APP) && sIsUnified) {
-        return NS_OK;
-    }
-
-    nsCAutoString omniJarSpec;
-    if (sPath[aType]) {
-        nsresult rv = NS_GetURLSpecFromActualFile(sPath[aType], omniJarSpec);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        result = "jar:";
-        result += omniJarSpec;
-        result += "!";
-    } else {
-        nsCOMPtr<nsIFile> dir;
-        nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile), getter_AddRefs(dir));
-        nsresult rv = NS_GetURLSpecFromActualFile(dir, result);
-        NS_ENSURE_SUCCESS(rv, rv);
-    }
-    result += "/";
-    return NS_OK;
-}
-
-} /* namespace mozilla */
--- a/xpcom/build/Omnijar.h
+++ b/xpcom/build/Omnijar.h
@@ -16,17 +16,16 @@
  *
  * The Initial Developer of the Original Code is
  * Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2010
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Michael Wu <mwu@mozilla.com>
- *   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
@@ -35,130 +34,29 @@
  * 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 ***** */
 
 #ifndef mozilla_Omnijar_h
 #define mozilla_Omnijar_h
 
-#include "nscore.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
+class nsILocalFile;
+class nsZipArchive;
 
-class nsIFile;
-class nsZipArchive;
-class nsIURI;
+#ifdef MOZ_OMNIJAR
 
 namespace mozilla {
 
-class Omnijar {
-private:
 /**
- * Store an nsIFile for an omni.jar. We can store two paths here, one
- * for GRE (corresponding to resource://gre/) and one for APP
- * (corresponding to resource:/// and resource://app/), but only
- * store one when both point to the same location (unified).
- */
-static nsIFile *sPath[2];
-
-/**
- * Cached nsZipArchives for the corresponding sPath
- */
-static nsZipArchive *sReader[2];
-
-/**
- * Has Omnijar::Init() been called?
- */
-static PRPackedBool sInitialized;
-
-public:
-enum Type {
-    GRE = 0,
-    APP = 1
-};
-
-/**
- * Returns whether SetBase has been called at least once with
- * a valid nsIFile
- */
-static inline PRPackedBool
-IsInitialized()
-{
-    return sInitialized;
-}
-
-/**
- * Initializes the Omnijar API with the given directory or file for GRE and
- * APP. Each of the paths given can be:
- * - a file path, pointing to the omnijar file,
- * - a directory path, pointing to a directory containing an "omni.jar" file,
- * - nsnull for autodetection of an "omni.jar" file.
- */
-static void Init(nsIFile *aGrePath = nsnull, nsIFile *aAppPath = nsnull);
-
-/**
- * Cleans up the Omnijar API
+ * This returns the path to the omnijar.
+ * If the omnijar isn't available, this function will return null.
+ * Callers should fallback to flat packaging if null.
  */
-static void CleanUp();
-
-/**
- * Returns an nsIFile pointing to the omni.jar file for GRE or APP.
- * Returns nsnull when there is no corresponding omni.jar.
- * Also returns nsnull for APP in the unified case.
- */
-static inline already_AddRefed<nsIFile>
-GetPath(Type aType)
-{
-    NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
-    NS_IF_ADDREF(sPath[aType]);
-    return sPath[aType];
-}
-
-/**
- * Returns whether GRE or APP use an omni.jar. Returns PR_False for
- * APP when using an omni.jar in the unified case.
- */
-static inline PRBool
-HasOmnijar(Type aType)
-{
-    NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
-    return !!sPath[aType];
-}
-
-/**
- * Returns a nsZipArchive pointer for the omni.jar file for GRE or
- * APP. Returns nsnull in the same cases GetPath() would.
- */
-static inline nsZipArchive *
-GetReader(Type aType)
-{
-    NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
-    return sReader[aType];
-}
-
-/**
- * Returns a nsZipArchive pointer for the given path IAOI the given
- * path is the omni.jar for either GRE or APP.
- */
-static nsZipArchive *GetReader(nsIFile *aPath);
-
-/**
- * Returns the URI string corresponding to the omni.jar or directory
- * for GRE or APP. i.e. jar:/path/to/omni.jar!/ for omni.jar and
- * /path/to/base/dir/ otherwise. Returns an empty string for APP in
- * the unified case.
- * The returned URI is guaranteed to end with a slash.
- */
-static nsresult GetURIString(Type aType, nsACString &result);
-
-private:
-/**
- * Used internally, respectively by Init() and CleanUp()
- */
-static void InitOne(nsIFile *aPath, Type aType);
-static void CleanUpOne(Type aType);
-
-}; /* class Omnijar */
+nsILocalFile *OmnijarPath();
+nsZipArchive *OmnijarReader();
+void SetOmnijar(nsILocalFile* aPath);
 
 } /* namespace mozilla */
 
+#endif /* MOZ_OMNIJAR */
+
 #endif /* mozilla_Omnijar_h */
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -452,21 +452,35 @@ NS_InitXPCOM2(nsIServiceManager* *result
         nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
     }
     
     if (appFileLocationProvider) {
         rv = nsDirectoryService::gService->RegisterProvider(appFileLocationProvider);
         if (NS_FAILED(rv)) return rv;
     }
 
+#ifdef MOZ_OMNIJAR
     NS_TIME_FUNCTION_MARK("Next: Omnijar init");
 
-    if (!mozilla::Omnijar::IsInitialized()) {
-        mozilla::Omnijar::Init();
+    if (!mozilla::OmnijarPath()) {
+        nsCOMPtr<nsILocalFile> omnijar;
+        nsCOMPtr<nsIFile> file;
+
+        rv = NS_ERROR_FAILURE;
+        nsDirectoryService::gService->Get(NS_GRE_DIR,
+                                          NS_GET_IID(nsIFile),
+                                          getter_AddRefs(file));
+        if (file)
+            rv = file->Append(NS_LITERAL_STRING("omni.jar"));
+        if (NS_SUCCEEDED(rv))
+            omnijar = do_QueryInterface(file);
+        if (NS_SUCCEEDED(rv))
+            mozilla::SetOmnijar(omnijar);
     }
+#endif
 
     if ((sCommandLineWasInitialized = !CommandLine::IsInitialized())) {
         NS_TIME_FUNCTION_MARK("Next: IPC command line init");
 
 #ifdef OS_WIN
         CommandLine::Init(0, nsnull);
 #else
         nsCOMPtr<nsIFile> binaryFile;
@@ -736,16 +750,18 @@ ShutdownXPCOM(nsIServiceManager* servMgr
         CommandLine::Terminate();
         sCommandLineWasInitialized = false;
     }
     if (sExitManager) {
         delete sExitManager;
         sExitManager = nsnull;
     }
 
-    mozilla::Omnijar::CleanUp();
+#ifdef MOZ_OMNIJAR
+    mozilla::SetOmnijar(nsnull);
+#endif
 
     NS_LogTerm();
 
     return NS_OK;
 }
 
 } // namespace mozilla
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -169,16 +169,18 @@ NS_DEFINE_CID(kCategoryManagerCID, NS_CA
 #define COMPMGR_TIME_FUNCTION_CONTRACTID(cid)                                  \
   NS_TIME_FUNCTION_MIN_FMT(5, "%s (line %d) (contractid: %s)", MOZ_FUNCTION_NAME, \
                            __LINE__, (cid))
 #else
 #define COMPMGR_TIME_FUNCTION_CID(cid) do {} while (0)
 #define COMPMGR_TIME_FUNCTION_CONTRACTID(cid) do {} while (0)
 #endif
 
+#define kOMNIJAR_PREFIX  NS_LITERAL_CSTRING("resource:///")
+
 nsresult
 nsGetServiceFromCategory::operator()(const nsIID& aIID, void** aInstancePtr) const
 {
     nsresult rv;
     nsXPIDLCString value;
     nsCOMPtr<nsICategoryManager> catman;
     nsComponentManagerImpl *compMgr = nsComponentManagerImpl::gComponentManager;
     if (!compMgr) {
@@ -378,44 +380,47 @@ nsresult nsComponentManagerImpl::Init()
 
     nsCategoryManager::GetSingleton()->SuppressNotifications(true);
 
     RegisterModule(&kXPCOMModule, NULL);
 
     for (PRUint32 i = 0; i < sStaticModules->Length(); ++i)
         RegisterModule((*sStaticModules)[i], NULL);
 
-    nsCOMPtr<nsIFile> appOmnijar = mozilla::Omnijar::GetPath(mozilla::Omnijar::APP);
-    if (appOmnijar) {
-        cl = sModuleLocations->InsertElementAt(1); // Insert after greDir
-        cl->type = NS_COMPONENT_LOCATION;
-        cl->location = do_QueryInterface(appOmnijar);
-        cl->jar = true;
+#ifdef MOZ_OMNIJAR
+    if (mozilla::OmnijarPath()) {
+        nsCOMPtr<nsIZipReader> omnijarReader = new nsJAR();
+        rv = omnijarReader->Open(mozilla::OmnijarPath());
+        if (NS_SUCCEEDED(rv))
+            RegisterJarManifest(omnijarReader, "chrome.manifest", false);
     }
-    nsCOMPtr<nsIFile> greOmnijar = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE);
-    if (greOmnijar) {
-        cl = sModuleLocations->InsertElementAt(0);
-        cl->type = NS_COMPONENT_LOCATION;
-        cl->location = do_QueryInterface(greOmnijar);
-        cl->jar = true;
-    }
+#endif
 
     for (PRUint32 i = 0; i < sModuleLocations->Length(); ++i) {
         ComponentLocation& l = sModuleLocations->ElementAt(i);
         if (!l.jar) {
             RegisterManifestFile(l.type, l.location, false);
             continue;
         }
 
         nsCOMPtr<nsIZipReader> reader = do_CreateInstance(kZipReaderCID, &rv);
         rv = reader->Open(l.location);
         if (NS_SUCCEEDED(rv))
             RegisterJarManifest(reader, "chrome.manifest", false);
     }
 
+#ifdef MOZ_OMNIJAR
+    if (mozilla::OmnijarPath()) {
+        cl = sModuleLocations->InsertElementAt(0);
+        cl->type = NS_COMPONENT_LOCATION;
+        cl->location = mozilla::OmnijarPath();
+        cl->jar = true;
+    }
+#endif
+
     nsCategoryManager::GetSingleton()->SuppressNotifications(false);
 
     mStatus = NORMAL;
 
     return NS_OK;
 }
 
 void
--- a/xulrunner/confvars.sh
+++ b/xulrunner/confvars.sh
@@ -36,16 +36,15 @@
 #
 # ***** END LICENSE BLOCK *****
 
 MOZ_APP_NAME=xulrunner
 MOZ_APP_DISPLAYNAME=XULRunner
 MOZ_UPDATER=1
 MOZ_XULRUNNER=1
 MOZ_ENABLE_LIBXUL=1
-MOZ_CHROME_FILE_FORMAT=omni
 MOZ_STATIC_BUILD_UNSUPPORTED=1
 MOZ_APP_VERSION=$MOZILLA_VERSION
 if test "$MOZ_STORAGE"; then
   MOZ_PLACES=1
 fi
 MOZ_EXTENSIONS_DEFAULT=" gnomevfs"
 MOZ_URL_CLASSIFIER=1