Commit 8d21faa4 authored by Joe Mason's avatar Joe Mason Committed by Chromium LUCI CQ

[PM] Add WebMeasureMemorySecurityChecker

Adds a browser-side security check that the frame making a
performance.measureMemory request is allowed to use the API, to guard
against compromised renderers skipping the renderer-side security check.
Currently it only checks that the frame is same-origin with the page's
main frame. Once an accessor for crossOriginIsolated status is added on
the browser side, the class can check that too.

R=fdoray

Bug: 1085129
Change-Id: I73b1955dafa0dec248e86783aee4e8d8e4cdcda1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2588249Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Commit-Queue: Joe Mason <joenotcharles@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837160}
parent 4e01bd27
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "components/performance_manager/graph/process_node_impl.h" #include "components/performance_manager/graph/process_node_impl.h"
#include "components/performance_manager/graph/worker_node_impl.h" #include "components/performance_manager/graph/worker_node_impl.h"
#include "components/performance_manager/public/v8_memory/web_memory.h" #include "components/performance_manager/public/v8_memory/web_memory.h"
#include "third_party/blink/public/common/features.h"
namespace performance_manager { namespace performance_manager {
...@@ -684,9 +683,9 @@ void FrameNodeImpl::DocumentProperties::Reset(FrameNodeImpl* frame_node, ...@@ -684,9 +683,9 @@ void FrameNodeImpl::DocumentProperties::Reset(FrameNodeImpl* frame_node,
void FrameNodeImpl::OnWebMemoryMeasurementRequested( void FrameNodeImpl::OnWebMemoryMeasurementRequested(
mojom::WebMemoryMeasurement::Mode mode, mojom::WebMemoryMeasurement::Mode mode,
OnWebMemoryMeasurementRequestedCallback callback) { OnWebMemoryMeasurementRequestedCallback callback) {
CHECK(base::FeatureList::IsEnabled( v8_memory::WebMeasureMemory(
blink::features::kWebMeasureMemoryViaPerformanceManager)); this, mode, v8_memory::WebMeasureMemorySecurityChecker::Create(),
v8_memory::WebMeasureMemory(this, mode, std::move(callback)); std::move(callback), mojo::GetBadMessageCallback());
} }
} // namespace performance_manager } // namespace performance_manager
...@@ -19,12 +19,43 @@ class FrameNode; ...@@ -19,12 +19,43 @@ class FrameNode;
namespace v8_memory { namespace v8_memory {
// Implements mojom::DocumentCoordinationUnit::OnWebMemoryMeasurementRequest. // Verifies that a frame is allowed to call WebMeasureMemory.
// Measures memory usage of each frame in the browsing context group of the //
// given frame and invokes the given callback with the result. // The production implementation repeats the checks in the
void WebMeasureMemory(const FrameNode*, // performance.measureMemory spec (see the comments on WebMeasureMemory for the
mojom::WebMemoryMeasurement::Mode, // link and version). These checks are performed first on the renderer side but
base::OnceCallback<void(mojom::WebMemoryMeasurementPtr)>); // repeated in the browser to guard against a compromised renderer invoking
// performance.measureMemory without them.
class WebMeasureMemorySecurityChecker {
public:
virtual ~WebMeasureMemorySecurityChecker() = default;
// Creates a WebMeasureMemorySecurityChecker for production use.
static std::unique_ptr<WebMeasureMemorySecurityChecker> Create();
// Invokes |measure_memory_closure| on the PM sequence if |frame| is allowed
// to call WebMeasureMemory, |bad_message_callback| otherwise.
virtual void CheckMeasureMemoryIsAllowed(
const FrameNode* frame,
base::OnceClosure measure_memory_closure,
mojo::ReportBadMessageCallback bad_message_callback) const = 0;
};
// Implements mojom::DocumentCoordinationUnit::OnWebMemoryMeasurementRequest to
// perform a memory measurement as defined in the performance.measureMemory
// spec at https://wicg.github.io/performance-measure-memory (this
// implementation targets the draft of 20 October 2020.)
//
// Verifies that |frame_node| is allowed to measure memory using
// |security_checker|. If so, measures memory usage of each frame in
// |frame_node|'s browsing context group and invokes |result_callback| with the
// result; if not, invokes |bad_message_callback|.
void WebMeasureMemory(
const FrameNode* frame_node,
mojom::WebMemoryMeasurement::Mode mode,
std::unique_ptr<WebMeasureMemorySecurityChecker> security_checker,
base::OnceCallback<void(mojom::WebMemoryMeasurementPtr)> result_callback,
mojo::ReportBadMessageCallback bad_message_callback);
} // namespace v8_memory } // namespace v8_memory
......
...@@ -88,6 +88,8 @@ WebMemoryAggregator::~WebMemoryAggregator() = default; ...@@ -88,6 +88,8 @@ WebMemoryAggregator::~WebMemoryAggregator() = default;
WebMemoryAggregator::NodeAggregationType WebMemoryAggregator::NodeAggregationType
WebMemoryAggregator::FindNodeAggregationType(const FrameNode* frame_node) { WebMemoryAggregator::FindNodeAggregationType(const FrameNode* frame_node) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
auto* node = frame_node; auto* node = frame_node;
while (node && node != aggregation_start_node_) { while (node && node != aggregation_start_node_) {
...@@ -126,6 +128,7 @@ WebMemoryAggregator::FindNodeAggregationType(const FrameNode* frame_node) { ...@@ -126,6 +128,7 @@ WebMemoryAggregator::FindNodeAggregationType(const FrameNode* frame_node) {
mojom::WebMemoryMeasurementPtr mojom::WebMemoryMeasurementPtr
WebMemoryAggregator::AggregateMeasureMemoryResult() { WebMemoryAggregator::AggregateMeasureMemoryResult() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
aggregation_result_ = mojom::WebMemoryMeasurement::New(); aggregation_result_ = mojom::WebMemoryMeasurement::New();
VisitFrame(nullptr, aggregation_start_node_); VisitFrame(nullptr, aggregation_start_node_);
...@@ -141,6 +144,7 @@ WebMemoryAggregator::AggregateMeasureMemoryResult() { ...@@ -141,6 +144,7 @@ WebMemoryAggregator::AggregateMeasureMemoryResult() {
bool WebMemoryAggregator::VisitFrame( bool WebMemoryAggregator::VisitFrame(
mojom::WebMemoryBreakdownEntry* enclosing_aggregation_point, mojom::WebMemoryBreakdownEntry* enclosing_aggregation_point,
const FrameNode* frame_node) { const FrameNode* frame_node) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(aggregation_result_); DCHECK(aggregation_result_);
DCHECK(enclosing_aggregation_point || frame_node == aggregation_start_node_); DCHECK(enclosing_aggregation_point || frame_node == aggregation_start_node_);
DCHECK(frame_node); DCHECK(frame_node);
...@@ -224,6 +228,7 @@ bool WebMemoryAggregator::VisitFrame( ...@@ -224,6 +228,7 @@ bool WebMemoryAggregator::VisitFrame(
bool WebMemoryAggregator::VisitOpenedPage( bool WebMemoryAggregator::VisitOpenedPage(
mojom::WebMemoryBreakdownEntry* enclosing_aggregation_point, mojom::WebMemoryBreakdownEntry* enclosing_aggregation_point,
const PageNode* page_node) { const PageNode* page_node) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (ShouldFollowOpenerLink(page_node)) { if (ShouldFollowOpenerLink(page_node)) {
// Visit only the "current" main frame instead of all of the main frames // Visit only the "current" main frame instead of all of the main frames
// (non-current ones are either about to die, or represent an ongoing // (non-current ones are either about to die, or represent an ongoing
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string> #include <string>
#include "base/optional.h" #include "base/optional.h"
#include "base/sequence_checker.h"
#include "components/performance_manager/public/mojom/web_memory.mojom.h" #include "components/performance_manager/public/mojom/web_memory.mojom.h"
#include "url/origin.h" #include "url/origin.h"
...@@ -19,9 +20,9 @@ class PageNode; ...@@ -19,9 +20,9 @@ class PageNode;
namespace v8_memory { namespace v8_memory {
// Traverses the graph of execution contexts to find the results of the last // Traverses the graph of execution contexts to find the results of the last
// memory measurement and aggregates them according to the rules defined in // memory measurement and aggregates them according to the rules defined in the
// https://wicg.github.io/performance-measure-memory. (This implements the // performance.measureMemory spec. (See public/v8_memory/web_memory.h for the
// draft of 20 October 2020.) // link and spec version.)
class WebMemoryAggregator { class WebMemoryAggregator {
public: public:
// Constructs an aggregator for the results of a memory request from // Constructs an aggregator for the results of a memory request from
...@@ -94,7 +95,10 @@ class WebMemoryAggregator { ...@@ -94,7 +95,10 @@ class WebMemoryAggregator {
// Stores the result of the aggregation. This is populated by // Stores the result of the aggregation. This is populated by
// AggregateMeasureMemoryResult. // AggregateMeasureMemoryResult.
mojom::WebMemoryMeasurementPtr aggregation_result_; mojom::WebMemoryMeasurementPtr aggregation_result_
GUARDED_BY_CONTEXT(sequence_checker_);
SEQUENCE_CHECKER(sequence_checker_);
}; };
namespace internal { namespace internal {
......
...@@ -10,9 +10,13 @@ ...@@ -10,9 +10,13 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/check.h" #include "base/check.h"
#include "base/memory/ptr_util.h"
#include "components/performance_manager/public/graph/frame_node.h" #include "components/performance_manager/public/graph/frame_node.h"
#include "components/performance_manager/public/graph/graph.h"
#include "components/performance_manager/public/graph/page_node.h"
#include "components/performance_manager/public/graph/process_node.h" #include "components/performance_manager/public/graph/process_node.h"
#include "components/performance_manager/public/v8_memory/web_memory.h" #include "components/performance_manager/public/v8_memory/web_memory.h"
#include "third_party/blink/public/common/features.h"
#include "url/gurl.h" #include "url/gurl.h"
#include "url/origin.h" #include "url/origin.h"
...@@ -95,6 +99,26 @@ WebMemoryMeasurer::WebMemoryMeasurer( ...@@ -95,6 +99,26 @@ WebMemoryMeasurer::WebMemoryMeasurer(
WebMemoryMeasurer::~WebMemoryMeasurer() = default; WebMemoryMeasurer::~WebMemoryMeasurer() = default;
// static
void WebMemoryMeasurer::MeasureMemory(const FrameNode* frame_node,
mojom::WebMemoryMeasurement::Mode mode,
MeasurementCallback callback) {
// Can't use make_unique with a private constructor.
auto measurer = base::WrapUnique(new WebMemoryMeasurer(
frame_node->GetFrameToken(),
WebMeasurementModeToRequestMeasurementMode(mode), std::move(callback)));
// Create a measurement complete callback to own |measurer|. It
// will be deleted when the callback is executed or dropped.
V8DetailedMemoryRequestOneShot* request = measurer->request();
auto measurement_complete_callback = base::BindOnce(
&WebMemoryMeasurer::MeasurementComplete, std::move(measurer));
// Start memory measurement for the process of the given frame.
request->StartMeasurement(frame_node->GetProcessNode(),
std::move(measurement_complete_callback));
}
void WebMemoryMeasurer::MeasurementComplete( void WebMemoryMeasurer::MeasurementComplete(
const ProcessNode* process_node, const ProcessNode* process_node,
const V8DetailedMemoryProcessData*) { const V8DetailedMemoryProcessData*) {
...@@ -103,6 +127,49 @@ void WebMemoryMeasurer::MeasurementComplete( ...@@ -103,6 +127,49 @@ void WebMemoryMeasurer::MeasurementComplete(
std::move(callback_).Run(BuildMemoryUsageResult(frame_token_, process_node)); std::move(callback_).Run(BuildMemoryUsageResult(frame_token_, process_node));
} }
////////////////////////////////////////////////////////////////////////////////
// WebMeasureMemorySecurityCheckerImpl
// Implements the public function in public/v8_memory/web_memory.h
std::unique_ptr<WebMeasureMemorySecurityChecker>
WebMeasureMemorySecurityChecker::Create() {
return std::make_unique<WebMeasureMemorySecurityCheckerImpl>();
}
void WebMeasureMemorySecurityCheckerImpl::CheckMeasureMemoryIsAllowed(
const FrameNode* frame,
base::OnceClosure measure_memory_closure,
mojo::ReportBadMessageCallback bad_message_callback) const {
DCHECK(frame);
DCHECK_ON_GRAPH_SEQUENCE(frame->GetGraph());
// TODO(crbug/1085129): The frame may have navigated since it sent the
// measureMemory request. We could return true if the new document is allowed
// to measure memory, but the actual document that sent the request is not.
// If that happens the DocumentCoordinationUnit mojo interface is reset so
// the measurement result will be thrown away, so this is not a security
// issue, but it does mean doing extra work.
if (!base::FeatureList::IsEnabled(
blink::features::kWebMeasureMemoryViaPerformanceManager)) {
std::move(bad_message_callback)
.Run("WebMeasureMemoryViaPerformanceManager feature is disabled");
return;
}
// "Memory measurement allowed" predicate from
// https://wicg.github.io/performance-measure-memory/ section 3.2.
if (url::Origin::Create(frame->GetURL()) !=
url::Origin::Create(frame->GetPageNode()->GetMainFrameNode()->GetURL())) {
std::move(bad_message_callback)
.Run("performance.measureMemory called from cross-origin subframe");
return;
}
// TODO(crbug/1085129): Check crossOriginIsolated once this is available in
// the browser. This will need to be done on the UI sequence, and return the
// result to the PM sequence to run the closure.
std::move(measure_memory_closure).Run();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Free functions // Free functions
...@@ -110,20 +177,19 @@ void WebMemoryMeasurer::MeasurementComplete( ...@@ -110,20 +177,19 @@ void WebMemoryMeasurer::MeasurementComplete(
void WebMeasureMemory( void WebMeasureMemory(
const FrameNode* frame_node, const FrameNode* frame_node,
mojom::WebMemoryMeasurement::Mode mode, mojom::WebMemoryMeasurement::Mode mode,
base::OnceCallback<void(mojom::WebMemoryMeasurementPtr)> callback) { std::unique_ptr<WebMeasureMemorySecurityChecker> security_checker,
auto measurer = std::make_unique<WebMemoryMeasurer>( base::OnceCallback<void(mojom::WebMemoryMeasurementPtr)> result_callback,
frame_node->GetFrameToken(), mojo::ReportBadMessageCallback bad_message_callback) {
WebMeasurementModeToRequestMeasurementMode(mode), std::move(callback)); DCHECK(frame_node);
DCHECK(security_checker);
// Create a measurement complete callback to own |measurer|. It
// will be deleted when the callback is executed or dropped. // Validate that |frame_node| is allowed to measure memory, then start the
V8DetailedMemoryRequestOneShot* request = measurer->request(); // measurement.
auto measurement_complete_callback = base::BindOnce( security_checker->CheckMeasureMemoryIsAllowed(
&WebMemoryMeasurer::MeasurementComplete, std::move(measurer)); frame_node,
base::BindOnce(&WebMemoryMeasurer::MeasureMemory, frame_node, mode,
// Start memory measurement for the process of the given frame. std::move(result_callback)),
request->StartMeasurement(frame_node->GetProcessNode(), std::move(bad_message_callback));
std::move(measurement_complete_callback));
} }
} // namespace v8_memory } // namespace v8_memory
......
...@@ -8,12 +8,15 @@ ...@@ -8,12 +8,15 @@
#include <memory> #include <memory>
#include "base/callback.h" #include "base/callback.h"
#include "base/sequence_checker.h"
#include "components/performance_manager/public/mojom/web_memory.mojom.h" #include "components/performance_manager/public/mojom/web_memory.mojom.h"
#include "components/performance_manager/public/v8_memory/v8_detailed_memory.h" #include "components/performance_manager/public/v8_memory/v8_detailed_memory.h"
#include "components/performance_manager/public/v8_memory/web_memory.h"
#include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/common/tokens/tokens.h"
namespace performance_manager { namespace performance_manager {
class FrameNode;
class ProcessNode; class ProcessNode;
namespace v8_memory { namespace v8_memory {
...@@ -28,24 +31,52 @@ class WebMemoryMeasurer { ...@@ -28,24 +31,52 @@ class WebMemoryMeasurer {
using MeasurementCallback = using MeasurementCallback =
base::OnceCallback<void(mojom::WebMemoryMeasurementPtr)>; base::OnceCallback<void(mojom::WebMemoryMeasurementPtr)>;
WebMemoryMeasurer(const blink::LocalFrameToken&, // Implements WebMeasureMemory (from public/v8_memory/web_memory.h) by
V8DetailedMemoryRequest::MeasurementMode, // instantiating a WebMemoryMeasurer.
MeasurementCallback); static void MeasureMemory(const FrameNode* frame_node,
mojom::WebMemoryMeasurement::Mode mode,
MeasurementCallback callback);
~WebMemoryMeasurer(); ~WebMemoryMeasurer();
WebMemoryMeasurer(const WebMemoryMeasurer& other) = delete; WebMemoryMeasurer(const WebMemoryMeasurer& other) = delete;
WebMemoryMeasurer& operator=(const WebMemoryMeasurer& other) = delete; WebMemoryMeasurer& operator=(const WebMemoryMeasurer& other) = delete;
V8DetailedMemoryRequestOneShot* request() const { return request_.get(); } V8DetailedMemoryRequestOneShot* request() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return request_.get();
}
// A callback for V8DetailedMemoryRequestOneShot. // A callback for V8DetailedMemoryRequestOneShot.
void MeasurementComplete(const ProcessNode*, void MeasurementComplete(const ProcessNode*,
const V8DetailedMemoryProcessData*); const V8DetailedMemoryProcessData*);
private: private:
friend class WebMemoryImplTest;
WebMemoryMeasurer(const blink::LocalFrameToken&,
V8DetailedMemoryRequest::MeasurementMode,
MeasurementCallback);
blink::LocalFrameToken frame_token_; blink::LocalFrameToken frame_token_;
MeasurementCallback callback_; MeasurementCallback callback_;
std::unique_ptr<V8DetailedMemoryRequestOneShot> request_; std::unique_ptr<V8DetailedMemoryRequestOneShot> request_
GUARDED_BY_CONTEXT(sequence_checker_);
SEQUENCE_CHECKER(sequence_checker_);
};
// The default implementation of WebMeasureMemorySecurityChecker.
class WebMeasureMemorySecurityCheckerImpl
: public WebMeasureMemorySecurityChecker {
public:
WebMeasureMemorySecurityCheckerImpl() = default;
~WebMeasureMemorySecurityCheckerImpl() override = default;
void CheckMeasureMemoryIsAllowed(
const FrameNode* frame,
base::OnceClosure measure_memory_closure,
mojo::ReportBadMessageCallback bad_message_callback) const override;
}; };
} // namespace v8_memory } // namespace v8_memory
......
...@@ -31,8 +31,6 @@ namespace performance_manager { ...@@ -31,8 +31,6 @@ namespace performance_manager {
namespace v8_memory { namespace v8_memory {
namespace {
using WebMemoryImplPMTest = V8MemoryPerformanceManagerTestHarness; using WebMemoryImplPMTest = V8MemoryPerformanceManagerTestHarness;
class WebMemoryImplTest : public WebMemoryTestHarness { class WebMemoryImplTest : public WebMemoryTestHarness {
...@@ -41,6 +39,25 @@ class WebMemoryImplTest : public WebMemoryTestHarness { ...@@ -41,6 +39,25 @@ class WebMemoryImplTest : public WebMemoryTestHarness {
base::flat_map<std::string, Bytes> expected); base::flat_map<std::string, Bytes> expected);
}; };
class FakeSecurityChecker : public WebMeasureMemorySecurityChecker {
public:
explicit FakeSecurityChecker(bool allowed) : allowed_(allowed) {}
void CheckMeasureMemoryIsAllowed(
const FrameNode* frame_node,
base::OnceClosure measure_memory_closure,
mojo::ReportBadMessageCallback bad_message_callback) const override {
if (allowed_) {
std::move(measure_memory_closure).Run();
} else {
std::move(bad_message_callback).Run("disallowed");
}
}
private:
bool allowed_;
};
void WebMemoryImplTest::MeasureAndVerify( void WebMemoryImplTest::MeasureAndVerify(
FrameNodeImpl* frame, FrameNodeImpl* frame,
base::flat_map<std::string, Bytes> expected) { base::flat_map<std::string, Bytes> expected) {
...@@ -110,6 +127,11 @@ TEST_F(WebMemoryImplPMTest, WebMeasureMemory) { ...@@ -110,6 +127,11 @@ TEST_F(WebMemoryImplPMTest, WebMeasureMemory) {
EXPECT_EQ(1001u, entry->bytes); EXPECT_EQ(1001u, entry->bytes);
run_loop.Quit(); run_loop.Quit();
}); });
auto bad_message_callback =
base::BindLambdaForTesting([&](const std::string& error) {
ADD_FAILURE() << error;
run_loop.Quit();
});
base::WeakPtr<FrameNode> frame_node_wrapper = base::WeakPtr<FrameNode> frame_node_wrapper =
PerformanceManager::GetFrameNodeForRenderFrameHost(main_frame()); PerformanceManager::GetFrameNodeForRenderFrameHost(main_frame());
...@@ -117,9 +139,10 @@ TEST_F(WebMemoryImplPMTest, WebMeasureMemory) { ...@@ -117,9 +139,10 @@ TEST_F(WebMemoryImplPMTest, WebMeasureMemory) {
FROM_HERE, base::BindLambdaForTesting([&]() { FROM_HERE, base::BindLambdaForTesting([&]() {
ASSERT_TRUE(frame_node_wrapper); ASSERT_TRUE(frame_node_wrapper);
FrameNode* frame_node = frame_node_wrapper.get(); FrameNode* frame_node = frame_node_wrapper.get();
WebMeasureMemory(frame_node, WebMeasureMemory(
mojom::WebMemoryMeasurement::Mode::kDefault, frame_node, mojom::WebMemoryMeasurement::Mode::kDefault,
std::move(measurement_callback)); std::make_unique<FakeSecurityChecker>(true),
std::move(measurement_callback), std::move(bad_message_callback));
})); }));
// Set up and bind the mock reporter. // Set up and bind the mock reporter.
...@@ -148,6 +171,8 @@ TEST_F(WebMemoryImplPMTest, MeasurementInterrupted) { ...@@ -148,6 +171,8 @@ TEST_F(WebMemoryImplPMTest, MeasurementInterrupted) {
base::BindOnce([](mojom::WebMemoryMeasurementPtr result) { base::BindOnce([](mojom::WebMemoryMeasurementPtr result) {
FAIL() << "Measurement callback ran unexpectedly"; FAIL() << "Measurement callback ran unexpectedly";
}); });
auto bad_message_callback =
base::BindOnce([](const std::string& error) { FAIL() << error; });
base::WeakPtr<FrameNode> frame_node_wrapper = base::WeakPtr<FrameNode> frame_node_wrapper =
PerformanceManager::GetFrameNodeForRenderFrameHost(child_frame()); PerformanceManager::GetFrameNodeForRenderFrameHost(child_frame());
...@@ -155,9 +180,10 @@ TEST_F(WebMemoryImplPMTest, MeasurementInterrupted) { ...@@ -155,9 +180,10 @@ TEST_F(WebMemoryImplPMTest, MeasurementInterrupted) {
FROM_HERE, base::BindLambdaForTesting([&]() { FROM_HERE, base::BindLambdaForTesting([&]() {
ASSERT_TRUE(frame_node_wrapper); ASSERT_TRUE(frame_node_wrapper);
FrameNode* frame_node = frame_node_wrapper.get(); FrameNode* frame_node = frame_node_wrapper.get();
WebMeasureMemory(frame_node, WebMeasureMemory(
mojom::WebMemoryMeasurement::Mode::kDefault, frame_node, mojom::WebMemoryMeasurement::Mode::kDefault,
std::move(measurement_callback)); std::make_unique<FakeSecurityChecker>(true),
std::move(measurement_callback), std::move(bad_message_callback));
})); }));
// Set up and bind the mock reporter. // Set up and bind the mock reporter.
...@@ -183,7 +209,35 @@ TEST_F(WebMemoryImplPMTest, MeasurementInterrupted) { ...@@ -183,7 +209,35 @@ TEST_F(WebMemoryImplPMTest, MeasurementInterrupted) {
task_environment()->FastForwardBy(base::TimeDelta::FromSeconds(5)); task_environment()->FastForwardBy(base::TimeDelta::FromSeconds(5));
} }
} // namespace TEST_F(WebMemoryImplPMTest, MeasurementDisallowed) {
// Call WebMeasureMemory on the performance manager sequence but expect the
// mojo ReportBadMessage callback to be called.
base::RunLoop run_loop;
auto measurement_callback =
base::BindLambdaForTesting([&](mojom::WebMemoryMeasurementPtr result) {
ADD_FAILURE() << "Measurement callback ran unexpectedly.";
run_loop.Quit();
});
auto bad_message_callback =
base::BindLambdaForTesting([&](const std::string& error) {
SUCCEED() << error;
run_loop.Quit();
});
base::WeakPtr<FrameNode> frame_node_wrapper =
PerformanceManager::GetFrameNodeForRenderFrameHost(main_frame());
PerformanceManager::CallOnGraph(
FROM_HERE, base::BindLambdaForTesting([&]() {
ASSERT_TRUE(frame_node_wrapper);
FrameNode* frame_node = frame_node_wrapper.get();
WebMeasureMemory(
frame_node, mojom::WebMemoryMeasurement::Mode::kDefault,
std::make_unique<FakeSecurityChecker>(false),
std::move(measurement_callback), std::move(bad_message_callback));
}));
run_loop.Run();
}
} // namespace v8_memory } // namespace v8_memory
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment