зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1583321 - Allow sending same entry multiple times during one IPC call. r=nika
Differential Revision: https://phabricator.services.mozilla.com/D46935 --HG-- extra : rebase_source : 48fcbe1dc8c83af1d85575c32e33a904636d31de extra : source : 184c14258def58dd1796cf2259a6fecf1cbc055c extra : histedit_source : 3423197858c817b2c10140543105550a7b2ca913
This commit is contained in:
Родитель
bc0cfa0be9
Коммит
3d62c6c2fb
|
@ -0,0 +1,78 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "mozilla/dom/MaybeNewPSHEntry.h"
|
||||
#include "mozilla/dom/PContentParent.h"
|
||||
#include "mozilla/dom/SHEntryChild.h"
|
||||
#include "mozilla/dom/SHEntryParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
template <>
|
||||
struct IPDLParamTraits<dom::NewPSHEntry> {
|
||||
static void Write(IPC::Message* aMsg, IProtocol* aActor,
|
||||
dom::NewPSHEntry&& aEntry) {
|
||||
MOZ_RELEASE_ASSERT(aActor->GetSide() == ParentSide, "wrong side!");
|
||||
|
||||
WriteIPDLParam(aMsg, aActor, std::move(aEntry.mEndpoint));
|
||||
WriteIPDLParam(aMsg, aActor, aEntry.mSharedID);
|
||||
}
|
||||
|
||||
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
|
||||
IProtocol* aActor, dom::NewPSHEntry* aEntry) {
|
||||
MOZ_RELEASE_ASSERT(aActor->GetSide() == ChildSide, "wrong side!");
|
||||
|
||||
return ReadIPDLParam(aMsg, aIter, aActor, &aEntry->mEndpoint) &&
|
||||
ReadIPDLParam(aMsg, aIter, aActor, &aEntry->mSharedID);
|
||||
}
|
||||
};
|
||||
|
||||
/* static */
|
||||
void IPDLParamTraits<dom::CrossProcessSHEntry*>::Write(
|
||||
IPC::Message* aMsg, IProtocol* aActor, dom::CrossProcessSHEntry* aEntry) {
|
||||
MOZ_RELEASE_ASSERT(aActor->GetSide() == ParentSide, "wrong side!");
|
||||
MOZ_DIAGNOSTIC_ASSERT(aActor->ToplevelProtocol()->GetProtocolId() ==
|
||||
PContentMsgStart);
|
||||
|
||||
dom::MaybeNewPSHEntryParent entry(static_cast<dom::PSHEntryParent*>(nullptr));
|
||||
if (aEntry) {
|
||||
entry = static_cast<dom::LegacySHEntry*>(aEntry)->GetOrCreateActor(
|
||||
static_cast<dom::PContentParent*>(aActor->ToplevelProtocol()));
|
||||
}
|
||||
|
||||
WriteIPDLParam(aMsg, aActor, std::move(entry));
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool IPDLParamTraits<dom::CrossProcessSHEntry*>::Read(
|
||||
const IPC::Message* aMsg, PickleIterator* aIter,
|
||||
mozilla::ipc::IProtocol* aActor, RefPtr<dom::CrossProcessSHEntry>* aEntry) {
|
||||
MOZ_RELEASE_ASSERT(aActor->GetSide() == ChildSide, "wrong side!");
|
||||
|
||||
dom::MaybeNewPSHEntryChild actor(static_cast<dom::PSHEntryChild*>(nullptr));
|
||||
if (!ReadIPDLParam(aMsg, aIter, aActor, &actor)) {
|
||||
aActor->FatalError("Error deserializing MaybeNewPSHEntry");
|
||||
return false;
|
||||
}
|
||||
|
||||
return actor.match(
|
||||
[&](dom::PSHEntryChild*& entry) {
|
||||
*aEntry = static_cast<dom::SHEntryChild*>(entry);
|
||||
return true;
|
||||
},
|
||||
[&](dom::NewPSHEntry& newEntry) {
|
||||
RefPtr<dom::SHEntryChild> entry =
|
||||
new dom::SHEntryChild(newEntry.mSharedID);
|
||||
dom::ContentChild::GetSingleton()->BindPSHEntryEndpoint(
|
||||
std::move(newEntry.mEndpoint), do_AddRef(entry).take());
|
||||
*aEntry = entry.forget();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_MaybeNewPSHEntry_h
|
||||
#define mozilla_dom_MaybeNewPSHEntry_h
|
||||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/Variant.h"
|
||||
#include "mozilla/ipc/IPDLParamTraits.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class LegacySHEntry;
|
||||
class PSHEntryChild;
|
||||
class PSHEntryParent;
|
||||
class SHEntryChild;
|
||||
|
||||
struct NewPSHEntry final {
|
||||
mozilla::ipc::ManagedEndpoint<PSHEntryChild> mEndpoint;
|
||||
uint64_t mSharedID;
|
||||
};
|
||||
|
||||
typedef Variant<PSHEntryParent*, NewPSHEntry> MaybeNewPSHEntryParent;
|
||||
typedef Variant<PSHEntryChild*, NewPSHEntry> MaybeNewPSHEntryChild;
|
||||
|
||||
// Any IPDL protocol trying to pass this (as argument or return value) needs to
|
||||
// be managed by PContent.
|
||||
class CrossProcessSHEntry {
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
|
||||
SHEntryChild* ToSHEntryChild();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
namespace ipc {
|
||||
|
||||
template <>
|
||||
struct IPDLParamTraits<dom::CrossProcessSHEntry*> {
|
||||
static void Write(IPC::Message* aMsg, IProtocol* aActor,
|
||||
dom::CrossProcessSHEntry* aEntry);
|
||||
|
||||
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
|
||||
IProtocol* aActor, RefPtr<dom::CrossProcessSHEntry>* aEntry);
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_dom_MaybeNewPSHEntry_h */
|
|
@ -1,27 +0,0 @@
|
|||
/* 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 PSHEntry;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
union PSHEntryOrSharedID
|
||||
{
|
||||
PSHEntry;
|
||||
uint64_t;
|
||||
};
|
||||
|
||||
struct NewPSHEntry {
|
||||
ManagedEndpoint<PSHEntryChild> endpoint;
|
||||
uint64_t sharedID;
|
||||
};
|
||||
|
||||
union MaybeNewPSHEntry {
|
||||
nullable PSHEntry;
|
||||
NewPSHEntry;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -6,8 +6,8 @@ include protocol PContent;
|
|||
include protocol PSHistory;
|
||||
|
||||
include DOMTypes;
|
||||
include NewPSHEntry;
|
||||
|
||||
using refcounted class mozilla::dom::CrossProcessSHEntry from "mozilla/dom/MaybeNewPSHEntry.h";
|
||||
using refcounted class nsDocShellLoadState from "mozilla/dom/DocShellMessageUtils.h";
|
||||
using struct nsID from "nsID.h";
|
||||
using nsIntRect from "nsRect.h";
|
||||
|
@ -16,6 +16,8 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
|
||||
sync protocol PSHEntry {
|
||||
// IPDLParamTraits<dom::CrossProcessSHEntry*>::Write relies on PContent being
|
||||
// the manager.
|
||||
manager PContent;
|
||||
|
||||
parent:
|
||||
|
@ -37,7 +39,7 @@ parent:
|
|||
async SetSticky(bool sticky);
|
||||
sync GetPostData() returns (nsIInputStream postData);
|
||||
async SetPostData(nsIInputStream postData);
|
||||
sync GetParent() returns (MaybeNewPSHEntry parentEntry);
|
||||
sync GetParent() returns (CrossProcessSHEntry parentEntry);
|
||||
async SetParent(nullable PSHEntry parentEntry);
|
||||
sync GetLoadType() returns (uint32_t loadType);
|
||||
async SetLoadType(uint32_t loadType);
|
||||
|
@ -100,8 +102,8 @@ parent:
|
|||
async SetLoadTypeAsHistory();
|
||||
sync AddChild(nullable PSHEntry childEntry, int32_t offset, bool useRemoteSubframes) returns (nsresult result);
|
||||
sync RemoveChild(PSHEntry childEntry) returns (nsresult result);
|
||||
sync GetChildAt(int32_t index) returns (MaybeNewPSHEntry childEntry);
|
||||
sync GetChildSHEntryIfHasNoDynamicallyAddedChild(int32_t childOffset) returns (MaybeNewPSHEntry childEntry);
|
||||
sync GetChildAt(int32_t index) returns (CrossProcessSHEntry childEntry);
|
||||
sync GetChildSHEntryIfHasNoDynamicallyAddedChild(int32_t childOffset) returns (CrossProcessSHEntry childEntry);
|
||||
sync ReplaceChild(PSHEntry newChildEntry) returns (nsresult result);
|
||||
async ClearEntry(uint64_t aNewSharedID);
|
||||
sync CreateLoadInfo() returns (nsDocShellLoadState loadState);
|
||||
|
|
|
@ -6,9 +6,9 @@ include protocol PContent;
|
|||
include protocol PSHEntry;
|
||||
|
||||
include DOMTypes;
|
||||
include NewPSHEntry;
|
||||
|
||||
using refcounted class mozilla::dom::BrowsingContext from "mozilla/dom/BrowsingContext.h";
|
||||
using refcounted class mozilla::dom::CrossProcessSHEntry from "mozilla/dom/MaybeNewPSHEntry.h";
|
||||
using refcounted class nsDocShellLoadState from "mozilla/dom/DocShellMessageUtils.h";
|
||||
|
||||
using struct nsID from "nsID.h";
|
||||
|
@ -19,7 +19,7 @@ namespace dom {
|
|||
|
||||
struct LoadSHEntryData
|
||||
{
|
||||
MaybeNewPSHEntry shEntry;
|
||||
CrossProcessSHEntry shEntry;
|
||||
BrowsingContext browsingContext;
|
||||
nsDocShellLoadState loadState;
|
||||
};
|
||||
|
@ -30,6 +30,8 @@ union LoadSHEntryResult {
|
|||
};
|
||||
|
||||
sync protocol PSHistory {
|
||||
// IPDLParamTraits<dom::CrossProcessSHEntry*>::Write relies on PContent being
|
||||
// the manager.
|
||||
manager PContent;
|
||||
|
||||
parent:
|
||||
|
@ -38,7 +40,7 @@ parent:
|
|||
sync SetIndex(int32_t index) returns (nsresult result);
|
||||
sync GetRequestedIndex() returns (int32_t index);
|
||||
async InternalSetRequestedIndex(int32_t index);
|
||||
sync GetEntryAtIndex(int32_t index) returns (nsresult result, MaybeNewPSHEntry entry);
|
||||
sync GetEntryAtIndex(int32_t index) returns (nsresult result, CrossProcessSHEntry entry);
|
||||
sync PurgeHistory(int32_t numEntries) returns (nsresult result);
|
||||
sync ReloadCurrentEntry() returns (LoadSHEntryResult load);
|
||||
sync GotoIndex(int32_t index) returns (LoadSHEntryResult load);
|
||||
|
@ -53,8 +55,9 @@ parent:
|
|||
sync RemoveEntries(nsID[] ids, int32_t index) returns (bool didRemove);
|
||||
async RemoveFrameEntries(PSHEntry entry);
|
||||
sync Reload(uint32_t reloadFlags) returns (LoadSHEntryResult load);
|
||||
sync GetAllEntries() returns (MaybeNewPSHEntry[] entries);
|
||||
sync FindEntryForBFCache(uint64_t sharedID, bool includeCurrentEntry) returns (MaybeNewPSHEntry entries, int32_t startIndex);
|
||||
sync GetAllEntries() returns (CrossProcessSHEntry[] entries);
|
||||
sync FindEntryForBFCache(uint64_t sharedID, bool includeCurrentEntry)
|
||||
returns (CrossProcessSHEntry entries, int32_t startIndex);
|
||||
async Evict(PSHEntry[] entry);
|
||||
async EnsureCorrectEntryAtCurrIndex(PSHEntry entry);
|
||||
async EvictContentViewersOrReplaceEntry(nullable PSHEntry newSHEntry, bool replace);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "SHEntryChild.h"
|
||||
#include "SHistoryChild.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/StaticPrefs_docshell.h"
|
||||
#include "mozilla/dom/MaybeNewPSHEntry.h"
|
||||
#include "nsDocShellEditorData.h"
|
||||
#include "nsDocShellLoadState.h"
|
||||
#include "nsIContentViewer.h"
|
||||
|
@ -593,12 +595,12 @@ SHEntryChild::Clone(nsISHEntry** aResult) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
SHEntryChild::GetParent(nsISHEntry** aResult) {
|
||||
MaybeNewPSHEntry parent;
|
||||
RefPtr<CrossProcessSHEntry> parent;
|
||||
if (!SendGetParent(&parent)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aResult = SHEntryChild::GetOrCreate(parent).take();
|
||||
*aResult = parent ? do_AddRef(parent->ToSHEntryChild()).take() : nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -808,21 +810,21 @@ SHEntryChild::RemoveChild(nsISHEntry* aChild) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
SHEntryChild::GetChildAt(int32_t aIndex, nsISHEntry** aResult) {
|
||||
MaybeNewPSHEntry child;
|
||||
RefPtr<CrossProcessSHEntry> child;
|
||||
if (!SendGetChildAt(aIndex, &child)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aResult = SHEntryChild::GetOrCreate(child).take();
|
||||
*aResult = child ? do_AddRef(child->ToSHEntryChild()).take() : nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
SHEntryChild::GetChildSHEntryIfHasNoDynamicallyAddedChild(int32_t aChildOffset,
|
||||
nsISHEntry** aChild) {
|
||||
MaybeNewPSHEntry child;
|
||||
RefPtr<CrossProcessSHEntry> child;
|
||||
SendGetChildSHEntryIfHasNoDynamicallyAddedChild(aChildOffset, &child);
|
||||
*aChild = SHEntryChild::GetOrCreate(child).take();
|
||||
*aChild = child ? do_AddRef(child->ToSHEntryChild()).take() : nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1012,20 +1014,5 @@ void SHEntryChild::EvictContentViewer() {
|
|||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<SHEntryChild> SHEntryChild::GetOrCreate(
|
||||
MaybeNewPSHEntry& aEntry) {
|
||||
RefPtr<SHEntryChild> entry;
|
||||
if (aEntry.type() == MaybeNewPSHEntry::TNewPSHEntry) {
|
||||
NewPSHEntry& newEntry = aEntry.get_NewPSHEntry();
|
||||
entry = new SHEntryChild(newEntry.sharedID());
|
||||
ContentChild::GetSingleton()->BindPSHEntryEndpoint(
|
||||
std::move(newEntry.endpoint()), do_AddRef(entry).take());
|
||||
} else {
|
||||
entry = static_cast<SHEntryChild*>(aEntry.get_PSHEntryChild());
|
||||
}
|
||||
return entry.forget();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define mozilla_dom_SHEntryChild_h
|
||||
|
||||
#include "mozilla/dom/PSHEntryChild.h"
|
||||
#include "mozilla/dom/MaybeNewPSHEntry.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsExpirationTracker.h"
|
||||
#include "nsIBFCacheEntry.h"
|
||||
|
@ -84,8 +85,11 @@ class SHEntryChildShared final : public nsIBFCacheEntry,
|
|||
/**
|
||||
* Session history entry actor for the child process.
|
||||
*/
|
||||
class SHEntryChild final : public PSHEntryChild, public nsISHEntry {
|
||||
class SHEntryChild final : public PSHEntryChild,
|
||||
public nsISHEntry,
|
||||
public CrossProcessSHEntry {
|
||||
friend class PSHEntryChild;
|
||||
using PSHEntryChild::CrossProcessSHEntry;
|
||||
|
||||
public:
|
||||
explicit SHEntryChild(const SHEntryChild* aClone)
|
||||
|
@ -99,8 +103,6 @@ class SHEntryChild final : public PSHEntryChild, public nsISHEntry {
|
|||
|
||||
void EvictContentViewer();
|
||||
|
||||
static already_AddRefed<SHEntryChild> GetOrCreate(MaybeNewPSHEntry& aEntry);
|
||||
|
||||
protected:
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override {
|
||||
mIPCActorDeleted = true;
|
||||
|
@ -113,6 +115,11 @@ class SHEntryChild final : public PSHEntryChild, public nsISHEntry {
|
|||
bool mIPCActorDeleted;
|
||||
};
|
||||
|
||||
inline SHEntryChild* CrossProcessSHEntry::ToSHEntryChild() {
|
||||
MOZ_ASSERT(XRE_IsContentProcess(), "Wrong side!");
|
||||
return static_cast<SHEntryChild*>(this);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "SHEntryParent.h"
|
||||
#include "SHistoryParent.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/MaybeNewPSHEntry.h"
|
||||
#include "nsStructuredCloneContainer.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -24,21 +25,22 @@ void SHEntrySharedParent::Destroy() {
|
|||
SHEntrySharedParentState::Destroy();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(LegacySHEntry, nsSHEntry)
|
||||
|
||||
SHEntryParent* LegacySHEntry::CreateActor() {
|
||||
MOZ_ASSERT(!mActor);
|
||||
mActor = new SHEntryParent(this);
|
||||
return mActor;
|
||||
}
|
||||
|
||||
void LegacySHEntry::GetOrCreateActor(PContentParent* aContentParent,
|
||||
MaybeNewPSHEntry& aEntry) {
|
||||
if (!mActor) {
|
||||
mActor = new SHEntryParent(this);
|
||||
aEntry =
|
||||
NewPSHEntry(aContentParent->OpenPSHEntryEndpoint(mActor), mShared->mID);
|
||||
} else {
|
||||
aEntry = mActor;
|
||||
MaybeNewPSHEntryParent LegacySHEntry::GetOrCreateActor(
|
||||
PContentParent* aContentParent) {
|
||||
if (mActor) {
|
||||
return AsVariant(static_cast<PSHEntryParent*>(mActor));
|
||||
}
|
||||
|
||||
return AsVariant(NewPSHEntry{
|
||||
aContentParent->OpenPSHEntryEndpoint(CreateActor()), mShared->mID});
|
||||
}
|
||||
|
||||
void LegacySHEntry::AbandonBFCacheEntry(uint64_t aNewSharedID) {
|
||||
|
@ -156,9 +158,9 @@ bool SHEntryParent::RecvSetPostData(nsIInputStream* aPostData) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SHEntryParent::RecvGetParent(MaybeNewPSHEntry* aParentEntry) {
|
||||
bool SHEntryParent::RecvGetParent(RefPtr<CrossProcessSHEntry>* aParentEntry) {
|
||||
nsCOMPtr<nsISHEntry> parent = mEntry->GetParent();
|
||||
GetOrCreate(parent, aParentEntry);
|
||||
*aParentEntry = parent.forget().downcast<LegacySHEntry>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -507,21 +509,21 @@ bool SHEntryParent::RecvRemoveChild(PSHEntryParent* aChild, nsresult* aResult) {
|
|||
}
|
||||
|
||||
bool SHEntryParent::RecvGetChildAt(const int32_t& aIndex,
|
||||
MaybeNewPSHEntry* aChild) {
|
||||
RefPtr<CrossProcessSHEntry>* aChild) {
|
||||
nsCOMPtr<nsISHEntry> child;
|
||||
DebugOnly<nsresult> rv = mEntry->GetChildAt(aIndex, getter_AddRefs(child));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Didn't expect this to fail.");
|
||||
|
||||
GetOrCreate(child, aChild);
|
||||
*aChild = child.forget().downcast<LegacySHEntry>();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SHEntryParent::RecvGetChildSHEntryIfHasNoDynamicallyAddedChild(
|
||||
const int32_t& aChildOffset, MaybeNewPSHEntry* aChild) {
|
||||
const int32_t& aChildOffset, RefPtr<CrossProcessSHEntry>* aChild) {
|
||||
nsCOMPtr<nsISHEntry> child;
|
||||
mEntry->GetChildSHEntryIfHasNoDynamicallyAddedChild(aChildOffset,
|
||||
getter_AddRefs(child));
|
||||
GetOrCreate(child, aChild);
|
||||
*aChild = child.forget().downcast<LegacySHEntry>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -532,15 +534,6 @@ bool SHEntryParent::RecvReplaceChild(PSHEntryParent* aNewChild,
|
|||
return true;
|
||||
}
|
||||
|
||||
void SHEntryParent::GetOrCreate(PContentParent* aManager, nsISHEntry* aSHEntry,
|
||||
MaybeNewPSHEntry& aResult) {
|
||||
if (aSHEntry) {
|
||||
static_cast<LegacySHEntry*>(aSHEntry)->GetOrCreateActor(aManager, aResult);
|
||||
} else {
|
||||
aResult = (PSHEntryParent*)nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool SHEntryParent::RecvClearEntry(const uint64_t& aNewSharedID) {
|
||||
mEntry->ClearEntry();
|
||||
mEntry->AbandonBFCacheEntry(aNewSharedID);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define mozilla_dom_SHistoryEntry_h
|
||||
|
||||
#include "mozilla/dom/PSHEntryParent.h"
|
||||
#include "mozilla/dom/MaybeNewPSHEntry.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsSHEntry.h"
|
||||
#include "nsSHEntryShared.h"
|
||||
|
@ -41,7 +42,7 @@ class SHEntrySharedParent : public SHEntrySharedParentState {
|
|||
* The actor is (re)created as needed, whenever we need to return an entry to
|
||||
* the child process. The lifetime is determined by the child side.
|
||||
*/
|
||||
class LegacySHEntry final : public nsSHEntry {
|
||||
class LegacySHEntry final : public nsSHEntry, public CrossProcessSHEntry {
|
||||
public:
|
||||
LegacySHEntry(PContentParent* aParent, uint64_t aSharedID)
|
||||
: nsSHEntry(new SHEntrySharedParent(aParent, aSharedID)),
|
||||
|
@ -49,8 +50,9 @@ class LegacySHEntry final : public nsSHEntry {
|
|||
explicit LegacySHEntry(const LegacySHEntry& aEntry)
|
||||
: nsSHEntry(aEntry), mActor(nullptr) {}
|
||||
|
||||
void GetOrCreateActor(PContentParent* aContentParent,
|
||||
MaybeNewPSHEntry& aEntry);
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
MaybeNewPSHEntryParent GetOrCreateActor(PContentParent* aContentParent);
|
||||
|
||||
using nsSHEntry::AbandonBFCacheEntry;
|
||||
void AbandonBFCacheEntry(uint64_t aNewSharedID);
|
||||
|
@ -65,6 +67,8 @@ class LegacySHEntry final : public nsSHEntry {
|
|||
friend class SHEntryParent;
|
||||
friend class ContentParent;
|
||||
|
||||
~LegacySHEntry() {}
|
||||
|
||||
SHEntryParent* CreateActor();
|
||||
|
||||
SHEntryParent* mActor;
|
||||
|
@ -83,9 +87,6 @@ class SHEntryParent final : public PSHEntryParent {
|
|||
explicit SHEntryParent(LegacySHEntry* aEntry)
|
||||
: PSHEntryParent(), mEntry(aEntry) {}
|
||||
|
||||
static void GetOrCreate(PContentParent* aManager, nsISHEntry* aSHEntry,
|
||||
MaybeNewPSHEntry& aResult);
|
||||
|
||||
LegacySHEntry* GetSHEntry() { return mEntry; }
|
||||
|
||||
protected:
|
||||
|
@ -110,7 +111,7 @@ class SHEntryParent final : public PSHEntryParent {
|
|||
bool RecvSetSticky(const bool& aSticky);
|
||||
bool RecvGetPostData(RefPtr<nsIInputStream>* aPostData);
|
||||
bool RecvSetPostData(nsIInputStream* aPostData);
|
||||
bool RecvGetParent(MaybeNewPSHEntry* aParentEntry);
|
||||
bool RecvGetParent(RefPtr<CrossProcessSHEntry>* aParentEntry);
|
||||
bool RecvSetParent(PSHEntryParent* aParentEntry);
|
||||
bool RecvGetLoadType(uint32_t* aLoadType);
|
||||
bool RecvSetLoadType(const uint32_t& aLoadType);
|
||||
|
@ -180,15 +181,13 @@ class SHEntryParent final : public PSHEntryParent {
|
|||
bool RecvAddChild(PSHEntryParent* aChild, const int32_t& aOffset,
|
||||
const bool& aUseRemoteSubframes, nsresult* aResult);
|
||||
bool RecvRemoveChild(PSHEntryParent* aChild, nsresult* aResult);
|
||||
bool RecvGetChildAt(const int32_t& aIndex, MaybeNewPSHEntry* aChild);
|
||||
bool RecvGetChildAt(const int32_t& aIndex,
|
||||
RefPtr<CrossProcessSHEntry>* aChild);
|
||||
bool RecvGetChildSHEntryIfHasNoDynamicallyAddedChild(
|
||||
const int32_t& aChildOffset, MaybeNewPSHEntry* aChild);
|
||||
const int32_t& aChildOffset, RefPtr<CrossProcessSHEntry>* aChild);
|
||||
bool RecvReplaceChild(PSHEntryParent* aNewChild, nsresult* aResult);
|
||||
bool RecvClearEntry(const uint64_t& aNewSharedID);
|
||||
|
||||
void GetOrCreate(nsISHEntry* aSHEntry, MaybeNewPSHEntry* aResult) {
|
||||
GetOrCreate(Manager(), aSHEntry, *aResult);
|
||||
}
|
||||
bool RecvCreateLoadInfo(RefPtr<nsDocShellLoadState>* aLoadState);
|
||||
|
||||
RefPtr<LegacySHEntry> mEntry;
|
||||
|
|
|
@ -95,16 +95,15 @@ SHistoryChild::InternalSetRequestedIndex(int32_t aRequestedIndex) {
|
|||
NS_IMETHODIMP
|
||||
SHistoryChild::GetEntryAtIndex(int32_t aIndex, nsISHEntry** aResult) {
|
||||
nsresult rv;
|
||||
MaybeNewPSHEntry entry;
|
||||
RefPtr<CrossProcessSHEntry> entry;
|
||||
if (!SendGetEntryAtIndex(aIndex, &rv, &entry)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
RefPtr<SHEntryChild> child;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
child = SHEntryChild::GetOrCreate(entry);
|
||||
}
|
||||
child.forget(aResult);
|
||||
return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aResult = entry ? do_AddRef(entry->ToSHEntryChild()).take() : nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -245,14 +244,14 @@ NS_IMETHODIMP
|
|||
SHistoryChild::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aBFEntry) {
|
||||
SHEntryChildShared* shared = static_cast<SHEntryChildShared*>(aBFEntry);
|
||||
|
||||
MaybeNewPSHEntry entry;
|
||||
RefPtr<CrossProcessSHEntry> entry;
|
||||
int32_t index;
|
||||
if (!SendFindEntryForBFCache(shared->GetID(), false, &entry, &index)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<SHEntryChild> shEntry = SHEntryChild::GetOrCreate(entry);
|
||||
if (shEntry) {
|
||||
RefPtr<SHEntryChild> shEntry;
|
||||
if (entry && (shEntry = entry->ToSHEntryChild())) {
|
||||
shEntry->EvictContentViewer();
|
||||
SendEvict(nsTArray<PSHEntryChild*>({shEntry.get()}));
|
||||
}
|
||||
|
@ -262,7 +261,7 @@ SHistoryChild::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aBFEntry) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
SHistoryChild::EvictAllContentViewers(void) {
|
||||
nsTArray<MaybeNewPSHEntry> entries;
|
||||
nsTArray<RefPtr<CrossProcessSHEntry>> entries;
|
||||
if (!SendGetAllEntries(&entries)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -270,8 +269,8 @@ SHistoryChild::EvictAllContentViewers(void) {
|
|||
// Keep a strong reference to all the entries, we're going to send the array
|
||||
// back to the parent!
|
||||
nsTArray<RefPtr<SHEntryChild>> shEntries(entries.Length());
|
||||
for (MaybeNewPSHEntry& entry : entries) {
|
||||
RefPtr<SHEntryChild> shEntry = SHEntryChild::GetOrCreate(entry);
|
||||
for (RefPtr<CrossProcessSHEntry>& entry : entries) {
|
||||
RefPtr<SHEntryChild> shEntry = entry->ToSHEntryChild();
|
||||
shEntry->EvictContentViewer();
|
||||
shEntries.AppendElement(shEntry.forget());
|
||||
}
|
||||
|
@ -318,7 +317,7 @@ SHistoryChild::EnsureCorrectEntryAtCurrIndex(nsISHEntry* aEntry) {
|
|||
|
||||
NS_IMETHODIMP_(void)
|
||||
SHistoryChild::RemoveDynEntriesForBFCacheEntry(nsIBFCacheEntry* aBFEntry) {
|
||||
MaybeNewPSHEntry entry;
|
||||
RefPtr<CrossProcessSHEntry> entry;
|
||||
int32_t index;
|
||||
if (!SendFindEntryForBFCache(
|
||||
static_cast<SHEntryChildShared*>(aBFEntry)->GetID(), true, &entry,
|
||||
|
@ -326,8 +325,8 @@ SHistoryChild::RemoveDynEntriesForBFCacheEntry(nsIBFCacheEntry* aBFEntry) {
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<SHEntryChild> shEntry = SHEntryChild::GetOrCreate(entry);
|
||||
if (shEntry) {
|
||||
RefPtr<SHEntryChild> shEntry;
|
||||
if (entry && (shEntry = entry->ToSHEntryChild())) {
|
||||
RemoveDynEntries(index, shEntry);
|
||||
}
|
||||
}
|
||||
|
@ -364,7 +363,10 @@ nsresult SHistoryChild::LoadURI(LoadSHEntryData& aLoadData) {
|
|||
nsCOMPtr<nsIDocShell> docShell = aLoadData.browsingContext()->GetDocShell();
|
||||
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
|
||||
|
||||
RefPtr<SHEntryChild> entry = SHEntryChild::GetOrCreate(aLoadData.shEntry());
|
||||
RefPtr<SHEntryChild> entry;
|
||||
if (aLoadData.shEntry()) {
|
||||
entry = aLoadData.shEntry()->ToSHEntryChild();
|
||||
}
|
||||
|
||||
// FIXME Should this be sent through IPC?
|
||||
aLoadData.loadState()->SetSHEntry(entry);
|
||||
|
|
|
@ -27,11 +27,9 @@ static void FillInLoadResult(PContentParent* aManager, nsresult aRv,
|
|||
const nsSHistory::LoadEntryResult& aLoadResult,
|
||||
LoadSHEntryResult* aResult) {
|
||||
if (NS_SUCCEEDED(aRv)) {
|
||||
MaybeNewPSHEntry entry;
|
||||
static_cast<LegacySHEntry*>(aLoadResult.mLoadState->SHEntry())
|
||||
->GetOrCreateActor(aManager, entry);
|
||||
*aResult = LoadSHEntryData(std::move(entry), aLoadResult.mBrowsingContext,
|
||||
aLoadResult.mLoadState);
|
||||
*aResult = LoadSHEntryData(
|
||||
static_cast<LegacySHEntry*>(aLoadResult.mLoadState->SHEntry()),
|
||||
aLoadResult.mBrowsingContext, aLoadResult.mLoadState);
|
||||
} else {
|
||||
*aResult = aRv;
|
||||
}
|
||||
|
@ -67,10 +65,10 @@ bool SHistoryParent::RecvInternalSetRequestedIndex(int32_t aIndex) {
|
|||
}
|
||||
|
||||
bool SHistoryParent::RecvGetEntryAtIndex(int32_t aIndex, nsresult* aResult,
|
||||
MaybeNewPSHEntry* aEntry) {
|
||||
RefPtr<CrossProcessSHEntry>* aEntry) {
|
||||
nsCOMPtr<nsISHEntry> entry;
|
||||
*aResult = mHistory->GetEntryAtIndex(aIndex, getter_AddRefs(entry));
|
||||
SHEntryParent::GetOrCreate(Manager(), entry, *aEntry);
|
||||
*aEntry = entry.forget().downcast<LegacySHEntry>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -83,11 +81,9 @@ bool SHistoryParent::RecvReloadCurrentEntry(LoadSHEntryResult* aLoadResult) {
|
|||
nsSHistory::LoadEntryResult loadResult;
|
||||
nsresult rv = mHistory->ReloadCurrentEntry(loadResult);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MaybeNewPSHEntry entry;
|
||||
SHEntryParent::GetOrCreate(Manager(), loadResult.mLoadState->SHEntry(),
|
||||
entry);
|
||||
*aLoadResult = LoadSHEntryData(
|
||||
std::move(entry), loadResult.mBrowsingContext, loadResult.mLoadState);
|
||||
static_cast<LegacySHEntry*>(loadResult.mLoadState->SHEntry()),
|
||||
loadResult.mBrowsingContext, loadResult.mLoadState);
|
||||
} else {
|
||||
*aLoadResult = rv;
|
||||
}
|
||||
|
@ -185,21 +181,20 @@ bool SHistoryParent::RecvReload(const uint32_t& aReloadFlags,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SHistoryParent::RecvGetAllEntries(nsTArray<MaybeNewPSHEntry>* aEntries) {
|
||||
bool SHistoryParent::RecvGetAllEntries(
|
||||
nsTArray<RefPtr<CrossProcessSHEntry>>* aEntries) {
|
||||
nsTArray<nsCOMPtr<nsISHEntry>>& entries = mHistory->Entries();
|
||||
uint32_t length = entries.Length();
|
||||
aEntries->AppendElements(length);
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
SHEntryParent::GetOrCreate(Manager(), entries[i].get(),
|
||||
aEntries->ElementAt(i));
|
||||
aEntries->ElementAt(i) = static_cast<LegacySHEntry*>(entries[i].get());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SHistoryParent::RecvFindEntryForBFCache(const uint64_t& aSharedID,
|
||||
const bool& aIncludeCurrentEntry,
|
||||
MaybeNewPSHEntry* aEntry,
|
||||
int32_t* aIndex) {
|
||||
bool SHistoryParent::RecvFindEntryForBFCache(
|
||||
const uint64_t& aSharedID, const bool& aIncludeCurrentEntry,
|
||||
RefPtr<CrossProcessSHEntry>* aEntry, int32_t* aIndex) {
|
||||
int32_t currentIndex;
|
||||
mHistory->GetIndex(¤tIndex);
|
||||
int32_t startSafeIndex, endSafeIndex;
|
||||
|
@ -209,20 +204,20 @@ bool SHistoryParent::RecvFindEntryForBFCache(const uint64_t& aSharedID,
|
|||
nsresult rv = mHistory->GetEntryAtIndex(i, getter_AddRefs(entry));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
if (static_cast<LegacySHEntry*>(entry.get())->GetSharedStateID() ==
|
||||
aSharedID) {
|
||||
RefPtr<LegacySHEntry> shEntry = entry.forget().downcast<LegacySHEntry>();
|
||||
if (shEntry->GetSharedStateID() == aSharedID) {
|
||||
if (!aIncludeCurrentEntry && i == currentIndex) {
|
||||
*aEntry = (PSHEntryParent*)nullptr;
|
||||
*aEntry = nullptr;
|
||||
*aIndex = -1;
|
||||
} else {
|
||||
SHEntryParent::GetOrCreate(Manager(), entry, *aEntry);
|
||||
*aEntry = shEntry.forget();
|
||||
*aIndex = i;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*aEntry = (PSHEntryParent*)nullptr;
|
||||
*aEntry = nullptr;
|
||||
*aIndex = -1;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ class SHistoryParent final : public PSHistoryParent {
|
|||
bool RecvGetRequestedIndex(int32_t* aIndex);
|
||||
bool RecvInternalSetRequestedIndex(int32_t aIndex);
|
||||
bool RecvGetEntryAtIndex(int32_t aIndex, nsresult* aResult,
|
||||
MaybeNewPSHEntry* aEntry);
|
||||
RefPtr<CrossProcessSHEntry>* aEntry);
|
||||
bool RecvPurgeHistory(int32_t aNumEntries, nsresult* aResult);
|
||||
bool RecvReloadCurrentEntry(LoadSHEntryResult* aLoadResult);
|
||||
bool RecvGotoIndex(int32_t aIndex, LoadSHEntryResult* aLoadResult);
|
||||
|
@ -73,10 +73,11 @@ class SHistoryParent final : public PSHistoryParent {
|
|||
bool* aDidRemove);
|
||||
bool RecvRemoveFrameEntries(PSHEntryParent* aEntry);
|
||||
bool RecvReload(const uint32_t& aReloadFlags, LoadSHEntryResult* aLoadResult);
|
||||
bool RecvGetAllEntries(nsTArray<MaybeNewPSHEntry>* aEntries);
|
||||
bool RecvGetAllEntries(nsTArray<RefPtr<CrossProcessSHEntry>>* aEntries);
|
||||
bool RecvFindEntryForBFCache(const uint64_t& aSharedID,
|
||||
const bool& aIncludeCurrentEntry,
|
||||
MaybeNewPSHEntry* aEntry, int32_t* aIndex);
|
||||
RefPtr<CrossProcessSHEntry>* aEntry,
|
||||
int32_t* aIndex);
|
||||
bool RecvEvict(nsTArray<PSHEntryParent*>&& aEntries);
|
||||
bool RecvEnsureCorrectEntryAtCurrIndex(PSHEntryParent* aEntry);
|
||||
bool RecvEvictContentViewersOrReplaceEntry(PSHEntryParent* aNewSHEntry,
|
||||
|
|
|
@ -14,7 +14,6 @@ XPIDL_SOURCES += [
|
|||
XPIDL_MODULE = 'shistory'
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'NewPSHEntry.ipdlh',
|
||||
'PSHEntry.ipdl',
|
||||
'PSHistory.ipdl',
|
||||
]
|
||||
|
@ -27,6 +26,7 @@ EXPORTS += [
|
|||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'ChildSHistory.h',
|
||||
'MaybeNewPSHEntry.h',
|
||||
'ParentSHistory.h',
|
||||
'SHEntryChild.h',
|
||||
'SHEntryParent.h',
|
||||
|
@ -36,6 +36,7 @@ EXPORTS.mozilla.dom += [
|
|||
|
||||
UNIFIED_SOURCES += [
|
||||
'ChildSHistory.cpp',
|
||||
'MaybeNewPSHEntry.cpp',
|
||||
'nsSHEntry.cpp',
|
||||
'nsSHEntryShared.cpp',
|
||||
'nsSHistory.cpp',
|
||||
|
|
|
@ -66,7 +66,6 @@ include ClientIPCTypes;
|
|||
include HangTypes;
|
||||
include PrefsTypes;
|
||||
include NeckoChannelParams;
|
||||
include NewPSHEntry;
|
||||
|
||||
#if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
|
||||
include protocol PSandboxTesting;
|
||||
|
@ -332,6 +331,12 @@ struct PostMessageData
|
|||
bool isFromPrivateWindow;
|
||||
};
|
||||
|
||||
union PSHEntryOrSharedID
|
||||
{
|
||||
PSHEntry;
|
||||
uint64_t;
|
||||
};
|
||||
|
||||
/**
|
||||
* The PContent protocol is a top-level protocol between the UI process
|
||||
* and a content process. There is exactly one PContentParent/PContentChild pair
|
||||
|
|
Загрузка…
Ссылка в новой задаче