Commit 463ec8a7 authored by Francois Doray's avatar Francois Doray Committed by Commit Bot

RC: Add LifecycleUnit::Unfreeze().

This will be used to periodically unfreeze LifecycleUnits, to allow
them to update their state.

Bug: 775644
Change-Id: I498930c8a555ddf3581099e61972aaeac6a36d91
Reviewed-on: https://chromium-review.googlesource.com/1099973
Commit-Queue: François Doray <fdoray@chromium.org>
Reviewed-by: default avatarFadi Meawad <fmeawad@chromium.org>
Reviewed-by: default avatarSébastien Marchand <sebmarchand@chromium.org>
Cr-Commit-Position: refs/heads/master@{#568451}
parent 9781ec38
...@@ -120,10 +120,6 @@ class LifecycleUnit { ...@@ -120,10 +120,6 @@ class LifecycleUnit {
// successful. // successful.
virtual bool Load() = 0; virtual bool Load() = 0;
// Request that the LifecycleUnit be frozen, return true if the request is
// successfully sent.
virtual bool Freeze() = 0;
// Returns the estimated number of kilobytes that would be freed if this // Returns the estimated number of kilobytes that would be freed if this
// LifecycleUnit was discarded. // LifecycleUnit was discarded.
// //
...@@ -154,6 +150,13 @@ class LifecycleUnit { ...@@ -154,6 +150,13 @@ class LifecycleUnit {
virtual bool CanDiscard(DiscardReason reason, virtual bool CanDiscard(DiscardReason reason,
DecisionDetails* decision_details) const = 0; DecisionDetails* decision_details) const = 0;
// Request that the LifecycleUnit be frozen, return true if the request is
// successfully sent.
virtual bool Freeze() = 0;
// Unfreezes this LifecycleUnit. Returns true on success.
virtual bool Unfreeze() = 0;
// Discards this LifecycleUnit. // Discards this LifecycleUnit.
// //
// TODO(fdoray): Consider handling urgent discard with groups of // TODO(fdoray): Consider handling urgent discard with groups of
......
...@@ -67,6 +67,9 @@ bool IsValidStateChange(LifecycleUnitState from, ...@@ -67,6 +67,9 @@ bool IsValidStateChange(LifecycleUnitState from,
} }
case LifecycleUnitState::PENDING_FREEZE: { case LifecycleUnitState::PENDING_FREEZE: {
switch (to) { switch (to) {
// Unfreeze() is called.
case LifecycleUnitState::ACTIVE:
return reason == StateChangeReason::BROWSER_INITIATED;
// Discard(kProactive) is called. // Discard(kProactive) is called.
case LifecycleUnitState::PENDING_DISCARD: case LifecycleUnitState::PENDING_DISCARD:
return reason == StateChangeReason::BROWSER_INITIATED; return reason == StateChangeReason::BROWSER_INITIATED;
...@@ -83,9 +86,12 @@ bool IsValidStateChange(LifecycleUnitState from, ...@@ -83,9 +86,12 @@ bool IsValidStateChange(LifecycleUnitState from,
} }
case LifecycleUnitState::FROZEN: { case LifecycleUnitState::FROZEN: {
switch (to) { switch (to) {
// The renderer re-activates the page because it became visible. // Unfreeze() is called or the renderer re-activates the page because it
case LifecycleUnitState::ACTIVE: // became visible.
return reason == StateChangeReason::RENDERER_INITIATED; case LifecycleUnitState::ACTIVE: {
return reason == StateChangeReason::BROWSER_INITIATED ||
reason == StateChangeReason::RENDERER_INITIATED;
}
// Discard(kProactive|kUrgent|kExternal) is called. // Discard(kProactive|kUrgent|kExternal) is called.
case LifecycleUnitState::DISCARDED: { case LifecycleUnitState::DISCARDED: {
return reason == StateChangeReason::BROWSER_INITIATED || return reason == StateChangeReason::BROWSER_INITIATED ||
...@@ -328,19 +334,6 @@ bool TabLifecycleUnitSource::TabLifecycleUnit::Load() { ...@@ -328,19 +334,6 @@ bool TabLifecycleUnitSource::TabLifecycleUnit::Load() {
return true; return true;
} }
bool TabLifecycleUnitSource::TabLifecycleUnit::Freeze() {
if (!IsValidStateChange(GetState(), LifecycleUnitState::PENDING_FREEZE,
StateChangeReason::BROWSER_INITIATED)) {
return false;
}
SetState(LifecycleUnitState::PENDING_FREEZE,
StateChangeReason::BROWSER_INITIATED);
GetWebContents()->SetPageFrozen(true);
return true;
}
int TabLifecycleUnitSource::TabLifecycleUnit:: int TabLifecycleUnitSource::TabLifecycleUnit::
GetEstimatedMemoryFreedOnDiscardKB() const { GetEstimatedMemoryFreedOnDiscardKB() const {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
...@@ -502,6 +495,37 @@ bool TabLifecycleUnitSource::TabLifecycleUnit::CanDiscard( ...@@ -502,6 +495,37 @@ bool TabLifecycleUnitSource::TabLifecycleUnit::CanDiscard(
return decision_details->IsPositive(); return decision_details->IsPositive();
} }
bool TabLifecycleUnitSource::TabLifecycleUnit::Freeze() {
if (!IsValidStateChange(GetState(), LifecycleUnitState::PENDING_FREEZE,
StateChangeReason::BROWSER_INITIATED)) {
return false;
}
// WebContents::SetPageFrozen() DCHECKs if the page is visible.
if (GetWebContents()->GetVisibility() == content::Visibility::VISIBLE)
return false;
SetState(LifecycleUnitState::PENDING_FREEZE,
StateChangeReason::BROWSER_INITIATED);
GetWebContents()->SetPageFrozen(true);
return true;
}
bool TabLifecycleUnitSource::TabLifecycleUnit::Unfreeze() {
if (!IsValidStateChange(GetState(), LifecycleUnitState::ACTIVE,
StateChangeReason::BROWSER_INITIATED)) {
return false;
}
// WebContents::SetPageFrozen() DCHECKs if the page is visible.
if (GetWebContents()->GetVisibility() == content::Visibility::VISIBLE)
return false;
SetState(LifecycleUnitState::ACTIVE, StateChangeReason::BROWSER_INITIATED);
GetWebContents()->SetPageFrozen(false);
return true;
}
bool TabLifecycleUnitSource::TabLifecycleUnit::Discard(DiscardReason reason) { bool TabLifecycleUnitSource::TabLifecycleUnit::Discard(DiscardReason reason) {
// Can't discard a tab when it isn't in a tabstrip. // Can't discard a tab when it isn't in a tabstrip.
if (!tab_strip_model_) if (!tab_strip_model_)
......
...@@ -91,12 +91,13 @@ class TabLifecycleUnitSource::TabLifecycleUnit ...@@ -91,12 +91,13 @@ class TabLifecycleUnitSource::TabLifecycleUnit
content::Visibility GetVisibility() const override; content::Visibility GetVisibility() const override;
LifecycleUnitLoadingState GetLoadingState() const override; LifecycleUnitLoadingState GetLoadingState() const override;
bool Load() override; bool Load() override;
bool Freeze() override;
int GetEstimatedMemoryFreedOnDiscardKB() const override; int GetEstimatedMemoryFreedOnDiscardKB() const override;
bool CanPurge() const override; bool CanPurge() const override;
bool CanFreeze(DecisionDetails* decision_details) const override; bool CanFreeze(DecisionDetails* decision_details) const override;
bool CanDiscard(DiscardReason reason, bool CanDiscard(DiscardReason reason,
DecisionDetails* decision_details) const override; DecisionDetails* decision_details) const override;
bool Freeze() override;
bool Unfreeze() override;
bool Discard(DiscardReason discard_reason) override; bool Discard(DiscardReason discard_reason) override;
ukm::SourceId GetUkmSourceId() const override; ukm::SourceId GetUkmSourceId() const override;
......
...@@ -55,6 +55,11 @@ namespace { ...@@ -55,6 +55,11 @@ namespace {
constexpr char kBlinkPageLifecycleFeature[] = "PageLifecycle"; constexpr char kBlinkPageLifecycleFeature[] = "PageLifecycle";
constexpr base::TimeDelta kShortDelay = base::TimeDelta::FromSeconds(1); constexpr base::TimeDelta kShortDelay = base::TimeDelta::FromSeconds(1);
constexpr char kMainFrameFrozenStateJS[] =
"window.domAutomationController.send(mainFrameFreezeCount);";
constexpr char kChildFrameFrozenStateJS[] =
"window.domAutomationController.send(childFrameFreezeCount);";
bool ObserveNavEntryCommitted(const GURL& expected_url, bool ObserveNavEntryCommitted(const GURL& expected_url,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) { const content::NotificationDetails& details) {
...@@ -154,6 +159,104 @@ class TabManagerTest : public InProcessBrowserTest { ...@@ -154,6 +159,104 @@ class TabManagerTest : public InProcessBrowserTest {
ASSERT_EQ(2, tsm()->count()); ASSERT_EQ(2, tsm()->count());
} }
// Opens 2 tabs. Calls Freeze() on the background tab. Verifies that it
// transitions to the PENDING_FREEZE, and that onfreeze callbacks runs on the
// page. The background tab is PENDING_FREEZE when this returns.
void TestTransitionFromActiveToPendingFreeze() {
// Setup the embedded_test_server to serve a cross-site frame.
content::SetupCrossSiteRedirector(embedded_test_server());
ASSERT_TRUE(embedded_test_server()->Start());
// Opening two tabs, where the second tab is backgrounded.
GURL main_url(
embedded_test_server()->GetURL("a.com", "/iframe_cross_site.html"));
OpenTwoTabs(GURL(chrome::kChromeUIAboutURL), main_url);
constexpr int kFreezingIndex = 1;
LifecycleUnit* const lifecycle_unit = GetLifecycleUnitAt(kFreezingIndex);
content::WebContents* const content = GetWebContentsAt(kFreezingIndex);
// Grab the frames.
content::RenderFrameHost* main_frame = content->GetMainFrame();
ASSERT_EQ(3u, content->GetAllFrames().size());
// The page has 2 iframes, we will use the first one.
content::RenderFrameHost* child_frame = content->GetAllFrames()[1];
// Verify that the main frame and subframe are cross-site.
EXPECT_FALSE(content::SiteInstance::IsSameWebSite(
browser()->profile(), main_frame->GetLastCommittedURL(),
child_frame->GetLastCommittedURL()));
if (content::AreAllSitesIsolatedForTesting()) {
EXPECT_NE(main_frame->GetProcess()->GetID(),
child_frame->GetProcess()->GetID());
}
// Ensure that the tab is hidden or backgrounded.
bool hidden_state_result;
EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
main_frame,
"window.domAutomationController.send("
"window.document.hidden);",
&hidden_state_result));
EXPECT_TRUE(hidden_state_result);
EXPECT_TRUE(content::ExecuteScript(
main_frame,
"if (window.location.pathname != '/iframe_cross_site.html')"
" throw 'Incorrect frame';"
"mainFrameFreezeCount = 0;"
"window.document.onfreeze = function(){ mainFrameFreezeCount++; };"));
EXPECT_TRUE(content::ExecuteScript(
child_frame,
"if (window.location.pathname != '/title1.html') throw 'Incorrect "
"frame';"
"childFrameFreezeCount = 0;"
"window.document.onfreeze = function(){ childFrameFreezeCount++; };"));
// freeze_count_result should be 0 for both frames, if it is undefined then
// we are in the wrong frame/tab.
int freeze_count_result;
EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
main_frame, kMainFrameFrozenStateJS, &freeze_count_result));
EXPECT_EQ(0, freeze_count_result);
EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
child_frame, kChildFrameFrozenStateJS, &freeze_count_result));
EXPECT_EQ(0, freeze_count_result);
// Freeze the tab. If it fails then we might be freezing a visible tab.
EXPECT_EQ(LifecycleUnitState::ACTIVE, lifecycle_unit->GetState());
EXPECT_TRUE(lifecycle_unit->Freeze());
EXPECT_EQ(LifecycleUnitState::PENDING_FREEZE, lifecycle_unit->GetState());
}
// Opens 2 tabs. Calls Freeze() on the background tab. Verifies that it
// transitions to the PENDING_FREEZE and FROZEN states, and that onfreeze
// callbacks runs on the page. The background tabs is FROZEN when this
// returns.
void TestTransitionFromActiveToFrozen() {
TestTransitionFromActiveToPendingFreeze();
{
ExpectStateTransitionObserver expect_state_transition(
GetLifecycleUnitAt(1), LifecycleUnitState::FROZEN);
expect_state_transition.Wait();
}
content::WebContents* const content = GetWebContentsAt(1);
content::RenderFrameHost* main_frame = content->GetMainFrame();
content::RenderFrameHost* child_frame = content->GetAllFrames()[1];
// freeze_count_result should be exactly 1 for both frames. The value is
// incremented in the onfreeze callback. If it is >1, then the callback was
// called more than once.
int freeze_count_result = 0;
EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
main_frame, kMainFrameFrozenStateJS, &freeze_count_result));
EXPECT_EQ(1, freeze_count_result);
EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
child_frame, kChildFrameFrozenStateJS, &freeze_count_result));
EXPECT_EQ(1, freeze_count_result);
}
// Gets the TabLifecycleUnit from |contents| and sends the signal that // Gets the TabLifecycleUnit from |contents| and sends the signal that
// indicates that the page is frozen. In production, this is sent by the // indicates that the page is frozen. In production, this is sent by the
// renderer process. This is done to finish a proactive tab discard. // renderer process. This is done to finish a proactive tab discard.
...@@ -822,98 +925,41 @@ IN_PROC_BROWSER_TEST_F(TabManagerTest, ...@@ -822,98 +925,41 @@ IN_PROC_BROWSER_TEST_F(TabManagerTest,
// - Freeze(): ACTIVE->PENDING_FREEZE // - Freeze(): ACTIVE->PENDING_FREEZE
// - Freeze happens in renderer: PENDING_FREEZE->FROZEN // - Freeze happens in renderer: PENDING_FREEZE->FROZEN
// - Tab is made visible: FROZEN->ACTIVE // - Tab is made visible: FROZEN->ACTIVE
IN_PROC_BROWSER_TEST_F(TabManagerTest, TabFreeze) { IN_PROC_BROWSER_TEST_F(TabManagerTest, TabFreezeAndMakeVisible) {
const char kMainFrameFrozenStateJS[] = TestTransitionFromActiveToFrozen();
"window.domAutomationController.send(mainFrameFreezeCount);";
const char kChildFrameFrozenStateJS[] =
"window.domAutomationController.send(childFrameFreezeCount);";
const char kHiddenStateJS[] =
"window.domAutomationController.send("
"window.document.hidden);";
// Setup the embedded_test_server to serve a cross-site frame.
content::SetupCrossSiteRedirector(embedded_test_server());
ASSERT_TRUE(embedded_test_server()->Start());
// Opening two tabs, where the second tab is backgrounded.
GURL main_url(
embedded_test_server()->GetURL("a.com", "/iframe_cross_site.html"));
OpenTwoTabs(GURL(chrome::kChromeUIAboutURL), main_url);
constexpr int kFreezingIndex = 1;
LifecycleUnit* const lifecycle_unit = GetLifecycleUnitAt(kFreezingIndex);
content::WebContents* const content = GetWebContentsAt(kFreezingIndex);
// Grab the frames.
content::RenderFrameHost* main_frame = content->GetMainFrame();
ASSERT_EQ(3u, content->GetAllFrames().size());
// The page has 2 iframes, we will use the first one.
content::RenderFrameHost* child_frame = content->GetAllFrames()[1];
// Verify that the main frame and subframe are cross-site.
EXPECT_FALSE(content::SiteInstance::IsSameWebSite(
browser()->profile(), main_frame->GetLastCommittedURL(),
child_frame->GetLastCommittedURL()));
if (content::AreAllSitesIsolatedForTesting()) {
EXPECT_NE(main_frame->GetProcess()->GetID(),
child_frame->GetProcess()->GetID());
}
// Ensure that the tab is hidden or backgrounded.
bool hidden_state_result;
EXPECT_TRUE(content::ExecuteScriptAndExtractBool(main_frame, kHiddenStateJS,
&hidden_state_result));
EXPECT_TRUE(hidden_state_result);
EXPECT_TRUE(content::ExecuteScript(
main_frame,
"if (window.location.pathname != '/iframe_cross_site.html')"
" throw 'Incorrect frame';"
"mainFrameFreezeCount = 0;"
"window.document.onfreeze = function(){ mainFrameFreezeCount++; };"));
EXPECT_TRUE(content::ExecuteScript(
child_frame,
"if (window.location.pathname != '/title1.html') throw 'Incorrect frame';"
"childFrameFreezeCount = 0;"
"window.document.onfreeze = function(){ childFrameFreezeCount++; };"));
// freeze_count_result should be 0 for both frames, if it is undefined then we
// are in the wrong frame/tab.
int freeze_count_result;
EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
main_frame, kMainFrameFrozenStateJS, &freeze_count_result));
EXPECT_EQ(0, freeze_count_result);
EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
child_frame, kChildFrameFrozenStateJS, &freeze_count_result));
EXPECT_EQ(0, freeze_count_result);
// Freeze the tab. If it fails then we might be freezing a visible tab.
EXPECT_EQ(LifecycleUnitState::ACTIVE, lifecycle_unit->GetState());
EXPECT_TRUE(lifecycle_unit->Freeze());
EXPECT_EQ(LifecycleUnitState::PENDING_FREEZE, lifecycle_unit->GetState());
// Make the tab visible. It should transition to the ACTIVE state.
GetWebContentsAt(1)->WasShown();
{ {
ExpectStateTransitionObserver expect_state_transition( ExpectStateTransitionObserver expect_state_transition(
lifecycle_unit, LifecycleUnitState::FROZEN); GetLifecycleUnitAt(1), LifecycleUnitState::ACTIVE);
expect_state_transition.Wait(); expect_state_transition.Wait();
} }
}
// freeze_count_result should be exactly 1 for both frames. The value is // Verifies the following state transitions for a tab:
// incremented in the onfreeze callback. If it is >1, then the callback was // - Initial state: ACTIVE
// called more than once. // - Freeze(): ACTIVE->PENDING_FREEZE
EXPECT_TRUE(content::ExecuteScriptAndExtractInt( // - Freeze happens in renderer: PENDING_FREEZE->FROZEN
main_frame, kMainFrameFrozenStateJS, &freeze_count_result)); // - Unfreeze(): FROZEN->ACTIVE
EXPECT_EQ(1, freeze_count_result); IN_PROC_BROWSER_TEST_F(TabManagerTest, TabFreezeAndUnfreeze) {
EXPECT_TRUE(content::ExecuteScriptAndExtractInt( TestTransitionFromActiveToFrozen();
child_frame, kChildFrameFrozenStateJS, &freeze_count_result));
EXPECT_EQ(1, freeze_count_result); // Unfreeze the tab. It should transition to the ACTIVE state.
EXPECT_TRUE(GetLifecycleUnitAt(1)->Unfreeze());
// Make the tab visible. It should be unfrozen. EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(1)->GetState());
content->WasShown(); }
{
ExpectStateTransitionObserver expect_state_transition( // Verifies the following state transitions for a tab:
lifecycle_unit, LifecycleUnitState::ACTIVE); // - Initial state: ACTIVE
expect_state_transition.Wait(); // - Freeze(): ACTIVE->PENDING_FREEZE
} // - Unfreeze(): PENDING_FREEZE->ACTIVE
IN_PROC_BROWSER_TEST_F(TabManagerTest, TabPendingFreezeAndUnfreeze) {
TestTransitionFromActiveToPendingFreeze();
// Unfreeze the tab. It should transition to the ACTIVE state.
EXPECT_TRUE(GetLifecycleUnitAt(1)->Unfreeze());
EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(1)->GetState());
} }
// Verifies the following state transitions for a tab: // Verifies the following state transitions for a tab:
...@@ -921,13 +967,9 @@ IN_PROC_BROWSER_TEST_F(TabManagerTest, TabFreeze) { ...@@ -921,13 +967,9 @@ IN_PROC_BROWSER_TEST_F(TabManagerTest, TabFreeze) {
// - Freeze(): ACTIVE->PENDING_FREEZE // - Freeze(): ACTIVE->PENDING_FREEZE
// - Discard(kProactive): PENDING_FREEZE->PENDING_DISCARD // - Discard(kProactive): PENDING_FREEZE->PENDING_DISCARD
// - Freeze happens in renderer: PENDING_DISCARD->DISCARDED // - Freeze happens in renderer: PENDING_DISCARD->DISCARDED
IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs, IN_PROC_BROWSER_TEST_F(TabManagerTest,
TabFreezeAndProactiveDiscardBeforeFreezeCompletes) { TabFreezeAndProactiveDiscardBeforeFreezeCompletes) {
// Freeze the background tab. TestTransitionFromActiveToPendingFreeze();
EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(1)->GetState());
GetLifecycleUnitAt(1)->Freeze();
EXPECT_EQ(LifecycleUnitState::PENDING_FREEZE,
GetLifecycleUnitAt(1)->GetState());
// Proactively discard the background tab. // Proactively discard the background tab.
EXPECT_TRUE(GetLifecycleUnitAt(1)->Discard(DiscardReason::kProactive)); EXPECT_TRUE(GetLifecycleUnitAt(1)->Discard(DiscardReason::kProactive));
...@@ -962,19 +1004,8 @@ IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs, ...@@ -962,19 +1004,8 @@ IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs,
// - Freeze(): ACTIVE->PENDING_FREEZE // - Freeze(): ACTIVE->PENDING_FREEZE
// - Freeze happens in renderer: PENDING_FREEZE->FROZEN // - Freeze happens in renderer: PENDING_FREEZE->FROZEN
// - Discard(kUrgent): FROZEN->DISCARDED // - Discard(kUrgent): FROZEN->DISCARDED
IN_PROC_BROWSER_TEST_F(TabManagerTestWithTwoTabs, TabFreezeAndUrgentDiscard) { IN_PROC_BROWSER_TEST_F(TabManagerTest, TabFreezeAndUrgentDiscard) {
// Freeze the background tab. TestTransitionFromActiveToFrozen();
EXPECT_EQ(LifecycleUnitState::ACTIVE, GetLifecycleUnitAt(1)->GetState());
EXPECT_TRUE(GetLifecycleUnitAt(1)->Freeze());
EXPECT_EQ(LifecycleUnitState::PENDING_FREEZE,
GetLifecycleUnitAt(1)->GetState());
// Expect a transition to FROZEN when the page is frozen by the renderer.
{
ExpectStateTransitionObserver expect_state_transition(
GetLifecycleUnitAt(1), LifecycleUnitState::FROZEN);
expect_state_transition.Wait();
}
// Urgently discard the background tab. // Urgently discard the background tab.
EXPECT_TRUE(GetLifecycleUnitAt(1)->Discard(DiscardReason::kUrgent)); EXPECT_TRUE(GetLifecycleUnitAt(1)->Discard(DiscardReason::kUrgent));
......
...@@ -52,10 +52,6 @@ bool TestLifecycleUnit::Load() { ...@@ -52,10 +52,6 @@ bool TestLifecycleUnit::Load() {
return false; return false;
} }
bool TestLifecycleUnit::Freeze() {
return false;
}
int TestLifecycleUnit::GetEstimatedMemoryFreedOnDiscardKB() const { int TestLifecycleUnit::GetEstimatedMemoryFreedOnDiscardKB() const {
return 0; return 0;
} }
...@@ -73,6 +69,14 @@ bool TestLifecycleUnit::CanDiscard(DiscardReason reason, ...@@ -73,6 +69,14 @@ bool TestLifecycleUnit::CanDiscard(DiscardReason reason,
return can_discard_; return can_discard_;
} }
bool TestLifecycleUnit::Freeze() {
return false;
}
bool TestLifecycleUnit::Unfreeze() {
return false;
}
bool TestLifecycleUnit::Discard(DiscardReason discard_reason) { bool TestLifecycleUnit::Discard(DiscardReason discard_reason) {
return false; return false;
} }
......
...@@ -33,12 +33,13 @@ class TestLifecycleUnit : public LifecycleUnitBase { ...@@ -33,12 +33,13 @@ class TestLifecycleUnit : public LifecycleUnitBase {
content::Visibility GetVisibility() const override; content::Visibility GetVisibility() const override;
LifecycleUnitLoadingState GetLoadingState() const override; LifecycleUnitLoadingState GetLoadingState() const override;
bool Load() override; bool Load() override;
bool Freeze() override;
int GetEstimatedMemoryFreedOnDiscardKB() const override; int GetEstimatedMemoryFreedOnDiscardKB() const override;
bool CanPurge() const override; bool CanPurge() const override;
bool CanFreeze(DecisionDetails* decision_details) const override; bool CanFreeze(DecisionDetails* decision_details) const override;
bool CanDiscard(DiscardReason reason, bool CanDiscard(DiscardReason reason,
DecisionDetails* decision_details) const override; DecisionDetails* decision_details) const override;
bool Freeze() override;
bool Unfreeze() override;
bool Discard(DiscardReason discard_reason) override; bool Discard(DiscardReason discard_reason) override;
private: private:
......
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