Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(598)

Unified Diff: content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc

Issue 2927173002: Prevent CompositingHelper from prematurely Satisfying Surface reference (Closed)
Patch Set: Release a pending sequence if new one received Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | content/renderer/child_frame_compositing_helper.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc b/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc
index d03ebb4b4ca4b8218e28e9e750a887a4ae87ea9f..b572962db33406facabcff433ae1b33bd33ea433 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc
+++ b/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc
@@ -3,8 +3,11 @@
// found in the LICENSE file.
#include "base/macros.h"
+#include "cc/surfaces/surface_id.h"
+#include "cc/surfaces/surface_sequence.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -114,4 +117,92 @@ IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest,
EXPECT_EQ(gfx::Size(75, 75), rwhv->GetVisibleViewportSize());
}
+// A class to filter RequireSequence and SatisfySequence messages sent from
+// an embedding renderer for its child's Surfaces.
+class SurfaceRefMessageFilter : public BrowserMessageFilter {
+ public:
+ SurfaceRefMessageFilter()
+ : BrowserMessageFilter(FrameMsgStart),
+ require_message_loop_runner_(new content::MessageLoopRunner),
+ satisfy_message_loop_runner_(new content::MessageLoopRunner),
+ satisfy_received_(false),
+ require_received_first_(false) {}
+
+ void WaitForRequire() { require_message_loop_runner_->Run(); }
+
+ void WaitForSatisfy() { satisfy_message_loop_runner_->Run(); }
+
+ bool require_received_first() { return require_received_first_; }
+
+ protected:
+ ~SurfaceRefMessageFilter() override {}
+
+ private:
+ // BrowserMessageFilter:
+ bool OnMessageReceived(const IPC::Message& message) override {
+ IPC_BEGIN_MESSAGE_MAP(SurfaceRefMessageFilter, message)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_RequireSequence, OnRequire)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_SatisfySequence, OnSatisfy)
+ IPC_END_MESSAGE_MAP()
+ return false;
+ }
+
+ void OnRequire(const cc::SurfaceId& id, const cc::SurfaceSequence sequence) {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&SurfaceRefMessageFilter::OnRequireOnUI, this));
+ }
+
+ void OnRequireOnUI() {
+ if (!satisfy_received_)
+ require_received_first_ = true;
+ require_message_loop_runner_->Quit();
+ }
+
+ void OnSatisfy(const cc::SurfaceSequence sequence) {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&SurfaceRefMessageFilter::OnSatisfyOnUI, this));
+ }
+
+ void OnSatisfyOnUI() {
+ satisfy_received_ = true;
+ satisfy_message_loop_runner_->Quit();
+ }
+
+ scoped_refptr<content::MessageLoopRunner> require_message_loop_runner_;
+ scoped_refptr<content::MessageLoopRunner> satisfy_message_loop_runner_;
+ bool satisfy_received_;
+ bool require_received_first_;
+
+ DISALLOW_COPY_AND_ASSIGN(SurfaceRefMessageFilter);
+};
+
+// Test that when a child frame submits its first compositor frame, the
+// embedding renderer process properly acquires and releases references to the
+// new Surface. See https://crbug.com/701175.
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest,
+ ChildFrameSurfaceReference) {
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(a)")));
+
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ ASSERT_EQ(1U, root->child_count());
+
+ scoped_refptr<SurfaceRefMessageFilter> filter = new SurfaceRefMessageFilter();
+ root->current_frame_host()->GetProcess()->AddFilter(filter.get());
+
+ GURL foo_url = embedded_test_server()->GetURL("foo.com", "/title1.html");
+ NavigateFrameToURL(root->child_at(0), foo_url);
+
+ // If one of these messages isn't received, this test times out.
+ filter->WaitForRequire();
+ filter->WaitForSatisfy();
+
+ EXPECT_TRUE(filter->require_received_first());
+}
+
} // namespace content
« no previous file with comments | « no previous file | content/renderer/child_frame_compositing_helper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698