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