Commit 4eef09d0 authored by Francois Doray's avatar Francois Doray Committed by Commit Bot

Add resource_coordinator::DiscardCondition.

This enum replaces resource_coordinator::TabManager::DiscardTabCondition.
It can be used by code that doesn't depend on TabManager and/or
that is unrelated to tabs.

TBR=msw@chromium.org

Bug: 775644
Change-Id: I71931a4f32c161bec467e1851d2a68ab843d2d24
Reviewed-on: https://chromium-review.googlesource.com/738298Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Reviewed-by: default avatarChris Hamilton <chrisha@chromium.org>
Commit-Queue: François Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517419}
parent 315f4d32
......@@ -2552,6 +2552,7 @@ split_static_library("browser") {
"repost_form_warning_controller.h",
"resource_coordinator/background_tab_navigation_throttle.cc",
"resource_coordinator/background_tab_navigation_throttle.h",
"resource_coordinator/discard_condition.h",
"resource_coordinator/tab_lifetime_observer.cc",
"resource_coordinator/tab_lifetime_observer.h",
"resource_coordinator/tab_manager.cc",
......
......@@ -6,6 +6,7 @@
#include "base/memory/ptr_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/resource_coordinator/discard_condition.h"
#include "chrome/browser/resource_coordinator/tab_manager.h"
namespace memory {
......@@ -25,8 +26,8 @@ void ChromeMemoryCoordinatorDelegate::DiscardTab(bool skip_unload_handlers) {
if (g_browser_process->GetTabManager()) {
g_browser_process->GetTabManager()->DiscardTab(
skip_unload_handlers
? resource_coordinator::TabManager::kUrgentShutdown
: resource_coordinator::TabManager::kProactiveShutdown);
? resource_coordinator::DiscardCondition::kUrgent
: resource_coordinator::DiscardCondition::kProactive);
}
#endif
}
......
// Copyright 2017 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.
#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_DISCARD_CONDITION_H_
#define CHROME_BROWSER_RESOURCE_COORDINATOR_DISCARD_CONDITION_H_
namespace resource_coordinator {
enum class DiscardCondition {
// The discard happens proactively when the machine is in a good state.
kProactive,
// The discard happens because the machine is in a critical condition.
kUrgent,
};
} // namespace resource_coordinator
#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_DISCARD_CONDITION_H_
......@@ -105,14 +105,14 @@ IN_PROC_BROWSER_TEST_F(TabLifetimeObserverTest, OnDiscardStateChange) {
// Discards both tabs and make sure the events were observed properly.
EXPECT_TRUE(tab_manager->DiscardTabById(ContentsId(GetContents(index_1)),
TabManager::kProactiveShutdown));
DiscardCondition::kProactive));
EXPECT_EQ(1, tabmanager_observer.nb_events());
EXPECT_EQ(ContentsId(GetContents(index_1)),
ContentsId(tabmanager_observer.content()));
EXPECT_TRUE(tabmanager_observer.is_discarded());
EXPECT_TRUE(tab_manager->DiscardTabById(ContentsId(GetContents(index_2)),
TabManager::kProactiveShutdown));
DiscardCondition::kProactive));
EXPECT_EQ(2, tabmanager_observer.nb_events());
EXPECT_EQ(ContentsId(GetContents(index_2)),
ContentsId(tabmanager_observer.content()));
......@@ -120,7 +120,7 @@ IN_PROC_BROWSER_TEST_F(TabLifetimeObserverTest, OnDiscardStateChange) {
// Discarding an already discarded tab shouldn't fire the observers.
EXPECT_FALSE(tab_manager->DiscardTabById(ContentsId(GetContents(index_1)),
TabManager::kProactiveShutdown));
DiscardCondition::kProactive));
EXPECT_EQ(2, tabmanager_observer.nb_events());
// Reload tab 1.
......@@ -147,7 +147,7 @@ IN_PROC_BROWSER_TEST_F(TabLifetimeObserverTest, OnDiscardStateChange) {
// receive events anymore.
tab_manager->RemoveObserver(&tabmanager_observer);
EXPECT_TRUE(tab_manager->DiscardTabById(ContentsId(GetContents(index_1)),
TabManager::kProactiveShutdown));
DiscardCondition::kProactive));
EXPECT_EQ(4, tabmanager_observer.nb_events());
}
......
......@@ -427,7 +427,7 @@ bool TabManager::CanDiscardTab(const TabStats& tab_stats) const {
return true;
}
void TabManager::DiscardTab(DiscardTabCondition condition) {
void TabManager::DiscardTab(DiscardCondition condition) {
#if defined(OS_CHROMEOS)
// Call Chrome OS specific low memory handling process.
if (base::FeatureList::IsEnabled(features::kArcMemoryManagement)) {
......@@ -439,7 +439,7 @@ void TabManager::DiscardTab(DiscardTabCondition condition) {
}
WebContents* TabManager::DiscardTabById(int64_t target_web_contents_id,
DiscardTabCondition condition) {
DiscardCondition condition) {
TabStripModel* model;
int index = FindTabStripModelById(target_web_contents_id, &model);
......@@ -452,13 +452,15 @@ WebContents* TabManager::DiscardTabById(int64_t target_web_contents_id,
}
WebContents* TabManager::DiscardTabByExtension(content::WebContents* contents) {
if (contents)
return DiscardTabById(IdFromWebContents(contents), kProactiveShutdown);
if (contents) {
return DiscardTabById(IdFromWebContents(contents),
DiscardCondition::kProactive);
}
return DiscardTabImpl(kProactiveShutdown);
return DiscardTabImpl(DiscardCondition::kProactive);
}
void TabManager::LogMemoryAndDiscardTab(DiscardTabCondition condition) {
void TabManager::LogMemoryAndDiscardTab(DiscardCondition condition) {
LogMemory("Tab Discards Memory details",
base::Bind(&TabManager::PurgeMemoryAndDiscardTab, condition));
}
......@@ -635,7 +637,7 @@ void TabManager::OnAutoDiscardableStateChange(content::WebContents* contents,
}
// static
void TabManager::PurgeMemoryAndDiscardTab(DiscardTabCondition condition) {
void TabManager::PurgeMemoryAndDiscardTab(DiscardCondition condition) {
TabManager* manager = g_browser_process->GetTabManager();
manager->PurgeBrowserMemory();
manager->DiscardTab(condition);
......@@ -823,7 +825,7 @@ void TabManager::PurgeBackgroundedTabsIfNeeded() {
WebContents* TabManager::DiscardWebContentsAt(int index,
TabStripModel* model,
DiscardTabCondition condition) {
DiscardCondition condition) {
WebContents* old_contents = model->GetWebContentsAt(index);
// Can't discard tabs that are already discarded.
......@@ -867,7 +869,7 @@ WebContents* TabManager::DiscardWebContentsAt(int index,
false);
#ifdef OS_CHROMEOS
if (!fast_shutdown_success && condition == kUrgentShutdown) {
if (!fast_shutdown_success && condition == DiscardCondition::kUrgent) {
content::RenderFrameHost* main_frame = old_contents->GetMainFrame();
// We avoid fast shutdown on tabs with beforeunload handlers on the main
// frame, as that is often an indication of unsaved user state.
......@@ -941,7 +943,7 @@ void TabManager::OnMemoryPressure(
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
break;
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
LogMemoryAndDiscardTab(kUrgentShutdown);
LogMemoryAndDiscardTab(DiscardCondition::kUrgent);
break;
default:
NOTREACHED();
......@@ -1045,8 +1047,7 @@ TabManager::WebContentsData* TabManager::GetWebContentsData(
// TODO(jamescook): This should consider tabs with references to other tabs,
// such as tabs created with JavaScript window.open(). Potentially consider
// discarding the entire set together, or use that in the priority computation.
content::WebContents* TabManager::DiscardTabImpl(
DiscardTabCondition condition) {
content::WebContents* TabManager::DiscardTabImpl(DiscardCondition condition) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
TabStatsList stats = GetTabStats();
......
......@@ -21,6 +21,7 @@
#include "base/strings/string16.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "chrome/browser/resource_coordinator/discard_condition.h"
#include "chrome/browser/resource_coordinator/tab_lifetime_observer.h"
#include "chrome/browser/resource_coordinator/tab_stats.h"
#include "chrome/browser/sessions/session_restore_observer.h"
......@@ -108,23 +109,19 @@ class TabManager : public TabStripModelObserver,
// discarding a particular tab from about:discards.
bool CanDiscardTab(const TabStats& tab_stats) const;
// Indicates the criticality of the situation when attempting to discard a
// tab.
enum DiscardTabCondition { kProactiveShutdown, kUrgentShutdown };
// Discards a tab to free the memory occupied by its renderer. The tab still
// exists in the tab-strip; clicking on it will reload it. If the |condition|
// is urgent, an aggressive fast-kill will be attempted if the sudden
// termination disablers are allowed to be ignored (e.g. On ChromeOS, we can
// ignore an unload handler and fast-kill the tab regardless).
void DiscardTab(DiscardTabCondition condition);
void DiscardTab(DiscardCondition condition);
// Discards a tab with the given unique ID. The tab still exists in the
// tab-strip; clicking on it will reload it. Returns null if the tab cannot
// be found or cannot be discarded. Otherwise returns the new web_contents
// of the discarded tab.
content::WebContents* DiscardTabById(int64_t target_web_contents_id,
DiscardTabCondition condition);
DiscardCondition condition);
// Method used by the extensions API to discard tabs. If |contents| is null,
// discards the least important tab using DiscardTab(). Otherwise discards
......@@ -135,7 +132,7 @@ class TabManager : public TabStripModelObserver,
// Log memory statistics for the running processes, then discards a tab.
// Tab discard happens sometime later, as collecting the statistics touches
// multiple threads and takes time.
void LogMemoryAndDiscardTab(DiscardTabCondition condition);
void LogMemoryAndDiscardTab(DiscardCondition condition);
// Log memory statistics for the running processes, then call the callback.
void LogMemory(const std::string& title, const base::Closure& callback);
......@@ -310,7 +307,7 @@ class TabManager : public TabStripModelObserver,
void OnAutoDiscardableStateChange(content::WebContents* contents,
bool is_auto_discardable);
static void PurgeMemoryAndDiscardTab(DiscardTabCondition condition);
static void PurgeMemoryAndDiscardTab(DiscardCondition condition);
// Returns true if the |url| represents an internal Chrome web UI page that
// can be easily reloaded and hence makes a good choice to discard.
......@@ -365,7 +362,7 @@ class TabManager : public TabStripModelObserver,
// the operation fails (return value used only in testing).
content::WebContents* DiscardWebContentsAt(int index,
TabStripModel* model,
DiscardTabCondition condition);
DiscardCondition condition);
// Pause or resume background tab opening according to memory pressure change
// if there are pending background tabs.
......@@ -403,7 +400,7 @@ class TabManager : public TabStripModelObserver,
// Implementation of DiscardTab. Returns null if no tab was discarded.
// Otherwise returns the new web_contents of the discarded tab.
content::WebContents* DiscardTabImpl(DiscardTabCondition condition);
content::WebContents* DiscardTabImpl(DiscardCondition condition);
// Returns true if tabs can be discarded only once.
bool CanOnlyDiscardOnce() const;
......
......@@ -423,8 +423,7 @@ void TabManagerDelegate::ScheduleEarlyOomPrioritiesAdjustment() {
// If able to get the list of ARC procsses, prioritize tabs and apps as a whole.
// Otherwise try to kill tabs only.
void TabManagerDelegate::LowMemoryKill(
TabManager::DiscardTabCondition condition) {
void TabManagerDelegate::LowMemoryKill(DiscardCondition condition) {
LoadTabListAndArcProcesses(
tab_manager_, base::BindOnce(&TabManagerDelegate::LowMemoryKillImpl,
weak_ptr_factory_.GetWeakPtr(), condition));
......@@ -609,7 +608,7 @@ bool TabManagerDelegate::KillArcProcess(const int nspid) {
}
bool TabManagerDelegate::KillTab(const TabStats& tab_stats,
TabManager::DiscardTabCondition condition) {
DiscardCondition condition) {
// Check |tab_manager_| is alive before taking tabs into consideration.
return tab_manager_ && tab_manager_->CanDiscardTab(tab_stats) &&
tab_manager_->DiscardTabById(tab_stats.tab_contents_id, condition);
......@@ -620,7 +619,7 @@ chromeos::DebugDaemonClient* TabManagerDelegate::GetDebugDaemonClient() {
}
void TabManagerDelegate::LowMemoryKillImpl(
TabManager::DiscardTabCondition condition,
DiscardCondition condition,
const TabStatsList& tab_list,
const std::vector<arc::ArcProcess>& arc_processes) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
......
......@@ -74,7 +74,7 @@ class TabManagerDelegate : public wm::ActivationChangeObserver,
aura::Window* lost_active) override;
// Kills a process on memory pressure.
void LowMemoryKill(TabManager::DiscardTabCondition condition);
void LowMemoryKill(DiscardCondition condition);
// Returns oom_score_adj of a process if the score is cached by |this|.
// If couldn't find the score in the cache, returns -1001 since the valid
......@@ -96,8 +96,7 @@ class TabManagerDelegate : public wm::ActivationChangeObserver,
// Kills a tab. Returns true if the tab is killed successfully.
// Virtual for unit testing.
virtual bool KillTab(const TabStats& tab_stats,
TabManager::DiscardTabCondition condition);
virtual bool KillTab(const TabStats& tab_stats, DiscardCondition condition);
// Get debugd client instance. Virtual for unit testing.
virtual chromeos::DebugDaemonClient* GetDebugDaemonClient();
......@@ -141,7 +140,7 @@ class TabManagerDelegate : public wm::ActivationChangeObserver,
void OnFocusTabScoreAdjustmentTimeout();
// Kills a process after getting all info of tabs and apps.
void LowMemoryKillImpl(TabManager::DiscardTabCondition condition,
void LowMemoryKillImpl(DiscardCondition condition,
const TabStatsList& tab_list,
const std::vector<arc::ArcProcess>& arc_processes);
......
......@@ -159,8 +159,7 @@ class MockTabManagerDelegate : public TabManagerDelegate {
return true;
}
bool KillTab(const TabStats& tab_stats,
TabManager::DiscardTabCondition condition) override {
bool KillTab(const TabStats& tab_stats, DiscardCondition condition) override {
killed_tabs_.push_back(tab_stats.tab_contents_id);
return true;
}
......@@ -339,7 +338,7 @@ TEST_F(TabManagerDelegateTest, DoNotKillRecentlyKilledArcProcesses) {
memory_stat->SetTargetMemoryToFreeKB(250000);
memory_stat->SetProcessPss(30, 10000);
TabStatsList tab_list;
tab_manager_delegate.LowMemoryKillImpl(TabManager::kUrgentShutdown, tab_list,
tab_manager_delegate.LowMemoryKillImpl(DiscardCondition::kUrgent, tab_list,
arc_processes);
auto killed_arc_processes = tab_manager_delegate.GetKilledArcProcesses();
......@@ -417,8 +416,8 @@ TEST_F(TabManagerDelegateTest, KillMultipleProcesses) {
memory_stat->SetProcessPss(20, 30000);
memory_stat->SetProcessPss(10, 100000);
tab_manager_delegate.LowMemoryKillImpl(TabManager::kProactiveShutdown,
tab_list, arc_processes);
tab_manager_delegate.LowMemoryKillImpl(DiscardCondition::kProactive, tab_list,
arc_processes);
auto killed_arc_processes = tab_manager_delegate.GetKilledArcProcesses();
auto killed_tabs = tab_manager_delegate.GetKilledTabs();
......
......@@ -431,7 +431,7 @@ TEST_F(TabManagerTest, DiscardWebContentsAt) {
// Discard one of the tabs.
WebContents* null_contents1 = tab_manager.DiscardWebContentsAt(
0, &tabstrip, TabManager::kProactiveShutdown);
0, &tabstrip, DiscardCondition::kProactive);
ASSERT_EQ(2, tabstrip.count());
EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
......@@ -446,7 +446,7 @@ TEST_F(TabManagerTest, DiscardWebContentsAt) {
tab_manager.GetWebContentsData(tabstrip.GetWebContentsAt(0))
->SetDiscardState(false);
WebContents* null_contents2 = tab_manager.DiscardWebContentsAt(
0, &tabstrip, TabManager::kProactiveShutdown);
0, &tabstrip, DiscardCondition::kProactive);
ASSERT_EQ(2, tabstrip.count());
EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
......@@ -489,8 +489,7 @@ TEST_F(TabManagerTest, ReloadDiscardedTabContextMenu) {
->NavigateAndCommit(GURL("chrome://newtab"));
EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
tab_manager.DiscardWebContentsAt(1, &tabstrip,
TabManager::kProactiveShutdown);
tab_manager.DiscardWebContentsAt(1, &tabstrip, DiscardCondition::kProactive);
EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
tabstrip.GetWebContentsAt(1)->GetController().Reload(
......@@ -519,7 +518,7 @@ TEST_F(TabManagerTest, DiscardedTabKeepsLastActiveTime) {
EXPECT_EQ(new_last_active_time, test_contents->GetLastActiveTime());
WebContents* null_contents = tab_manager.DiscardWebContentsAt(
1, &tabstrip, TabManager::kProactiveShutdown);
1, &tabstrip, DiscardCondition::kProactive);
EXPECT_EQ(new_last_active_time, null_contents->GetLastActiveTime());
tabstrip.CloseAllTabs();
......@@ -759,7 +758,7 @@ TEST_F(TabManagerTest, DiscardTabWithNonVisibleTabs) {
tab_manager.test_browser_info_list_.push_back(browser_info2);
for (int i = 0; i < 4; ++i)
tab_manager.DiscardTab(TabManager::kProactiveShutdown);
tab_manager.DiscardTab(DiscardCondition::kProactive);
// Active tab in a visible window should not be discarded.
EXPECT_FALSE(tab_manager.IsTabDiscarded(tab_strip1.GetWebContentsAt(0)));
......
......@@ -428,23 +428,21 @@ std::string AboutDiscards(const std::string& path) {
std::vector<std::string> url_split =
base::SplitString(path, "?", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
if (!url_split.empty()) {
resource_coordinator::TabManager::DiscardTabCondition discard_condition;
if ((url_split.size() > 1 &&
url_split[1] == kAboutDiscardsSkipUnloadHandlersCommand)) {
discard_condition = resource_coordinator::TabManager::kUrgentShutdown;
} else {
discard_condition = resource_coordinator::TabManager::kProactiveShutdown;
}
resource_coordinator::DiscardCondition condition =
(url_split.size() > 1 &&
url_split[1] == kAboutDiscardsSkipUnloadHandlersCommand)
? resource_coordinator::DiscardCondition::kUrgent
: resource_coordinator::DiscardCondition::kProactive;
std::vector<std::string> path_split = base::SplitString(
url_split[0], "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
if (path_split.size() == 2 && path_split[0] == kAboutDiscardsRunCommand &&
base::StringToInt64(path_split[1], &web_content_id)) {
tab_manager->DiscardTabById(web_content_id, discard_condition);
tab_manager->DiscardTabById(web_content_id, condition);
return BuildAboutDiscardsRunPage();
} else if (path_split.size() == 1 &&
path_split[0] == kAboutDiscardsRunCommand) {
tab_manager->DiscardTab(discard_condition);
tab_manager->DiscardTab(condition);
return BuildAboutDiscardsRunPage();
}
}
......
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