• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/unique_fd.h>
24 #include <healthd/healthd.h>
25 
26 namespace android {
27 namespace hardware {
28 namespace health {
29 
30 class HealthLoop {
31   public:
32     HealthLoop();
33 
34     // Client is responsible for holding this forever. Process will exit
35     // when this is destroyed.
36     virtual ~HealthLoop();
37 
38     // Initialize and start the main loop. This function does not exit unless
39     // the process is interrupted.
40     // Once the loop is started, event handlers are no longer allowed to be
41     // registered.
42     int StartLoop();
43 
44   protected:
45     // healthd_mode_ops overrides. Note that healthd_mode_ops->battery_update
46     // is missing because it is only used by BatteryMonitor.
47     // Init is called right after epollfd_ is initialized (so RegisterEvent
48     // is allowed) but before other things are initialized (so SetChargerOnline
49     // is not allowed.)
50     // The implementation of Init() should pull configuration from the
51     // underlying health HAL (via getHealthConfig()), and store it into
52     // |config|. The implementation may not initialize:
53     // - screen_on, because charger calls getScreenOn() from the HAL directly
54     // - ignorePowerSupplyNames, because it isn't used by any clients of the
55     // health HAL.
56     virtual void Init(healthd_config* config) = 0;
57     virtual void Heartbeat() = 0;
58     virtual int PrepareToWait() = 0;
59 
60     // Note that this is NOT healthd_mode_ops->battery_update(BatteryProperties*),
61     // which is called by BatteryMonitor after values are fetched. This is the
62     // implementation of healthd_battery_update(), which calls
63     // the correct IHealth::update(),
64     // which calls BatteryMonitor::update(), which calls
65     // healthd_mode_ops->battery_update(BatteryProperties*).
66     virtual void ScheduleBatteryUpdate() = 0;
67 
68     // Register an epoll event. When there is an event, |func| will be
69     // called with |this| as the first argument and |epevents| as the second.
70     // This may be called in a different thread from where StartLoop is called
71     // (for obvious reasons; StartLoop never ends).
72     // Once the loop is started, event handlers are no longer allowed to be
73     // registered.
74     using BoundFunction = std::function<void(HealthLoop*, uint32_t /* epevents */)>;
75     int RegisterEvent(int fd, BoundFunction func, EventWakeup wakeup);
76 
77     // Helper for implementing ScheduleBatteryUpdate(). An implementation of
78     // ScheduleBatteryUpdate should get charger_online from BatteryMonitor::update(),
79     // then reset wake alarm interval by calling AdjustWakealarmPeriods.
80     void AdjustWakealarmPeriods(bool charger_online);
81 
82   private:
83     struct EventHandler {
84         HealthLoop* object = nullptr;
85         int fd;
86         BoundFunction func;
87     };
88 
89     int InitInternal();
90     void MainLoop();
91     void WakeAlarmInit();
92     void WakeAlarmEvent(uint32_t);
93     void UeventInit();
94     void UeventEvent(uint32_t);
95     void WakeAlarmSetInterval(int interval);
96     void PeriodicChores();
97 
98     // These are fixed after InitInternal() is called.
99     struct healthd_config healthd_config_;
100     android::base::unique_fd wakealarm_fd_;
101     android::base::unique_fd uevent_fd_;
102 
103     android::base::unique_fd epollfd_;
104     std::vector<std::unique_ptr<EventHandler>> event_handlers_;
105     int awake_poll_interval_;  // -1 for no epoll timeout
106     int wakealarm_wake_interval_;
107 
108     // If set to true, future RegisterEvent() will be rejected. This is to ensure all
109     // events are registered before StartLoop().
110     bool reject_event_register_ = false;
111 };
112 
113 }  // namespace health
114 }  // namespace hardware
115 }  // namespace android
116