diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 0d4df0e40bb5..95fd1aecdaa3 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 05135cfcbfd7..be940c19618e 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index a49bf08c8097..d143b68aa0fa 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 0d4df0e40bb5..95fd1aecdaa3 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index f5f01d10c2ad..151dc501e189 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "82537f452462222ac77bb22f19a6ceb89aeade95", + "revision": "1450b977cb8e074f2e9fe2a12049005204febf72", "repo_path": "/integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 039d52a11665..29bca210d916 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 9d0f10b29fef..c99ab4d393d8 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index b03df80d5e1b..63b4a1d4b2f3 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index b60f424a700a..8d90319d9371 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index 2f8aa7000a90..d501abc42f0a 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 0391f78f55f4..22f03aedba71 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index 1e7ec0fcbb82..9757f62b65a1 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -41,7 +41,6 @@ EXPORTS.mozilla += [ UNIFIED_SOURCES += [ 'AppProcessChecker.cpp', 'ColorPickerParent.cpp', - 'ContentChild.cpp', 'ContentParent.cpp', 'ContentProcess.cpp', 'CrashReporterParent.cpp', @@ -57,10 +56,12 @@ UNIFIED_SOURCES += [ ] # Blob.cpp cannot be compiled in unified mode because it triggers a fatal gcc warning. +# ContentChild.cpp cannot be compiled in unified mode because it forces NSPR logging. # CrashReporterChild.cpp cannot be compiled in unified mode because of name clashes # in OS X headers. SOURCES += [ 'Blob.cpp', + 'ContentChild.cpp', 'CrashReporterChild.cpp', ] diff --git a/uriloader/exthandler/ExternalHelperAppChild.cpp b/uriloader/exthandler/ExternalHelperAppChild.cpp index 4cafa692193a..f2d54135af0a 100644 --- a/uriloader/exthandler/ExternalHelperAppChild.cpp +++ b/uriloader/exthandler/ExternalHelperAppChild.cpp @@ -5,7 +5,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ExternalHelperAppChild.h" +#include "mozilla/net/ChannelDiverterChild.h" +#include "nsIDivertableChannel.h" #include "nsIInputStream.h" +#include "nsIFTPChannel.h" #include "nsIRequest.h" #include "nsIResumableChannel.h" #include "nsNetUtil.h" @@ -57,30 +60,56 @@ ExternalHelperAppChild::OnDataAvailable(nsIRequest *request, NS_IMETHODIMP ExternalHelperAppChild::OnStartRequest(nsIRequest *request, nsISupports *ctx) { + nsCOMPtr divertable = do_QueryInterface(request); + if (divertable) { + return DivertToParent(divertable, request); + } + nsresult rv = mHandler->OnStartRequest(request, ctx); NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED); nsCString entityID; nsCOMPtr resumable(do_QueryInterface(request)); - if (resumable) + if (resumable) { resumable->GetEntityID(entityID); + } SendOnStartRequest(entityID); return NS_OK; } - NS_IMETHODIMP ExternalHelperAppChild::OnStopRequest(nsIRequest *request, nsISupports *ctx, nsresult status) { - nsresult rv = mHandler->OnStopRequest(request, ctx, status); - SendOnStopRequest(status); + // mHandler can be null if we diverted the request to the parent + if (mHandler) { + nsresult rv = mHandler->OnStopRequest(request, ctx, status); + SendOnStopRequest(status); + NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED); + } - NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED); return NS_OK; } +nsresult +ExternalHelperAppChild::DivertToParent(nsIDivertableChannel *divertable, nsIRequest *request) +{ + mozilla::net::ChannelDiverterChild *diverter = nullptr; + nsresult rv = divertable->DivertToParent(&diverter); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + MOZ_ASSERT(diverter); + if (SendDivertToParentUsing(diverter)) { + mHandler->DidDivertRequest(request); + mHandler = nullptr; + return NS_OK; + } + + return NS_ERROR_FAILURE; +} bool ExternalHelperAppChild::RecvCancel(const nsresult& aStatus) diff --git a/uriloader/exthandler/ExternalHelperAppChild.h b/uriloader/exthandler/ExternalHelperAppChild.h index 6b58a8b7e3d5..a93cbbc38526 100644 --- a/uriloader/exthandler/ExternalHelperAppChild.h +++ b/uriloader/exthandler/ExternalHelperAppChild.h @@ -8,8 +8,11 @@ #define mozilla_dom_ExternalHelperAppChild_h #include "mozilla/dom/PExternalHelperAppChild.h" +#include "nsExternalHelperAppService.h" #include "nsIStreamListener.h" +class nsIDivertableChannel; + namespace mozilla { namespace dom { @@ -26,11 +29,13 @@ public: // Give the listener a real nsExternalAppHandler to complete processing on // the child. - void SetHandler(nsIStreamListener *handler) { mHandler = handler; } + void SetHandler(nsExternalAppHandler *handler) { mHandler = handler; } virtual bool RecvCancel(const nsresult& aStatus) MOZ_OVERRIDE; private: - nsCOMPtr mHandler; + nsresult DivertToParent(nsIDivertableChannel *divertable, nsIRequest *request); + + nsRefPtr mHandler; nsresult mStatus; }; diff --git a/uriloader/exthandler/ExternalHelperAppParent.cpp b/uriloader/exthandler/ExternalHelperAppParent.cpp index 7d89cbcd1e44..a61dc529d9e6 100644 --- a/uriloader/exthandler/ExternalHelperAppParent.cpp +++ b/uriloader/exthandler/ExternalHelperAppParent.cpp @@ -18,6 +18,7 @@ #include "mozilla/ipc/URIUtils.h" #include "nsNetUtil.h" #include "nsIDocument.h" +#include "mozilla/net/ChannelDiverterParent.h" #include "mozilla/unused.h" @@ -26,18 +27,21 @@ using namespace mozilla::ipc; namespace mozilla { namespace dom { -NS_IMPL_ISUPPORTS_INHERITED4(ExternalHelperAppParent, +NS_IMPL_ISUPPORTS_INHERITED5(ExternalHelperAppParent, nsHashPropertyBag, nsIRequest, nsIChannel, nsIMultiPartChannel, - nsIResumableChannel) + nsIResumableChannel, + nsIStreamListener) ExternalHelperAppParent::ExternalHelperAppParent( const OptionalURIParams& uri, const int64_t& aContentLength) : mURI(DeserializeURI(uri)) , mPending(false) + , mDiverted(false) + , mIPCClosed(false) , mLoadFlags(0) , mStatus(NS_OK) , mContentLength(aContentLength) @@ -86,9 +90,25 @@ ExternalHelperAppParent::Init(ContentParent *parent, aForceSave, getter_AddRefs(mListener)); } +void +ExternalHelperAppParent::ActorDestroy(ActorDestroyReason why) +{ + mIPCClosed = true; +} + +void +ExternalHelperAppParent::Delete() +{ + if (!mIPCClosed) { + unused << Send__delete__(this); + } +} + bool ExternalHelperAppParent::RecvOnStartRequest(const nsCString& entityID) { + MOZ_ASSERT(!mDiverted, "child forwarding callbacks after request was diverted"); + mEntityID = entityID; mPending = true; mStatus = mListener->OnStartRequest(this, nullptr); @@ -103,7 +123,9 @@ ExternalHelperAppParent::RecvOnDataAvailable(const nsCString& data, if (NS_FAILED(mStatus)) return true; - NS_ASSERTION(mPending, "must be pending!"); + MOZ_ASSERT(!mDiverted, "child forwarding callbacks after request was diverted"); + MOZ_ASSERT(mPending, "must be pending!"); + nsCOMPtr stringStream; DebugOnly rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(), count, NS_ASSIGNMENT_DEPEND); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create dependent string!"); @@ -115,13 +137,59 @@ ExternalHelperAppParent::RecvOnDataAvailable(const nsCString& data, bool ExternalHelperAppParent::RecvOnStopRequest(const nsresult& code) { + MOZ_ASSERT(!mDiverted, "child forwarding callbacks after request was diverted"); + mPending = false; mListener->OnStopRequest(this, nullptr, (NS_SUCCEEDED(code) && NS_FAILED(mStatus)) ? mStatus : code); - unused << Send__delete__(this); + Delete(); return true; } +bool +ExternalHelperAppParent::RecvDivertToParentUsing(PChannelDiverterParent* diverter) +{ + MOZ_ASSERT(diverter); + auto p = static_cast(diverter); + p->DivertTo(this); + mDiverted = true; + unused << p->Send__delete__(p); + return true; +} + +// +// nsIStreamListener +// + +NS_IMETHODIMP +ExternalHelperAppParent::OnDataAvailable(nsIRequest *request, + nsISupports *ctx, + nsIInputStream *input, + uint64_t offset, + uint32_t count) +{ + MOZ_ASSERT(mDiverted); + return mListener->OnDataAvailable(request, ctx, input, offset, count); +} + +NS_IMETHODIMP +ExternalHelperAppParent::OnStartRequest(nsIRequest *request, nsISupports *ctx) +{ + MOZ_ASSERT(mDiverted); + return mListener->OnStartRequest(request, ctx); +} + +NS_IMETHODIMP +ExternalHelperAppParent::OnStopRequest(nsIRequest *request, + nsISupports *ctx, + nsresult status) +{ + MOZ_ASSERT(mDiverted); + nsresult rv = mListener->OnStopRequest(request, ctx, status); + Delete(); + return rv; +} + ExternalHelperAppParent::~ExternalHelperAppParent() { } diff --git a/uriloader/exthandler/ExternalHelperAppParent.h b/uriloader/exthandler/ExternalHelperAppParent.h index b735d33c034f..a6f6af706124 100644 --- a/uriloader/exthandler/ExternalHelperAppParent.h +++ b/uriloader/exthandler/ExternalHelperAppParent.h @@ -8,6 +8,7 @@ #include "nsIChannel.h" #include "nsIMultiPartChannel.h" #include "nsIResumableChannel.h" +#include "nsIStreamListener.h" #include "nsHashPropertyBag.h" namespace IPC { @@ -20,6 +21,10 @@ namespace ipc { class OptionalURIParams; } // namespace ipc +namespace net { +class PChannelDiverterParent; +} // namespace net + namespace dom { class ContentParent; @@ -30,6 +35,7 @@ class ExternalHelperAppParent : public PExternalHelperAppParent , public nsIChannel , public nsIMultiPartChannel , public nsIResumableChannel + , public nsIStreamListener { typedef mozilla::ipc::OptionalURIParams OptionalURIParams; @@ -39,6 +45,8 @@ public: NS_DECL_NSICHANNEL NS_DECL_NSIMULTIPARTCHANNEL NS_DECL_NSIRESUMABLECHANNEL + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSIREQUESTOBSERVER bool RecvOnStartRequest(const nsCString& entityID) MOZ_OVERRIDE; bool RecvOnDataAvailable(const nsCString& data, @@ -46,6 +54,8 @@ public: const uint32_t& count) MOZ_OVERRIDE; bool RecvOnStopRequest(const nsresult& code) MOZ_OVERRIDE; + bool RecvDivertToParentUsing(PChannelDiverterParent* diverter) MOZ_OVERRIDE; + ExternalHelperAppParent(const OptionalURIParams& uri, const int64_t& contentLength); void Init(ContentParent *parent, const nsCString& aMimeContentType, @@ -57,10 +67,16 @@ public: PBrowserParent* aBrowser); virtual ~ExternalHelperAppParent(); +protected: + virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; + void Delete(); + private: nsCOMPtr mListener; nsCOMPtr mURI; bool mPending; + DebugOnly mDiverted; + bool mIPCClosed; nsLoadFlags mLoadFlags; nsresult mStatus; int64_t mContentLength; diff --git a/uriloader/exthandler/PExternalHelperApp.ipdl b/uriloader/exthandler/PExternalHelperApp.ipdl index f120689f8def..914b7cc2ddd1 100644 --- a/uriloader/exthandler/PExternalHelperApp.ipdl +++ b/uriloader/exthandler/PExternalHelperApp.ipdl @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ include protocol PContent; +include protocol PChannelDiverter; namespace mozilla { namespace dom { @@ -16,6 +17,8 @@ parent: OnDataAvailable(nsCString data, uint64_t offset, uint32_t count); OnStopRequest(nsresult code); + DivertToParentUsing(PChannelDiverter diverter); + child: Cancel(nsresult aStatus); __delete__(); diff --git a/uriloader/exthandler/moz.build b/uriloader/exthandler/moz.build index 5c0e7dfb7fe3..af950623c405 100644 --- a/uriloader/exthandler/moz.build +++ b/uriloader/exthandler/moz.build @@ -56,7 +56,6 @@ EXPORTS.mozilla.dom += [ ] UNIFIED_SOURCES += [ - 'ExternalHelperAppChild.cpp', 'ExternalHelperAppParent.cpp', 'nsLocalHandlerApp.cpp', 'nsMIMEInfoImpl.cpp', @@ -64,6 +63,7 @@ UNIFIED_SOURCES += [ # These files can't be built in unified mode because they force NSPR logging. SOURCES += [ + 'ExternalHelperAppChild.cpp', 'nsExternalHelperAppService.cpp', 'nsExternalProtocolHandler.cpp', ] diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp index 39aed0f4e5fa..c30065529e30 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -1202,10 +1202,10 @@ NS_INTERFACE_MAP_BEGIN(nsExternalAppHandler) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamListener) NS_INTERFACE_MAP_ENTRY(nsIStreamListener) NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) - NS_INTERFACE_MAP_ENTRY(nsIHelperAppLauncher) + NS_INTERFACE_MAP_ENTRY(nsIHelperAppLauncher) NS_INTERFACE_MAP_ENTRY(nsICancelable) NS_INTERFACE_MAP_ENTRY(nsITimerCallback) - NS_INTERFACE_MAP_ENTRY(nsIBackgroundFileSaverObserver) + NS_INTERFACE_MAP_ENTRY(nsIBackgroundFileSaverObserver) NS_INTERFACE_MAP_END_THREADSAFE nsExternalAppHandler::nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo, @@ -1271,6 +1271,15 @@ nsExternalAppHandler::~nsExternalAppHandler() MOZ_ASSERT(!mSaver, "Saver should hold a reference to us until deleted"); } +void +nsExternalAppHandler::DidDivertRequest(nsIRequest *request) +{ + MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Content, "in child process"); + // Remove our request from the child loadGroup + RetargetLoadNotifications(request); + MaybeCloseWindow(); +} + NS_IMETHODIMP nsExternalAppHandler::SetWebProgressListener(nsIWebProgressListener2 * aWebProgressListener) { // This is always called by nsHelperDlg.js. Go ahead and register the diff --git a/uriloader/exthandler/nsExternalHelperAppService.h b/uriloader/exthandler/nsExternalHelperAppService.h index b029a59c85a2..8e5ed9948962 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.h +++ b/uriloader/exthandler/nsExternalHelperAppService.h @@ -237,6 +237,11 @@ public: ~nsExternalAppHandler(); + /** + * Clean up after the request was diverted to the parent process. + */ + void DidDivertRequest(nsIRequest *request); + protected: nsCOMPtr mTempFile; nsCOMPtr mSourceUrl;