diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index 8fa3acf502bc1..314bf29101554 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -295,6 +295,7 @@ LIBANDROID { AThermal_getCurrentThermalStatus; # introduced=30 AThermal_registerThermalStatusListener; # introduced=30 AThermal_unregisterThermalStatusListener; # introduced=30 + AThermal_getThermalHeadroom; # introduced=31 local: *; }; diff --git a/native/android/thermal.cpp b/native/android/thermal.cpp index 545c423908a08..1f6ef4755aff6 100644 --- a/native/android/thermal.cpp +++ b/native/android/thermal.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -52,6 +53,7 @@ struct AThermalManager { status_t getCurrentThermalStatus(int32_t *status); status_t addListener(AThermal_StatusCallback, void *data); status_t removeListener(AThermal_StatusCallback, void *data); + status_t getThermalHeadroom(int32_t forecastSeconds, float *result); private: AThermalManager(sp service); sp mThermalSvc; @@ -184,6 +186,18 @@ status_t AThermalManager::getCurrentThermalStatus(int32_t *status) { return OK; } +status_t AThermalManager::getThermalHeadroom(int32_t forecastSeconds, float *result) { + binder::Status ret = mThermalSvc->getThermalHeadroom(forecastSeconds, result); + + if (!ret.isOk()) { + if (ret.exceptionCode() == binder::Status::EX_SECURITY) { + return EPERM; + } + return EPIPE; + } + return OK; +} + /** * Acquire an instance of the thermal manager. This must be freed using * {@link AThermal_releaseManager}. @@ -259,3 +273,32 @@ int AThermal_unregisterThermalStatusListener(AThermalManager *manager, AThermal_StatusCallback callback, void *data) { return manager->removeListener(callback, data); } + +/** + * Provides an estimate of how much thermal headroom the device currently has + * before hitting severe throttling. + * + * Note that this only attempts to track the headroom of slow-moving sensors, + * such as the skin temperature sensor. This means that there is no benefit to + * calling this function more frequently than about once per second, and attempts + * to call significantly more frequently may result in the function returning {@code NaN}. + * + * See also PowerManager#getThermalHeadroom. + * + * @param manager The manager instance to use + * @param forecastSeconds how many seconds in the future to forecast + * @return a value greater than or equal to 0.0 where 1.0 indicates the SEVERE throttling + * threshold. Returns NaN if the device does not support this functionality or if + * this function is called significantly faster than once per second. + */ +float AThermal_getThermalHeadroom(AThermalManager *manager, + int forecastSeconds) { + float result = 0.0f; + status_t ret = manager->getThermalHeadroom(forecastSeconds, &result); + + if (ret != OK) { + result = std::numeric_limits::quiet_NaN(); + } + + return result; +}