blob: 93eedde8c34a03ec733e65c60d1fd4481503b817 [file] [log] [blame]
// 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_TAB_MANAGER_FEATURES_H_
#define CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_FEATURES_H_
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/no_destructor.h"
#include "base/system/sys_info.h"
#include "base/time/time.h"
namespace features {
extern const base::Feature kCustomizedTabLoadTimeout;
extern const base::Feature kProactiveTabFreezeAndDiscard;
extern const base::Feature kStaggeredBackgroundTabOpening;
extern const base::Feature kStaggeredBackgroundTabOpeningExperiment;
extern const base::Feature kTabRanker;
} // namespace features
namespace resource_coordinator {
// The name of the ProactiveTabFreezeAndDiscard feature.
extern const char kProactiveTabFreezeAndDiscardFeatureName[];
// The name of the |ShouldProactivelyDiscard| parameter of the
// ProactiveTabFreezeAndDiscard feature.
extern const char kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscardParam[];
// The name of the |ShouldPeriodicallyUnfreeze| parameter of the
// ProactiveTabFreezeAndDiscard feature.
extern const char
kProactiveTabFreezeAndDiscard_ShouldPeriodicallyUnfreezeParam[];
// The name of the |FreezingProtectMediaOnly| parameter of the
// ProactiveTabFreezeAndDiscard feature.
extern const char kProactiveTabFreezeAndDiscard_FreezingProtectMediaOnlyParam[];
// Parameters used by the proactive tab discarding feature.
//
// Proactive discarding has 5 key parameters:
//
// - min/max occluded timeouts
// - min/soft_max/hard_max loaded tab counts
//
// Proactive tab discarding decisions are made at two points in time:
//
// - when a new tab is created
// - when a max occluded timeout fires
//
// The following is a description of the initial simple proactive discarding
// logic. First, the number of loaded tabs is converted into one of 4 tab count
// states (LOW, MODERATE, HIGH, EXCESSIVE) using 3 simple thresholds.
//
// +-------+----------+---------+-----------+
// + LOW | MODERATE | HIGH | EXCESSIVE |
// +-------+----------+---------+-----------+
// 0 n_low n_mod n_high +inf
//
// Depending on the tab count state, tabs are eligible for proactive discarding
// at different time tresholds, where the timeout is longer for lower tab
// count states. When in the low state the timeout is effectively infinite (no
// proactive discarding will occur), and when in the excessive state the timeout
// is zero (discarding will occur immediately).
//
// This logic is independent of urgent discarding, which may embark when things
// are sufficiently bad. Similarly, manual or extension driven discards can
// override this logic. Finally, proactive discarding can only discard occluded
// tabs, so it is always possible to have arbitrarily many visible tabs.
//
// NOTE: This is extremely simplistic, and by design. We will be using this to
// do a very simple "lightspeed" experiment to determine how much possible
// savings proactive discarding can hope to achieve.
struct ProactiveTabFreezeAndDiscardParams {
ProactiveTabFreezeAndDiscardParams();
ProactiveTabFreezeAndDiscardParams(
const ProactiveTabFreezeAndDiscardParams& rhs);
// Static definition of the different parameters that can be used by this
// feature.
static constexpr base::FeatureParam<bool> kShouldProactivelyDiscard{
&features::kProactiveTabFreezeAndDiscard,
kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscardParam, false};
static constexpr base::FeatureParam<bool> kShouldPeriodicallyUnfreeze{
&features::kProactiveTabFreezeAndDiscard,
kProactiveTabFreezeAndDiscard_ShouldPeriodicallyUnfreezeParam, false};
// 50% of people cap out at 4 tabs, so for them proactive discarding won't
// even be invoked. See Tabs.MaxTabsInADay.
// TODO(chrisha): This should eventually be informed by the number of tabs
// typically used over a given time horizon (metric being developed).
static constexpr base::FeatureParam<int> kLowLoadedTabCount{
&features::kProactiveTabFreezeAndDiscard, "LowLoadedTabCount", 4};
// Testing in the lab shows that 2GB devices suffer beyond 6 tabs, and 4GB
// devices suffer beyond about 12 tabs. As a very simple first step, we'll aim
// at allowing 3 tabs per GB of RAM on a system before proactive discarding
// kicks in. This is a system resource dependent max, which is combined with
// the DefaultMaxLoadedTabCount to determine the max on a system.
static constexpr base::FeatureParam<int> kModerateLoadedTabsPerGbRam{
&features::kProactiveTabFreezeAndDiscard, "ModerateLoadedTabsPerGbRam",
3};
// 99.9% of people cap out with fewer than this number, so only 0.1% of the
// population should ever encounter proactive discarding based on this cap.
static constexpr base::FeatureParam<int> kHighLoadedTabCount{
&features::kProactiveTabFreezeAndDiscard, "HighLoadedTabCount", 100};
// Current discarding uses 10 minutes as a minimum cap. This uses
// exponentially increasing timeouts beyond that.
static constexpr base::FeatureParam<int> kLowOccludedTimeout{
&features::kProactiveTabFreezeAndDiscard, "LowOccludedTimeoutSeconds",
6 * base::Time::kSecondsPerHour};
static constexpr base::FeatureParam<int> kModerateOccludedTimeout{
&features::kProactiveTabFreezeAndDiscard,
"ModerateOccludedTimeoutSeconds", 1 * base::Time::kSecondsPerHour};
static constexpr base::FeatureParam<int> kHighOccludedTimeout{
&features::kProactiveTabFreezeAndDiscard, "HighOccludedTimeoutSeconds",
10 * base::Time::kSecondsPerMinute};
static constexpr base::FeatureParam<int> kFreezeTimeout{
&features::kProactiveTabFreezeAndDiscard, "FreezeTimeout",
5 * base::Time::kSecondsPerMinute};
static constexpr base::FeatureParam<int> kUnfreezeTimeout{
&features::kProactiveTabFreezeAndDiscard, "UnfreezeTimeout",
15 * base::Time::kSecondsPerMinute};
static constexpr base::FeatureParam<int> kRefreezeTimeout{
&features::kProactiveTabFreezeAndDiscard, "RefreezeTimeout", 10};
static constexpr base::FeatureParam<bool> kFreezingProtectMediaOnly{
&features::kProactiveTabFreezeAndDiscard,
kProactiveTabFreezeAndDiscard_FreezingProtectMediaOnlyParam, false};
// Whether tabs should be proactively discarded. When the
// |kProactiveTabFreezeAndDiscard| feature is enabled and this is false, only
// proactive tab freezing happens.
bool should_proactively_discard;
// Whether frozen tabs should periodically be unfrozen to update their state.
bool should_periodically_unfreeze;
// Tab count (inclusive) beyond which the state transitions to MODERATE.
// Intended to cover the majority of simple workflows and be small enough that
// it is very unlikely that memory pressure will be encountered with this many
// tabs loaded.
int low_loaded_tab_count;
// Tab count (inclusive) beyond which the state transitions to HIGH. This
// value is determined based on the available system memory, and is ensured to
// be in the interval [low_loaded_tab_count, high_loaded_tab_count].
int moderate_loaded_tab_count;
// Tab count (inclusive) beyond which the state transitions to EXCESSIVE.
// Not relative to system memory, as its intended to be a hard cap
// more akin to a maximum mental model size.
int high_loaded_tab_count;
// Amount of time a tab must be occluded before eligible for proactive
// discard when the tab count state is LOW.
base::TimeDelta low_occluded_timeout;
// Amount of time a tab must be occluded before eligible for proactive
// discard when the tab count state is MODERATE.
base::TimeDelta moderate_occluded_timeout;
// Amount of time a tab must be occluded before eligible for proactive
// discard when the tab count state is HIGH.
base::TimeDelta high_occluded_timeout;
// Amount of time a tab must be occluded before it is frozen.
base::TimeDelta freeze_timeout;
// Amount of time a tab must be unfrozen before it is temporarily unfrozen.
base::TimeDelta unfreeze_timeout;
// Amount of time that a tab stays unfrozen before being frozen again.
base::TimeDelta refreeze_timeout;
// Only media tabs are protected from freezing.
bool freezing_protect_media_only;
};
// Gets parameters for the proactive tab discarding feature. This does no
// parameter validation, and sets the default values if the feature is not
// enabled.
ProactiveTabFreezeAndDiscardParams GetProactiveTabFreezeAndDiscardParams(
int memory_in_gb = base::SysInfo::AmountOfPhysicalMemory() /
(1024 * 1024 * 1024));
// Return a static ProactiveTabFreezeAndDiscardParams object that can be used by
// all the classes that need one.
const ProactiveTabFreezeAndDiscardParams&
GetStaticProactiveTabFreezeAndDiscardParams();
ProactiveTabFreezeAndDiscardParams*
GetMutableStaticProactiveTabFreezeAndDiscardParamsForTesting();
base::TimeDelta GetTabLoadTimeout(const base::TimeDelta& default_timeout);
// Gets number of oldest tab that should be scored by TabRanker.
int GetNumOldestTabsToScoreWithTabRanker();
// Gets ProcessType of tabs that should be scored by TabRanker.
int GetProcessTypeToScoreWithTabRanker();
// Gets number of oldest tabs that should be logged by TabRanker.
int GetNumOldestTabsToLogWithTabRanker();
// Whether to disable background time TabMetrics log.
bool DisableBackgroundLogWithTabRanker();
// Gets reload count penalty parameter for TabRanker.
float GetDiscardCountPenaltyTabRanker();
// Gets mru penalty parameter that converts mru index to scores.
float GetMRUScorerPenaltyTabRanker();
// Gets which type of scorer to use for TabRanker.
int GetScorerTypeForTabRanker();
} // namespace resource_coordinator
#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_FEATURES_H_