Commit 2a7240dd authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Chromium LUCI CQ

Improve error messages of memory measurement API

This also adds a support for the --disable-web-security flag that is
useful for local testing.

Bug: 1085129
Change-Id: Ia76fb151d6d97a141d69ecf48b17b172513d5225
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2629509Reviewed-by: default avatarJoe Mason <joenotcharles@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843628}
parent 07a3b281
......@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/check.h"
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "components/performance_manager/public/graph/frame_node.h"
#include "components/performance_manager/public/graph/graph.h"
......@@ -23,6 +24,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "third_party/blink/public/common/features.h"
#include "url/gurl.h"
#include "url/origin.h"
......@@ -77,7 +79,9 @@ void CheckIsCrossOriginIsolatedOnUISeq(
return;
}
if (rfh->GetCrossOriginIsolationStatus() ==
content::RenderFrameHost::CrossOriginIsolationStatus::kNotIsolated) {
content::RenderFrameHost::CrossOriginIsolationStatus::kNotIsolated &&
!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableWebSecurity)) {
std::move(bad_message_callback)
.Run("Requesting frame must be cross-origin isolated.");
return;
......
......@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
......@@ -57,14 +58,81 @@ void MeasureMemoryController::Trace(Visitor* visitor) const {
visitor->Trace(promise_resolver_);
}
namespace {
enum class ApiStatus {
kAvailable,
kNotAvailableDueToFlag,
kNotAvailableDueToDetachedContext,
kNotAvailableDueToCrossOriginContext,
kNotAvailableDueToCrossOriginIsolation,
kNotAvailableDueToResourceCoordinator,
};
ApiStatus CheckMeasureMemoryAvailability(LocalDOMWindow* window) {
if (!base::FeatureList::IsEnabled(
features::kWebMeasureMemoryViaPerformanceManager)) {
return ApiStatus::kNotAvailableDueToFlag;
}
if (!window) {
return ApiStatus::kNotAvailableDueToDetachedContext;
}
LocalFrame* local_frame = window->GetFrame();
if (!local_frame) {
return ApiStatus::kNotAvailableDueToDetachedContext;
}
if (!window->CrossOriginIsolatedCapability() &&
local_frame->GetSettings()->GetWebSecurityEnabled()) {
return ApiStatus::kNotAvailableDueToCrossOriginIsolation;
}
// CrossOriginIsolated is also set for same-agent cross-origin iframe.
// Allow only iframes that have the same origin as the main frame.
// Note that COOP guarantees that all main frames have the same origin.
if (local_frame->IsCrossOriginToMainFrame()) {
return ApiStatus::kNotAvailableDueToCrossOriginContext;
}
// We need DocumentResourceCoordinator to query PerformanceManager.
if (!window->document()) {
return ApiStatus::kNotAvailableDueToDetachedContext;
}
if (!window->document()->GetResourceCoordinator()) {
return ApiStatus::kNotAvailableDueToResourceCoordinator;
}
return ApiStatus::kAvailable;
}
} // anonymous namespace
ScriptPromise MeasureMemoryController::StartMeasurement(
ScriptState* script_state,
ExceptionState& exception_state) {
if (!IsMeasureMemoryAvailable(LocalDOMWindow::From(script_state))) {
exception_state.ThrowSecurityError(
"performance.measureUserAgentSpecificMemory is not available in"
" this context");
return ScriptPromise();
switch (auto status = CheckMeasureMemoryAvailability(
LocalDOMWindow::From(script_state))) {
case ApiStatus::kAvailable:
break;
case ApiStatus::kNotAvailableDueToFlag:
case ApiStatus::kNotAvailableDueToResourceCoordinator:
exception_state.ThrowSecurityError(
"performance.measureUserAgentSpecificMemory is not available.");
return ScriptPromise();
case ApiStatus::kNotAvailableDueToDetachedContext:
exception_state.ThrowSecurityError(
"performance.measureUserAgentSpecificMemory is not supported"
" in detached iframes.");
return ScriptPromise();
case ApiStatus::kNotAvailableDueToCrossOriginContext:
exception_state.ThrowSecurityError(
"performance.measureUserAgentSpecificMemory is not supported"
" in cross-origin iframes.");
return ScriptPromise();
case ApiStatus::kNotAvailableDueToCrossOriginIsolation:
exception_state.ThrowSecurityError(
"performance.measureUserAgentSpecificMemory requires"
" cross-origin isolation.");
return ScriptPromise();
}
v8::Isolate* isolate = script_state->GetIsolate();
v8::TryCatch try_catch(isolate);
......@@ -91,29 +159,6 @@ ScriptPromise MeasureMemoryController::StartMeasurement(
return ScriptPromise(script_state, promise_resolver->GetPromise());
}
bool MeasureMemoryController::IsMeasureMemoryAvailable(LocalDOMWindow* window) {
if (!base::FeatureList::IsEnabled(
features::kWebMeasureMemoryViaPerformanceManager)) {
return false;
}
if (!window || !window->CrossOriginIsolatedCapability()) {
return false;
}
// CrossOriginIsolated is also set for same-agent cross-origin iframe.
// Allow only iframes that have the same origin as the main frame.
// Note that COOP guarantees that all main frames have the same origin.
LocalFrame* local_frame = window->GetFrame();
if (!local_frame || local_frame->IsCrossOriginToMainFrame()) {
return false;
}
// We need DocumentResourceCoordinator to query PerformanceManager.
if (!window->document() || !window->document()->GetResourceCoordinator()) {
return false;
}
return true;
}
namespace {
......
......@@ -17,7 +17,6 @@
namespace blink {
class LocalDOMWindow;
class ScriptState;
class ExceptionState;
......@@ -44,7 +43,6 @@ class MeasureMemoryController final
void Trace(Visitor* visitor) const;
private:
static bool IsMeasureMemoryAvailable(LocalDOMWindow* window);
// Invoked when the memory of the main V8 isolate is measured.
void MeasurementComplete(
performance_manager::mojom::blink::WebMemoryMeasurementPtr);
......
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