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