blob: e5d46b5b8addb5933904c71a81b8393c0a36e343 [file] [log] [blame]
Chris Ye1a5a8882020-01-15 10:51:47 -08001/*
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)
Chris Forbes56e925a2020-09-15 09:34:59 -070056#define __INTRODUCED_IN(__api_level) /* nothing */
Chris Ye1a5a8882020-01-15 10:51:47 -080057#endif
58
59#ifdef __cplusplus
60extern "C" {
61#endif
62
gfan5d5faa42021-04-12 15:14:29 -070063/**
64 * Thermal status used in function {@link AThermal_getCurrentThermalStatus} and
65 * {@link AThermal_StatusCallback}.
66 */
Chris Ye1a5a8882020-01-15 10:51:47 -080067enum 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};
Dan Albertc796b902024-08-01 22:36:07 +000088typedef enum AThermalStatus AThermalStatus;
Chris Ye1a5a8882020-01-15 10:51:47 -080089
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 */
108typedef 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 */
Xiang Wang800af342024-01-09 13:24:41 -0800115typedef void (*AThermal_StatusCallback)(void* _Nullable data, AThermalStatus status);
Chris Ye1a5a8882020-01-15 10:51:47 -0800116
117/**
118 * Acquire an instance of the thermal manager. This must be freed using
119 * {@link AThermal_releaseManager}.
120 *
Elliott Hughes7be0e2d2020-06-02 13:05:04 -0700121 * Available since API level 30.
122 *
Chris Ye1a5a8882020-01-15 10:51:47 -0800123 * @return manager instance on success, nullptr on failure.
Elliott Hughes7be0e2d2020-06-02 13:05:04 -0700124 */
Xiang Wang800af342024-01-09 13:24:41 -0800125AThermalManager* _Nonnull AThermal_acquireManager() __INTRODUCED_IN(30);
Chris Ye1a5a8882020-01-15 10:51:47 -0800126
127/**
128 * Release the thermal manager pointer acquired via
129 * {@link AThermal_acquireManager}.
130 *
Elliott Hughes7be0e2d2020-06-02 13:05:04 -0700131 * Available since API level 30.
Chris Ye1a5a8882020-01-15 10:51:47 -0800132 *
Elliott Hughes7be0e2d2020-06-02 13:05:04 -0700133 * @param manager The manager to be released.
Chris Ye1a5a8882020-01-15 10:51:47 -0800134 */
Xiang Wang800af342024-01-09 13:24:41 -0800135void AThermal_releaseManager(AThermalManager* _Nonnull manager) __INTRODUCED_IN(30);
Chris Ye1a5a8882020-01-15 10:51:47 -0800136
137/**
138 * Gets the current thermal status.
139 *
Elliott Hughes7be0e2d2020-06-02 13:05:04 -0700140 * Available since API level 30.
141 *
Chris Ye1a5a8882020-01-15 10:51:47 -0800142 * @param manager The manager instance to use to query the thermal status.
Xiang Wang684eaa72024-10-23 17:41:11 -0700143 * Acquired via {@link AThermal_acquireManager}.
Chris Ye1a5a8882020-01-15 10:51:47 -0800144 *
145 * @return current thermal status, ATHERMAL_STATUS_ERROR on failure.
Elliott Hughes7be0e2d2020-06-02 13:05:04 -0700146 */
Xiang Wang800af342024-01-09 13:24:41 -0800147AThermalStatus
Xiang Wang684eaa72024-10-23 17:41:11 -0700148AThermal_getCurrentThermalStatus(AThermalManager *_Nonnull manager) __INTRODUCED_IN(30);
Chris Ye1a5a8882020-01-15 10:51:47 -0800149
150/**
Xiang Wang684eaa72024-10-23 17:41:11 -0700151 * Register a thermal status listener for thermal status change.
Chris Ye1a5a8882020-01-15 10:51:47 -0800152 *
Elliott Hughes7be0e2d2020-06-02 13:05:04 -0700153 * Available since API level 30.
154 *
Chris Ye1a5a8882020-01-15 10:51:47 -0800155 * @param manager The manager instance to use to register.
Xiang Wang684eaa72024-10-23 17:41:11 -0700156 * Acquired via {@link AThermal_acquireManager}.
157 * @param callback The callback function to be called on system binder thread pool when thermal
158 * status updated.
Chris Ye1a5a8882020-01-15 10:51:47 -0800159 * @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.
Xiang Wang684eaa72024-10-23 17:41:11 -0700163 * EPIPE if communication with the system service has failed, the listener will not get
164 * removed and this call should be retried
Chris Ye1a5a8882020-01-15 10:51:47 -0800165 */
Xiang Wang684eaa72024-10-23 17:41:11 -0700166int AThermal_registerThermalStatusListener(AThermalManager *_Nonnull manager,
Xiang Wang800af342024-01-09 13:24:41 -0800167 AThermal_StatusCallback _Nullable callback,
168 void* _Nullable data) __INTRODUCED_IN(30);
Chris Ye1a5a8882020-01-15 10:51:47 -0800169
170/**
Xiang Wang684eaa72024-10-23 17:41:11 -0700171 * Unregister a thermal status listener previously registered.
172 *
173 * No subsequent invocations of the callback will occur after this function returns successfully.
Chris Ye1a5a8882020-01-15 10:51:47 -0800174 *
Elliott Hughes7be0e2d2020-06-02 13:05:04 -0700175 * Available since API level 30.
176 *
Chris Ye1a5a8882020-01-15 10:51:47 -0800177 * @param manager The manager instance to use to unregister.
Xiang Wang684eaa72024-10-23 17:41:11 -0700178 * Acquired via {@link AThermal_acquireManager}.
179 * @param callback The callback function that was previously registered.
Chris Ye1a5a8882020-01-15 10:51:47 -0800180 * @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.
Chris Ye1a5a8882020-01-15 10:51:47 -0800184 * EPIPE if communication with the system service has failed.
185 */
Xiang Wang800af342024-01-09 13:24:41 -0800186int AThermal_unregisterThermalStatusListener(AThermalManager* _Nonnull manager,
187 AThermal_StatusCallback _Nullable callback,
188 void* _Nullable data) __INTRODUCED_IN(30);
Chris Ye1a5a8882020-01-15 10:51:47 -0800189
Chris Forbes56e925a2020-09-15 09:34:59 -0700190/**
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
Elliott Hughesd4b452c2023-09-15 22:52:03 +0000197 * more frequently may result in the function returning `NaN`.
Chris Forbes56e925a2020-09-15 09:34:59 -0700198 *
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
Elliott Hughesd4b452c2023-09-15 22:52:03 +0000203 * returned regardless of the value of `forecastSeconds`.
Chris Forbes56e925a2020-09-15 09:34:59 -0700204 *
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
gfan5d5faa42021-04-12 15:14:29 -0700207 * (or will be) throttled at {@link #ATHERMAL_STATUS_SEVERE}. Such throttling can affect the
Chris Forbes56e925a2020-09-15 09:34:59 -0700208 * 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
gfan5d5faa42021-04-12 15:14:29 -0700210 * may correspond to {@link #ATHERMAL_STATUS_SEVERE}, but may also represent heavier throttling.
Chris Forbes56e925a2020-09-15 09:34:59 -0700211 *
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 */
Xiang Wang800af342024-01-09 13:24:41 -0800228float AThermal_getThermalHeadroom(AThermalManager* _Nonnull manager,
229 int forecastSeconds) __INTRODUCED_IN(31);
Chris Forbes56e925a2020-09-15 09:34:59 -0700230
Xiang Wange6c65b32023-10-09 13:39:37 -0700231/**
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 */
242struct AThermalHeadroomThreshold {
243 float headroom;
244 AThermalStatus thermalStatus;
245};
Dan Albertc796b902024-08-01 22:36:07 +0000246typedef struct AThermalHeadroomThreshold AThermalHeadroomThreshold;
Xiang Wange6c65b32023-10-09 13:39:37 -0700247
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
Xiang Wang684eaa72024-10-23 17:41:11 -0700259 * (or `AThermal_getThermalHeadroom(10)=0.75}`, one can expect that in 10 seconds the system
Xiang Wange6c65b32023-10-09 13:39:37 -0700260 * 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
Xiang Wang684eaa72024-10-23 17:41:11 -0700267 * of 0.75 (or `AThermal_getThermalHeadroom(0)=0.75`) exceeding the threshold of 0.7 above
Xiang Wange6c65b32023-10-09 13:39:37 -0700268 * will always come with lightly throttled state
Xiang Wang684eaa72024-10-23 17:41:11 -0700269 * (or `AThermal_getCurrentThermalStatus()=ATHERMAL_STATUS_LIGHT`) but it can be lower
270 * (or `AThermal_getCurrentThermalStatus()=ATHERMAL_STATUS_NONE`).
Xiang Wange6c65b32023-10-09 13:39:37 -0700271 * 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>
Xiang Wang684eaa72024-10-23 17:41:11 -0700276 * 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>
Xiang Wange6c65b32023-10-09 13:39:37 -0700284 *
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
Xiang Wang684eaa72024-10-23 17:41:11 -0700288 * 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.
Xiang Wange6c65b32023-10-09 13:39:37 -0700291 * @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 */
Xiang Wang800af342024-01-09 13:24:41 -0800298int AThermal_getThermalHeadroomThresholds(AThermalManager* _Nonnull manager,
299 const AThermalHeadroomThreshold* _Nonnull
300 * _Nullable outThresholds,
301 size_t* _Nonnull size) __INTRODUCED_IN(35);
Xiang Wange6c65b32023-10-09 13:39:37 -0700302
Xiang Wang684eaa72024-10-23 17:41:11 -0700303/**
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 */
320typedef 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 */
342int 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
364int AThermal_unregisterThermalHeadroomListener(AThermalManager* _Nonnull manager,
365 AThermal_HeadroomCallback _Nullable callback,
366 void* _Nullable data) __INTRODUCED_IN(36);
367
Chris Ye1a5a8882020-01-15 10:51:47 -0800368#ifdef __cplusplus
369}
370#endif
371
372#endif // _ANDROID_THERMAL_H
373
374/** @} */