thermalservice: add HIDL ThermalCallback implementation
The IThermalCallback implementation in thermalserviced enables vendor
thermal management code to send thermal events to ThermalService.
Test: manual: marlin with modified thermal-engine.conf
Bug: 30982366
Change-Id: Ic566bc51aebcd03163f8909f846ee4f7025ed472
diff --git a/services/thermalservice/Android.bp b/services/thermalservice/Android.bp
index 02268b7..d754560 100644
--- a/services/thermalservice/Android.bp
+++ b/services/thermalservice/Android.bp
@@ -1,3 +1,7 @@
+subdirs = [
+ "libthermalcallback"
+]
+
cc_library {
name: "libthermalservice",
@@ -33,10 +37,17 @@
"thermalserviced.cpp",
],
+ include_dirs: ["frameworks/native"],
+
shared_libs: [
"libthermalservice",
"libbinder",
"libutils",
+ "libthermalcallback",
+ "android.hardware.thermal@1.1",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
],
cflags: [
diff --git a/services/thermalservice/libthermalcallback/Android.bp b/services/thermalservice/libthermalcallback/Android.bp
new file mode 100644
index 0000000..e98506e
--- /dev/null
+++ b/services/thermalservice/libthermalcallback/Android.bp
@@ -0,0 +1,19 @@
+cc_library_shared {
+ name: "libthermalcallback",
+ srcs: [
+ "ThermalCallback.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ include_dirs: ["frameworks/native"],
+ shared_libs: [
+ "android.hardware.thermal@1.1",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libthermalservice",
+ "libutils",
+ ],
+}
diff --git a/services/thermalservice/libthermalcallback/ThermalCallback.cpp b/services/thermalservice/libthermalcallback/ThermalCallback.cpp
new file mode 100644
index 0000000..5e094fa
--- /dev/null
+++ b/services/thermalservice/libthermalcallback/ThermalCallback.cpp
@@ -0,0 +1,69 @@
+#define LOG_TAG "android.hardware.thermal.thermalcallback@1.1-impl"
+#include <log/log.h>
+
+#include "ThermalCallback.h"
+#include "services/thermalservice/ThermalService.h"
+#include <math.h>
+#include <android/os/Temperature.h>
+#include <hardware/thermal.h>
+
+namespace android {
+namespace hardware {
+namespace thermal {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::os::ThermalService;
+using ::android::hardware::thermal::V1_0::TemperatureType;
+
+// Register a binder ThermalService object for sending events
+void ThermalCallback::registerThermalService(sp<ThermalService> thermalService)
+{
+ mThermalService = thermalService;
+}
+
+// Methods from IThermalCallback::V1_1 follow.
+Return<void> ThermalCallback::notifyThrottling(
+ bool isThrottling,
+ const android::hardware::thermal::V1_0::Temperature& temperature) {
+
+ // Convert HIDL IThermal Temperature to binder IThermalService Temperature.
+ if (mThermalService != nullptr) {
+ float value = NAN;
+ int type = DEVICE_TEMPERATURE_UNKNOWN;
+
+ switch(temperature.type) {
+ case TemperatureType::CPU:
+ type = DEVICE_TEMPERATURE_CPU;
+ break;
+ case TemperatureType::GPU:
+ type = DEVICE_TEMPERATURE_GPU;
+ break;
+ case TemperatureType::BATTERY:
+ type = DEVICE_TEMPERATURE_BATTERY;
+ break;
+ case TemperatureType::SKIN:
+ type = DEVICE_TEMPERATURE_SKIN;
+ break;
+ case TemperatureType::UNKNOWN:
+ default:
+ type = DEVICE_TEMPERATURE_UNKNOWN;
+ break;
+ }
+
+ value = temperature.currentValue == UNKNOWN_TEMPERATURE ? NAN :
+ temperature.currentValue;
+
+ android::os::Temperature thermal_svc_temp(value, type);
+ mThermalService->notifyThrottling(isThrottling, thermal_svc_temp);
+ } else {
+ ALOGE("IThermalService binder service not created, drop throttling event");
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace thermal
+} // namespace hardware
+} // namespace android
diff --git a/services/thermalservice/libthermalcallback/ThermalCallback.h b/services/thermalservice/libthermalcallback/ThermalCallback.h
new file mode 100644
index 0000000..3d72c68
--- /dev/null
+++ b/services/thermalservice/libthermalcallback/ThermalCallback.h
@@ -0,0 +1,43 @@
+#ifndef ANDROID_HARDWARE_THERMAL_V1_1_THERMALCALLBACK_H
+#define ANDROID_HARDWARE_THERMAL_V1_1_THERMALCALLBACK_H
+
+#include <android/hardware/thermal/1.1/IThermalCallback.h>
+#include <android/hardware/thermal/1.0/types.h>
+#include <android/os/Temperature.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "services/thermalservice/ThermalService.h"
+
+namespace android {
+namespace hardware {
+namespace thermal {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::os::ThermalService;
+
+class ThermalCallback : public IThermalCallback {
+ public:
+ // Register a binder ThermalService object for sending events
+ void registerThermalService(sp<ThermalService> thermalService);
+
+ // Methods from IThermalCallback::V1_1 follow.
+ Return<void> notifyThrottling(
+ bool isThrottling,
+ const android::hardware::thermal::V1_0::Temperature& temperature)
+ override;
+
+ private:
+ // Our registered binder ThermalService object to use for sending events
+ sp<android::os::ThermalService> mThermalService;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace thermal
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_THERMAL_V1_1_THERMALCALLBACK_H
diff --git a/services/thermalservice/thermalserviced.cpp b/services/thermalservice/thermalserviced.cpp
index 281851d..b9315b8 100644
--- a/services/thermalservice/thermalserviced.cpp
+++ b/services/thermalservice/thermalserviced.cpp
@@ -19,21 +19,103 @@
#include "thermalserviced.h"
#include "ThermalService.h"
+#include "libthermalcallback/ThermalCallback.h"
+#include <android/hardware/thermal/1.1/IThermal.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <hidl/HidlTransportSupport.h>
using namespace android;
+using ::android::hardware::thermal::V1_1::IThermal;
+using ::android::hardware::thermal::V1_0::Temperature;
+using ::android::hardware::thermal::V1_1::IThermalCallback;
+using ::android::hardware::thermal::V1_1::implementation::ThermalCallback;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::hidl_death_recipient;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::os::ThermalService;
+
+template<typename T>
+using Return = hardware::Return<T>;
+
+namespace {
+
+// Our thermalserviced main object
+ThermalServiceDaemon* gThermalServiceDaemon;
+
+// Thermal HAL client
+sp<IThermal> gThermalHal = nullptr;
+
+// Binder death notifier informing of Thermal HAL death.
+struct ThermalServiceDeathRecipient : hidl_death_recipient {
+ virtual void serviceDied(
+ uint64_t cookie __unused, const wp<IBase>& who __unused) {
+ gThermalHal = nullptr;
+ ALOGE("IThermal HAL died");
+ gThermalServiceDaemon->getThermalHal();
+ }
+};
+
+sp<ThermalServiceDeathRecipient> gThermalHalDied = nullptr;
+
+} // anonymous namespace
void ThermalServiceDaemon::thermalServiceStartup() {
// Binder IThermalService startup
mThermalService = new android::os::ThermalService;
mThermalService->publish(mThermalService);
+ // Register IThermalService object with IThermalCallback
+ if (mThermalCallback != nullptr)
+ mThermalCallback->registerThermalService(mThermalService);
IPCThreadState::self()->joinThreadPool();
}
+// Lookup Thermal HAL, register death notifier, register our
+// ThermalCallback with the Thermal HAL.
+void ThermalServiceDaemon::getThermalHal() {
+ gThermalHal = IThermal::getService();
+ if (gThermalHal == nullptr) {
+ ALOGW("Unable to get Thermal HAL V1.1, vendor thermal event notification not available");
+ return;
+ }
+
+ // Binder death notifier for Thermal HAL
+ if (gThermalHalDied == nullptr)
+ gThermalHalDied = new ThermalServiceDeathRecipient();
+
+ if (gThermalHalDied != nullptr)
+ gThermalHal->linkToDeath(gThermalHalDied, 0x451F /* cookie */);
+
+ if (mThermalCallback != nullptr) {
+ Return<void> ret = gThermalHal->registerThermalCallback(
+ mThermalCallback);
+ if (!ret.isOk())
+ ALOGE("registerThermalCallback failed, status: %s",
+ ret.description().c_str());
+ }
+}
+
+void ThermalServiceDaemon::thermalCallbackStartup() {
+ status_t err;
+
+ // HIDL IThermalCallback startup
+ // Need at least 2 threads in thread pool since we wait for dead HAL
+ // to come back on the binder death notification thread and we need
+ // another thread for the incoming service now available call.
+ configureRpcThreadpool(2, false /* callerWillJoin */);
+ mThermalCallback = new ThermalCallback();
+ err = mThermalCallback->registerAsService();
+ ALOGE_IF(err != OK, "Cannot register %s: %d",
+ IThermalCallback::descriptor, err);
+
+ // Lookup Thermal HAL and register our ThermalCallback.
+ getThermalHal();
+}
int main(int /*argc*/, char** /*argv*/) {
- ThermalServiceDaemon* daemon = new ThermalServiceDaemon();
- daemon->thermalServiceStartup();
+ gThermalServiceDaemon = new ThermalServiceDaemon();
+ gThermalServiceDaemon->thermalCallbackStartup();
+ gThermalServiceDaemon->thermalServiceStartup();
+ /* NOTREACHED */
}
diff --git a/services/thermalservice/thermalserviced.h b/services/thermalservice/thermalserviced.h
index 5268a3a..309e2fe 100644
--- a/services/thermalservice/thermalserviced.h
+++ b/services/thermalservice/thermalserviced.h
@@ -18,16 +18,23 @@
#define ANDROID_THERMALSERVICE_THERMALSERVICED_H
#include "ThermalService.h"
+#include "libthermalcallback/ThermalCallback.h"
using namespace android;
+using ::android::hardware::thermal::V1_0::Temperature;
+using ::android::hardware::thermal::V1_1::implementation::ThermalCallback;
+using ::android::os::ThermalService;
class ThermalServiceDaemon {
public:
void thermalServiceStartup();
+ void thermalCallbackStartup();
+ void getThermalHal();
ThermalServiceDaemon() {};
private:
- sp<android::os::ThermalService> mThermalService;
+ sp<ThermalService> mThermalService;
+ sp<ThermalCallback> mThermalCallback;
};
#endif // ANDROID_THERMALSERVICE_THERMALSERVICED_H