Commit ed31bec5 authored by Francois Doray's avatar Francois Doray Committed by Commit Bot

[PM] Add an "origin trial freeze policy" on PageNode.

The value of the "origin trial freeze policy" of a page is updated
by the FreezeOriginTrialPolicyAggregatorAccess, which aggregates
policies from the page's current frames.

Bug: 999594
Change-Id: I8d71a4639ffb1e78854e82c3a309854ca0a6cd08
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1779106
Commit-Queue: François Doray <fdoray@chromium.org>
Reviewed-by: default avatarSigurður Ásgeirsson <siggi@chromium.org>
Reviewed-by: default avatarSébastien Marchand <sebmarchand@chromium.org>
Cr-Commit-Position: refs/heads/master@{#693356}
parent 4df60cee
......@@ -23,6 +23,11 @@ class FreezeOriginTrialPolicyAggregatorAccess {
static StorageType* GetInternalStorage(PageNodeImpl* page_node) {
return &page_node->freeze_origin_trial_policy_data_;
}
static void SetOriginTrialFreezePolicy(PageNodeImpl* page_node,
InterventionPolicy policy) {
page_node->SetOriginTrialFreezePolicy(policy);
}
};
class FreezeOriginTrialPolicyAggregator::Data
......@@ -48,6 +53,13 @@ class FreezeOriginTrialPolicyAggregator::Data
--num_current_frames_for_policy[static_cast<size_t>(policy)];
}
// Updates the page's origin trial freeze policy from current data.
void UpdateOriginTrialFreezePolicy(PageNodeImpl* page_node) {
FreezeOriginTrialPolicyAggregatorAccess::SetOriginTrialFreezePolicy(
page_node, ComputeOriginTrialFreezePolicy());
}
private:
// Computes the page's origin trial freeze policy from current data.
InterventionPolicy ComputeOriginTrialFreezePolicy() const {
if (GetNumCurrentFramesForPolicy(InterventionPolicy::kUnknown))
......@@ -63,7 +75,6 @@ class FreezeOriginTrialPolicyAggregator::Data
return InterventionPolicy::kDefault;
}
private:
// Returns the number of current frames with |policy| on the page that owns
// this Data.
uint32_t GetNumCurrentFramesForPolicy(InterventionPolicy policy) const {
......@@ -84,14 +95,6 @@ FreezeOriginTrialPolicyAggregator::FreezeOriginTrialPolicyAggregator() =
FreezeOriginTrialPolicyAggregator::~FreezeOriginTrialPolicyAggregator() =
default;
// static
InterventionPolicy
FreezeOriginTrialPolicyAggregator::GetOriginTrialFreezePolicyForTesting(
PageNodeImpl* page_node) {
Data* data = Data::GetOrCreate(page_node);
return data->ComputeOriginTrialFreezePolicy();
}
void FreezeOriginTrialPolicyAggregator::OnFrameNodeAdded(
const FrameNode* frame_node) {
DCHECK(!frame_node->IsCurrent());
......@@ -106,6 +109,7 @@ void FreezeOriginTrialPolicyAggregator::OnBeforeFrameNodeRemoved(
DCHECK(data);
data->DecrementFrameCountForPolicy(
frame_node->GetOriginTrialFreezePolicy());
data->UpdateOriginTrialFreezePolicy(page_node);
}
}
......@@ -120,6 +124,7 @@ void FreezeOriginTrialPolicyAggregator::OnIsCurrentChanged(
data->DecrementFrameCountForPolicy(
frame_node->GetOriginTrialFreezePolicy());
}
data->UpdateOriginTrialFreezePolicy(page_node);
}
void FreezeOriginTrialPolicyAggregator::OnOriginTrialFreezePolicyChanged(
......@@ -133,6 +138,7 @@ void FreezeOriginTrialPolicyAggregator::OnOriginTrialFreezePolicyChanged(
data->DecrementFrameCountForPolicy(previous_value);
data->IncrementFrameCountForPolicy(
frame_node->GetOriginTrialFreezePolicy());
data->UpdateOriginTrialFreezePolicy(page_node);
}
}
......
......@@ -10,8 +10,6 @@
namespace performance_manager {
class PageNodeImpl;
// Computes the freeze origin trial policy of a page by aggregating the freeze
// origin trial policies of its current frames.
class FreezeOriginTrialPolicyAggregator : public FrameNode::ObserverDefaultImpl,
......@@ -20,10 +18,6 @@ class FreezeOriginTrialPolicyAggregator : public FrameNode::ObserverDefaultImpl,
FreezeOriginTrialPolicyAggregator();
~FreezeOriginTrialPolicyAggregator() override;
// Returns the current freeze origin trial policy for |page_node|.
static InterventionPolicy GetOriginTrialFreezePolicyForTesting(
PageNodeImpl* page_node);
private:
class Data;
......
......@@ -26,11 +26,6 @@ class FreezeOriginTrialPolicyAggregatorTest : public GraphTestHarness {
}
};
InterventionPolicy GetOriginTrialFreezePolicy(PageNodeImpl* page_node) {
return FreezeOriginTrialPolicyAggregator::
GetOriginTrialFreezePolicyForTesting(page_node);
}
void ExpectInitialPolicyWorks(GraphImpl* mock_graph,
InterventionPolicy f0_policy,
InterventionPolicy f1_policy,
......@@ -42,18 +37,16 @@ void ExpectInitialPolicyWorks(GraphImpl* mock_graph,
TestNodeWrapper<PageNodeImpl>::Create(mock_graph);
// Check the initial values before any frames are added.
EXPECT_EQ(InterventionPolicy::kDefault,
GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(InterventionPolicy::kDefault, page->origin_trial_freeze_policy());
// Create an initial frame. Expect the page policy to be
// |f0_policy_aggregated| when it is made current.
TestNodeWrapper<FrameNodeImpl> f0 = TestNodeWrapper<FrameNodeImpl>::Create(
mock_graph, process.get(), page.get());
f0->SetOriginTrialFreezePolicy(f0_policy);
EXPECT_EQ(InterventionPolicy::kDefault,
GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(InterventionPolicy::kDefault, page->origin_trial_freeze_policy());
f0->SetIsCurrent(true);
EXPECT_EQ(f0_policy_aggregated, GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(f0_policy_aggregated, page->origin_trial_freeze_policy());
// Create a second frame and expect the page policy to be
// |f0f1_policy_aggregated| when it is made current.
......@@ -61,19 +54,19 @@ void ExpectInitialPolicyWorks(GraphImpl* mock_graph,
mock_graph, process.get(), page.get(), f0.get(), 1);
f1->SetOriginTrialFreezePolicy(f1_policy);
f1->SetIsCurrent(true);
EXPECT_EQ(f0f1_policy_aggregated, GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(f0f1_policy_aggregated, page->origin_trial_freeze_policy());
// Make the second frame non-current. Expect the page policy to go back to
// |f0_policy_aggregated|.
f1->SetIsCurrent(false);
EXPECT_EQ(f0_policy_aggregated, GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(f0_policy_aggregated, page->origin_trial_freeze_policy());
f1->SetIsCurrent(true);
EXPECT_EQ(f0f1_policy_aggregated, GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(f0f1_policy_aggregated, page->origin_trial_freeze_policy());
// Remove the second frame. Expect the page policy to go back to
// |f0_policy_aggregated|.
f1.reset();
EXPECT_EQ(f0_policy_aggregated, GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(f0_policy_aggregated, page->origin_trial_freeze_policy());
}
} // namespace
......@@ -198,19 +191,15 @@ TEST_F(FreezeOriginTrialPolicyAggregatorTest, PolicyChanges) {
graph(), process.get(), page.get());
frame->SetIsCurrent(true);
EXPECT_EQ(InterventionPolicy::kUnknown,
GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(InterventionPolicy::kUnknown, page->origin_trial_freeze_policy());
frame->SetOriginTrialFreezePolicy(InterventionPolicy::kOptIn);
EXPECT_EQ(InterventionPolicy::kOptIn, GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(InterventionPolicy::kOptIn, page->origin_trial_freeze_policy());
frame->SetOriginTrialFreezePolicy(InterventionPolicy::kOptOut);
EXPECT_EQ(InterventionPolicy::kOptOut,
GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(InterventionPolicy::kOptOut, page->origin_trial_freeze_policy());
frame->SetOriginTrialFreezePolicy(InterventionPolicy::kDefault);
EXPECT_EQ(InterventionPolicy::kDefault,
GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(InterventionPolicy::kDefault, page->origin_trial_freeze_policy());
frame->SetOriginTrialFreezePolicy(InterventionPolicy::kUnknown);
EXPECT_EQ(InterventionPolicy::kUnknown,
GetOriginTrialFreezePolicy(page.get()));
EXPECT_EQ(InterventionPolicy::kUnknown, page->origin_trial_freeze_policy());
}
} // namespace performance_manager
......@@ -178,6 +178,12 @@ PageNodeImpl::LifecycleState PageNodeImpl::lifecycle_state() const {
return lifecycle_state_.value();
}
PageNodeImpl::InterventionPolicy PageNodeImpl::origin_trial_freeze_policy()
const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return origin_trial_freeze_policy_.value();
}
const base::flat_set<FrameNodeImpl*>& PageNodeImpl::main_frame_nodes() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return main_frame_nodes_;
......@@ -296,6 +302,12 @@ PageNodeImpl::LifecycleState PageNodeImpl::GetLifecycleState() const {
return lifecycle_state();
}
PageNodeImpl::InterventionPolicy PageNodeImpl::GetOriginTrialFreezePolicy()
const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return origin_trial_freeze_policy();
}
int64_t PageNodeImpl::GetNavigationID() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return navigation_id();
......@@ -336,4 +348,9 @@ void PageNodeImpl::SetLifecycleState(LifecycleState lifecycle_state) {
lifecycle_state_.SetAndMaybeNotify(this, lifecycle_state);
}
void PageNodeImpl::SetOriginTrialFreezePolicy(InterventionPolicy policy) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
origin_trial_freeze_policy_.SetAndMaybeNotify(this, policy);
}
} // namespace performance_manager
......@@ -40,9 +40,9 @@ class PageNodeImpl
// dereferenced on the UI thread.
const WebContentsProxy& contents_proxy() const;
void SetIsLoading(bool is_loading);
void SetIsVisible(bool is_visible);
void SetIsAudible(bool is_audible);
void SetIsLoading(bool is_loading);
void SetUkmSourceId(ukm::SourceId ukm_source_id);
void OnFaviconUpdated();
void OnTitleUpdated();
......@@ -78,6 +78,7 @@ class PageNodeImpl
bool is_loading() const;
ukm::SourceId ukm_source_id() const;
LifecycleState lifecycle_state() const;
InterventionPolicy origin_trial_freeze_policy() const;
const base::flat_set<FrameNodeImpl*>& main_frame_nodes() const;
base::TimeTicks usage_estimate_time() const;
base::TimeDelta cumulative_cpu_usage_estimate() const;
......@@ -116,6 +117,7 @@ class PageNodeImpl
bool IsLoading() const override;
ukm::SourceId GetUkmSourceID() const override;
LifecycleState GetLifecycleState() const override;
InterventionPolicy GetOriginTrialFreezePolicy() const override;
int64_t GetNavigationID() const override;
base::TimeDelta GetTimeSinceLastNavigation() const override;
const FrameNode* GetMainFrameNode() const override;
......@@ -130,6 +132,7 @@ class PageNodeImpl
void SetPageAlmostIdle(bool page_almost_idle);
void SetLifecycleState(LifecycleState lifecycle_state);
void SetOriginTrialFreezePolicy(InterventionPolicy policy);
// The WebContentsProxy associated with this page.
const WebContentsProxy contents_proxy_;
......@@ -210,6 +213,12 @@ class PageNodeImpl
LifecycleState,
&PageNodeObserver::OnPageLifecycleStateChanged>
lifecycle_state_{LifecycleState::kRunning};
// The origin trial freeze policy of this page. This is aggregated from the
// origin trial freeze policy of each current frame in the frame tree.
ObservedProperty::NotifiesOnlyOnChanges<
InterventionPolicy,
&PageNodeObserver::OnPageOriginTrialFreezePolicyChanged>
origin_trial_freeze_policy_{InterventionPolicy::kDefault};
// Storage for PageAlmostIdle user data.
std::unique_ptr<NodeAttachedData> page_almost_idle_data_;
......
......@@ -170,9 +170,8 @@ void RunOriginTrialTestOnPMSequence(
performance_manager::GraphImpl* graph) {
auto page_nodes = graph->GetAllPageNodeImpls();
EXPECT_EQ(1U, page_nodes.size());
auto policy = FreezeOriginTrialPolicyAggregator::
GetOriginTrialFreezePolicyForTesting(page_nodes[0]);
EXPECT_EQ(expected_policy, policy);
EXPECT_EQ(expected_policy,
page_nodes[0]->origin_trial_freeze_policy());
std::move(quit_closure).Run();
},
run_loop.QuitClosure(), expected_policy));
......
......@@ -208,6 +208,7 @@ class LenientMockObserver : public PageNodeImpl::Observer {
MOCK_METHOD1(OnIsLoadingChanged, void(const PageNode*));
MOCK_METHOD1(OnUkmSourceIdChanged, void(const PageNode*));
MOCK_METHOD1(OnPageLifecycleStateChanged, void(const PageNode*));
MOCK_METHOD1(OnPageOriginTrialFreezePolicyChanged, void(const PageNode*));
MOCK_METHOD1(OnPageAlmostIdleChanged, void(const PageNode*));
MOCK_METHOD1(OnMainFrameNavigationCommitted, void(const PageNode*));
MOCK_METHOD1(OnTitleUpdated, void(const PageNode*));
......
......@@ -12,7 +12,8 @@
#include "chrome/browser/performance_manager/public/graph/node.h"
#include "chrome/browser/performance_manager/public/web_contents_proxy.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/resource_coordinator/public/mojom/lifecycle.mojom-shared.h"
#include "services/resource_coordinator/public/mojom/coordination_unit.mojom.h"
#include "services/resource_coordinator/public/mojom/lifecycle.mojom.h"
class GURL;
......@@ -26,6 +27,7 @@ class PageNodeObserver;
// Extensions.
class PageNode : public Node {
public:
using InterventionPolicy = resource_coordinator::mojom::InterventionPolicy;
using LifecycleState = resource_coordinator::mojom::LifecycleState;
using Observer = PageNodeObserver;
class ObserverDefaultImpl;
......@@ -66,6 +68,9 @@ class PageNode : public Node {
// PageNodeObserver::OnPageLifecycleStateChanged.
virtual LifecycleState GetLifecycleState() const = 0;
// Returns the freeze policy set via origin trial.
virtual InterventionPolicy GetOriginTrialFreezePolicy() const = 0;
// Returns the navigation ID associated with the last committed navigation
// event for the main frame of this page.
// See PageNodeObserver::OnMainFrameNavigationCommitted.
......@@ -116,22 +121,26 @@ class PageNodeObserver {
// Notifications of property changes.
// Invoked when the |is_visible| property changes.
// Invoked when the IsVisible property changes.
virtual void OnIsVisibleChanged(const PageNode* page_node) = 0;
// Invoked when the |is_audible| property changes.
// Invoked when the IsAudible property changes.
virtual void OnIsAudibleChanged(const PageNode* page_node) = 0;
// Invoked when the |is_loading| property changes.
// Invoked when the IsLoading property changes.
virtual void OnIsLoadingChanged(const PageNode* page_node) = 0;
// Invoked when the |ukm_source_id| property changes.
// Invoked when the UkmSourceId property changes.
virtual void OnUkmSourceIdChanged(const PageNode* page_node) = 0;
// Invoked when the |lifecycle_state| property changes.
// Invoked when the PageLifecycleState property changes.
virtual void OnPageLifecycleStateChanged(const PageNode* page_node) = 0;
// Invoked when the |page_almost_idle| property changes.
// Invoked when the OriginTrialFreezePolicy property changes.
virtual void OnPageOriginTrialFreezePolicyChanged(
const PageNode* page_node) = 0;
// Invoked when the PageAlmostIdle property changes.
virtual void OnPageAlmostIdleChanged(const PageNode* page_node) = 0;
// This is fired when a main frame navigation commits. It indicates that the
......@@ -172,6 +181,8 @@ class PageNode::ObserverDefaultImpl : public PageNodeObserver {
void OnIsLoadingChanged(const PageNode* page_node) override {}
void OnUkmSourceIdChanged(const PageNode* page_node) override {}
void OnPageLifecycleStateChanged(const PageNode* page_node) override {}
void OnPageOriginTrialFreezePolicyChanged(
const PageNode* page_node) override {}
void OnPageAlmostIdleChanged(const PageNode* page_node) override {}
void OnMainFrameNavigationCommitted(const PageNode* page_node) override {}
void OnTitleUpdated(const PageNode* page_node) override {}
......
......@@ -79,6 +79,9 @@ class WebUIGraphDumpImpl : public mojom::WebUIGraphDump,
// Ignored.
void OnPageLifecycleStateChanged(const PageNode* page_node) override {}
// Ignored.
void OnPageOriginTrialFreezePolicyChanged(
const PageNode* page_node) override {}
// Ignored.
void OnPageAlmostIdleChanged(const PageNode* page_node) override {}
void OnMainFrameNavigationCommitted(const PageNode* page_node) override;
void OnTitleUpdated(const PageNode* page_node) override {} // Ignored.
......
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