mirror of
https://github.com/PixelExperience-Devices/device_xiaomi_sm6250-common.git
synced 2025-07-01 15:29:53 +09:00
sm6250-common: Update thermal HAL
* From hardware/google/pixel at d774cbb949e98627e4172bf8fc11e8d954599aa7. Change-Id: I3a3a0c29575d0595e71a30f1e64e33ca34d2eb27
This commit is contained in:
@ -15,6 +15,11 @@
|
||||
*/
|
||||
#include <cutils/uevent.h>
|
||||
#include <dirent.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
@ -23,8 +28,10 @@
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
|
||||
#include "thermal-helper.h"
|
||||
#include "thermal_watcher.h"
|
||||
|
||||
namespace android {
|
||||
@ -33,27 +40,360 @@ namespace thermal {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using std::chrono_literals::operator""ms;
|
||||
namespace {
|
||||
|
||||
void ThermalWatcher::registerFilesToWatch(const std::set<std::string> &sensors_to_watch,
|
||||
bool uevent_monitor) {
|
||||
monitored_sensors_.insert(sensors_to_watch.begin(), sensors_to_watch.end());
|
||||
if (!uevent_monitor) {
|
||||
is_polling_ = true;
|
||||
return;
|
||||
static int nlErrorHandle(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
|
||||
int *ret = reinterpret_cast<int *>(arg);
|
||||
*ret = err->error;
|
||||
LOG(ERROR) << __func__ << "nl_groups: " << nla->nl_groups << ", nl_pid: " << nla->nl_pid;
|
||||
|
||||
return NL_STOP;
|
||||
}
|
||||
|
||||
static int nlFinishHandle(struct nl_msg *msg, void *arg) {
|
||||
int *ret = reinterpret_cast<int *>(arg);
|
||||
*ret = 1;
|
||||
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
||||
|
||||
LOG(VERBOSE) << __func__ << ": nlmsg type: " << nlh->nlmsg_type;
|
||||
|
||||
return NL_OK;
|
||||
}
|
||||
|
||||
static int nlAckHandle(struct nl_msg *msg, void *arg) {
|
||||
int *ret = reinterpret_cast<int *>(arg);
|
||||
*ret = 1;
|
||||
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
||||
|
||||
LOG(VERBOSE) << __func__ << ": nlmsg type: " << nlh->nlmsg_type;
|
||||
|
||||
return NL_OK;
|
||||
}
|
||||
|
||||
static int nlSeqCheckHandle(struct nl_msg *msg, void *arg) {
|
||||
int *ret = reinterpret_cast<int *>(arg);
|
||||
*ret = 1;
|
||||
struct nlmsghdr *nlh = nlmsg_hdr(msg);
|
||||
|
||||
LOG(VERBOSE) << __func__ << ": nlmsg type: " << nlh->nlmsg_type;
|
||||
|
||||
return NL_OK;
|
||||
}
|
||||
|
||||
struct HandlerArgs {
|
||||
const char *group;
|
||||
int id;
|
||||
};
|
||||
|
||||
static int nlSendMsg(struct nl_sock *sock, struct nl_msg *msg,
|
||||
int (*rx_handler)(struct nl_msg *, void *), void *data) {
|
||||
int err, done = 0;
|
||||
|
||||
std::unique_ptr<nl_cb, decltype(&nl_cb_put)> cb(nl_cb_alloc(NL_CB_DEFAULT), nl_cb_put);
|
||||
|
||||
err = nl_send_auto_complete(sock, msg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = 0;
|
||||
nl_cb_err(cb.get(), NL_CB_CUSTOM, nlErrorHandle, &err);
|
||||
nl_cb_set(cb.get(), NL_CB_FINISH, NL_CB_CUSTOM, nlFinishHandle, &done);
|
||||
nl_cb_set(cb.get(), NL_CB_ACK, NL_CB_CUSTOM, nlAckHandle, &done);
|
||||
|
||||
if (rx_handler != NULL)
|
||||
nl_cb_set(cb.get(), NL_CB_VALID, NL_CB_CUSTOM, rx_handler, data);
|
||||
|
||||
while (err == 0 && done == 0) nl_recvmsgs(sock, cb.get());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nlFamilyHandle(struct nl_msg *msg, void *arg) {
|
||||
struct HandlerArgs *grp = reinterpret_cast<struct HandlerArgs *>(arg);
|
||||
struct nlattr *tb[CTRL_ATTR_MAX + 1];
|
||||
struct genlmsghdr *gnlh = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
|
||||
struct nlattr *mcgrp;
|
||||
int rem_mcgrp;
|
||||
|
||||
nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
|
||||
|
||||
if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
|
||||
LOG(ERROR) << __func__ << "Multicast group not found";
|
||||
return -1;
|
||||
}
|
||||
|
||||
nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], rem_mcgrp) {
|
||||
struct nlattr *tb_mcgrp[CTRL_ATTR_MCAST_GRP_MAX + 1];
|
||||
|
||||
nla_parse(tb_mcgrp, CTRL_ATTR_MCAST_GRP_MAX, reinterpret_cast<nlattr *>(nla_data(mcgrp)),
|
||||
nla_len(mcgrp), NULL);
|
||||
|
||||
if (!tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME] || !tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID])
|
||||
continue;
|
||||
|
||||
if (strncmp(reinterpret_cast<char *>(nla_data(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME])),
|
||||
grp->group, nla_len(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
|
||||
continue;
|
||||
|
||||
grp->id = nla_get_u32(tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nlGetMulticastId(struct nl_sock *sock, const char *family, const char *group) {
|
||||
int err = 0, ctrlid;
|
||||
struct HandlerArgs grp = {
|
||||
.group = group,
|
||||
.id = -ENOENT,
|
||||
};
|
||||
|
||||
std::unique_ptr<nl_msg, decltype(&nlmsg_free)> msg(nlmsg_alloc(), nlmsg_free);
|
||||
|
||||
ctrlid = genl_ctrl_resolve(sock, "nlctrl");
|
||||
|
||||
genlmsg_put(msg.get(), 0, 0, ctrlid, 0, 0, CTRL_CMD_GETFAMILY, 0);
|
||||
|
||||
nla_put_string(msg.get(), CTRL_ATTR_FAMILY_NAME, family);
|
||||
|
||||
err = nlSendMsg(sock, msg.get(), nlFamilyHandle, &grp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = grp.id;
|
||||
LOG(INFO) << group << " multicast_id: " << grp.id;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool socketAddMembership(struct nl_sock *sock, const char *group) {
|
||||
int mcid = nlGetMulticastId(sock, THERMAL_GENL_FAMILY_NAME, group);
|
||||
if (mcid < 0) {
|
||||
LOG(ERROR) << "Failed to get multicast id: " << group;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nl_socket_add_membership(sock, mcid)) {
|
||||
LOG(ERROR) << "Failed to add netlink socket membership: " << group;
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Added netlink socket membership: " << group;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int handleEvent(struct nl_msg *n, void *arg) {
|
||||
struct nlmsghdr *nlh = nlmsg_hdr(n);
|
||||
struct genlmsghdr *glh = genlmsg_hdr(nlh);
|
||||
struct nlattr *attrs[THERMAL_GENL_ATTR_MAX + 1];
|
||||
int *tz_id = reinterpret_cast<int *>(arg);
|
||||
|
||||
genlmsg_parse(nlh, 0, attrs, THERMAL_GENL_ATTR_MAX, NULL);
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_TZ_TRIP_UP) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_TZ_TRIP_UP";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
*tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
}
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
|
||||
LOG(INFO) << "Thermal zone trip id: "
|
||||
<< nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_TZ_TRIP_DOWN) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_TZ_TRIP_DOWN";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
*tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
}
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
|
||||
LOG(INFO) << "Thermal zone trip id: "
|
||||
<< nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_TZ_GOV_CHANGE) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_TZ_GOV_CHANGE";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
*tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
}
|
||||
if (attrs[THERMAL_GENL_ATTR_GOV_NAME])
|
||||
LOG(INFO) << "Governor name: " << nla_get_string(attrs[THERMAL_GENL_ATTR_GOV_NAME]);
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_TZ_CREATE) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_TZ_CREATE";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
*tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
}
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_NAME])
|
||||
LOG(INFO) << "Thermal zone name: " << nla_get_string(attrs[THERMAL_GENL_ATTR_TZ_NAME]);
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_TZ_DELETE) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_TZ_DELETE";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
*tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
}
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_TZ_DISABLE) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_TZ_DISABLE";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
*tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
}
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_TZ_ENABLE) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_TZ_ENABLE";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
*tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
}
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_TZ_TRIP_CHANGE) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_TZ_TRIP_CHANGE";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
*tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
}
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
|
||||
LOG(INFO) << "Trip id:: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_TYPE])
|
||||
LOG(INFO) << "Trip type: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TYPE]);
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_TEMP])
|
||||
LOG(INFO) << "Trip temp: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TEMP]);
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_HYST])
|
||||
LOG(INFO) << "Trip hyst: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_HYST]);
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_TZ_TRIP_ADD) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_TZ_TRIP_ADD";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID])
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
|
||||
LOG(INFO) << "Trip id:: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_TYPE])
|
||||
LOG(INFO) << "Trip type: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TYPE]);
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_TEMP])
|
||||
LOG(INFO) << "Trip temp: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TEMP]);
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_HYST])
|
||||
LOG(INFO) << "Trip hyst: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_HYST]);
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_TZ_TRIP_DELETE) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_TZ_TRIP_DELETE";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
*tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
}
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
|
||||
LOG(INFO) << "Trip id:: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_CDEV_STATE_UPDATE) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_CDEV_STATE_UPDATE";
|
||||
if (attrs[THERMAL_GENL_ATTR_CDEV_ID])
|
||||
LOG(INFO) << "Cooling device id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_ID]);
|
||||
if (attrs[THERMAL_GENL_ATTR_CDEV_CUR_STATE])
|
||||
LOG(INFO) << "Cooling device current state: "
|
||||
<< nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_CUR_STATE]);
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_CDEV_ADD) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_CDEV_ADD";
|
||||
if (attrs[THERMAL_GENL_ATTR_CDEV_NAME])
|
||||
LOG(INFO) << "Cooling device name: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_NAME]);
|
||||
if (attrs[THERMAL_GENL_ATTR_CDEV_ID])
|
||||
LOG(INFO) << "Cooling device id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_ID]);
|
||||
if (attrs[THERMAL_GENL_ATTR_CDEV_MAX_STATE])
|
||||
LOG(INFO) << "Cooling device max state: "
|
||||
<< nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_MAX_STATE]);
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_EVENT_CDEV_DELETE) {
|
||||
LOG(INFO) << "THERMAL_GENL_EVENT_CDEV_DELETE";
|
||||
if (attrs[THERMAL_GENL_ATTR_CDEV_ID])
|
||||
LOG(INFO) << "Cooling device id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_ID]);
|
||||
}
|
||||
|
||||
if (glh->cmd == THERMAL_GENL_SAMPLING_TEMP) {
|
||||
LOG(INFO) << "THERMAL_GENL_SAMPLING_TEMP";
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
|
||||
LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
*tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
|
||||
}
|
||||
if (attrs[THERMAL_GENL_ATTR_TZ_TEMP])
|
||||
LOG(INFO) << "Thermal zone temp: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ThermalWatcher::registerFilesToWatch(const std::set<std::string> &sensors_to_watch) {
|
||||
LOG(INFO) << "Uevent register file to watch...";
|
||||
monitored_sensors_.insert(sensors_to_watch.begin(), sensors_to_watch.end());
|
||||
|
||||
uevent_fd_.reset((TEMP_FAILURE_RETRY(uevent_open_socket(64 * 1024, true))));
|
||||
if (uevent_fd_.get() < 0) {
|
||||
LOG(ERROR) << "failed to open uevent socket";
|
||||
is_polling_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
fcntl(uevent_fd_, F_SETFL, O_NONBLOCK);
|
||||
|
||||
looper_->addFd(uevent_fd_.get(), 0, Looper::EVENT_INPUT, nullptr, nullptr);
|
||||
is_polling_ = false;
|
||||
thermal_triggered_ = true;
|
||||
sleep_ms_ = std::chrono::milliseconds(0);
|
||||
last_update_time_ = boot_clock::now();
|
||||
}
|
||||
|
||||
void ThermalWatcher::registerFilesToWatchNl(const std::set<std::string> &sensors_to_watch) {
|
||||
LOG(INFO) << "Thermal genl register file to watch...";
|
||||
monitored_sensors_.insert(sensors_to_watch.begin(), sensors_to_watch.end());
|
||||
|
||||
sk_thermal = nl_socket_alloc();
|
||||
if (!sk_thermal) {
|
||||
LOG(ERROR) << "nl_socket_alloc failed";
|
||||
return;
|
||||
}
|
||||
|
||||
if (genl_connect(sk_thermal)) {
|
||||
LOG(ERROR) << "genl_connect failed: sk_thermal";
|
||||
return;
|
||||
}
|
||||
|
||||
thermal_genl_fd_.reset(nl_socket_get_fd(sk_thermal));
|
||||
if (thermal_genl_fd_.get() < 0) {
|
||||
LOG(ERROR) << "Failed to create thermal netlink socket";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!socketAddMembership(sk_thermal, THERMAL_GENL_EVENT_GROUP_NAME)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Currently, only the update_temperature() will send thermal genl samlping events
|
||||
* from kernel. To avoid thermal-hal busy because samlping events are sent
|
||||
* too frequently, ignore thermal genl samlping events until we figure out how to use it.
|
||||
*
|
||||
if (!socketAddMembership(sk_thermal, THERMAL_GENL_SAMPLING_GROUP_NAME)) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
fcntl(thermal_genl_fd_, F_SETFL, O_NONBLOCK);
|
||||
looper_->addFd(thermal_genl_fd_.get(), 0, Looper::EVENT_INPUT, nullptr, nullptr);
|
||||
sleep_ms_ = std::chrono::milliseconds(0);
|
||||
last_update_time_ = boot_clock::now();
|
||||
}
|
||||
|
||||
@ -96,9 +436,10 @@ void ThermalWatcher::parseUevent(std::set<std::string> *sensors_set) {
|
||||
cp = msg;
|
||||
while (*cp) {
|
||||
std::string uevent = cp;
|
||||
auto findSubSystemThermal = uevent.find("SUBSYSTEM=thermal");
|
||||
if (!thermal_event) {
|
||||
if (uevent.find("SUBSYSTEM=") == 0) {
|
||||
if (uevent.find("SUBSYSTEM=thermal") != std::string::npos) {
|
||||
if (!uevent.find("SUBSYSTEM=")) {
|
||||
if (findSubSystemThermal != std::string::npos) {
|
||||
thermal_event = true;
|
||||
} else {
|
||||
break;
|
||||
@ -122,34 +463,64 @@ void ThermalWatcher::parseUevent(std::set<std::string> *sensors_set) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/175367921): Consider for potentially adding more type of event in the function
|
||||
// instead of just add the sensors to the list.
|
||||
void ThermalWatcher::parseGenlink(std::set<std::string> *sensors_set) {
|
||||
int err = 0, done = 0, tz_id = -1;
|
||||
|
||||
std::unique_ptr<nl_cb, decltype(&nl_cb_put)> cb(nl_cb_alloc(NL_CB_DEFAULT), nl_cb_put);
|
||||
|
||||
nl_cb_err(cb.get(), NL_CB_CUSTOM, nlErrorHandle, &err);
|
||||
nl_cb_set(cb.get(), NL_CB_FINISH, NL_CB_CUSTOM, nlFinishHandle, &done);
|
||||
nl_cb_set(cb.get(), NL_CB_ACK, NL_CB_CUSTOM, nlAckHandle, &done);
|
||||
nl_cb_set(cb.get(), NL_CB_SEQ_CHECK, NL_CB_CUSTOM, nlSeqCheckHandle, &done);
|
||||
nl_cb_set(cb.get(), NL_CB_VALID, NL_CB_CUSTOM, handleEvent, &tz_id);
|
||||
|
||||
while (!done && !err) {
|
||||
nl_recvmsgs(sk_thermal, cb.get());
|
||||
|
||||
if (tz_id < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
if (getThermalZoneTypeById(tz_id, &name) &&
|
||||
std::find(monitored_sensors_.begin(), monitored_sensors_.end(), name) !=
|
||||
monitored_sensors_.end()) {
|
||||
sensors_set->insert(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThermalWatcher::wake() {
|
||||
looper_->wake();
|
||||
}
|
||||
|
||||
bool ThermalWatcher::threadLoop() {
|
||||
LOG(VERBOSE) << "ThermalWatcher polling...";
|
||||
// Polling interval 2s
|
||||
static constexpr int kMinPollIntervalMs = 2000;
|
||||
// Max uevent timeout 5mins
|
||||
static constexpr int kUeventPollTimeoutMs = 300000;
|
||||
|
||||
int fd;
|
||||
std::set<std::string> sensors;
|
||||
|
||||
auto time_elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now() -
|
||||
last_update_time_)
|
||||
.count();
|
||||
int timeout = (thermal_triggered_ || is_polling_) ? kMinPollIntervalMs : kUeventPollTimeoutMs;
|
||||
if (time_elapsed_ms < timeout && looper_->pollOnce(timeout, &fd, nullptr, nullptr) >= 0) {
|
||||
if (fd != uevent_fd_.get()) {
|
||||
last_update_time_);
|
||||
|
||||
if (time_elapsed_ms < sleep_ms_ &&
|
||||
looper_->pollOnce(sleep_ms_.count(), &fd, nullptr, nullptr) >= 0) {
|
||||
if (fd != uevent_fd_.get() && fd != thermal_genl_fd_.get()) {
|
||||
return true;
|
||||
} else if (fd == thermal_genl_fd_.get()) {
|
||||
parseGenlink(&sensors);
|
||||
} else if (fd == uevent_fd_.get()) {
|
||||
parseUevent(&sensors);
|
||||
}
|
||||
parseUevent(&sensors);
|
||||
// Ignore cb_ if uevent is not from monitored sensors
|
||||
if (sensors.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
thermal_triggered_ = cb_(sensors);
|
||||
|
||||
sleep_ms_ = cb_(sensors);
|
||||
last_update_time_ = boot_clock::now();
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user