author | Doug Turner <dougt@dougt.org> |
Tue, 10 Aug 2010 18:33:38 -0700 | |
changeset 49368 | b1be7d4acee211e547389d0d0151c0ebfd774027 |
parent 49326 | 1b12ed9d1c48de3a0b62673b7229ee9aef72438b (current diff) |
parent 49367 | 14342400e38b822ae1fbd091031d380a98b3b98a (diff) |
child 49370 | b89bd32f1245896103b93414f4841e3820fcb679 |
child 49376 | adbf1571c30d04349e22a7a0cbb8151da0c872a0 |
push id | 1 |
push user | root |
push date | Tue, 26 Apr 2011 22:38:44 +0000 |
treeherder | mozilla-beta@bfdb6e623a36 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | dougt |
milestone | 2.0b4pre |
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
|
caps/tests/mochitest/test_bug292789.html | file | annotate | diff | comparison | revisions | |
ipc/glue/GeckoChildProcessHost.cpp | file | annotate | diff | comparison | revisions |
--- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -47,16 +47,21 @@ const Cc = Components.classes; const Cr = Components.results; const Cu = Components.utils; const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); +XPCOMUtils.defineLazyGetter(this, "NetUtil", function() { + Cu.import("resource://gre/modules/NetUtil.jsm"); + return NetUtil; +}); + const PREF_EM_NEW_ADDONS_LIST = "extensions.newAddons"; const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser"; const PREF_PLUGINS_UPDATEURL = "plugins.update.url"; // We try to backup bookmarks at idle times, to avoid doing that at shutdown. // Number of idle seconds before trying to backup bookmarks. 15 minutes. const BOOKMARKS_BACKUP_IDLE_TIME = 15 * 60; // Minimum interval in milliseconds between backups. @@ -835,36 +840,38 @@ BrowserGlue.prototype = { } catch(ex) {} if (!autoExportHTML && smartBookmarksVersion != -1) Services.prefs.setIntPref("browser.places.smartBookmarksVersion", 0); // Get bookmarks.html file location var dirService = Cc["@mozilla.org/file/directory_service;1"]. getService(Ci.nsIProperties); - var bookmarksFile = null; + var bookmarksURI = null; if (restoreDefaultBookmarks) { // User wants to restore bookmarks.html file from default profile folder - bookmarksFile = dirService.get("profDef", Ci.nsILocalFile); - bookmarksFile.append("bookmarks.html"); + bookmarksURI = NetUtil.newURI("resource:///defaults/profile/bookmarks.html"); } - else - bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile); + else { + var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile); + if (bookmarksFile.exists()) + bookmarksURI = NetUtil.newURI(bookmarksFile); + } - if (bookmarksFile.exists()) { + if (bookmarksURI) { // Add an import observer. It will ensure that smart bookmarks are // created once the operation is complete. Services.obs.addObserver(this, "bookmarks-restore-success", false); Services.obs.addObserver(this, "bookmarks-restore-failed", false); // Import from bookmarks.html file. try { var importer = Cc["@mozilla.org/browser/places/import-export-service;1"]. getService(Ci.nsIPlacesImportExportService); - importer.importHTMLFromFile(bookmarksFile, true /* overwrite existing */); + importer.importHTMLFromURI(bookmarksURI, true /* overwrite existing */); } catch (err) { // Report the error, but ignore it. Cu.reportError("Bookmarks.html file could be corrupt. " + err); Services.obs.removeObserver(this, "bookmarks-restore-success"); Services.obs.removeObserver(this, "bookmarks-restore-failed"); } } else
--- a/caps/tests/mochitest/Makefile.in +++ b/caps/tests/mochitest/Makefile.in @@ -46,10 +46,14 @@ include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/rules.mk _TEST_FILES = test_bug423375.html \ test_bug246699.html \ test_bug292789.html \ test_bug470804.html \ $(NULL) +test_bug292789.html : % : %.in + $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ + $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@ + libs:: $(_TEST_FILES) $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
rename from caps/tests/mochitest/test_bug292789.html rename to caps/tests/mochitest/test_bug292789.html.in --- a/caps/tests/mochitest/test_bug292789.html +++ b/caps/tests/mochitest/test_bug292789.html.in @@ -33,34 +33,42 @@ function testScriptSrc(aCallback) { "content can still load <script> from chrome://global"); is(typeof XPInstallConfirm, "undefined", "content should not be able to load <script> from chrome://mozapps"); /** make sure the last one didn't pass because someone ** moved the resource **/ var resjs = document.createElement("script"); +#ifdef MOZ_CHROME_FILE_FORMAT_JAR resjs.src = "jar:resource://gre/chrome/toolkit.jar!/content/mozapps/xpinstall/xpinstallConfirm.js"; +#else + resjs.src = "resource://gre/chrome/toolkit/content/mozapps/xpinstall/xpinstallConfirm.js"; +#endif resjs.onload = scriptOnload; document.getElementById("content").appendChild(resjs); function scriptOnload() { is(typeof XPInstallConfirm, "object", "xpinstallConfirm.js has not moved unexpectedly"); // trigger the callback if (aCallback) aCallback(); } } /** <img src=""> tests **/ var img_global = "chrome://global/skin/icons/Error.png"; var img_mozapps = "chrome://mozapps/skin/passwordmgr/key.png"; +#ifdef MOZ_CHROME_FILE_FORMAT_JAR var res_mozapps = "jar:resource://gre/chrome/toolkit.jar!/skin/classic/mozapps/passwordmgr/key.png"; +#else +var res_mozapps = "resource://gre/chrome/toolkit/skin/classic/mozapps/passwordmgr/key.png"; +#endif var imgTests = [[img_global, "success"], [img_mozapps, "fail"], [res_mozapps, "success"]]; var curImgTest = 0; function runImgTest() {
--- a/config/system-headers +++ b/config/system-headers @@ -1031,9 +1031,12 @@ conic/conicconnectionevent.h conic/conicstatisticsevent.h #endif #if MOZ_NATIVE_LIBEVENT==1 event.h #endif #ifdef MOZ_ENABLE_LIBPROXY proxy.h #endif +#if MOZ_PLATFORM_MAEMO==6 +contentaction/contentaction.h +#endif
--- a/content/html/content/src/nsHTMLDNSPrefetch.cpp +++ b/content/html/content/src/nsHTMLDNSPrefetch.cpp @@ -101,16 +101,21 @@ nsHTMLDNSPrefetch::Initialize() sDisablePrefetchHTTPSPref = nsContentUtils::GetBoolPref("network.dns.disablePrefetchFromHTTPS", PR_TRUE); NS_IF_RELEASE(sDNSService); nsresult rv; rv = CallGetService(kDNSServiceCID, &sDNSService); if (NS_FAILED(rv)) return rv; +#ifdef MOZ_IPC + if (mozilla::net::IsNeckoChild()) + mozilla::net::NeckoChild::InitNeckoChild(); +#endif + sInitialized = PR_TRUE; return NS_OK; } nsresult nsHTMLDNSPrefetch::Shutdown() { if (!sInitialized) {
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -48,16 +48,18 @@ #include "nsIPrefLocalizedString.h" #include "nsIObserverService.h" #include "nsContentUtils.h" #include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "nsServiceManagerUtils.h" #include "nsThreadUtils.h" #include "nsChromeRegistryChrome.h" +#include "nsExternalHelperAppService.h" +#include "nsCExternalHandlerService.h" #ifdef ANDROID #include "AndroidBridge.h" using namespace mozilla; #endif using namespace mozilla::ipc; using namespace mozilla::net; @@ -465,16 +467,27 @@ ContentParent::RecvSetURITitle(const IPC const nsString& title) { nsCOMPtr<nsIURI> ourURI(uri); IHistory *history = nsContentUtils::GetHistory(); history->SetURITitle(ourURI, title); return true; } +bool +ContentParent::RecvLoadURIExternal(const IPC::URI& uri) +{ + nsCOMPtr<nsIExternalProtocolService> extProtService(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID)); + if (!extProtService) + return true; + nsCOMPtr<nsIURI> ourURI(uri); + extProtService->LoadURI(ourURI, nsnull); + return true; +} + /* void onDispatchedEvent (in nsIThreadInternal thread); */ NS_IMETHODIMP ContentParent::OnDispatchedEvent(nsIThreadInternal *thread) { if (mOldObserver) return mOldObserver->OnDispatchedEvent(thread); return NS_OK;
--- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -157,16 +157,18 @@ private: virtual bool RecvNotifyIME(const int&, const int&); virtual bool RecvNotifyIMEChange(const nsString&, const PRUint32&, const int&, const int&, const int&) ; + virtual bool RecvLoadURIExternal(const IPC::URI& uri); + mozilla::Monitor mMonitor; GeckoChildProcessHost* mSubprocess; int mRunToCompletionDepth; bool mShouldCallUnblockChild; nsCOMPtr<nsIThreadObserver> mOldObserver;
--- a/dom/ipc/Makefile.in +++ b/dom/ipc/Makefile.in @@ -77,13 +77,14 @@ include $(topsrcdir)/ipc/chromium/chromi include $(topsrcdir)/config/rules.mk LOCAL_INCLUDES += \ -I$(srcdir)/../../content/base/src \ -I$(srcdir)/../../content/events/src \ -I$(srcdir)/../../toolkit/components/places/src \ -I$(srcdir)/../src/geolocation \ -I$(topsrcdir)/chrome/src \ + -I$(topsrcdir)/uriloader/exthandler \ $(NULL) CXXFLAGS += $(TK_CFLAGS) DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
--- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -76,16 +76,18 @@ parent: PNecko(); // Services remoting async StartVisitedQuery(URI uri); async VisitURI(URI uri, URI referrer, PRUint32 flags); async SetURITitle(URI uri, nsString title); + async LoadURIExternal(URI uri); + // PrefService messages sync GetPrefType(nsCString prefName) returns (PRInt32 retValue, nsresult rv); sync GetBoolPref(nsCString prefName) returns (PRBool retValue, nsresult rv); sync GetIntPref(nsCString prefName) returns (PRInt32 retValue, nsresult rv); sync GetCharPref(nsCString prefName) returns (nsCString retValue, nsresult rv); sync GetPrefLocalizedString(nsCString prefName) returns (nsString retValue, nsresult rv); sync PrefHasUserValue(nsCString prefName) returns (PRBool retValue, nsresult rv); sync PrefIsLocked(nsCString prefName) returns (PRBool retValue, nsresult rv);
--- a/embedding/android/AndroidManifest.xml.in +++ b/embedding/android/AndroidManifest.xml.in @@ -9,17 +9,18 @@ <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="5"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:label="@MOZ_APP_DISPLAYNAME@" - android:icon="@drawable/icon"> + android:icon="@drawable/icon" + android:debuggable="true"> <activity android:name="App" android:label="@MOZ_APP_DISPLAYNAME@" android:configChanges="keyboard|keyboardHidden|orientation|mcc|mnc" android:windowSoftInputMode="stateUnspecified|adjustResize" android:launchMode="singleInstance"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
--- a/embedding/android/GeckoAppShell.java +++ b/embedding/android/GeckoAppShell.java @@ -152,17 +152,17 @@ class GeckoAppShell GeckoAppShell.nativeInit(); // Tell Gecko where the target surface view is for rendering GeckoAppShell.setSurfaceView(GeckoApp.surfaceView); sGeckoRunning = true; // First argument is the .apk path - String combinedArgs = apkPath; + String combinedArgs = apkPath + " -omnijar " + apkPath; if (args != null) combinedArgs += " " + args; if (url != null) combinedArgs += " " + url; // and go GeckoAppShell.nativeRun(combinedArgs); }
--- a/embedding/browser/webBrowser/nsWebBrowser.cpp +++ b/embedding/browser/webBrowser/nsWebBrowser.cpp @@ -86,16 +86,17 @@ // Printing Includes #ifdef NS_PRINTING #include "nsIWebBrowserPrint.h" #include "nsIContentViewer.h" #endif // PSM2 includes #include "nsISecureBrowserUI.h" +#include "nsXULAppAPI.h" using namespace mozilla::layers; static NS_DEFINE_IID(kWindowCID, NS_WINDOW_CID); static NS_DEFINE_CID(kChildCID, NS_CHILD_CID); static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); @@ -785,16 +786,17 @@ NS_IMETHODIMP nsWebBrowser::SetProperty( } break; case nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH: { NS_ENSURE_STATE(mDocShell); NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG); mDocShell->SetAllowDNSPrefetch(!!aValue); } + break; case nsIWebBrowserSetup::SETUP_USE_GLOBAL_HISTORY: { NS_ENSURE_STATE(mDocShell); NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG); rv = EnableGlobalHistory(!!aValue); mShouldEnableHistory = aValue; } break; @@ -1225,20 +1227,22 @@ NS_IMETHODIMP nsWebBrowser::Create() // events from subframes. To solve that we install our own chrome event handler // that always gets called (even for subframes) for any bubbling event. if (!mInitInfo->sessionHistory) { mInitInfo->sessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); } mDocShellAsNav->SetSessionHistory(mInitInfo->sessionHistory); - - // Hook up global history. Do not fail if we can't - just warn. - rv = EnableGlobalHistory(mShouldEnableHistory); - NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "EnableGlobalHistory() failed"); + + if (XRE_GetProcessType() == GeckoProcessType_Default) { + // Hook up global history. Do not fail if we can't - just warn. + rv = EnableGlobalHistory(mShouldEnableHistory); + NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "EnableGlobalHistory() failed"); + } NS_ENSURE_SUCCESS(mDocShellAsWin->Create(), NS_ERROR_FAILURE); // Hook into the OnSecurityChange() notification for lock/unlock icon // updates nsCOMPtr<nsIDOMWindow> domWindow; rv = GetContentDOMWindow(getter_AddRefs(domWindow)); if (NS_SUCCEEDED(rv))
--- a/intl/locale/src/nsLocaleService.cpp +++ b/intl/locale/src/nsLocaleService.cpp @@ -55,16 +55,19 @@ # include "nsIOS2Locale.h" #elif defined(XP_MACOSX) # include <Carbon/Carbon.h> # include "nsIMacLocale.h" #elif defined(XP_UNIX) || defined(XP_BEOS) # include <locale.h> # include <stdlib.h> # include "nsIPosixLocale.h" +#if (MOZ_PLATFORM_MAEMO >= 6) +# include "nsIGConfService.h" +#endif #endif // // implementation constants const int LocaleListLength = 6; const char* LocaleList[LocaleListLength] = { NSILOCALE_COLLATE, @@ -169,34 +172,53 @@ nsLocaleService::nsLocaleService(void) nsAutoString category, category_platform; nsLocale* resultLocale; int i; resultLocale = new nsLocale(); if ( resultLocale == NULL ) { return; } + + // Get system configuration + char* lang = getenv("LANG"); +#if (MOZ_PLATFORM_MAEMO >= 6) + nsCAutoString gconfLocaleString; + nsresult rv; + nsCOMPtr<nsIGConfService> gconf = + do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) { + rv = gconf->GetString(NS_LITERAL_CSTRING("/meegotouch/i18n/language"), + gconfLocaleString); + if (NS_SUCCEEDED(rv) && !gconfLocaleString.IsEmpty()) { + lang = static_cast<const char*>(gconfLocaleString.get()); + // For setlocale() doing the right thing we need to export + // this as LANG to the environment + setenv("LANG", lang, 1); + } + } +#endif for( i = 0; i < LocaleListLength; i++ ) { nsresult result; + // setlocale( , "") evaluates LC_* and LANG char* lc_temp = setlocale(posix_locale_category[i], ""); CopyASCIItoUTF16(LocaleList[i], category); - category_platform = category; + category_platform = category; category_platform.AppendLiteral("##PLATFORM"); if (lc_temp != nsnull) { result = posixConverter->GetXPLocale(lc_temp, xpLocale); CopyASCIItoUTF16(lc_temp, platformLocale); } else { - char* lang = getenv("LANG"); if ( lang == nsnull ) { platformLocale.AssignLiteral("en_US"); result = posixConverter->GetXPLocale("en-US", xpLocale); } else { CopyASCIItoUTF16(lang, platformLocale); - result = posixConverter->GetXPLocale(lang, xpLocale); + result = posixConverter->GetXPLocale(lang, xpLocale); } } if (NS_FAILED(result)) { return; } resultLocale->AddCategory(category, xpLocale); resultLocale->AddCategory(category_platform, platformLocale); }
--- a/ipc/chromium/src/chrome/common/child_process_host.cc +++ b/ipc/chromium/src/chrome/common/child_process_host.cc @@ -6,16 +6,17 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "base/message_loop.h" #include "base/process_util.h" #include "base/singleton.h" #include "base/waitable_event.h" #ifdef CHROMIUM_MOZILLA_BUILD +#include "mozilla/ipc/ProcessChild.h" #include "mozilla/ipc/BrowserProcessSubThread.h" typedef mozilla::ipc::BrowserProcessSubThread ChromeThread; #else #include "chrome/browser/chrome_thread.h" #endif #include "chrome/common/ipc_logging.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" @@ -117,16 +118,18 @@ bool ChildProcessHost::Send(IPC::Message } return channel_->Send(msg); } void ChildProcessHost::Notify(NotificationType type) { #ifdef CHROMIUM_MOZILLA_BUILD MessageLoop* loop = ChromeThread::GetMessageLoop(ChromeThread::IO); if (!loop) + loop = mozilla::ipc::ProcessChild::message_loop(); + if (!loop) loop = MessageLoop::current(); loop->PostTask( #else resource_dispatcher_host_->ui_loop()->PostTask( #endif FROM_HERE, new ChildNotificationTask(type, this)); }
--- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -249,24 +249,16 @@ GeckoChildProcessHost::PerformAsyncLaunc #ifdef OS_LINUX #ifdef ANDROID path += "/lib"; #endif newEnvVars["LD_LIBRARY_PATH"] = path.get(); #elif OS_MACOSX newEnvVars["DYLD_LIBRARY_PATH"] = path.get(); #endif -#ifdef MOZ_OMNIJAR - // Make sure the child process can find the omnijar - // See ScopedXPCOMStartup::Initialize in nsAppRunner.cpp - nsCAutoString omnijarPath; - if (mozilla::OmnijarPath()) - mozilla::OmnijarPath()->GetNativePath(omnijarPath); - newEnvVars["OMNIJAR_PATH"] = omnijarPath.get(); -#endif } else { exePath = FilePath(CommandLine::ForCurrentProcess()->argv()[0]); exePath = exePath.DirName(); } #ifdef OS_MACOSX // We need to use an App Bundle on OS X so that we can hide @@ -291,16 +283,27 @@ 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 omnijarPath; + if (mozilla::OmnijarPath()) { + mozilla::OmnijarPath()->GetNativePath(omnijarPath); + childArgv.push_back("-omnijar"); + childArgv.push_back(omnijarPath.get()); + } +#endif + childArgv.push_back(pidstring); childArgv.push_back(childProcessType); #if defined(MOZ_CRASHREPORTER) # if defined(OS_LINUX) int childCrashFd, childCrashRemapFd; if (!CrashReporter::CreateNotificationPipeForChild( &childCrashFd, &childCrashRemapFd)) @@ -341,16 +344,28 @@ 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 omnijarPath; + if (mozilla::OmnijarPath()) { + mozilla::OmnijarPath()->GetPath(omnijarPath); + cmdLine.AppendLooseValue(UTF8ToWide("-omnijar")); + cmdLine.AppendLooseValue(omnijarPath.get()); + } +#endif + cmdLine.AppendLooseValue(UTF8ToWide(pidstring)); cmdLine.AppendLooseValue(UTF8ToWide(childProcessType)); #if defined(MOZ_CRASHREPORTER) cmdLine.AppendLooseValue( UTF8ToWide(CrashReporter::GetChildNotificationPipe())); #endif base::LaunchApp(cmdLine, false, false, &process);
--- a/ipc/testshell/XPCShellEnvironment.cpp +++ b/ipc/testshell/XPCShellEnvironment.cpp @@ -1210,16 +1210,19 @@ XPCShellEnvironment::Init() return true; } bool XPCShellEnvironment::EvaluateString(const nsString& aString, nsString* aResult) { + XPCShellEnvironment* env = Environment(mCx); + XPCShellEnvironment::AutoContextPusher pusher(env); + JSAutoRequest ar(mCx); JS_ClearPendingException(mCx); JSObject* global = GetGlobalObject(); JSScript* script = JS_CompileUCScriptForPrincipals(mCx, global, GetPrincipal(),
--- a/js/src/config/system-headers +++ b/js/src/config/system-headers @@ -1031,9 +1031,12 @@ conic/conicconnectionevent.h conic/conicstatisticsevent.h #endif #if MOZ_NATIVE_LIBEVENT==1 event.h #endif #ifdef MOZ_ENABLE_LIBPROXY proxy.h #endif +#if MOZ_PLATFORM_MAEMO==6 +contentaction/contentaction.h +#endif
--- a/js/src/xpconnect/tests/unit/test_import.js +++ b/js/src/xpconnect/tests/unit/test_import.js @@ -62,23 +62,22 @@ function run_test() { // try on a new object var scope2 = {}; Components.utils.import("resource://gre/modules/XPCOMUtils.jsm", scope2); do_check_eq(typeof(scope2.XPCOMUtils), "object"); do_check_eq(typeof(scope2.XPCOMUtils.generateNSGetFactory), "function"); do_check_true(scope2.XPCOMUtils == scope.XPCOMUtils); - // try on a new object using a file URL + // try on a new object using the resolved URL var res = Components.classes["@mozilla.org/network/protocol;1?name=resource"] .getService(Components.interfaces.nsIResProtocolHandler); var resURI = res.newURI("resource://gre/modules/XPCOMUtils.jsm", null, null); dump("resURI: " + resURI + "\n"); var filePath = res.resolveURI(resURI); - do_check_eq(filePath.indexOf("file://"), 0); var scope3 = {}; Components.utils.import(filePath, scope3); do_check_eq(typeof(scope3.XPCOMUtils), "object"); do_check_eq(typeof(scope3.XPCOMUtils.generateNSGetFactory), "function"); do_check_true(scope3.XPCOMUtils == scope.XPCOMUtils); // make sure we throw when the second arg is bogus
--- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -44,33 +44,50 @@ #include "mozilla/net/NeckoChild.h" #include "mozilla/net/HttpChannelChild.h" #include "nsStringStream.h" #include "nsHttpHandler.h" #include "nsMimeTypes.h" #include "nsNetUtil.h" -class Callback +namespace mozilla { +namespace net { + +class ChildChannelEvent { public: - virtual bool Run() = 0; + virtual void Run() = 0; }; -namespace mozilla { -namespace net { +// Ensures any incoming IPDL msgs are queued during its lifetime, and flushes +// the queue when it goes out of scope. +class AutoEventEnqueuer +{ +public: + AutoEventEnqueuer(HttpChannelChild* channel) : mChannel(channel) + { + mChannel->BeginEventQueueing(); + } + ~AutoEventEnqueuer() + { + mChannel->FlushEventQueue(); + } +private: + HttpChannelChild *mChannel; +}; // C++ file contents HttpChannelChild::HttpChannelChild() : mIsFromCache(PR_FALSE) , mCacheEntryAvailable(PR_FALSE) , mCacheExpirationTime(nsICache::NO_EXPIRATION_TIME) , mState(HCC_NEW) , mIPCOpen(false) - , mShouldBuffer(true) + , mQueuePhase(PHASE_UNQUEUED) { LOG(("Creating HttpChannelChild @%x\n", this)); } HttpChannelChild::~HttpChannelChild() { LOG(("Destroying HttpChannelChild @%x\n", this)); } @@ -113,96 +130,166 @@ HttpChannelChild::AddIPDLReference() void HttpChannelChild::ReleaseIPDLReference() { NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference"); mIPCOpen = false; Release(); } +void +HttpChannelChild::FlushEventQueue() +{ + NS_ABORT_IF_FALSE(mQueuePhase != PHASE_UNQUEUED, + "Queue flushing should not occur if PHASE_UNQUEUED"); + + // Queue already being flushed. + if (mQueuePhase != PHASE_QUEUEING) + return; + + if (mEventQueue.Length() > 0) { + // It is possible for new callbacks to be enqueued as we are + // flushing the queue, so the queue must not be cleared until + // all callbacks have run. + mQueuePhase = PHASE_FLUSHING; + + nsCOMPtr<nsIHttpChannel> kungFuDeathGrip(this); + for (PRUint32 i = 0; i < mEventQueue.Length(); i++) { + mEventQueue[i]->Run(); + } + mEventQueue.Clear(); + } + + mQueuePhase = PHASE_UNQUEUED; +} + +class StartRequestEvent : public ChildChannelEvent +{ + public: + StartRequestEvent(HttpChannelChild* child, + const nsHttpResponseHead& responseHead, + const PRBool& useResponseHead, + const PRBool& isFromCache, + const PRBool& cacheEntryAvailable, + const PRUint32& cacheExpirationTime, + const nsCString& cachedCharset) + : mChild(child) + , mResponseHead(responseHead) + , mUseResponseHead(useResponseHead) + , mIsFromCache(isFromCache) + , mCacheEntryAvailable(cacheEntryAvailable) + , mCacheExpirationTime(cacheExpirationTime) + , mCachedCharset(cachedCharset) + {} + + void Run() + { + mChild->OnStartRequest(mResponseHead, mUseResponseHead, mIsFromCache, + mCacheEntryAvailable, mCacheExpirationTime, + mCachedCharset); + } + private: + HttpChannelChild* mChild; + nsHttpResponseHead mResponseHead; + PRBool mUseResponseHead; + PRBool mIsFromCache; + PRBool mCacheEntryAvailable; + PRUint32 mCacheExpirationTime; + nsCString mCachedCharset; +}; + bool HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead, const PRBool& useResponseHead, const PRBool& isFromCache, const PRBool& cacheEntryAvailable, const PRUint32& cacheExpirationTime, const nsCString& cachedCharset) { + if (ShouldEnqueue()) { + EnqueueEvent(new StartRequestEvent(this, responseHead, useResponseHead, + isFromCache, cacheEntryAvailable, + cacheExpirationTime, cachedCharset)); + } else { + OnStartRequest(responseHead, useResponseHead, isFromCache, + cacheEntryAvailable, cacheExpirationTime, cachedCharset); + } + return true; +} + +void +HttpChannelChild::OnStartRequest(const nsHttpResponseHead& responseHead, + const PRBool& useResponseHead, + const PRBool& isFromCache, + const PRBool& cacheEntryAvailable, + const PRUint32& cacheExpirationTime, + const nsCString& cachedCharset) +{ LOG(("HttpChannelChild::RecvOnStartRequest [this=%x]\n", this)); mState = HCC_ONSTART; if (useResponseHead) mResponseHead = new nsHttpResponseHead(responseHead); else mResponseHead = nsnull; mIsFromCache = isFromCache; mCacheEntryAvailable = cacheEntryAvailable; mCacheExpirationTime = cacheExpirationTime; mCachedCharset = cachedCharset; + AutoEventEnqueuer ensureSerialDispatch(this); + nsresult rv = mListener->OnStartRequest(this, mListenerContext); - if (NS_FAILED(rv)) { + if (NS_SUCCEEDED(rv)) { + if (mResponseHead) + SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie)); + } else { // TODO: Cancel request: (bug 536317) // - Send Cancel msg to parent // - drop any in flight OnDataAvail msgs we receive // - make sure we do call OnStopRequest eventually - return true; } - - if (mResponseHead) - SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie)); - - bool ret = true; - nsCOMPtr<nsIHttpChannel> kungFuDeathGrip(this); - for (PRUint32 i = 0; i < mBufferedCallbacks.Length(); i++) { - ret = mBufferedCallbacks[i]->Run(); - if (!ret) - break; - } - mBufferedCallbacks.Clear(); - mShouldBuffer = false; - return ret; } -class DataAvailableEvent : public Callback +class DataAvailableEvent : public ChildChannelEvent { public: DataAvailableEvent(HttpChannelChild* child, const nsCString& data, const PRUint32& offset, const PRUint32& count) : mChild(child) , mData(data) , mOffset(offset) , mCount(count) {} - bool Run() - { - return mChild->OnDataAvailable(mData, mOffset, mCount); - } - + void Run() { mChild->OnDataAvailable(mData, mOffset, mCount); } private: HttpChannelChild* mChild; nsCString mData; PRUint32 mOffset; PRUint32 mCount; }; bool HttpChannelChild::RecvOnDataAvailable(const nsCString& data, const PRUint32& offset, const PRUint32& count) { - DataAvailableEvent* event = new DataAvailableEvent(this, data, offset, count); - return BufferOrDispatch(event); + if (ShouldEnqueue()) { + EnqueueEvent(new DataAvailableEvent(this, data, offset, count)); + } else { + OnDataAvailable(data, offset, count); + } + return true; } -bool +void HttpChannelChild::OnDataAvailable(const nsCString& data, const PRUint32& offset, const PRUint32& count) { LOG(("HttpChannelChild::RecvOnDataAvailable [this=%x]\n", this)); mState = HCC_ONDATA; @@ -213,188 +300,182 @@ HttpChannelChild::OnDataAvailable(const // rest. nsCOMPtr<nsIInputStream> stringStream; nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(), count, NS_ASSIGNMENT_DEPEND); if (NS_FAILED(rv)) { // TODO: what to do here? Cancel request? Very unlikely to fail. - return false; + return; } + + AutoEventEnqueuer ensureSerialDispatch(this); + rv = mListener->OnDataAvailable(this, mListenerContext, stringStream, offset, count); stringStream->Close(); if (NS_FAILED(rv)) { // TODO: Cancel request: see OnStartRequest. Bug 536317 } - return true; } -class StopRequestEvent : public Callback +class StopRequestEvent : public ChildChannelEvent { public: StopRequestEvent(HttpChannelChild* child, const nsresult& statusCode) : mChild(child) , mStatusCode(statusCode) {} - bool Run() - { - return mChild->OnStopRequest(mStatusCode); - } - + void Run() { mChild->OnStopRequest(mStatusCode); } private: HttpChannelChild* mChild; nsresult mStatusCode; }; bool HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode) { - StopRequestEvent* event = new StopRequestEvent(this, statusCode); - return BufferOrDispatch(event); + if (ShouldEnqueue()) { + EnqueueEvent(new StopRequestEvent(this, statusCode)); + } else { + OnStopRequest(statusCode); + } + return true; } -bool +void HttpChannelChild::OnStopRequest(const nsresult& statusCode) { LOG(("HttpChannelChild::RecvOnStopRequest [this=%x status=%u]\n", this, statusCode)); mState = HCC_ONSTOP; mIsPending = PR_FALSE; mStatus = statusCode; - mListener->OnStopRequest(this, mListenerContext, statusCode); - mListener = 0; - mListenerContext = 0; - mCacheEntryAvailable = PR_FALSE; - if (mLoadGroup) - mLoadGroup->RemoveRequest(this, nsnull, statusCode); + { // We must flush the queue before we Send__delete__, + // so make sure this goes out of scope before then. + AutoEventEnqueuer ensureSerialDispatch(this); + + mListener->OnStopRequest(this, mListenerContext, statusCode); + mListener = 0; + mListenerContext = 0; + mCacheEntryAvailable = PR_FALSE; + + if (mLoadGroup) + mLoadGroup->RemoveRequest(this, nsnull, statusCode); + } // This calls NeckoChild::DeallocPHttpChannel(), which deletes |this| if IPDL // holds the last reference. Don't rely on |this| existing after here. PHttpChannelChild::Send__delete__(this); - return true; } -class ProgressEvent : public Callback +class ProgressEvent : public ChildChannelEvent { public: ProgressEvent(HttpChannelChild* child, const PRUint64& progress, const PRUint64& progressMax) : mChild(child) , mProgress(progress) , mProgressMax(progressMax) {} - bool Run() - { - return mChild->OnProgress(mProgress, mProgressMax); - } - + void Run() { mChild->OnProgress(mProgress, mProgressMax); } private: HttpChannelChild* mChild; PRUint64 mProgress, mProgressMax; }; bool HttpChannelChild::RecvOnProgress(const PRUint64& progress, const PRUint64& progressMax) { - ProgressEvent* event = new ProgressEvent(this, progress, progressMax); - return BufferOrDispatch(event); + if (ShouldEnqueue()) { + EnqueueEvent(new ProgressEvent(this, progress, progressMax)); + } else { + OnProgress(progress, progressMax); + } + return true; } -bool +void HttpChannelChild::OnProgress(const PRUint64& progress, const PRUint64& progressMax) { LOG(("HttpChannelChild::RecvOnProgress [this=%p progress=%llu/%llu]\n", this, progress, progressMax)); // cache the progress sink so we don't have to query for it each time. if (!mProgressSink) GetCallback(mProgressSink); + AutoEventEnqueuer ensureSerialDispatch(this); + // block socket status event after Cancel or OnStopRequest has been called. if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending && !(mLoadFlags & LOAD_BACKGROUND)) { if (progress > 0) { NS_ASSERTION(progress <= progressMax, "unexpected progress values"); mProgressSink->OnProgress(this, nsnull, progress, progressMax); } } - - return true; } -class StatusEvent : public Callback +class StatusEvent : public ChildChannelEvent { public: StatusEvent(HttpChannelChild* child, const nsresult& status, const nsString& statusArg) : mChild(child) , mStatus(status) , mStatusArg(statusArg) {} - bool Run() - { - return mChild->OnStatus(mStatus, mStatusArg); - } - + void Run() { mChild->OnStatus(mStatus, mStatusArg); } private: HttpChannelChild* mChild; nsresult mStatus; nsString mStatusArg; }; bool HttpChannelChild::RecvOnStatus(const nsresult& status, const nsString& statusArg) { - StatusEvent* event = new StatusEvent(this, status, statusArg); - return BufferOrDispatch(event); + if (ShouldEnqueue()) { + EnqueueEvent(new StatusEvent(this, status, statusArg)); + } else { + OnStatus(status, statusArg); + } + return true; } -bool +void HttpChannelChild::OnStatus(const nsresult& status, const nsString& statusArg) { LOG(("HttpChannelChild::RecvOnStatus [this=%p status=%x]\n", this, status)); // cache the progress sink so we don't have to query for it each time. if (!mProgressSink) GetCallback(mProgressSink); + AutoEventEnqueuer ensureSerialDispatch(this); + // block socket status event after Cancel or OnStopRequest has been called. if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending && !(mLoadFlags & LOAD_BACKGROUND)) { mProgressSink->OnStatus(this, nsnull, status, statusArg.get()); } - - return true; -} - -bool -HttpChannelChild::BufferOrDispatch(Callback* callback) -{ - if (mShouldBuffer) { - mBufferedCallbacks.AppendElement(callback); - return true; - } - - bool result = callback->Run(); - delete callback; - return result; } //----------------------------------------------------------------------------- // HttpChannelChild::nsIRequest //----------------------------------------------------------------------------- NS_IMETHODIMP HttpChannelChild::Cancel(nsresult status)
--- a/netwerk/protocol/http/HttpChannelChild.h +++ b/netwerk/protocol/http/HttpChannelChild.h @@ -53,24 +53,22 @@ #include "nsICacheInfoChannel.h" #include "nsIApplicationCache.h" #include "nsIApplicationCacheChannel.h" #include "nsIEncodedChannel.h" #include "nsIUploadChannel2.h" #include "nsIResumableChannel.h" #include "nsIProxiedChannel.h" #include "nsITraceableChannel.h" -#include "mozilla/Mutex.h" - -class nsIRunnable; -class Callback; namespace mozilla { namespace net { +class ChildChannelEvent; + // TODO: replace with IPDL states: bug 536319 enum HttpChannelChildState { HCC_NEW, HCC_OPENED, HCC_ONSTART, HCC_ONDATA, HCC_ONSTOP }; @@ -143,35 +141,76 @@ private: PRPackedBool mCacheEntryAvailable; PRUint32 mCacheExpirationTime; nsCString mCachedCharset; // FIXME: replace with IPDL states (bug 536319) enum HttpChannelChildState mState; bool mIPCOpen; - // Workaround for Necko re-entrancy dangers. We buffer all messages - // received until OnStartRequest completes. - nsTArray<nsAutoPtr<Callback> > mBufferedCallbacks; - bool mShouldBuffer; + // Workaround for Necko re-entrancy dangers. We buffer IPDL messages in a + // queue if still dispatching previous one(s) to listeners/observers. + // Otherwise synchronous XMLHttpRequests and/or other code that spins the + // event loop (ex: IPDL rpc) could cause listener->OnDataAvailable (for + // instance) to be called before mListener->OnStartRequest has completed. + void BeginEventQueueing(); + void FlushEventQueue(); + void EnqueueEvent(ChildChannelEvent* callback); + bool ShouldEnqueue(); - bool BufferOrDispatch(Callback* callback); + nsTArray<nsAutoPtr<ChildChannelEvent> > mEventQueue; + enum { + PHASE_UNQUEUED, + PHASE_QUEUEING, + PHASE_FLUSHING + } mQueuePhase; - // This class does not actually implement the stream listener interface. - // These functions actually perform the actions associated with the - // corresponding IPDL receivers above. - bool OnDataAvailable(const nsCString& data, + void OnStartRequest(const nsHttpResponseHead& responseHead, + const PRBool& useResponseHead, + const PRBool& isFromCache, + const PRBool& cacheEntryAvailable, + const PRUint32& cacheExpirationTime, + const nsCString& cachedCharset); + void OnDataAvailable(const nsCString& data, const PRUint32& offset, const PRUint32& count); - bool OnStopRequest(const nsresult& statusCode); - bool OnProgress(const PRUint64& progress, const PRUint64& progressMax); - bool OnStatus(const nsresult& status, const nsString& statusArg); + void OnStopRequest(const nsresult& statusCode); + void OnProgress(const PRUint64& progress, const PRUint64& progressMax); + void OnStatus(const nsresult& status, const nsString& statusArg); + friend class AutoEventEnqueuer; + friend class StartRequestEvent; friend class StopRequestEvent; friend class DataAvailableEvent; friend class ProgressEvent; friend class StatusEvent; }; +//----------------------------------------------------------------------------- +// inline functions +//----------------------------------------------------------------------------- + +inline void +HttpChannelChild::BeginEventQueueing() +{ + if (mQueuePhase == PHASE_FLUSHING) + return; + // Store incoming IPDL messages for later. + mQueuePhase = PHASE_QUEUEING; +} + +inline bool +HttpChannelChild::ShouldEnqueue() +{ + return mQueuePhase != PHASE_UNQUEUED; +} + +inline void +HttpChannelChild::EnqueueEvent(ChildChannelEvent* callback) +{ + mEventQueue.AppendElement(callback); +} + + } // namespace net } // namespace mozilla #endif // mozilla_net_HttpChannelChild_h
--- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -3244,16 +3244,19 @@ nsHttpChannel::AsyncOpen(nsIStreamListen LOG(("nsHttpChannel::AsyncOpen [this=%p]\n", this)); NS_ENSURE_ARG_POINTER(listener); NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED); nsresult rv; + if (mCanceled) + return mStatus; + rv = NS_CheckPortSafety(mURI); if (NS_FAILED(rv)) return rv; if (!(mConnectionInfo && mConnectionInfo->UsingHttpProxy())) { // Start a DNS lookup very early in case the real open is queued the DNS can // happen in parallel. Do not do so in the presence of an HTTP proxy as // all lookups other than for the proxy itself are done by the proxy.
--- a/netwerk/protocol/res/nsResProtocolHandler.cpp +++ b/netwerk/protocol/res/nsResProtocolHandler.cpp @@ -90,35 +90,30 @@ nsresult nsResURL::EnsureFile() { nsresult rv; NS_ENSURE_TRUE(gResHandler, NS_ERROR_NOT_AVAILABLE); nsCAutoString spec; rv = gResHandler->ResolveURI(this, spec); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) + return rv; -#if defined(MOZ_CHROME_FILE_FORMAT_JAR) || defined(MOZ_OMNIJAR) - nsCAutoString host; - rv = GetHost(host); + nsCAutoString scheme; + rv = net_ExtractURLScheme(spec, nsnull, nsnull, &scheme); if (NS_FAILED(rv)) return rv; - // Deal with the fact resource://gre-resouces/ urls do not resolve to files - if (host.Equals(kGRE_RESOURCES)) + + // Bug 585869: + // In most cases, the scheme is jar if it's not file. + // Regardless, net_GetFileFromURLSpec should be avoided + // when the scheme isn't file. + if (!scheme.Equals(NS_LITERAL_CSTRING("file"))) return NS_ERROR_NO_INTERFACE; -#endif -#ifdef MOZ_OMNIJAR - if (mozilla::OmnijarPath()) { - if (host.Equals(kGRE)) - return NS_ERROR_NO_INTERFACE; - if (host.IsEmpty()) - return NS_ERROR_NO_INTERFACE; - } -#endif rv = net_GetFileFromURLSpec(spec, getter_AddRefs(mFile)); #ifdef DEBUG_bsmedberg if (NS_SUCCEEDED(rv)) { PRBool exists = PR_TRUE; mFile->Exists(&exists); if (!exists) { printf("resource %s doesn't exist!\n", spec.get());
--- a/netwerk/test/unit/test_progress.js +++ b/netwerk/test/unit/test_progress.js @@ -5,48 +5,103 @@ var httpserver = new nsHttpServer(); var testpath = "/simple"; var httpbody = "0123456789"; var last = 0, max = 0; const STATUS_RECEIVING_FROM = 0x804b0006; const LOOPS = 50000; +const TYPE_ONSTATUS = 1; +const TYPE_ONPROGRESS = 2; +const TYPE_ONSTARTREQUEST = 3; +const TYPE_ONDATAAVAILABLE = 4; +const TYPE_ONSTOPREQUEST = 5; + var progressCallback = { + _listener: null, + _got_onstartrequest: false, + _got_onstatus_after_onstartrequest: false, + _last_callback_handled: null, + QueryInterface: function (iid) { - if (iid.equals(Ci.nsISupports) || iid.equals(Ci.nsIProgressEventSink)) + if (iid.equals(Ci.nsISupports) || + iid.equals(Ci.nsIProgressEventSink) || + iid.equals(Ci.nsIStreamListener) || + iid.equals(Ci.nsIRequestObserver)) return this; throw Cr.NS_ERROR_NO_INTERFACE; }, getInterface: function (iid) { - if (iid.equals(Ci.nsIProgressEventSink)) + if (iid.equals(Ci.nsIProgressEventSink) || + iid.equals(Ci.nsIStreamListener) || + iid.equals(Ci.nsIRequestObserver)) return this; throw Cr.NS_ERROR_NO_INTERFACE; }, + onStartRequest: function(request, context) { + do_check_eq(this._last_callback_handled, TYPE_ONSTATUS); + this._got_onstartrequest = true; + this._last_callback_handled = TYPE_ONSTARTREQUEST; + + this._listener = new ChannelListener(checkRequest, request); + this._listener.onStartRequest(request, context); + }, + + onDataAvailable: function(request, context, data, offset, count) { + do_check_eq(this._last_callback_handled, TYPE_ONPROGRESS); + this._last_callback_handled = TYPE_ONDATAAVAILABLE; + + this._listener.onDataAvailable(request, context, data, offset, count); + }, + + onStopRequest: function(request, context, status) { + do_check_eq(this._last_callback_handled, TYPE_ONDATAAVAILABLE); + do_check_true(this._got_onstatus_after_onstartrequest); + this._last_callback_handled = TYPE_ONSTOPREQUEST; + + this._listener.onStopRequest(request, context, status); + delete this._listener; + }, + onProgress: function (request, context, progress, progressMax) { + do_check_eq(this._last_callback_handled, TYPE_ONSTATUS); + this._last_callback_handled = TYPE_ONPROGRESS; + do_check_eq(mStatus, STATUS_RECEIVING_FROM); last = progress; max = progressMax; }, onStatus: function (request, context, status, statusArg) { + if (!this._got_onstartrequest) { + // Ensure that all messages before onStartRequest are onStatus + if (this._last_callback_handled) + do_check_eq(this._last_callback_handled, TYPE_ONSTATUS); + } else if (this._last_callback_handled == TYPE_ONSTARTREQUEST) { + this._got_onstatus_after_onstartrequest = true; + } else { + do_check_eq(this._last_callback_handled, TYPE_ONDATAAVAILABLE); + } + this._last_callback_handled = TYPE_ONSTATUS; + do_check_eq(statusArg, "localhost"); mStatus = status; }, mStatus: 0, }; function run_test() { httpserver.registerPathHandler(testpath, serverHandler); httpserver.start(4444); var channel = setupChannel(testpath); - channel.asyncOpen(new ChannelListener(checkRequest, channel), null); + channel.asyncOpen(progressCallback, null); do_test_pending(); } function setupChannel(path) { var ios = Cc["@mozilla.org/network/io-service;1"]. getService(Ci.nsIIOService); var chan = ios.newChannel("http://localhost:4444" + path, "", null); chan.QueryInterface(Ci.nsIHttpChannel);
--- a/netwerk/test/unit/test_xmlhttprequest.js +++ b/netwerk/test/unit/test_xmlhttprequest.js @@ -1,36 +1,53 @@ do_load_httpd_js(); var httpserver = new nsHttpServer(); var testpath = "/simple"; var httpbody = "<?xml version='1.0' ?><root>0123456789</root>"; +function createXHR(async) +{ + var xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] + .createInstance(Ci.nsIXMLHttpRequest); + xhr.open("GET", "http://localhost:4444" + testpath, async); + return xhr; +} + +function checkResults(xhr) +{ + if (xhr.readyState != 4) + return false; + + do_check_eq(xhr.status, 200); + do_check_eq(xhr.responseText, httpbody); + + var root_node = xhr.responseXML.getElementsByTagName('root').item(0); + do_check_eq(root_node.firstChild.data, "0123456789"); + return true; +} + function run_test() { httpserver.registerPathHandler(testpath, serverHandler); httpserver.start(4444); - var xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] - .createInstance(Ci.nsIXMLHttpRequest); - xhr.open("GET", "http://localhost:4444" + testpath, true); - xhr.onreadystatechange = function(event) { - if (xhr.readyState == 4) { - do_check_eq(xhr.status, 200); - do_check_eq(xhr.responseText, httpbody); + // Test sync XHR sending + var sync = createXHR(false); + sync.send(null); + checkResults(sync); - var root_node = xhr.responseXML.getElementsByTagName('root').item(0); - do_check_eq(root_node.firstChild.data, "0123456789"); - + // Test async XHR sending + let async = createXHR(true); + async.onreadystatechange = function(event) { + if (checkResults(async)) httpserver.stop(do_test_finished); - } - } - xhr.send(null); - + }; + async.send(null); do_test_pending(); } function serverHandler(metadata, response) { response.setHeader("Content-Type", "text/xml", false); response.bodyOutputStream.write(httpbody, httpbody.length); }
--- a/netwerk/test/unit_ipc/test_xmlhttprequest_wrap.js +++ b/netwerk/test/unit_ipc/test_xmlhttprequest_wrap.js @@ -1,4 +1,3 @@ function run_test() { - _dump('FIXME/bug 564351: temporarily disabled for perma-crash on e10s tinderbox'); - //run_test_in_child("../unit/test_xmlhttprequest.js"); + run_test_in_child("../unit/test_xmlhttprequest.js"); }
--- a/toolkit/components/places/public/nsIPlacesImportExportService.idl +++ b/toolkit/components/places/public/nsIPlacesImportExportService.idl @@ -34,23 +34,24 @@ * 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 "nsISupports.idl" interface nsILocalFile; +interface nsIURI; /** * The PlacesImportExport interface provides methods for importing * and exporting Places data. */ -[scriptable, uuid(21c00314-fa63-11db-8314-0800200c9a66)] +[scriptable, uuid(47a4a09e-c708-4e68-b2f2-664d982ce026)] interface nsIPlacesImportExportService: nsISupports { /** * Loads the given bookmarks.html file and replaces it with the current * bookmarks hierarchy (if aIsInitialImport is true) or appends it * (if aIsInitialImport is false). * * Three nsIObserverService notifications are fired as a result of the @@ -60,16 +61,21 @@ interface nsIPlacesImportExportService: * fired right after a failure occurs when importing the bookmarks. * Observers will be passed through their data parameters either "html" * if aIsInitialImport is false or "html-initial" if aIsInitialImport is * true. The observer subject will be null. */ void importHTMLFromFile(in nsILocalFile aFile, in boolean aIsInitialImport); /** + * Same thing as importHTMLFromFile, but takes a URI instead + */ + void importHTMLFromURI(in nsIURI aURI, in boolean aIsInitialImport); + + /** * Loads the given bookmarks.html file and puts it in the given folder * * Three nsIObserverService notifications are fired as a result of the * import. "bookmarks-restore-begin" is fired just before the import is * started. "bookmarks-restore-success" is fired right after the * bookmarks are successfully imported. "bookmarks-restore-failed" is * fired right after a failure occurs when importing the bookmarks. * Observers will be passed through their data parameters either "html"
--- a/toolkit/components/places/src/nsPlacesImportExportService.cpp +++ b/toolkit/components/places/src/nsPlacesImportExportService.cpp @@ -2177,16 +2177,43 @@ nsPlacesImportExportService::ImportHTMLF aIsInitialImport); } return rv; } NS_IMETHODIMP +nsPlacesImportExportService::ImportHTMLFromURI(nsIURI* aURI, + PRBool aIsInitialImport) +{ + NotifyImportObservers(RESTORE_BEGIN_NSIOBSERVER_TOPIC, -1, aIsInitialImport); + + // this version is exposed on the interface and disallows changing of roots + nsresult rv = ImportHTMLFromURIInternal(aURI, + PR_FALSE, + 0, + aIsInitialImport); + + if (NS_FAILED(rv)) { + NotifyImportObservers(RESTORE_FAILED_NSIOBSERVER_TOPIC, + -1, + aIsInitialImport); + } + else { + NotifyImportObservers(RESTORE_SUCCESS_NSIOBSERVER_TOPIC, + -1, + aIsInitialImport); + } + + return rv; +} + + +NS_IMETHODIMP nsPlacesImportExportService::ImportHTMLFromFileToFolder(nsILocalFile* aFile, PRInt64 aFolderId, PRBool aIsInitialImport) { NotifyImportObservers(RESTORE_BEGIN_NSIOBSERVER_TOPIC, aFolderId, aIsInitialImport); @@ -2212,18 +2239,17 @@ nsPlacesImportExportService::ImportHTMLF nsresult nsPlacesImportExportService::ImportHTMLFromFileInternal(nsILocalFile* aFile, PRBool aAllowRootChanges, PRInt64 aFolder, PRBool aIsImportDefaults) { - nsresult rv = EnsureServiceState(); - NS_ENSURE_SUCCESS(rv, rv); + nsresult rv; nsCOMPtr<nsIFile> file = do_QueryInterface(aFile); NS_ENSURE_STATE(file); #ifdef DEBUG_IMPORT nsAutoString path; file->GetPath(path); printf("\nImporting %s\n", NS_ConvertUTF16toUTF8(path).get()); @@ -2232,39 +2258,54 @@ nsPlacesImportExportService::ImportHTMLF // Confirm file to be imported exists. PRBool exists; rv = file->Exists(&exists); NS_ENSURE_SUCCESS(rv, rv); if (!exists) { return NS_ERROR_INVALID_ARG; } + nsCOMPtr<nsIIOService> ioservice = do_GetIOService(&rv); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsIURI> fileURI; + rv = ioservice->NewFileURI(file, getter_AddRefs(fileURI)); + NS_ENSURE_SUCCESS(rv, rv); + + return ImportHTMLFromURIInternal(fileURI, aAllowRootChanges, aFolder, aIsImportDefaults); +} + +nsresult +nsPlacesImportExportService::ImportHTMLFromURIInternal(nsIURI* aURI, + PRBool aAllowRootChanges, + PRInt64 aFolder, + PRBool aIsImportDefaults) +{ + nsresult rv = EnsureServiceState(); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID); NS_ENSURE_TRUE(parser, NS_ERROR_OUT_OF_MEMORY); nsCOMPtr<BookmarkContentSink> sink = new BookmarkContentSink(); NS_ENSURE_TRUE(sink, NS_ERROR_OUT_OF_MEMORY); rv = sink->Init(aAllowRootChanges, aFolder, aIsImportDefaults); NS_ENSURE_SUCCESS(rv, rv); parser->SetContentSink(sink); // Set the content type on the channel, otherwise the default "unknown" type // will confuse the parser. nsCOMPtr<nsIIOService> ioservice = do_GetIOService(&rv); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr<nsIURI> fileURI; - rv = ioservice->NewFileURI(file, getter_AddRefs(fileURI)); - NS_ENSURE_SUCCESS(rv, rv); - rv = ioservice->NewChannelFromURI(fileURI, getter_AddRefs(mImportChannel)); + rv = ioservice->NewChannelFromURI(aURI, getter_AddRefs(mImportChannel)); NS_ENSURE_SUCCESS(rv, rv); rv = mImportChannel->SetContentType(NS_LITERAL_CSTRING("text/html")); NS_ENSURE_SUCCESS(rv, rv); // Init parser. - rv = parser->Parse(fileURI, nsnull); + rv = parser->Parse(aURI, nsnull); NS_ENSURE_SUCCESS(rv, rv); // Run the import in batch mode, so it will be executed in a transaction // and will be faster. mIsImportDefaults = aIsImportDefaults; mBookmarksService->RunInBatchMode(this, parser); mImportChannel = nsnull;
--- a/toolkit/components/places/src/nsPlacesImportExportService.h +++ b/toolkit/components/places/src/nsPlacesImportExportService.h @@ -45,16 +45,18 @@ class nsPlacesImportExportService : publ nsCOMPtr<nsILivemarkService> mLivemarkService; nsCOMPtr<nsIMicrosummaryService> mMicrosummaryService; nsCOMPtr<nsIChannel> mImportChannel; PRBool mIsImportDefaults; nsresult ImportHTMLFromFileInternal(nsILocalFile* aFile, PRBool aAllowRootChanges, PRInt64 aFolder, PRBool aIsImportDefaults); + nsresult ImportHTMLFromURIInternal(nsIURI* aURI, PRBool aAllowRootChanges, + PRInt64 aFolder, PRBool aIsImportDefaults); nsresult WriteContainer(nsINavHistoryResultNode* aFolder, const nsACString& aIndent, nsIOutputStream* aOutput); nsresult WriteContainerHeader(nsINavHistoryResultNode* aFolder, const nsACString& aIndent, nsIOutputStream* aOutput); nsresult WriteTitle(nsINavHistoryResultNode* aItem, nsIOutputStream* aOutput); nsresult WriteItem(nsINavHistoryResultNode* aItem, const nsACString& aIndent, nsIOutputStream* aOutput); nsresult WriteLivemark(nsINavHistoryResultNode* aFolder, const nsACString& aIndent, nsIOutputStream* aOutput); nsresult WriteContainerContents(nsINavHistoryResultNode* aFolder, const nsACString& aIndent, nsIOutputStream* aOutput); nsresult WriteSeparator(nsINavHistoryResultNode* aItem, const nsACString& aIndent, nsIOutputStream* aOutput); nsresult WriteDescription(PRInt64 aId, PRInt32 aType, nsIOutputStream* aOutput);
--- a/toolkit/xre/MozMeegoAppService.h +++ b/toolkit/xre/MozMeegoAppService.h @@ -1,30 +1,42 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1 + * 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 mozilla.org code. + * The Original Code is Nokia. * - * The Initial Developer of the Original Code is - * Nokia Corporation. + * The Initial Developer of the Original Code is Nokia Corporation. * Portions created by the Initial Developer are Copyright (C) 2010 * the Initial Developer. All Rights Reserved. * - * Contributor(s): + * Contributor(s): + * + * 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 ***** */ #ifndef MOZMEEGOAPPSERVICE_H #define MOZMEEGOAPPSERVICE_H #include <MApplicationService>
--- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1109,20 +1109,16 @@ ScopedXPCOMStartup::~ScopedXPCOMStartup( appStartup->DestroyHiddenWindow(); gDirServiceProvider->DoShutdown(); WriteConsoleLog(); NS_ShutdownXPCOM(mServiceManager); mServiceManager = nsnull; - -#ifdef MOZ_OMNIJAR - mozilla::SetOmnijar(nsnull); -#endif } } // {95d89e3e-a169-41a3-8e56-719978e15b12} #define APPINFO_CID \ { 0x95d89e3e, 0xa169, 0x41a3, { 0x8e, 0x56, 0x71, 0x99, 0x78, 0xe1, 0x5b, 0x12 } } // {0C4A446C-EE82-41f2-8D04-D366D2C7A7D4} @@ -1170,26 +1166,16 @@ static const mozilla::Module kXREModule NSMODULE_DEFN(Apprunner) = &kXREModule; nsresult ScopedXPCOMStartup::Initialize() { NS_ASSERTION(gDirServiceProvider, "Should not get here!"); nsresult rv; -#ifdef MOZ_OMNIJAR - nsCOMPtr<nsILocalFile> lf; - char *omnijarPath = getenv("OMNIJAR_PATH"); - if (omnijarPath) - rv = NS_NewNativeLocalFile(nsDependentCString(omnijarPath), PR_TRUE, getter_AddRefs(lf)); - else - rv = XRE_GetBinaryPath(gArgv[0], getter_AddRefs(lf)); - if (NS_SUCCEEDED(rv)) - mozilla::SetOmnijar(lf); -#endif #ifndef MOZ_ENABLE_LIBXUL #ifndef _BUILD_STATIC_BIN XRE_AddStaticComponent(&kXREModule); #else for (const mozilla::Module *const *staticModules = kPStaticModules; *staticModules; ++staticModules) XRE_AddStaticComponent(*staticModules); @@ -3772,26 +3758,16 @@ XRE_InitCommandLine(int aArgc, char* aAr { nsresult rv = NS_OK; #if defined(MOZ_IPC) #if defined(OS_WIN) CommandLine::Init(aArgc, aArgv); #else -#ifdef MOZ_OMNIJAR - nsCOMPtr<nsILocalFile> lf; - char *omnijarPath = getenv("OMNIJAR_PATH"); - if (omnijarPath) - rv = NS_NewNativeLocalFile(nsDependentCString(omnijarPath), PR_TRUE, getter_AddRefs(lf)); - else - rv = XRE_GetBinaryPath(gArgv[0], getter_AddRefs(lf)); - if (NS_SUCCEEDED(rv)) - mozilla::SetOmnijar(lf); -#endif // these leak on error, but that's OK: we'll just exit() char** canonArgs = new char*[aArgc]; // get the canonical version of the binary's path nsCOMPtr<nsILocalFile> binFile; rv = XRE_GetBinaryPath(aArgv[0], getter_AddRefs(binFile)); if (NS_FAILED(rv)) @@ -3813,16 +3789,35 @@ 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 #endif + +#ifdef MOZ_OMNIJAR + const char *omnijarPath = nsnull; + ArgResult ar = CheckArg("omnijar", PR_FALSE, &omnijarPath); + if (ar == ARG_BAD) { + PR_fprintf(PR_STDERR, "Error: argument -omnijar requires an omnijar path\n"); + return NS_ERROR_FAILURE; + } + + if (!omnijarPath) + return rv; + + 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/uriloader/exthandler/Makefile.in +++ b/uriloader/exthandler/Makefile.in @@ -170,16 +170,18 @@ EXTRA_COMPONENTS = \ nsHandlerService.manifest \ nsWebHandlerApp.js \ nsWebHandlerApp.manifest \ $(NULL) # we don't want the shared lib, but we want to force the creation of a static lib. FORCE_STATIC_LIB = 1 SRCS_IN_OBJDIR = 1 +include $(topsrcdir)/config/config.mk +include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/config/rules.mk ifneq (,$(filter qt gtk2, $(MOZ_WIDGET_TOOLKIT))) CXXFLAGS += $(TK_CFLAGS) $(MOZ_DBUS_GLIB_CFLAGS) endif # the use of multiple VPATH dirs is broken in cygwin make ifeq ($(OS_ARCH),WINNT WINCE)
--- a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp +++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp @@ -37,17 +37,17 @@ #include "nsMIMEInfoAndroid.h" #include "AndroidBridge.h" #include "nsAndroidHandlerApp.h" #include "nsArrayUtils.h" #include "nsISupportsUtils.h" #include "nsStringEnumerator.h" #include "nsNetUtil.h" -NS_IMPL_ISUPPORTS1(nsMIMEInfoAndroid, nsIMIMEInfo) +NS_IMPL_ISUPPORTS2(nsMIMEInfoAndroid, nsIMIMEInfo, nsIHandlerInfo) nsMIMEInfoAndroid::~nsMIMEInfoAndroid() { } NS_IMETHODIMP nsMIMEInfoAndroid::LaunchDefaultWithFile(nsIFile* aFile) { @@ -225,19 +225,17 @@ nsMIMEInfoAndroid::SetPreferredAction(ns { mPrefAction = aPrefAction; return NS_OK; } NS_IMETHODIMP nsMIMEInfoAndroid::GetAlwaysAskBeforeHandling(PRBool* aAlwaysAsk) { - // the chooser dialog currently causes a crash on Android, avoid this by returning false here - // but be sure to return mAlwaysAsk when that gets fixed (bug 584896) - *aAlwaysAsk = PR_FALSE; + *aAlwaysAsk = mAlwaysAsk; return NS_OK; } NS_IMETHODIMP nsMIMEInfoAndroid::SetAlwaysAskBeforeHandling(PRBool aAlwaysAsk) { mAlwaysAsk = aAlwaysAsk; return NS_OK;
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -37,16 +37,25 @@ * 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 ***** */ +#ifdef MOZ_LOGGING +#define FORCE_PR_LOG +#endif + +#ifdef MOZ_IPC +#include "mozilla/dom/ContentChild.h" +#include "nsXULAppAPI.h" +#endif + #include "nsExternalHelperAppService.h" #include "nsCExternalHandlerService.h" #include "nsIURI.h" #include "nsIURL.h" #include "nsIFile.h" #include "nsIFileURL.h" #include "nsIChannel.h" #include "nsIDirectoryService.h" @@ -856,16 +865,23 @@ static const char kExternalProtocolPrefP static const char kExternalProtocolDefaultPref[] = "network.protocol-handler.external-default"; NS_IMETHODIMP nsExternalHelperAppService::LoadURI(nsIURI *aURI, nsIInterfaceRequestor *aWindowContext) { NS_ENSURE_ARG_POINTER(aURI); +#ifdef MOZ_IPC + if (XRE_GetProcessType() == GeckoProcessType_Content) { + mozilla::dom::ContentChild::GetSingleton()->SendLoadURIExternal(aURI); + return NS_OK; + } +#endif + nsCAutoString spec; aURI->GetSpec(spec); if (spec.Find("%00") != -1) return NS_ERROR_MALFORMED_URI; spec.ReplaceSubstring("\"", "%22"); spec.ReplaceSubstring("`", "%60");
--- a/widget/src/qt/nsWindow.cpp +++ b/widget/src/qt/nsWindow.cpp @@ -2077,17 +2077,19 @@ nsWindow::createQWidget(MozQWidget *pare widget->setFocusPolicy(Qt::WheelFocus); } // create a QGraphicsView if this is a new toplevel window if (mIsTopLevel) { QGraphicsView* newView = nsnull; #ifdef MOZ_ENABLE_MEEGOTOUCH - newView = new MozMGraphicsView(widget); + if (XRE_GetProcessType() == GeckoProcessType_Default) { + newView = new MozMGraphicsView(widget); + } else #else newView = new MozQGraphicsView(widget); #endif if (!newView) { delete widget; return nsnull; }
--- a/xpcom/base/nsDebugImpl.cpp +++ b/xpcom/base/nsDebugImpl.cpp @@ -388,18 +388,20 @@ RealBreak() #endif #elif defined(XP_OS2) asm("int $3"); #elif defined(XP_BEOS) #elif defined(XP_MACOSX) raise(SIGTRAP); #elif defined(__GNUC__) && (defined(__i386__) || defined(__i386) || defined(__x86_64__)) asm("int $3"); +#elif defined(__arm__) + asm("BKPT #0"); #else - // don't know how to break on this platform +#warning don't know how to break on this platform #endif } // Abort() calls this function, don't call it! static void Break(const char *aMsg) { #if defined(_WIN32) @@ -488,18 +490,20 @@ Break(const char *aMsg) #elif defined(XP_MACOSX) /* Note that we put this Mac OS X test above the GNUC/x86 test because the * GNUC/x86 test is also true on Intel Mac OS X and we want the PPC/x86 * impls to be the same. */ RealBreak(); #elif defined(__GNUC__) && (defined(__i386__) || defined(__i386) || defined(__x86_64__)) RealBreak(); +#elif defined(__arm__) + RealBreak(); #else - // don't know how to break on this platform +#warning don't know how to break on this platform #endif } static const nsDebugImpl kImpl; nsresult nsDebugImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr) {
--- a/xpcom/build/Omnijar.cpp +++ b/xpcom/build/Omnijar.cpp @@ -40,49 +40,62 @@ #include "nsILocalFile.h" #include "nsXULAppAPI.h" #include "nsZipArchive.h" static nsILocalFile* sOmnijarPath = nsnull; static nsZipArchive* sOmnijarReader = nsnull; +static void +SetupReader() +{ + if (!sOmnijarPath) { + return; + } + + nsZipArchive* zipReader = new nsZipArchive(); + if (!zipReader) { + NS_IF_RELEASE(sOmnijarPath); + return; + } + + if (NS_FAILED(zipReader->OpenArchive(sOmnijarPath))) { + delete zipReader; + NS_IF_RELEASE(sOmnijarPath); + return; + } + + sOmnijarReader = zipReader; +} + nsILocalFile* mozilla::OmnijarPath() { + if (!sOmnijarReader) + SetupReader(); + return sOmnijarPath; } nsZipArchive* mozilla::OmnijarReader() { + if (!sOmnijarReader) + SetupReader(); + return sOmnijarReader; } void mozilla::SetOmnijar(nsILocalFile* aPath) { NS_IF_RELEASE(sOmnijarPath); if (sOmnijarReader) { sOmnijarReader->CloseArchive(); delete sOmnijarReader; sOmnijarReader = nsnull; } - if (!aPath) { - return; - } - - nsZipArchive* zipReader = new nsZipArchive(); - if (!zipReader) { - return; - } - - if (NS_FAILED(zipReader->OpenArchive(aPath))) { - delete zipReader; - return; - } - - sOmnijarReader = zipReader; sOmnijarPath = aPath; - NS_ADDREF(sOmnijarPath); + NS_IF_ADDREF(sOmnijarPath); }
--- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -137,16 +137,17 @@ extern nsresult nsStringInputStreamConst #endif #include "nsSystemInfo.h" #include "nsMemoryReporterManager.h" #include <locale.h> #include "mozilla/Services.h" #include "mozilla/FunctionTimer.h" +#include "mozilla/Omnijar.h" #include "nsChromeRegistry.h" #include "nsChromeProtocolHandler.h" #ifdef MOZ_IPC #include "base/at_exit.h" #include "base/command_line.h" #include "base/message_loop.h" @@ -414,16 +415,17 @@ NS_InitXPCOM2(nsIServiceManager* *result setlocale(LC_ALL, ""); #endif #if defined(XP_UNIX) || defined(XP_OS2) NS_TIME_FUNCTION_MARK("Next: startup native charset utils"); NS_StartupNativeCharsetUtils(); #endif + NS_TIME_FUNCTION_MARK("Next: startup local file"); NS_StartupLocalFile(); StartupSpecialSystemDirectory(); rv = nsDirectoryService::RealInit(); if (NS_FAILED(rv)) @@ -452,16 +454,36 @@ 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::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 + #ifdef MOZ_IPC if ((sCommandLineWasInitialized = !CommandLine::IsInitialized())) { NS_TIME_FUNCTION_MARK("Next: IPC command line init"); #ifdef OS_WIN CommandLine::Init(0, nsnull); #else nsCOMPtr<nsIFile> binaryFile; @@ -729,14 +751,18 @@ ShutdownXPCOM(nsIServiceManager* servMgr sCommandLineWasInitialized = false; } if (sExitManager) { delete sExitManager; sExitManager = nsnull; } #endif +#ifdef MOZ_OMNIJAR + mozilla::SetOmnijar(nsnull); +#endif + NS_LogTerm(); return NS_OK; } } // namespace mozilla
--- a/xpcom/components/nsComponentManager.cpp +++ b/xpcom/components/nsComponentManager.cpp @@ -521,16 +521,19 @@ GetExtension(nsILocalFile* file) CutExtension(extension); return extension; } #ifdef MOZ_OMNIJAR void nsComponentManagerImpl::RegisterOmnijar(const char* aPath, bool aChromeOnly) { + if (!mozilla::OmnijarPath()) + return; + nsCOMPtr<nsIInputStream> is = mManifestLoader->LoadEntry(aPath); PRUint32 flen; is->Available(&flen); nsAutoArrayPtr<char> whole(new char[flen + 1]); if (!whole) return;