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