[performance_manager] Add an operation for visiting a page and its embeds
Introduce GraphOperations::VisitPageAndEmbedsPreOrder to run a visitor for a PageNode and all PageNodes embedded within it. This is useful for scenarios such as guest views, where one WebContents embeds another. Bug: 40925658 AX-Relnotes: n/a. Change-Id: I212a1e98de890e5d3675b2eeee698034dfa2ec0e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5352066 Reviewed-by: Joe Mason <joenotcharles@google.com> Commit-Queue: Greg Thompson <grt@chromium.org> Cr-Commit-Position: refs/heads/main@{#1341520}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
e9d9076646
commit
17d11552de
components/performance_manager
@ -166,6 +166,31 @@ bool GraphImplOperations::VisitFrameTreePostOrder(
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool GraphImplOperations::VisitPageAndEmbedsPreOrder(
|
||||
PageNodeImpl* page,
|
||||
PageNodeImplVisitor visitor) {
|
||||
if (!visitor(page)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (FrameNodeImpl* main_frame_node : page->main_frame_nodes()) {
|
||||
if (!VisitFrameAndChildrenPreOrder(
|
||||
main_frame_node, [&visitor](FrameNodeImpl* frame_node) {
|
||||
const FrameNode* const node = frame_node;
|
||||
for (const auto* page_node : node->GetEmbeddedPageNodes()) {
|
||||
if (!visitor(PageNodeImpl::FromNode(page_node))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool GraphImplOperations::HasFrame(const PageNodeImpl* page,
|
||||
FrameNodeImpl* frame) {
|
||||
|
@ -20,6 +20,7 @@ class WorkerNodeImpl;
|
||||
// graph.
|
||||
struct GraphImplOperations {
|
||||
using FrameNodeImplVisitor = base::FunctionRef<bool(FrameNodeImpl*)>;
|
||||
using PageNodeImplVisitor = base::FunctionRef<bool(PageNodeImpl*)>;
|
||||
using WorkerNodeImplVisitor = base::FunctionRef<bool(WorkerNodeImpl*)>;
|
||||
|
||||
// Returns the collection of page nodes that are associated with the given
|
||||
@ -59,6 +60,12 @@ struct GraphImplOperations {
|
||||
static bool VisitFrameTreePostOrder(const PageNodeImpl* page,
|
||||
FrameNodeImplVisitor visitor);
|
||||
|
||||
// Traverses the tree of embedded pages rooted at `page`, invoking `visitor`
|
||||
// for each page node. Returns false if `visitor` returns false (stopping the
|
||||
// traversal at that point); otherwise, returns `true`.
|
||||
static bool VisitPageAndEmbedsPreOrder(PageNodeImpl* page,
|
||||
PageNodeImplVisitor visitor);
|
||||
|
||||
// Returns true if the given |frame| is in the frame tree associated with the
|
||||
// given |page|.
|
||||
static bool HasFrame(const PageNodeImpl* page, FrameNodeImpl* frame);
|
||||
|
@ -57,6 +57,14 @@ bool GraphOperations::VisitFrameTreePostOrder(const PageNode* page,
|
||||
});
|
||||
}
|
||||
|
||||
// static
|
||||
bool GraphOperations::VisitPageAndEmbedsPreOrder(const PageNode* page,
|
||||
PageNodeVisitor visitor) {
|
||||
return GraphImplOperations::VisitPageAndEmbedsPreOrder(
|
||||
PageNodeImpl::FromNode(page),
|
||||
[&visitor](PageNodeImpl* page_impl) { return visitor(page_impl); });
|
||||
}
|
||||
|
||||
// static
|
||||
bool GraphOperations::HasFrame(const PageNode* page, const FrameNode* frame) {
|
||||
return GraphImplOperations::HasFrame(PageNodeImpl::FromNode(page),
|
||||
|
@ -26,6 +26,7 @@ class GraphOperationsTest : public GraphTestHarness {
|
||||
process2_ = CreateNode<ProcessNodeImpl>();
|
||||
page1_ = CreateNode<PageNodeImpl>();
|
||||
page2_ = CreateNode<PageNodeImpl>();
|
||||
page3_ = CreateNode<PageNodeImpl>();
|
||||
mainframe1_ = CreateFrameNodeAutoId(process1_.get(), page1_.get(), nullptr);
|
||||
mainframe2_ = CreateFrameNodeAutoId(process2_.get(), page2_.get(), nullptr);
|
||||
childframe1a_ =
|
||||
@ -36,12 +37,15 @@ class GraphOperationsTest : public GraphTestHarness {
|
||||
CreateFrameNodeAutoId(process1_.get(), page2_.get(), mainframe2_.get());
|
||||
childframe2b_ =
|
||||
CreateFrameNodeAutoId(process1_.get(), page2_.get(), mainframe2_.get());
|
||||
page3_->SetEmbedderFrameNodeAndEmbeddingType(
|
||||
mainframe1_.get(), PageNode::EmbeddingType::kGuestView);
|
||||
}
|
||||
|
||||
TestNodeWrapper<ProcessNodeImpl> process1_;
|
||||
TestNodeWrapper<ProcessNodeImpl> process2_;
|
||||
TestNodeWrapper<PageNodeImpl> page1_;
|
||||
TestNodeWrapper<PageNodeImpl> page2_;
|
||||
TestNodeWrapper<PageNodeImpl> page3_; // A guest of `page1_`.
|
||||
|
||||
// Root nodes. |mainframeX_| is in |processX_|.
|
||||
TestNodeWrapper<FrameNodeImpl> mainframe1_;
|
||||
@ -144,6 +148,27 @@ TEST_F(GraphOperationsTest, VisitFrameTree) {
|
||||
EXPECT_EQ(1u, visited.size());
|
||||
}
|
||||
|
||||
TEST_F(GraphOperationsTest, VisitPageEmbeds) {
|
||||
// Pages are visited embedder-to-embedded.
|
||||
std::vector<const PageNode*> visited;
|
||||
ASSERT_TRUE(GraphOperations::VisitPageAndEmbedsPreOrder(
|
||||
page1_.get(), [&visited](const PageNode* page_node) {
|
||||
visited.push_back(page_node);
|
||||
return true;
|
||||
}));
|
||||
EXPECT_THAT(visited, testing::ElementsAre(ToPublic(page1_.get()),
|
||||
ToPublic(page3_.get())));
|
||||
|
||||
// Stop after the first item.
|
||||
visited.clear();
|
||||
ASSERT_FALSE(GraphOperations::VisitPageAndEmbedsPreOrder(
|
||||
page1_.get(), [&visited](const PageNode* page_node) {
|
||||
visited.push_back(page_node);
|
||||
return false;
|
||||
}));
|
||||
EXPECT_THAT(visited, testing::ElementsAre(ToPublic(page1_.get())));
|
||||
}
|
||||
|
||||
TEST_F(GraphOperationsTest, HasFrame) {
|
||||
EXPECT_TRUE(GraphOperations::HasFrame(page1_.get(), childframe1a_.get()));
|
||||
EXPECT_FALSE(GraphOperations::HasFrame(page1_.get(), childframe2a_.get()));
|
||||
|
@ -19,6 +19,7 @@ class WorkerNode;
|
||||
// graph.
|
||||
struct GraphOperations {
|
||||
using FrameNodeVisitor = base::FunctionRef<bool(const FrameNode*)>;
|
||||
using PageNodeVisitor = base::FunctionRef<bool(const PageNode*)>;
|
||||
using WorkerNodeVisitor = base::FunctionRef<bool(const WorkerNode*)>;
|
||||
|
||||
// Returns the collection of page nodes that are associated with the given
|
||||
@ -47,6 +48,12 @@ struct GraphOperations {
|
||||
static bool VisitFrameTreePostOrder(const PageNode* page,
|
||||
FrameNodeVisitor visitor);
|
||||
|
||||
// Traverses the tree of embedded pages rooted at `page`, invoking `visitor`
|
||||
// for each page node. Returns false if `visitor` returns false (stopping the
|
||||
// traversal at that point); otherwise, returns `true`.
|
||||
static bool VisitPageAndEmbedsPreOrder(const PageNode* page,
|
||||
PageNodeVisitor visitor);
|
||||
|
||||
// Returns true if the given |frame| is in the frame tree associated with the
|
||||
// given |page|.
|
||||
static bool HasFrame(const PageNode* page, const FrameNode* frame);
|
||||
|
Reference in New Issue
Block a user