• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 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 #ifndef BASE_POWER_MONITOR_BATTERY_STATE_SAMPLER_H_
6 #define BASE_POWER_MONITOR_BATTERY_STATE_SAMPLER_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "base/base_export.h"
12 #include "base/observer_list.h"
13 #include "base/observer_list_types.h"
14 #include "base/power_monitor/battery_level_provider.h"
15 #include "base/power_monitor/power_monitor_buildflags.h"
16 #include "base/power_monitor/sampling_event_source.h"
17 #include "base/sequence_checker.h"
18 #include "third_party/abseil-cpp/absl/types/optional.h"
19 
20 namespace base {
21 
22 // Periodically samples the battery and notifies its observers.
23 class BASE_EXPORT BatteryStateSampler {
24  public:
25   class Observer : public base::CheckedObserver {
26    public:
27     // Note: The first sample taken by the BatteryStateSampler may be out of
28     // date (i.e. represent the battery state at an earlier time). Observers
29     // that want to ignore those stale samples should ignore the first call to
30     // OnBatteryStateSampled.
31     virtual void OnBatteryStateSampled(
32         const absl::optional<BatteryLevelProvider::BatteryState>&
33             battery_state) = 0;
34   };
35 
36   // Creates a BatteryStateSampler and initializes the global instance. Will
37   // DCHECK if an instance already exists.
38   BatteryStateSampler(
39       std::unique_ptr<SamplingEventSource> sampling_event_source =
40           CreateSamplingEventSource(),
41       std::unique_ptr<BatteryLevelProvider> battery_level_provider =
42           BatteryLevelProvider::Create());
43   ~BatteryStateSampler();
44 
45   // Returns the unique instance, or nullptr on platforms without a
46   // `BatteryLevelProvider` implementation.
47   static BatteryStateSampler* Get();
48 
49   // Adds/removes an observer. `OnBatteryStateSampled` will be immediately
50   // invoked upon adding an observer if an existing sample exists already.
51   void AddObserver(Observer* observer);
52   void RemoveObserver(Observer* observer);
53 
54   // Shuts down this instance but doesn't destroy it. This allows it to remain
55   // alive for its observers to deregister as they are destroyed without causing
56   // use-after-frees, but it won't serve any samples after this is called.
57   // Invoked in `PostMainMessageLoopRun`.
58   void Shutdown();
59 
60   // Creates, installs, and returns an instance of the sampler for testing.
61   // This is meant to be used in browser tests before browser init to control
62   // the sampler's behavior in the tests.
63   static std::unique_ptr<base::BatteryStateSampler> CreateInstanceForTesting(
64       std::unique_ptr<SamplingEventSource> sampling_event_source,
65       std::unique_ptr<BatteryLevelProvider> battery_level_provider);
66 
67   // Returns true if a sampler has been created using `CreateInstanceForTesting`
68   static bool HasTestingInstance();
69 
70  private:
71   // Returns a platform specific SamplingEventSource.
72   static std::unique_ptr<SamplingEventSource> CreateSamplingEventSource();
73 
74   // Called when the first battery sampled is obtained. Notifies current
75   // observers as they are waiting on the cached battery state.
76   void OnInitialBatteryStateSampled(
77       const absl::optional<BatteryLevelProvider::BatteryState>& battery_state);
78 
79   // Triggers the sampling of the battery state.
80   void OnSamplingEvent();
81 
82   // Notifies observers of the sampled battery state.
83   void OnBatteryStateSampled(
84       const absl::optional<BatteryLevelProvider::BatteryState>& battery_state);
85 
86   std::unique_ptr<SamplingEventSource> sampling_event_source_
87       GUARDED_BY_CONTEXT(sequence_checker_);
88 
89   std::unique_ptr<BatteryLevelProvider> battery_level_provider_
90       GUARDED_BY_CONTEXT(sequence_checker_);
91 
92   base::ObserverList<Observer> observer_list_
93       GUARDED_BY_CONTEXT(sequence_checker_);
94 
95   // Indicates if |last_battery_state_| contains an actual sample. Note: a
96   // separate bool is used to avoid nested optionals.
97   bool has_last_battery_state_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
98 
99   // The value of the last sample taken.
100   absl::optional<BatteryLevelProvider::BatteryState> last_battery_state_
101       GUARDED_BY_CONTEXT(sequence_checker_);
102 
103   SEQUENCE_CHECKER(sequence_checker_);
104 };
105 
106 }  // namespace base
107 
108 #endif  // BASE_POWER_MONITOR_BATTERY_STATE_SAMPLER_H_
109