зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1350058 - Update the content context if we close the downloading window. r=mconley
MozReview-Commit-ID: A5LsapsljMY --HG-- extra : rebase_source : bb35582e80c64f3cb8d563e14b24ed394a45ad5b
This commit is contained in:
Родитель
deeb9fdcf9
Коммит
9708f9f50d
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "ExternalHelperAppChild.h"
|
||||
#include "mozilla/net/ChannelDiverterChild.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "nsIDivertableChannel.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIFTPChannel.h"
|
||||
|
@ -63,9 +64,17 @@ ExternalHelperAppChild::OnStartRequest(nsIRequest *request, nsISupports *ctx)
|
|||
nsresult rv = mHandler->OnStartRequest(request, ctx);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Calling OnStartRequest could cause mHandler to close the window it was
|
||||
// loaded for. In that case, the TabParent in the parent context might then
|
||||
// point to the wrong window. Re-send the window context along with either
|
||||
// DivertToParent or SendOnStartRequest just in case.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window =
|
||||
do_GetInterface(mHandler->GetDialogParent());
|
||||
TabChild *tabChild = window ? mozilla::dom::TabChild::GetFrom(window) : nullptr;
|
||||
|
||||
nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
|
||||
if (divertable) {
|
||||
return DivertToParent(divertable, request);
|
||||
return DivertToParent(divertable, request, tabChild);
|
||||
}
|
||||
|
||||
nsCString entityID;
|
||||
|
@ -73,7 +82,7 @@ ExternalHelperAppChild::OnStartRequest(nsIRequest *request, nsISupports *ctx)
|
|||
if (resumable) {
|
||||
resumable->GetEntityID(entityID);
|
||||
}
|
||||
SendOnStartRequest(entityID);
|
||||
SendOnStartRequest(entityID, tabChild);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -94,7 +103,8 @@ ExternalHelperAppChild::OnStopRequest(nsIRequest *request,
|
|||
|
||||
nsresult
|
||||
ExternalHelperAppChild::DivertToParent(nsIDivertableChannel *divertable,
|
||||
nsIRequest *request)
|
||||
nsIRequest *request,
|
||||
TabChild *tabChild)
|
||||
{
|
||||
// nsIDivertable must know about content conversions before being diverted.
|
||||
MOZ_ASSERT(mHandler);
|
||||
|
@ -107,7 +117,7 @@ ExternalHelperAppChild::DivertToParent(nsIDivertableChannel *divertable,
|
|||
}
|
||||
MOZ_ASSERT(diverter);
|
||||
|
||||
if (SendDivertToParentUsing(diverter)) {
|
||||
if (SendDivertToParentUsing(diverter, tabChild)) {
|
||||
mHandler->DidDivertRequest(request);
|
||||
mHandler = nullptr;
|
||||
return NS_OK;
|
||||
|
|
|
@ -16,6 +16,8 @@ class nsIDivertableChannel;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class TabChild;
|
||||
|
||||
class ExternalHelperAppChild : public PExternalHelperAppChild
|
||||
, public nsIStreamListener
|
||||
{
|
||||
|
@ -33,7 +35,9 @@ public:
|
|||
virtual mozilla::ipc::IPCResult RecvCancel(const nsresult& aStatus) override;
|
||||
private:
|
||||
virtual ~ExternalHelperAppChild();
|
||||
MOZ_MUST_USE nsresult DivertToParent(nsIDivertableChannel *divertable, nsIRequest *request);
|
||||
MOZ_MUST_USE nsresult DivertToParent(nsIDivertableChannel *divertable,
|
||||
nsIRequest *request,
|
||||
TabChild *tabChild);
|
||||
|
||||
RefPtr<nsExternalAppHandler> mHandler;
|
||||
nsresult mStatus;
|
||||
|
|
|
@ -54,6 +54,30 @@ ExternalHelperAppParent::ExternalHelperAppParent(
|
|||
{
|
||||
}
|
||||
|
||||
already_AddRefed<nsIInterfaceRequestor>
|
||||
GetWindowFromTabParent(PBrowserParent* aBrowser)
|
||||
{
|
||||
if (!aBrowser) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> window;
|
||||
TabParent* tabParent = TabParent::GetFrom(aBrowser);
|
||||
if (tabParent->GetOwnerElement()) {
|
||||
window = do_QueryInterface(tabParent->GetOwnerElement()->OwnerDoc()->GetWindow());
|
||||
}
|
||||
|
||||
return window.forget();
|
||||
}
|
||||
|
||||
void
|
||||
UpdateContentContext(nsIStreamListener* aListener, PBrowserParent* aBrowser)
|
||||
{
|
||||
MOZ_ASSERT(aListener);
|
||||
nsCOMPtr<nsIInterfaceRequestor> window = GetWindowFromTabParent(aBrowser);
|
||||
static_cast<nsExternalAppHandler *>(aListener)->SetContentContext(window);
|
||||
}
|
||||
|
||||
void
|
||||
ExternalHelperAppParent::Init(ContentParent *parent,
|
||||
const nsCString& aMimeContentType,
|
||||
|
@ -117,10 +141,13 @@ ExternalHelperAppParent::Delete()
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ExternalHelperAppParent::RecvOnStartRequest(const nsCString& entityID)
|
||||
ExternalHelperAppParent::RecvOnStartRequest(const nsCString& entityID,
|
||||
PBrowserParent* contentContext)
|
||||
{
|
||||
MOZ_ASSERT(!mDiverted, "child forwarding callbacks after request was diverted");
|
||||
|
||||
UpdateContentContext(mListener, contentContext);
|
||||
|
||||
mEntityID = entityID;
|
||||
mPending = true;
|
||||
mStatus = mListener->OnStartRequest(this, nullptr);
|
||||
|
@ -159,9 +186,11 @@ ExternalHelperAppParent::RecvOnStopRequest(const nsresult& code)
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ExternalHelperAppParent::RecvDivertToParentUsing(PChannelDiverterParent* diverter)
|
||||
ExternalHelperAppParent::RecvDivertToParentUsing(PChannelDiverterParent* diverter,
|
||||
PBrowserParent* contentContext)
|
||||
{
|
||||
MOZ_ASSERT(diverter);
|
||||
UpdateContentContext(mListener, contentContext);
|
||||
auto p = static_cast<mozilla::net::ChannelDiverterParent*>(diverter);
|
||||
p->DivertTo(this);
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -68,13 +68,15 @@ public:
|
|||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnStartRequest(const nsCString& entityID) override;
|
||||
mozilla::ipc::IPCResult RecvOnStartRequest(const nsCString& entityID,
|
||||
PBrowserParent* aBrowser) override;
|
||||
mozilla::ipc::IPCResult RecvOnDataAvailable(const nsCString& data,
|
||||
const uint64_t& offset,
|
||||
const uint32_t& count) override;
|
||||
mozilla::ipc::IPCResult RecvOnStopRequest(const nsresult& code) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvDivertToParentUsing(PChannelDiverterParent* diverter) override;
|
||||
mozilla::ipc::IPCResult RecvDivertToParentUsing(PChannelDiverterParent* diverter,
|
||||
PBrowserParent* aBrowser) override;
|
||||
|
||||
bool WasFileChannel() override {
|
||||
return mWasFileChannel;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/* vim: set ft=cpp: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBrowser;
|
||||
include protocol PContent;
|
||||
include protocol PChannelDiverter;
|
||||
|
||||
|
@ -13,11 +15,11 @@ protocol PExternalHelperApp
|
|||
manager PContent;
|
||||
|
||||
parent:
|
||||
async OnStartRequest(nsCString entityID);
|
||||
async OnStartRequest(nsCString entityID, PBrowser windowContext);
|
||||
async OnDataAvailable(nsCString data, uint64_t offset, uint32_t count);
|
||||
async OnStopRequest(nsresult code);
|
||||
|
||||
async DivertToParentUsing(PChannelDiverter diverter);
|
||||
async DivertToParentUsing(PChannelDiverter diverter, PBrowser windowContext);
|
||||
|
||||
child:
|
||||
async Cancel(nsresult aStatus);
|
||||
|
|
|
@ -840,6 +840,8 @@ NS_IMETHODIMP nsExternalHelperAppService::DoContent(const nsACString& aMimeConte
|
|||
nsAutoCString buf;
|
||||
mimeInfo->GetPrimaryExtension(buf);
|
||||
|
||||
// NB: ExternalHelperAppParent depends on this listener always being an
|
||||
// nsExternalAppHandler. If this changes, make sure to update that code.
|
||||
nsExternalAppHandler * handler = new nsExternalAppHandler(mimeInfo,
|
||||
buf,
|
||||
aContentContext,
|
||||
|
|
|
@ -245,13 +245,21 @@ public:
|
|||
*/
|
||||
void MaybeApplyDecodingForExtension(nsIRequest *request);
|
||||
|
||||
protected:
|
||||
~nsExternalAppHandler();
|
||||
|
||||
/**
|
||||
* Get the dialog parent. Public for ExternalHelperAppChild::OnStartRequest.
|
||||
*/
|
||||
nsIInterfaceRequestor* GetDialogParent() {
|
||||
return mWindowContext ? mWindowContext : mContentContext;
|
||||
}
|
||||
|
||||
void SetContentContext(nsIInterfaceRequestor* context) {
|
||||
MOZ_ASSERT(!mWindowContext);
|
||||
mContentContext = context;
|
||||
}
|
||||
|
||||
protected:
|
||||
~nsExternalAppHandler();
|
||||
|
||||
nsCOMPtr<nsIFile> mTempFile;
|
||||
nsCOMPtr<nsIURI> mSourceUrl;
|
||||
nsString mTempFileExtension;
|
||||
|
|
Загрузка…
Ссылка в новой задаче