xref: /aosp_15_r20/external/cronet/base/task/sequence_manager/thread_controller_power_monitor.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2020 The Chromium Authors
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 "base/task/sequence_manager/thread_controller_power_monitor.h"
6 
7 #include "base/feature_list.h"
8 #include "base/power_monitor/power_monitor.h"
9 #include "base/trace_event/base_tracing.h"
10 
11 namespace base {
12 namespace sequence_manager {
13 namespace internal {
14 
15 namespace {
16 
17 // Activate the power management events that affect task scheduling.
18 BASE_FEATURE(kUsePowerMonitorWithThreadController,
19              "UsePowerMonitorWithThreadController",
20              FEATURE_ENABLED_BY_DEFAULT);
21 
22 // TODO(1074332): Remove this when the experiment becomes the default.
23 bool g_use_thread_controller_power_monitor_ = false;
24 
25 }  // namespace
26 
27 ThreadControllerPowerMonitor::ThreadControllerPowerMonitor() = default;
28 
~ThreadControllerPowerMonitor()29 ThreadControllerPowerMonitor::~ThreadControllerPowerMonitor() {
30   PowerMonitor::RemovePowerSuspendObserver(this);
31 }
32 
BindToCurrentThread()33 void ThreadControllerPowerMonitor::BindToCurrentThread() {
34   // Occasionally registration happens twice (i.e. when the
35   // ThreadController::SetDefaultTaskRunner() re-initializes the
36   // ThreadController).
37   if (is_observer_registered_)
38     PowerMonitor::RemovePowerSuspendObserver(this);
39 
40   // Register the observer to deliver notifications on the current thread.
41   PowerMonitor::AddPowerSuspendObserver(this);
42   is_observer_registered_ = true;
43 }
44 
IsProcessInPowerSuspendState()45 bool ThreadControllerPowerMonitor::IsProcessInPowerSuspendState() {
46   return is_power_suspended_;
47 }
48 
49 // static
InitializeFeatures()50 void ThreadControllerPowerMonitor::InitializeFeatures() {
51   DCHECK(!g_use_thread_controller_power_monitor_);
52   g_use_thread_controller_power_monitor_ =
53       FeatureList::IsEnabled(kUsePowerMonitorWithThreadController);
54 }
55 
56 // static
OverrideUsePowerMonitorForTesting(bool use_power_monitor)57 void ThreadControllerPowerMonitor::OverrideUsePowerMonitorForTesting(
58     bool use_power_monitor) {
59   g_use_thread_controller_power_monitor_ = use_power_monitor;
60 }
61 
62 // static
ResetForTesting()63 void ThreadControllerPowerMonitor::ResetForTesting() {
64   g_use_thread_controller_power_monitor_ = false;
65 }
66 
OnSuspend()67 void ThreadControllerPowerMonitor::OnSuspend() {
68   if (!g_use_thread_controller_power_monitor_)
69     return;
70   DCHECK(!is_power_suspended_);
71 
72   TRACE_EVENT_BEGIN("base", "ThreadController::Suspended",
73                     perfetto::Track(reinterpret_cast<uint64_t>(this),
74                                     perfetto::ThreadTrack::Current()));
75   is_power_suspended_ = true;
76 }
77 
OnResume()78 void ThreadControllerPowerMonitor::OnResume() {
79   if (!g_use_thread_controller_power_monitor_)
80     return;
81 
82   // It is possible a suspend was already happening before the observer was
83   // added to the power monitor. Ignoring the resume notification in that case.
84   if (is_power_suspended_) {
85     TRACE_EVENT_END("base" /* ThreadController::Suspended */,
86                     perfetto::Track(reinterpret_cast<uint64_t>(this),
87                                     perfetto::ThreadTrack::Current()));
88     is_power_suspended_ = false;
89   }
90 }
91 
92 }  // namespace internal
93 }  // namespace sequence_manager
94 }  // namespace base
95