1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/platform/scheduler/common/features.h"
6
7 #include "base/command_line.h"
8 #include "third_party/blink/public/common/features.h"
9 #include "third_party/blink/public/common/switches.h"
10 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
11
12 namespace blink {
13 namespace scheduler {
14
15 namespace {
16
17 enum class PolicyOverride { NO_OVERRIDE, FORCE_DISABLE, FORCE_ENABLE };
18
19 bool g_intensive_wake_up_throttling_policy_override_cached_ = false;
20
21 // Returns the IntensiveWakeUpThrottling policy settings. This is checked once
22 // on first access and cached. Note that that this is *not* thread-safe!
GetIntensiveWakeUpThrottlingPolicyOverride()23 PolicyOverride GetIntensiveWakeUpThrottlingPolicyOverride() {
24 static PolicyOverride policy = PolicyOverride::NO_OVERRIDE;
25 if (g_intensive_wake_up_throttling_policy_override_cached_)
26 return policy;
27
28 // Otherwise, check the command-line. Only values of "0" and "1" are valid,
29 // anything else is ignored (and allows the base::Feature to control the
30 // feature). This slow path will only be hit once per renderer process.
31 g_intensive_wake_up_throttling_policy_override_cached_ = true;
32 std::string value =
33 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
34 switches::kIntensiveWakeUpThrottlingPolicy);
35 if (value == switches::kIntensiveWakeUpThrottlingPolicy_ForceEnable) {
36 policy = PolicyOverride::FORCE_ENABLE;
37 } else if (value == switches::kIntensiveWakeUpThrottlingPolicy_ForceDisable) {
38 policy = PolicyOverride::FORCE_DISABLE;
39 } else {
40 // Necessary in testing configurations, as the policy can be parsed
41 // repeatedly.
42 policy = PolicyOverride::NO_OVERRIDE;
43 }
44
45 return policy;
46 }
47
48 } // namespace
49
ClearIntensiveWakeUpThrottlingPolicyOverrideCacheForTesting()50 void ClearIntensiveWakeUpThrottlingPolicyOverrideCacheForTesting() {
51 g_intensive_wake_up_throttling_policy_override_cached_ = false;
52 }
53
IsIntensiveWakeUpThrottlingEnabled()54 bool IsIntensiveWakeUpThrottlingEnabled() {
55 // If policy is present then respect it.
56 auto policy = GetIntensiveWakeUpThrottlingPolicyOverride();
57 if (policy != PolicyOverride::NO_OVERRIDE)
58 return policy == PolicyOverride::FORCE_ENABLE;
59 // Otherwise respect the base::Feature.
60 return base::FeatureList::IsEnabled(features::kIntensiveWakeUpThrottling);
61 }
62
63 // If a policy override is specified then stick to the published defaults so
64 // that admins get consistent behaviour that clients can't override. Otherwise
65 // use the base::FeatureParams.
66
GetIntensiveWakeUpThrottlingDurationBetweenWakeUps()67 base::TimeDelta GetIntensiveWakeUpThrottlingDurationBetweenWakeUps() {
68 DCHECK(IsIntensiveWakeUpThrottlingEnabled());
69
70 // Controls the period during which at most 1 wake up from throttleable
71 // TaskQueues in a page can take place.
72 static const base::FeatureParam<int>
73 kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds{
74 &features::kIntensiveWakeUpThrottling,
75 kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds_Name,
76 kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds_Default};
77
78 int seconds =
79 kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds_Default;
80 if (GetIntensiveWakeUpThrottlingPolicyOverride() ==
81 PolicyOverride::NO_OVERRIDE) {
82 seconds = kIntensiveWakeUpThrottling_DurationBetweenWakeUpsSeconds.Get();
83 }
84 return base::TimeDelta::FromSeconds(seconds);
85 }
86
GetIntensiveWakeUpThrottlingGracePeriod()87 base::TimeDelta GetIntensiveWakeUpThrottlingGracePeriod() {
88 DCHECK(IsIntensiveWakeUpThrottlingEnabled());
89
90 // Controls the time that elapses after a page is backgrounded before the
91 // throttling policy takes effect.
92 static const base::FeatureParam<int>
93 kIntensiveWakeUpThrottling_GracePeriodSeconds{
94 &features::kIntensiveWakeUpThrottling,
95 features::kIntensiveWakeUpThrottling_GracePeriodSeconds_Name,
96 kIntensiveWakeUpThrottling_GracePeriodSeconds_Default};
97
98 int seconds = kIntensiveWakeUpThrottling_GracePeriodSeconds_Default;
99 if (GetIntensiveWakeUpThrottlingPolicyOverride() ==
100 PolicyOverride::NO_OVERRIDE) {
101 seconds = kIntensiveWakeUpThrottling_GracePeriodSeconds.Get();
102 }
103 return base::TimeDelta::FromSeconds(seconds);
104 }
105
GetTimeToInhibitIntensiveThrottlingOnTitleOrFaviconUpdate()106 base::TimeDelta GetTimeToInhibitIntensiveThrottlingOnTitleOrFaviconUpdate() {
107 DCHECK(IsIntensiveWakeUpThrottlingEnabled());
108
109 constexpr int kDefaultSeconds = 3;
110
111 static const base::FeatureParam<int> kFeatureParam{
112 &features::kIntensiveWakeUpThrottling,
113 "inhibit_seconds_on_title_or_favicon_update_seconds", kDefaultSeconds};
114
115 int seconds = kDefaultSeconds;
116 if (GetIntensiveWakeUpThrottlingPolicyOverride() ==
117 PolicyOverride::NO_OVERRIDE) {
118 seconds = kFeatureParam.Get();
119 }
120
121 return base::TimeDelta::FromSeconds(seconds);
122 }
123
CanIntensivelyThrottleLowNestingLevel()124 bool CanIntensivelyThrottleLowNestingLevel() {
125 DCHECK(IsIntensiveWakeUpThrottlingEnabled());
126
127 static const base::FeatureParam<bool> kFeatureParam{
128 &features::kIntensiveWakeUpThrottling,
129 kIntensiveWakeUpThrottling_CanIntensivelyThrottleLowNestingLevel_Name,
130 kIntensiveWakeUpThrottling_CanIntensivelyThrottleLowNestingLevel_Default};
131
132 bool value =
133 kIntensiveWakeUpThrottling_CanIntensivelyThrottleLowNestingLevel_Default;
134 if (GetIntensiveWakeUpThrottlingPolicyOverride() ==
135 PolicyOverride::NO_OVERRIDE) {
136 value = kFeatureParam.Get();
137 }
138
139 return value;
140 }
141
142 } // namespace scheduler
143 } // namespace blink
144