blob: 3055d687afc1a9316c94d11c833dc788b3d053d6 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/performance_manager/public/web_contents_proxy.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/test/bind_test_util.h"
#include "chrome/browser/performance_manager/graph/page_node_impl.h"
#include "chrome/browser/performance_manager/performance_manager_tab_helper.h"
#include "chrome/browser/performance_manager/performance_manager_test_harness.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace performance_manager {
class WebContentsProxyTest : public PerformanceManagerTestHarness {
public:
WebContentsProxyTest() {}
~WebContentsProxyTest() override {}
void GetContentsViaProxy(bool delete_before_deref);
private:
DISALLOW_COPY_AND_ASSIGN(WebContentsProxyTest);
};
TEST_F(WebContentsProxyTest, EndToEnd) {
std::unique_ptr<content::WebContents> contents = CreateTestWebContents();
auto* helper = PerformanceManagerTabHelper::FromWebContents(contents.get());
auto* page_node = helper->page_node();
content::WebContents* proxy_contents = nullptr;
auto deref_proxy = base::BindLambdaForTesting(
[&proxy_contents](const WebContentsProxy& proxy,
base::OnceClosure quit_loop) {
proxy_contents = proxy.Get();
std::move(quit_loop).Run();
});
// Bounce over to the PM sequence, retrieve the proxy, bounce back to the UI
// thread, dereference it if possible, and save the returned contents. To be
// fair, it's entirely valid to grab the weak pointer directly on the UI
// thread, as the lifetime of the page node is managed their and the property
// being accessed is thread safe. However, this test aims to simulate what
// would happen with a policy message being posted from the graph.
{
base::RunLoop run_loop;
PerformanceManager::GetInstance()->CallOnGraph(
FROM_HERE,
base::BindLambdaForTesting(
[&deref_proxy, page_node,
quit_loop = run_loop.QuitClosure()](GraphImpl* graph) {
base::PostTask(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(deref_proxy, page_node->contents_proxy(),
std::move(quit_loop)));
}));
run_loop.Run();
EXPECT_EQ(contents.get(), proxy_contents);
}
// Run the same test, but this time destroy the contents prior to
// dereferencing the proxy.
{
base::RunLoop run_loop;
PerformanceManager::GetInstance()->CallOnGraph(
FROM_HERE,
base::BindLambdaForTesting([&contents, &deref_proxy, page_node,
quit_loop = run_loop.QuitClosure()](
GraphImpl* graph) {
base::PostTask(
FROM_HERE, {content::BrowserThread::UI},
base::BindLambdaForTesting([&contents]() { contents.reset(); }));
base::PostTask(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(deref_proxy, page_node->contents_proxy(),
std::move(quit_loop)));
}));
run_loop.Run();
// The contents was destroyed on the UI thread prior to dereferencing the
// proxy, so it should return nullptr.
EXPECT_FALSE(proxy_contents);
}
}
} // namespace performance_manager