/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @addtogroup Thermal * @{ */ /** * @file thermal.h */ #ifndef _ANDROID_THERMAL_H #define _ANDROID_THERMAL_H #include /****************************************************************** * * IMPORTANT NOTICE: * * This file is part of Android's set of stable system headers * exposed by the Android NDK (Native Development Kit). * * Third-party source AND binary code relies on the definitions * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES. * * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES) * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES */ /* * Structures and functions to access thermal status and register/unregister * thermal status listener in native code. */ #include #include #if !defined(__INTRODUCED_IN) #define __INTRODUCED_IN(__api_level) /* nothing */ #endif #ifdef __cplusplus extern "C" { #endif /** * Thermal status used in function {@link AThermal_getCurrentThermalStatus} and * {@link AThermal_StatusCallback}. */ enum AThermalStatus { /** Error in thermal status. */ ATHERMAL_STATUS_ERROR = -1, /** Not under throttling. */ ATHERMAL_STATUS_NONE = 0, /** Light throttling where UX is not impacted. */ ATHERMAL_STATUS_LIGHT = 1, /** Moderate throttling where UX is not largely impacted. */ ATHERMAL_STATUS_MODERATE = 2, /** Severe throttling where UX is largely impacted. */ ATHERMAL_STATUS_SEVERE = 3, /** Platform has done everything to reduce power. */ ATHERMAL_STATUS_CRITICAL = 4, /** * Key components in platform are shutting down due to thermal condition. * Device functionalities will be limited. */ ATHERMAL_STATUS_EMERGENCY = 5, /** Need shutdown immediately. */ ATHERMAL_STATUS_SHUTDOWN = 6, }; /** * An opaque type representing a handle to a thermal manager. * An instance of thermal manager must be acquired prior to * using thermal status APIs and must be released after use. * *

To use:

    *
  • Create a new thermal manager instance by calling the * {@link AThermal_acquireManager} function.
  • *
  • Get current thermal status with * {@link AThermal_getCurrentThermalStatus}.
  • *
  • Register a thermal status listener with * {@link AThermal_registerThermalStatusListener}.
  • *
  • Unregister a thermal status listener with * {@link AThermal_unregisterThermalStatusListener}.
  • *
  • Release the thermal manager instance with * {@link AThermal_releaseManager}.

* */ typedef struct AThermalManager AThermalManager; /** * Prototype of the function that is called when thermal status changes. * It's passed the updated thermal status as parameter, as well as the * pointer provided by the client that registered a callback. */ typedef void (*AThermal_StatusCallback)(void* _Nullable data, AThermalStatus status); /** * Acquire an instance of the thermal manager. This must be freed using * {@link AThermal_releaseManager}. * * Available since API level 30. * * @return manager instance on success, nullptr on failure. */ AThermalManager* _Nonnull AThermal_acquireManager() __INTRODUCED_IN(30); /** * Release the thermal manager pointer acquired via * {@link AThermal_acquireManager}. * * Available since API level 30. * * @param manager The manager to be released. */ void AThermal_releaseManager(AThermalManager* _Nonnull manager) __INTRODUCED_IN(30); /** * Gets the current thermal status. * * Available since API level 30. * * @param manager The manager instance to use to query the thermal status. * Acquired via {@link AThermal_acquireManager}. * * @return current thermal status, ATHERMAL_STATUS_ERROR on failure. */ AThermalStatus AThermal_getCurrentThermalStatus(AThermalManager* _Nonnull manager) __INTRODUCED_IN(30); /** * Register the thermal status listener for thermal status change. * * Available since API level 30. * * @param manager The manager instance to use to register. * Acquired via {@link AThermal_acquireManager}. * @param callback The callback function to be called when thermal status updated. * @param data The data pointer to be passed when callback is called. * * @return 0 on success * EINVAL if the listener and data pointer were previously added and not removed. * EPERM if the required permission is not held. * EPIPE if communication with the system service has failed. */ int AThermal_registerThermalStatusListener(AThermalManager* _Nonnull manager, AThermal_StatusCallback _Nullable callback, void* _Nullable data) __INTRODUCED_IN(30); /** * Unregister the thermal status listener previously resgistered. * * Available since API level 30. * * @param manager The manager instance to use to unregister. * Acquired via {@link AThermal_acquireManager}. * @param callback The callback function to be called when thermal status updated. * @param data The data pointer to be passed when callback is called. * * @return 0 on success * EINVAL if the listener and data pointer were not previously added. * EPERM if the required permission is not held. * EPIPE if communication with the system service has failed. */ int AThermal_unregisterThermalStatusListener(AThermalManager* _Nonnull manager, AThermal_StatusCallback _Nullable callback, void* _Nullable data) __INTRODUCED_IN(30); /** * 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 attempted to call significantly * more frequently may result in the function returning `NaN`. * * In addition, in order to be able to provide an accurate forecast, the system does * not attempt to forecast until it has multiple temperature samples from which to * extrapolate. This should only take a few seconds from the time of the first call, * but during this time, no forecasting will occur, and the current headroom will be * returned regardless of the value of `forecastSeconds`. * * The value returned is a non-negative float that represents how much of the thermal envelope * is in use (or is forecasted to be in use). A value of 1.0 indicates that the device is * (or will be) throttled at {@link #ATHERMAL_STATUS_SEVERE}. Such throttling can affect the * CPU, GPU, and other subsystems. Values may exceed 1.0, but there is no implied mapping * to specific thermal levels beyond that point. This means that values greater than 1.0 * may correspond to {@link #ATHERMAL_STATUS_SEVERE}, but may also represent heavier throttling. * * A value of 0.0 corresponds to a fixed distance from 1.0, but does not correspond to any * particular thermal status or temperature. Values on (0.0, 1.0] may be expected to scale * linearly with temperature, though temperature changes over time are typically not linear. * Negative values will be clamped to 0.0 before returning. * * Available since API level 31. * * @param manager The manager instance to use. * Acquired via {@link AThermal_acquireManager}. * @param forecastSeconds how many seconds into the future to forecast. Given that device * conditions may change at any time, forecasts from further in the * future will likely be less accurate than forecasts in the near future. * @return a value greater than equal to 0.0, where 1.0 indicates the SEVERE throttling threshold, * as described above. 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* _Nonnull manager, int forecastSeconds) __INTRODUCED_IN(31); /** * This struct defines an instance of headroom threshold value and its status. *

* The value should be monotonically non-decreasing as the thermal status increases. * For {@link ATHERMAL_STATUS_SEVERE}, its headroom threshold is guaranteed to * be 1.0f. For status below severe status, the value should be lower or equal * to 1.0f, and for status above severe, the value should be larger or equal to 1.0f. *

* Also see {@link AThermal_getThermalHeadroom} for explanation on headroom, and * {@link AThermal_getThermalHeadroomThresholds} for how to use this. */ struct AThermalHeadroomThreshold { float headroom; AThermalStatus thermalStatus; }; /** * Gets the thermal headroom thresholds for all available thermal status. * * A thermal status will only exist in output if the device manufacturer has the * corresponding threshold defined for at least one of its slow-moving skin temperature * sensors. If it's set, one should also expect to get it from * {@link #AThermal_getCurrentThermalStatus} or {@link AThermal_StatusCallback}. *

* The headroom threshold is used to interpret the possible thermal throttling status based on * the headroom prediction. For example, if the headroom threshold for * {@link ATHERMAL_STATUS_LIGHT} is 0.7, and a headroom prediction in 10s returns 0.75 * (or {@code AThermal_getThermalHeadroom(10)=0.75}), one can expect that in 10 seconds the system * could be in lightly throttled state if the workload remains the same. The app can consider * taking actions according to the nearest throttling status the difference between the headroom and * the threshold. *

* For new devices it's guaranteed to have a single sensor, but for older devices with multiple * sensors reporting different threshold values, the minimum threshold is taken to be conservative * on predictions. Thus, when reading real-time headroom, it's not guaranteed that a real-time value * of 0.75 (or {@code AThermal_getThermalHeadroom(0)}=0.75) exceeding the threshold of 0.7 above * will always come with lightly throttled state * (or {@code AThermal_getCurrentThermalStatus()=ATHERMAL_STATUS_LIGHT}) but it can be lower * (or {@code AThermal_getCurrentThermalStatus()=ATHERMAL_STATUS_NONE}). * While it's always guaranteed that the device won't be throttled heavier than the unmet * threshold's state, so a real-time headroom of 0.75 will never come with * {@link #ATHERMAL_STATUS_MODERATE} but always lower, and 0.65 will never come with * {@link ATHERMAL_STATUS_LIGHT} but {@link #ATHERMAL_STATUS_NONE}. *

* The returned list of thresholds is cached on first successful query and owned by the thermal * manager, which will not change between calls to this function. The caller should only need to * free the manager with {@link AThermal_releaseManager}. * * @param manager The manager instance to use. * Acquired via {@link AThermal_acquireManager}. * @param outThresholds non-null output pointer to null AThermalHeadroomThreshold pointer, which * will be set to the cached array of thresholds if thermal thresholds are supported * by the system or device, otherwise nullptr or unmodified. * @param size non-null output pointer whose value will be set to the size of the threshold array * or 0 if it's not supported. * @return 0 on success * EINVAL if outThresholds or size_t is nullptr, or *outThresholds is not nullptr. * EPIPE if communication with the system service has failed. * ENOSYS if the feature is disabled by the current system. */ int AThermal_getThermalHeadroomThresholds(AThermalManager* _Nonnull manager, const AThermalHeadroomThreshold* _Nonnull * _Nullable outThresholds, size_t* _Nonnull size) __INTRODUCED_IN(35); #ifdef __cplusplus } #endif #endif // _ANDROID_THERMAL_H /** @} */