xref: /aosp_15_r20/hardware/interfaces/health/utils/libhealthloop/include/health/HealthLoop.h (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <functional>
19 #include <memory>
20 #include <mutex>
21 #include <vector>
22 
23 #include <android-base/result.h>
24 #include <android-base/unique_fd.h>
25 #include <healthd/healthd.h>
26 
27 namespace android {
28 namespace hardware {
29 namespace health {
30 
31 class HealthLoop {
32   public:
33     HealthLoop();
34 
35     // Client is responsible for holding this forever. Process will exit
36     // when this is destroyed.
37     virtual ~HealthLoop();
38 
39     // Initialize and start the main loop. This function does not exit unless
40     // the process is interrupted.
41     // Once the loop is started, event handlers are no longer allowed to be
42     // registered.
43     int StartLoop();
44 
45   protected:
46     // healthd_mode_ops overrides. Note that healthd_mode_ops->battery_update
47     // is missing because it is only used by BatteryMonitor.
48     // Init is called right after epollfd_ is initialized (so RegisterEvent
49     // is allowed) but before other things are initialized (so SetChargerOnline
50     // is not allowed.)
51     // The implementation of Init() should pull configuration from the
52     // underlying health HAL (via getHealthConfig()), and store it into
53     // |config|. The implementation may not initialize:
54     // - screen_on, because charger calls getScreenOn() from the HAL directly
55     // - ignorePowerSupplyNames, because it isn't used by any clients of the
56     // health HAL.
57     virtual void Init(healthd_config* config) = 0;
58     virtual void Heartbeat() = 0;
59     virtual int PrepareToWait() = 0;
60 
61     // Note that this is NOT healthd_mode_ops->battery_update(BatteryProperties*),
62     // which is called by BatteryMonitor after values are fetched. This is the
63     // implementation of healthd_battery_update(), which calls
64     // the correct IHealth::update(),
65     // which calls BatteryMonitor::update(), which calls
66     // healthd_mode_ops->battery_update(BatteryProperties*).
67     virtual void ScheduleBatteryUpdate() = 0;
68 
69     // Register an epoll event. When there is an event, |func| will be
70     // called with |this| as the first argument and |epevents| as the second.
71     // This may be called in a different thread from where StartLoop is called
72     // (for obvious reasons; StartLoop never ends).
73     // Once the loop is started, event handlers are no longer allowed to be
74     // registered.
75     using BoundFunction = std::function<void(HealthLoop*, uint32_t /* epevents */)>;
76     int RegisterEvent(int fd, BoundFunction func, EventWakeup wakeup);
77 
78     // Helper for implementing ScheduleBatteryUpdate(). An implementation of
79     // ScheduleBatteryUpdate should get charger_online from BatteryMonitor::update(),
80     // then reset wake alarm interval by calling AdjustWakealarmPeriods.
81     void AdjustWakealarmPeriods(bool charger_online);
82 
83   private:
84     struct EventHandler {
85         HealthLoop* object = nullptr;
86         int fd;
87         BoundFunction func;
88     };
89 
90     int InitInternal();
91     static android::base::Result<void> AttachFilter(int uevent_fd);
92     void MainLoop();
93     void WakeAlarmInit();
94     void WakeAlarmEvent(uint32_t);
95     void UeventInit();
96     bool RecvUevents();
97     void UeventEvent(uint32_t);
98     void WakeAlarmSetInterval(int interval);
99     void PeriodicChores();
100 
101     // These are fixed after InitInternal() is called.
102     struct healthd_config healthd_config_;
103     android::base::unique_fd wakealarm_fd_;
104     android::base::unique_fd uevent_fd_;
105 
106     android::base::unique_fd epollfd_;
107     std::vector<std::unique_ptr<EventHandler>> event_handlers_;
108     int awake_poll_interval_;  // -1 for no epoll timeout
109     int wakealarm_wake_interval_;
110 
111     // If set to true, future RegisterEvent() will be rejected. This is to ensure all
112     // events are registered before StartLoop().
113     bool reject_event_register_ = false;
114 };
115 
116 }  // namespace health
117 }  // namespace hardware
118 }  // namespace android
119