1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * @addtogroup Thermal 19 * @{ 20 */ 21 22 /** 23 * @file thermal.h 24 */ 25 26 #ifndef _ANDROID_THERMAL_H 27 #define _ANDROID_THERMAL_H 28 29 #include <sys/cdefs.h> 30 31 /****************************************************************** 32 * 33 * IMPORTANT NOTICE: 34 * 35 * This file is part of Android's set of stable system headers 36 * exposed by the Android NDK (Native Development Kit). 37 * 38 * Third-party source AND binary code relies on the definitions 39 * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES. 40 * 41 * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES) 42 * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS 43 * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY 44 * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES 45 */ 46 47 /* 48 * Structures and functions to access thermal status and register/unregister 49 * thermal status listener in native code. 50 */ 51 52 #include <stdint.h> 53 #include <sys/types.h> 54 55 #if !defined(__INTRODUCED_IN) 56 #define __INTRODUCED_IN(__api_level) /* nothing */ 57 #endif 58 59 #ifdef __cplusplus 60 extern "C" { 61 #endif 62 63 /** 64 * Thermal status used in function {@link AThermal_getCurrentThermalStatus} and 65 * {@link AThermal_StatusCallback}. 66 */ 67 enum AThermalStatus { 68 /** Error in thermal status. */ 69 ATHERMAL_STATUS_ERROR = -1, 70 /** Not under throttling. */ 71 ATHERMAL_STATUS_NONE = 0, 72 /** Light throttling where UX is not impacted. */ 73 ATHERMAL_STATUS_LIGHT = 1, 74 /** Moderate throttling where UX is not largely impacted. */ 75 ATHERMAL_STATUS_MODERATE = 2, 76 /** Severe throttling where UX is largely impacted. */ 77 ATHERMAL_STATUS_SEVERE = 3, 78 /** Platform has done everything to reduce power. */ 79 ATHERMAL_STATUS_CRITICAL = 4, 80 /** 81 * Key components in platform are shutting down due to thermal condition. 82 * Device functionalities will be limited. 83 */ 84 ATHERMAL_STATUS_EMERGENCY = 5, 85 /** Need shutdown immediately. */ 86 ATHERMAL_STATUS_SHUTDOWN = 6, 87 }; 88 typedef enum AThermalStatus AThermalStatus; 89 90 /** 91 * An opaque type representing a handle to a thermal manager. 92 * An instance of thermal manager must be acquired prior to 93 * using thermal status APIs and must be released after use. 94 * 95 * <p>To use:<ul> 96 * <li>Create a new thermal manager instance by calling the 97 * {@link AThermal_acquireManager} function.</li> 98 * <li>Get current thermal status with 99 * {@link AThermal_getCurrentThermalStatus}.</li> 100 * <li>Register a thermal status listener with 101 * {@link AThermal_registerThermalStatusListener}.</li> 102 * <li>Unregister a thermal status listener with 103 * {@link AThermal_unregisterThermalStatusListener}.</li> 104 * <li>Release the thermal manager instance with 105 * {@link AThermal_releaseManager}.</li></ul></p> 106 * 107 */ 108 typedef struct AThermalManager AThermalManager; 109 110 /** 111 * Prototype of the function that is called when thermal status changes. 112 * It's passed the updated thermal status as parameter, as well as the 113 * pointer provided by the client that registered a callback. 114 */ 115 typedef void (*AThermal_StatusCallback)(void* _Nullable data, AThermalStatus status); 116 117 /** 118 * Acquire an instance of the thermal manager. This must be freed using 119 * {@link AThermal_releaseManager}. 120 * 121 * Available since API level 30. 122 * 123 * @return manager instance on success, nullptr on failure. 124 */ 125 AThermalManager* _Nonnull AThermal_acquireManager() __INTRODUCED_IN(30); 126 127 /** 128 * Release the thermal manager pointer acquired via 129 * {@link AThermal_acquireManager}. 130 * 131 * Available since API level 30. 132 * 133 * @param manager The manager to be released. 134 */ 135 void AThermal_releaseManager(AThermalManager* _Nonnull manager) __INTRODUCED_IN(30); 136 137 /** 138 * Gets the current thermal status. 139 * 140 * Available since API level 30. 141 * 142 * @param manager The manager instance to use to query the thermal status. 143 * Acquired via {@link AThermal_acquireManager}. 144 * 145 * @return current thermal status, ATHERMAL_STATUS_ERROR on failure. 146 */ 147 AThermalStatus 148 AThermal_getCurrentThermalStatus(AThermalManager *_Nonnull manager) __INTRODUCED_IN(30); 149 150 /** 151 * Register a thermal status listener for thermal status change. 152 * 153 * Available since API level 30. 154 * 155 * @param manager The manager instance to use to register. 156 * Acquired via {@link AThermal_acquireManager}. 157 * @param callback The callback function to be called on system binder thread pool when thermal 158 * status updated. 159 * @param data The data pointer to be passed when callback is called. 160 * 161 * @return 0 on success 162 * EINVAL if the listener and data pointer were previously added and not removed. 163 * EPIPE if communication with the system service has failed, the listener will not get 164 * removed and this call should be retried 165 */ 166 int AThermal_registerThermalStatusListener(AThermalManager *_Nonnull manager, 167 AThermal_StatusCallback _Nullable callback, 168 void* _Nullable data) __INTRODUCED_IN(30); 169 170 /** 171 * Unregister a thermal status listener previously registered. 172 * 173 * No subsequent invocations of the callback will occur after this function returns successfully. 174 * 175 * Available since API level 30. 176 * 177 * @param manager The manager instance to use to unregister. 178 * Acquired via {@link AThermal_acquireManager}. 179 * @param callback The callback function that was previously registered. 180 * @param data The data pointer to be passed when callback is called. 181 * 182 * @return 0 on success 183 * EINVAL if the listener and data pointer were not previously added. 184 * EPIPE if communication with the system service has failed. 185 */ 186 int AThermal_unregisterThermalStatusListener(AThermalManager* _Nonnull manager, 187 AThermal_StatusCallback _Nullable callback, 188 void* _Nullable data) __INTRODUCED_IN(30); 189 190 /** 191 * Provides an estimate of how much thermal headroom the device currently has before 192 * hitting severe throttling. 193 * 194 * Note that this only attempts to track the headroom of slow-moving sensors, such as 195 * the skin temperature sensor. This means that there is no benefit to calling this function 196 * more frequently than about once per second, and attempted to call significantly 197 * more frequently may result in the function returning `NaN`. 198 * 199 * In addition, in order to be able to provide an accurate forecast, the system does 200 * not attempt to forecast until it has multiple temperature samples from which to 201 * extrapolate. This should only take a few seconds from the time of the first call, 202 * but during this time, no forecasting will occur, and the current headroom will be 203 * returned regardless of the value of `forecastSeconds`. 204 * 205 * The value returned is a non-negative float that represents how much of the thermal envelope 206 * is in use (or is forecasted to be in use). A value of 1.0 indicates that the device is 207 * (or will be) throttled at {@link #ATHERMAL_STATUS_SEVERE}. Such throttling can affect the 208 * CPU, GPU, and other subsystems. Values may exceed 1.0, but there is no implied mapping 209 * to specific thermal levels beyond that point. This means that values greater than 1.0 210 * may correspond to {@link #ATHERMAL_STATUS_SEVERE}, but may also represent heavier throttling. 211 * 212 * A value of 0.0 corresponds to a fixed distance from 1.0, but does not correspond to any 213 * particular thermal status or temperature. Values on (0.0, 1.0] may be expected to scale 214 * linearly with temperature, though temperature changes over time are typically not linear. 215 * Negative values will be clamped to 0.0 before returning. 216 * 217 * Available since API level 31. 218 * 219 * @param manager The manager instance to use. 220 * Acquired via {@link AThermal_acquireManager}. 221 * @param forecastSeconds how many seconds into the future to forecast. Given that device 222 * conditions may change at any time, forecasts from further in the 223 * future will likely be less accurate than forecasts in the near future. 224 * @return a value greater than equal to 0.0, where 1.0 indicates the SEVERE throttling threshold, 225 * as described above. Returns NaN if the device does not support this functionality or 226 * if this function is called significantly faster than once per second. 227 */ 228 float AThermal_getThermalHeadroom(AThermalManager* _Nonnull manager, 229 int forecastSeconds) __INTRODUCED_IN(31); 230 231 /** 232 * This struct defines an instance of headroom threshold value and its status. 233 * <p> 234 * The value should be monotonically non-decreasing as the thermal status increases. 235 * For {@link ATHERMAL_STATUS_SEVERE}, its headroom threshold is guaranteed to 236 * be 1.0f. For status below severe status, the value should be lower or equal 237 * to 1.0f, and for status above severe, the value should be larger or equal to 1.0f. 238 * <p> 239 * Also see {@link AThermal_getThermalHeadroom} for explanation on headroom, and 240 * {@link AThermal_getThermalHeadroomThresholds} for how to use this. 241 */ 242 struct AThermalHeadroomThreshold { 243 float headroom; 244 AThermalStatus thermalStatus; 245 }; 246 typedef struct AThermalHeadroomThreshold AThermalHeadroomThreshold; 247 248 /** 249 * Gets the thermal headroom thresholds for all available thermal status. 250 * 251 * A thermal status will only exist in output if the device manufacturer has the 252 * corresponding threshold defined for at least one of its slow-moving skin temperature 253 * sensors. If it's set, one should also expect to get it from 254 * {@link #AThermal_getCurrentThermalStatus} or {@link AThermal_StatusCallback}. 255 * <p> 256 * The headroom threshold is used to interpret the possible thermal throttling status based on 257 * the headroom prediction. For example, if the headroom threshold for 258 * {@link ATHERMAL_STATUS_LIGHT} is 0.7, and a headroom prediction in 10s returns 0.75 259 * (or `AThermal_getThermalHeadroom(10)=0.75}`, one can expect that in 10 seconds the system 260 * could be in lightly throttled state if the workload remains the same. The app can consider 261 * taking actions according to the nearest throttling status the difference between the headroom and 262 * the threshold. 263 * <p> 264 * For new devices it's guaranteed to have a single sensor, but for older devices with multiple 265 * sensors reporting different threshold values, the minimum threshold is taken to be conservative 266 * on predictions. Thus, when reading real-time headroom, it's not guaranteed that a real-time value 267 * of 0.75 (or `AThermal_getThermalHeadroom(0)=0.75`) exceeding the threshold of 0.7 above 268 * will always come with lightly throttled state 269 * (or `AThermal_getCurrentThermalStatus()=ATHERMAL_STATUS_LIGHT`) but it can be lower 270 * (or `AThermal_getCurrentThermalStatus()=ATHERMAL_STATUS_NONE`). 271 * While it's always guaranteed that the device won't be throttled heavier than the unmet 272 * threshold's state, so a real-time headroom of 0.75 will never come with 273 * {@link #ATHERMAL_STATUS_MODERATE} but always lower, and 0.65 will never come with 274 * {@link ATHERMAL_STATUS_LIGHT} but {@link #ATHERMAL_STATUS_NONE}. 275 * <p> 276 * Starting in Android 16, this polling API may return different results when called depending on 277 * the device. The new headroom listener API {@link #AThermal_HeadroomCallback} can be used to 278 * detect headroom thresholds changes. 279 * <p> 280 * Before API level 36 the returned list of thresholds is cached on first successful query and owned 281 * by the thermal manager, which will not change between calls to this function. The caller should 282 * only need to free the manager with {@link AThermal_releaseManager}. 283 * <p> 284 * 285 * @param manager The manager instance to use. 286 * Acquired via {@link AThermal_acquireManager}. 287 * @param outThresholds non-null output pointer to null AThermalHeadroomThreshold pointer, which 288 * will be set to a new array of thresholds if thermal thresholds are supported 289 * by the system or device, otherwise nullptr or unmodified. The client should 290 * clean up the thresholds by array-deleting the threshold pointer. 291 * @param size non-null output pointer whose value will be set to the size of the threshold array 292 * or 0 if it's not supported. 293 * @return 0 on success 294 * EINVAL if outThresholds or size_t is nullptr, or *outThresholds is not nullptr. 295 * EPIPE if communication with the system service has failed. 296 * ENOSYS if the feature is disabled by the current system. 297 */ 298 int AThermal_getThermalHeadroomThresholds(AThermalManager* _Nonnull manager, 299 const AThermalHeadroomThreshold* _Nonnull 300 * _Nullable outThresholds, 301 size_t* _Nonnull size) __INTRODUCED_IN(35); 302 303 /** 304 * Prototype of the function that is called when thermal headroom or thresholds changes. 305 * It's passed the updated thermal headroom and thresholds as parameters, as well as the 306 * pointer provided by the client that registered a callback. 307 * 308 * @param data The data pointer to be passed when callback is called. 309 * @param headroom The current non-negative normalized headroom value, also see 310 * {@link AThermal_getThermalHeadroom}. 311 * @param forecastHeadroom The forecasted non-negative normalized headroom value, also see 312 * {@link AThermal_getThermalHeadroom}. 313 * @param forecastSeconds The seconds used for the forecast by the system. 314 * @param thresholds The current headroom thresholds. The thresholds pointer will be a constant 315 * shared across all callbacks registered from the same process, and it will be 316 * destroyed after all the callbacks are finished. If the client intents to 317 * persist the values, it should make a copy of it during the callback. 318 * @param thresholdsCount The count of thresholds. 319 */ 320 typedef void (*AThermal_HeadroomCallback)(void *_Nullable data, 321 float headroom, 322 float forecastHeadroom, 323 int forecastSeconds, 324 const AThermalHeadroomThreshold* _Nullable thresholds, 325 size_t thresholdsCount); 326 327 /** 328 * Register a thermal headroom listener for thermal headroom or thresholds change. 329 * 330 * Available since API level 36. 331 * 332 * @param manager The manager instance to use to register. 333 * Acquired via {@link AThermal_acquireManager}. 334 * @param callback The callback function to be called on system binder thread pool when thermal 335 * headroom or thresholds update. 336 * @param data The data pointer to be passed when callback is called. 337 * 338 * @return 0 on success 339 * EINVAL if the listener and data pointer were previously added and not removed. 340 * EPIPE if communication with the system service has failed. 341 */ 342 int AThermal_registerThermalHeadroomListener(AThermalManager* _Nonnull manager, 343 AThermal_HeadroomCallback _Nullable callback, 344 void* _Nullable data) __INTRODUCED_IN(36); 345 346 /** 347 * Unregister a thermal headroom listener previously registered. 348 * 349 * No subsequent invocations of the callback will occur after this function returns successfully. 350 * 351 * Available since API level 36. 352 * 353 * @param manager The manager instance to use to unregister. 354 * Acquired via {@link AThermal_acquireManager}. 355 * @param callback The callback function that was previously registered. 356 * @param data The data pointer that was previously registered. 357 * 358 * @return 0 on success 359 * EINVAL if the listener and data pointer were not previously added. 360 * EPIPE if communication with the system service has failed, the listener will not get 361 * removed and this call should be retried 362 */ 363 364 int AThermal_unregisterThermalHeadroomListener(AThermalManager* _Nonnull manager, 365 AThermal_HeadroomCallback _Nullable callback, 366 void* _Nullable data) __INTRODUCED_IN(36); 367 368 #ifdef __cplusplus 369 } 370 #endif 371 372 #endif // _ANDROID_THERMAL_H 373 374 /** @} */ 375