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:
Blake Kaplan 2017-03-23 17:01:30 -07:00
Родитель deeb9fdcf9
Коммит 9708f9f50d
7 изменённых файлов: 71 добавлений и 14 удалений

Просмотреть файл

@ -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;