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