diff options
author | davidchao <davidchao@google.com> | 2020-10-26 19:41:29 +0800 |
---|---|---|
committer | davidchao <davidchao@google.com> | 2021-01-05 21:29:19 +0800 |
commit | d9a195e7202bf7690377a0e049337ad7db51617a (patch) | |
tree | 2608b4dd0e6432332722c469a157e645217b2a71 /thermal | |
parent | f54f9cd93cead0c43083aeb1b8bb3bce33b535db (diff) | |
download | pixel-d9a195e7202bf7690377a0e049337ad7db51617a.tar.gz |
thermal: use thermal genl events from kernel to notify thermal-hal
Currently, thermal core cannot support multiple thermal zones with the
same adc thermistor, so we use thermal genl events to notify thermal-hal
when thermal sensor across the trip point.
Bug: 170682696
Test: boot and thermal-hal can receive thernal genl events from kernel.
Change-Id: Idf27cd6138e03e089832185d7de030f93c956373
Diffstat (limited to 'thermal')
-rw-r--r-- | thermal/Android.bp | 1 | ||||
-rw-r--r-- | thermal/thermal-helper.cpp | 17 | ||||
-rw-r--r-- | thermal/thermal-helper.h | 3 | ||||
-rw-r--r-- | thermal/utils/thermal_watcher.cpp | 376 | ||||
-rw-r--r-- | thermal/utils/thermal_watcher.h | 7 |
5 files changed, 402 insertions, 2 deletions
diff --git a/thermal/Android.bp b/thermal/Android.bp index f67c1f36..4ba9a365 100644 --- a/thermal/Android.bp +++ b/thermal/Android.bp @@ -23,6 +23,7 @@ cc_binary { "libhidlbase", "libjsoncpp", "libutils", + "libnl", "libbinder_ndk", "android.hardware.thermal@1.0", "android.hardware.thermal@2.0", diff --git a/thermal/thermal-helper.cpp b/thermal/thermal-helper.cpp index 24b44e40..6ac03dd3 100644 --- a/thermal/thermal-helper.cpp +++ b/thermal/thermal-helper.cpp @@ -338,6 +338,23 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) } } +bool getThermalZoneTypeById(int tz_id, std::string *type) { + std::string tz_type; + std::string path = + android::base::StringPrintf("%s/%s%d/%s", kThermalSensorsRoot.data(), + kSensorPrefix.data(), tz_id, kThermalNameFile.data()); + LOG(INFO) << "TZ Path: " << path; + if (!::android::base::ReadFileToString(path, &tz_type)) { + LOG(ERROR) << "Failed to read sensor: " << tz_type; + return false; + } + + // Strip the newline. + *type = ::android::base::Trim(tz_type); + LOG(INFO) << "TZ type: " << *type; + return true; +} + bool ThermalHelper::readCoolingDevice(std::string_view cooling_device, CoolingDevice_2_0 *out) const { // Read the file. If the file can't be read temp will be empty string. diff --git a/thermal/thermal-helper.h b/thermal/thermal-helper.h index 6d4af8c7..a03c21ce 100644 --- a/thermal/thermal-helper.h +++ b/thermal/thermal-helper.h @@ -73,6 +73,9 @@ using NotificationCallback = std::function<void(const Temperature_2_0 &t)>; using NotificationTime = std::chrono::time_point<std::chrono::steady_clock>; using CdevRequestStatus = std::map<std::string, int>; +// Get thermal_zone type +bool getThermalZoneTypeById(int tz_id, std::string *); + struct SensorStatus { ThrottlingSeverity severity; ThrottlingSeverity prev_hot_severity; diff --git a/thermal/utils/thermal_watcher.cpp b/thermal/utils/thermal_watcher.cpp index 86d7c46f..442fa338 100644 --- a/thermal/utils/thermal_watcher.cpp +++ b/thermal/utils/thermal_watcher.cpp @@ -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 { @@ -35,6 +42,305 @@ namespace implementation { using std::chrono_literals::operator""ms; +namespace { + +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) { monitored_sensors_.insert(sensors_to_watch.begin(), sensors_to_watch.end()); @@ -47,6 +353,40 @@ void ThermalWatcher::registerFilesToWatch(const std::set<std::string> &sensors_t fcntl(uevent_fd_, F_SETFL, O_NONBLOCK); looper_->addFd(uevent_fd_.get(), 0, Looper::EVENT_INPUT, nullptr, nullptr); + + 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(); } @@ -116,6 +456,35 @@ 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(); } @@ -131,10 +500,13 @@ bool ThermalWatcher::threadLoop() { if (time_elapsed_ms < sleep_ms_ && looper_->pollOnce(sleep_ms_.count(), &fd, nullptr, nullptr) >= 0) { - if (fd != uevent_fd_.get()) { + 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; diff --git a/thermal/utils/thermal_watcher.h b/thermal/utils/thermal_watcher.h index 76c38403..7cf46f6c 100644 --- a/thermal/utils/thermal_watcher.h +++ b/thermal/utils/thermal_watcher.h @@ -73,6 +73,9 @@ class ThermalWatcher : public ::android::Thread { // Parse uevent message void parseUevent(std::set<std::string> *sensor_name); + // Parse thermal netlink message + void parseGenlink(std::set<std::string> *sensor_name); + // Maps watcher filer descriptor to watched file path. std::unordered_map<int, std::string> watch_to_file_path_map_; @@ -86,12 +89,16 @@ class ThermalWatcher : public ::android::Thread { // For uevent socket registration. android::base::unique_fd uevent_fd_; + // For thermal genl socket registration. + android::base::unique_fd thermal_genl_fd_; // Sensor list which monitor flag is enabled. std::set<std::string> monitored_sensors_; // Sleep interval voting result std::chrono::milliseconds sleep_ms_; // Timestamp for last thermal update boot_clock::time_point last_update_time_; + // For thermal genl socket object. + struct nl_sock *sk_thermal; }; } // namespace implementation |