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