blob: 54b2740c1b45b3c78f59c624acc3b5f17717a184 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <memory>
#include <mutex>
#include <vector>
#include <android-base/unique_fd.h>
#include <healthd/healthd.h>
namespace android {
namespace hardware {
namespace health {
class HealthLoop {
public:
HealthLoop();
// Client is responsible for holding this forever. Process will exit
// when this is destroyed.
virtual ~HealthLoop();
// Initialize and start the main loop. This function does not exit unless
// the process is interrupted.
// Once the loop is started, event handlers are no longer allowed to be
// registered.
int StartLoop();
protected:
// healthd_mode_ops overrides. Note that healthd_mode_ops->battery_update
// is missing because it is only used by BatteryMonitor.
// Init is called right after epollfd_ is initialized (so RegisterEvent
// is allowed) but before other things are initialized (so SetChargerOnline
// is not allowed.)
// The implementation of Init() should pull configuration from the
// underlying health HAL (via getHealthConfig()), and store it into
// |config|. The implementation may not initialize:
// - screen_on, because charger calls getScreenOn() from the HAL directly
// - ignorePowerSupplyNames, because it isn't used by any clients of the
// health HAL.
virtual void Init(healthd_config* config) = 0;
virtual void Heartbeat() = 0;
virtual int PrepareToWait() = 0;
// Note that this is NOT healthd_mode_ops->battery_update(BatteryProperties*),
// which is called by BatteryMonitor after values are fetched. This is the
// implementation of healthd_battery_update(), which calls
// the correct IHealth::update(),
// which calls BatteryMonitor::update(), which calls
// healthd_mode_ops->battery_update(BatteryProperties*).
virtual void ScheduleBatteryUpdate() = 0;
// Register an epoll event. When there is an event, |func| will be
// called with |this| as the first argument and |epevents| as the second.
// This may be called in a different thread from where StartLoop is called
// (for obvious reasons; StartLoop never ends).
// Once the loop is started, event handlers are no longer allowed to be
// registered.
using BoundFunction = std::function<void(HealthLoop*, uint32_t /* epevents */)>;
int RegisterEvent(int fd, BoundFunction func, EventWakeup wakeup);
// Helper for implementing ScheduleBatteryUpdate(). An implementation of
// ScheduleBatteryUpdate should get charger_online from BatteryMonitor::update(),
// then reset wake alarm interval by calling AdjustWakealarmPeriods.
void AdjustWakealarmPeriods(bool charger_online);
private:
struct EventHandler {
HealthLoop* object = nullptr;
int fd;
BoundFunction func;
};
int InitInternal();
void MainLoop();
void WakeAlarmInit();
void WakeAlarmEvent(uint32_t);
void UeventInit();
void UeventEvent(uint32_t);
void WakeAlarmSetInterval(int interval);
void PeriodicChores();
// These are fixed after InitInternal() is called.
struct healthd_config healthd_config_;
android::base::unique_fd wakealarm_fd_;
android::base::unique_fd uevent_fd_;
android::base::unique_fd epollfd_;
std::vector<std::unique_ptr<EventHandler>> event_handlers_;
int awake_poll_interval_; // -1 for no epoll timeout
int wakealarm_wake_interval_;
// If set to true, future RegisterEvent() will be rejected. This is to ensure all
// events are registered before StartLoop().
bool reject_event_register_ = false;
};
} // namespace health
} // namespace hardware
} // namespace android