summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/android/input.h2
-rw-r--r--include/android/performance_hint.h324
-rw-r--r--include/android/surface_control_input_receiver.h9
-rw-r--r--include/android/system_health.h244
-rw-r--r--include/audiomanager/IAudioManager.h24
-rw-r--r--include/ftl/finalizer.h211
-rw-r--r--include/ftl/ignore.h42
-rw-r--r--include/ftl/small_map.h6
-rw-r--r--include/input/AccelerationCurve.h11
-rw-r--r--include/input/BlockingQueue.h15
-rw-r--r--include/input/DisplayTopologyGraph.h5
-rw-r--r--include/input/Input.h30
-rw-r--r--include/input/InputFlags.h35
-rw-r--r--include/input/InputVerifier.h5
-rw-r--r--include/input/PrintTools.h15
-rw-r--r--include/private/performance_hint_private.h6
-rw-r--r--include/private/system_health_private.h32
17 files changed, 803 insertions, 213 deletions
diff --git a/include/android/input.h b/include/android/input.h
index ee98d7aee9..2f6c5b57ff 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -849,6 +849,7 @@ enum {
* Refer to the documentation on the MotionEvent class for descriptions of each button.
*/
enum {
+ // LINT.IfChange(AMOTION_EVENT_BUTTON)
/** primary */
AMOTION_EVENT_BUTTON_PRIMARY = 1 << 0,
/** secondary */
@@ -861,6 +862,7 @@ enum {
AMOTION_EVENT_BUTTON_FORWARD = 1 << 4,
AMOTION_EVENT_BUTTON_STYLUS_PRIMARY = 1 << 5,
AMOTION_EVENT_BUTTON_STYLUS_SECONDARY = 1 << 6,
+ // LINT.ThenChange(/frameworks/native/libs/input/rust/input.rs,/frameworks/native/services/inputflinger/tests/fuzzers/FuzzedInputStream.h)
};
/**
diff --git a/include/android/performance_hint.h b/include/android/performance_hint.h
index 2b4a5f5f53..52dbb61ac5 100644
--- a/include/android/performance_hint.h
+++ b/include/android/performance_hint.h
@@ -29,7 +29,7 @@
* workloads are taking. The framework will then compare the actual durations to the target
* duration and attempt to help the client reach a steady state under the target.
*
- * Unlike reportActualWorkDuration, the "notify..." hints are intended to be sent in
+ * Unlike reportActualWorkDuration, the "notifyWorkload..." hints are intended to be sent in
* advance of large changes in the workload, to prevent them from going over the target
* when there is a sudden, unforseen change. Their effects are intended to last for only
* one cycle, after which reportActualWorkDuration will have a chance to catch up.
@@ -71,6 +71,10 @@
#include <stdint.h>
#include <unistd.h>
+#if !defined(__DEPRECATED_IN)
+#define __DEPRECATED_IN(__api_level, ...) __attribute__((__deprecated__))
+#endif
+
__BEGIN_DECLS
struct APerformanceHintManager;
@@ -116,13 +120,13 @@ typedef struct APerformanceHintManager APerformanceHintManager;
* An opaque type representing a handle to a performance hint session creation configuration.
* It is consumed by {@link APerformanceHint_createSessionUsingConfig}.
*
- * A session creation config encapsulates the required information for a session.
- * Additionally, the caller can set various settings for the session,
- * to be passed during creation, streamlining the session setup process.
- *
- * The caller may reuse this object and modify the settings in it
- * to create additional sessions.
+ * A session creation config encapsulates the required information for creating a session. The only
+ * mandatory parameter is the set of TIDs, set using {@link ASessionCreationConfig_setTids}. Only
+ * parameters relevant to the session need to be set, and any unspecified functionality will be
+ * treated as unused on the session. Configurations without a valid set of TIDs, or which try to
+ * enable automatic timing without the graphics pipeline mode, are considered invalid.
*
+ * The caller may reuse this object and modify the settings in it to create additional sessions.
*/
typedef struct ASessionCreationConfig ASessionCreationConfig;
@@ -181,27 +185,43 @@ APerformanceHintSession* _Nullable APerformanceHint_createSession(
int64_t initialTargetWorkDurationNanos) __INTRODUCED_IN(__ANDROID_API_T__);
/**
- * Creates a session for the given set of threads that are graphics pipeline threads
- * and set their initial target work duration.
+ * Creates a session using arguments from a corresponding {@link ASessionCreationConfig}.
+ *
+ * Note: when using graphics pipeline mode, using too many cumulative graphics pipeline threads is
+ * not a failure and will still create a session, but it will cause all graphics pipeline sessions
+ * to have undefined behavior and the method will return EBUSY.
*
* @param manager The performance hint manager instance.
* @param config The configuration struct containing required information
* to create a session.
- * @return APerformanceHintSession pointer on success, nullptr on failure.
+ * @param sessionOut A client-provided pointer, which will be set to the new APerformanceHintSession
+ * on success or EBUSY, and to nullptr on failure.
+ *
+ * @return 0 on success.
+ * EINVAL if the creation config is in an invalid state.
+ * EPIPE if communication failed.
+ * ENOTSUP if hint sessions are not supported, or if auto timing is enabled but unsupported.
+ * EBUSY if too many graphics pipeline threads are passed.
*/
-APerformanceHintSession* _Nullable APerformanceHint_createSessionUsingConfig(
+int APerformanceHint_createSessionUsingConfig(
APerformanceHintManager* _Nonnull manager,
- ASessionCreationConfig* _Nonnull config)
- __INTRODUCED_IN(36);
+ ASessionCreationConfig* _Nonnull config,
+ APerformanceHintSession * _Nullable * _Nonnull sessionOut) __INTRODUCED_IN(36);
/**
* Get preferred update rate information for this device.
*
+ * @deprecated Client side rate limiting is not necessary, rate limiting is handled in the
+ * framework. If you were using this to check for hint session support, please use
+ * {@link APerformanceHint_isFeatureSupported} instead.
+ *
* @param manager The performance hint manager instance.
* @return the preferred update rate supported by device software.
*/
int64_t APerformanceHint_getPreferredUpdateRateNanos(
- APerformanceHintManager* _Nonnull manager) __INTRODUCED_IN(__ANDROID_API_T__);
+ APerformanceHintManager* _Nonnull manager)
+ __INTRODUCED_IN(__ANDROID_API_T__) __DEPRECATED_IN(36, "Client-side rate limiting is not"
+ " necessary, use APerformanceHint_isFeatureSupported for support checking.");
/**
* Get maximum number of graphics pipieline threads per-app for this device.
@@ -216,9 +236,11 @@ int64_t APerformanceHint_getPreferredUpdateRateNanos(
* Updates this session's target duration for each cycle of work.
*
* @param session The performance hint session instance to update.
- * @param targetDurationNanos The new desired duration in nanoseconds. This must be positive.
+ * @param targetDurationNanos The new desired duration in nanoseconds. This must be positive for the
+ * session to report work durations, and may be zero to disable this functionality.
+ *
* @return 0 on success.
- * EINVAL if targetDurationNanos is not positive.
+ * EINVAL if targetDurationNanos is less than zero.
* EPIPE if communication with the system service has failed.
*/
int APerformanceHint_updateTargetWorkDuration(
@@ -235,7 +257,7 @@ int APerformanceHint_updateTargetWorkDuration(
* @param actualDurationNanos The duration of time the thread group took to complete its last
* task in nanoseconds. This must be positive.
* @return 0 on success.
- * EINVAL if actualDurationNanos is not positive.
+ * EINVAL if actualDurationNanos is not positive or the target it not positive.
* EPIPE if communication with the system service has failed.
*/
int APerformanceHint_reportActualWorkDuration(
@@ -258,15 +280,20 @@ void APerformanceHint_closeSession(
* Set a list of threads to the performance hint session. This operation will replace
* the current list of threads with the given list of threads.
*
+ * Note: when using a session with the graphics pipeline mode enabled, using too many cumulative
+ * graphics pipeline threads is not a failure, but it will cause all graphics pipeline sessions to
+ * have undefined behavior and the method will return EBUSY.
+ *
* @param session The performance hint session instance to update.
* @param threadIds The list of threads to be associated with this session. They must be part of
* this app's thread group.
* @param size The size of the list of threadIds.
* @return 0 on success.
* EINVAL if the list of thread ids is empty or if any of the thread ids are not part of
- the thread group.
+ * the thread group.
* EPIPE if communication with the system service has failed.
* EPERM if any thread id doesn't belong to the application.
+ * EBUSY if too many graphics pipeline threads were passed.
*/
int APerformanceHint_setThreads(
APerformanceHintSession* _Nonnull session,
@@ -311,89 +338,102 @@ int APerformanceHint_reportActualWorkDuration2(
AWorkDuration* _Nonnull workDuration) __INTRODUCED_IN(__ANDROID_API_V__);
/**
- * Informs the framework of an upcoming increase in the workload of a graphics pipeline
- * bound to this session. The user can specify whether the increase is expected to be
- * on the CPU, GPU, or both.
+ * Informs the framework of an upcoming increase in the workload of this session.
+ * The user can specify whether the increase is expected to be on the CPU, GPU, or both.
*
- * Sending hints for both CPU and GPU counts as two separate hints for the purposes of the
- * rate limiter.
+ * These hints should be sent shortly before the start of the cycle where the workload is going to
+ * change, or as early as possible during that cycle for maximum effect. Hints sent towards the end
+ * of the cycle may be interpreted as applying to the next cycle. Any unsupported hints will be
+ * silently dropped, to avoid the need for excessive support checking each time they are sent, and
+ * sending a hint for both CPU and GPU will count as two separate hints for the rate limiter. These
+ * hints should not be sent repeatedly for an ongoing expensive workload, as workload time reporting
+ * is intended to handle this.
*
+ * @param session The {@link APerformanceHintSession} instance to send a hint for.
* @param cpu Indicates if the workload increase is expected to affect the CPU.
* @param gpu Indicates if the workload increase is expected to affect the GPU.
- * @param debugName A required string used to identify this specific hint during
- * tracing. This debug string will only be held for the duration of the
- * method, and can be safely discarded after.
+ * @param identifier A required string used to distinguish this specific hint, using utf-8 encoding.
+ * This string will only be held for the duration of the method, and can be discarded after.
*
* @return 0 on success.
- * EINVAL if no hints were requested.
* EBUSY if the hint was rate limited.
* EPIPE if communication with the system service has failed.
- * ENOTSUP if the hint is not supported.
*/
int APerformanceHint_notifyWorkloadIncrease(
APerformanceHintSession* _Nonnull session,
- bool cpu, bool gpu, const char* _Nonnull debugName) __INTRODUCED_IN(36);
+ bool cpu, bool gpu, const char* _Nonnull identifier) __INTRODUCED_IN(36);
/**
- * Informs the framework of an upcoming reset in the workload of a graphics pipeline
- * bound to this session, or the imminent start of a new workload. The user can specify
- * whether the reset is expected to affect the CPU, GPU, or both.
+ * Informs the framework that the workload associated with this session is about to start, or that
+ * it is about to completely change, and that the system should discard any assumptions about its
+ * characteristics inferred from previous activity. The user can specify whether the reset is
+ * expected to affect the CPU, GPU, or both.
*
- * Sending hints for both CPU and GPU counts as two separate hints for the purposes of the
- * this load tracking.
+ * These hints should be sent shortly before the start of the cycle where the workload is going to
+ * change, or as early as possible during that cycle for maximum effect. Hints sent towards the end
+ * of the cycle may be interpreted as applying to the next cycle. Any unsupported hints will be
+ * silently dropped, to avoid the need for excessive support checking each time they are sent, and
+ * sending a hint for both CPU and GPU will count as two separate hints for the rate limiter. These
+ * hints should not be sent repeatedly for an ongoing expensive workload, as workload time reporting
+ * is intended to handle this.
*
+ * @param session The {@link APerformanceHintSession} instance to send a hint for.
* @param cpu Indicates if the workload reset is expected to affect the CPU.
* @param gpu Indicates if the workload reset is expected to affect the GPU.
- * @param debugName A required string used to identify this specific hint during
- * tracing. This debug string will only be held for the duration of the
- * method, and can be safely discarded after.
+ * @param identifier A required string used to distinguish this specific hint, using utf-8 encoding.
+ * This string will only be held for the duration of the method, and can be discarded after.
*
* @return 0 on success.
- * EINVAL if no hints were requested.
* EBUSY if the hint was rate limited.
* EPIPE if communication with the system service has failed.
- * ENOTSUP if the hint is not supported.
*/
int APerformanceHint_notifyWorkloadReset(
APerformanceHintSession* _Nonnull session,
- bool cpu, bool gpu, const char* _Nonnull debugName) __INTRODUCED_IN(36);
+ bool cpu, bool gpu, const char* _Nonnull identifier) __INTRODUCED_IN(36);
/**
- * Informs the framework of an upcoming one-off expensive frame for a graphics pipeline
- * bound to this session. This frame will be treated as not representative of the workload as a
- * whole, and it will be discarded the purposes of load tracking. The user can specify
- * whether the workload spike is expected to be on the CPU, GPU, or both.
+ * Informs the framework of an upcoming one-off expensive workload cycle for a given session.
+ * This cycle will be treated as not representative of the workload as a whole, and it will be
+ * discarded the purposes of load tracking. The user can specify whether the workload spike is
+ * expected to be on the CPU, GPU, or both.
*
- * Sending hints for both CPU and GPU counts as two separate hints for the purposes of the
- * rate limiter.
+ * These hints should be sent shortly before the start of the cycle where the workload is going to
+ * change, or as early as possible during that cycle for maximum effect. Hints sent towards the end
+ * of the cycle may be interpreted as applying to the next cycle. Any unsupported hints will be
+ * silently dropped, to avoid the need for excessive support checking each time they are sent, and
+ * sending a hint for both CPU and GPU will count as two separate hints for the rate limiter. These
+ * hints should not be sent repeatedly for an ongoing expensive workload, as workload time reporting
+ * is intended to handle this.
*
+ * @param session The {@link APerformanceHintSession} instance to send a hint for.
* @param cpu Indicates if the workload spike is expected to affect the CPU.
* @param gpu Indicates if the workload spike is expected to affect the GPU.
- * @param debugName A required string used to identify this specific hint during
- * tracing. This debug string will only be held for the duration of the
- * method, and can be safely discarded after.
+ * @param identifier A required string used to distinguish this specific hint, using utf-8 encoding.
+ * This string will only be held for the duration of the method, and can be discarded after.
*
* @return 0 on success.
- * EINVAL if no hints were requested.
* EBUSY if the hint was rate limited.
* EPIPE if communication with the system service has failed.
- * ENOTSUP if the hint is not supported.
*/
int APerformanceHint_notifyWorkloadSpike(
APerformanceHintSession* _Nonnull session,
- bool cpu, bool gpu, const char* _Nonnull debugName) __INTRODUCED_IN(36);
+ bool cpu, bool gpu, const char* _Nonnull identifier) __INTRODUCED_IN(36);
/**
* Associates a session with any {@link ASurfaceControl} or {@link ANativeWindow}
- * instances managed by this session.
+ * instances managed by this session. Any previously associated objects that are not passed
+ * in again lose their association. Invalid or dead instances are ignored, and passing both
+ * lists as null drops all current associations.
*
* This method is primarily intended for sessions that manage the timing of an entire
- * graphics pipeline end-to-end, such as those using the
+ * graphics pipeline end-to-end for frame pacing, such as those using the
* {@link ASessionCreationConfig_setGraphicsPipeline} API. However, any session directly
* or indirectly managing a graphics pipeline should still associate themselves with
* directly relevant ASurfaceControl or ANativeWindow instances for better optimization.
+ * Additionally, if the surface associated with a session changes, this method should be called
+ * again to re-create the association.
*
- * To see any benefit from this method, the client must make sure they are updating the framerate
+ * To see any benefit from this method, the client must make sure they are updating the frame rate
* of attached surfaces using methods such as {@link ANativeWindow_setFrameRate}, or by updating
* any associated ASurfaceControls with transactions that have {ASurfaceTransaction_setFrameRate}.
*
@@ -407,16 +447,77 @@ int APerformanceHint_notifyWorkloadSpike(
*
* @return 0 on success.
* EPIPE if communication has failed.
- * ENOTSUP if unsupported.
- * EINVAL if invalid or empty arguments passed.
+ * ENOTSUP if this is not supported on the device.
*/
int APerformanceHint_setNativeSurfaces(APerformanceHintSession* _Nonnull session,
- ANativeWindow* _Nonnull* _Nullable nativeWindows, int nativeWindowsSize,
- ASurfaceControl* _Nonnull* _Nullable surfaceControls, int surfaceControlsSize)
+ ANativeWindow* _Nonnull* _Nullable nativeWindows, size_t nativeWindowsSize,
+ ASurfaceControl* _Nonnull* _Nullable surfaceControls, size_t surfaceControlsSize)
__INTRODUCED_IN(36);
/**
+ * This enum represents different aspects of performance hint functionality. These can be passed
+ * to {@link APerformanceHint_isFeatureSupported} to determine whether the device exposes support
+ * for that feature.
+ *
+ * Some of these features will not expose failure to the client if used when unsupported, to prevent
+ * the client from needing to worry about handling different logic for each possible support
+ * configuration. The exception to this is features with important user-facing side effects, such as
+ * {@link APERF_HINT_AUTO_CPU} and {@link APERF_HINT_AUTO_GPU} modes which expect the client not to
+ * report durations while they are active.
+ */
+typedef enum APerformanceHintFeature : int32_t {
+ /**
+ * This value represents all APerformanceHintSession functionality. Using the Performance Hint
+ * API at all if this is not enabled will likely result in either
+ * {@link APerformanceHintManager} or {@link APerformanceHintSession} failing to create, or the
+ * session having little to no benefit even if creation succeeds.
+ */
+ APERF_HINT_SESSIONS,
+
+ /**
+ * This value represents the power efficiency mode, as exposed by
+ * {@link ASessionCreationConfig_setPreferPowerEfficiency} and
+ * {@link APerformanceHint_setPreferPowerEfficiency}.
+ */
+ APERF_HINT_POWER_EFFICIENCY,
+
+ /**
+ * This value the ability for sessions to bind to surfaces using
+ * {@link APerformanceHint_setNativeSurfaces} or
+ * {@link ASessionCreationConfig_setNativeSurfaces}
+ */
+ APERF_HINT_SURFACE_BINDING,
+
+ /**
+ * This value represents the "graphics pipeline" mode, as exposed by
+ * {@link ASessionCreationConfig_setGraphicsPipeline}.
+ */
+ APERF_HINT_GRAPHICS_PIPELINE,
+
+ /**
+ * This value represents the automatic CPU timing feature, as exposed by
+ * {@link ASessionCreationConfig_setUseAutoTiming}.
+ */
+ APERF_HINT_AUTO_CPU,
+
+ /**
+ * This value represents the automatic GPU timing feature, as exposed by
+ * {@link ASessionCreationConfig_setUseAutoTiming}.
+ */
+ APERF_HINT_AUTO_GPU,
+} APerformanceHintFeature;
+
+/**
+ * Checks whether the device exposes support for a specific feature.
+ *
+ * @param feature The specific feature enum to check.
+ *
+ * @return false if unsupported, true if supported.
+ */
+bool APerformanceHint_isFeatureSupported(APerformanceHintFeature feature) __INTRODUCED_IN(36);
+
+/**
* Creates a new AWorkDuration. When the client finishes using {@link AWorkDuration}, it should
* call {@link AWorkDuration_release()} to destroy {@link AWorkDuration} and release all resources
* associated with it.
@@ -478,8 +579,13 @@ void AWorkDuration_setActualGpuDurationNanos(AWorkDuration* _Nonnull aWorkDurati
/**
* Return the APerformanceHintSession wrapped by a Java PerformanceHintManager.Session object.
*
- * The Java session maintains ownership over the wrapped native session, so it cannot be
- * closed using {@link APerformanceHint_closeSession}.
+ * The Java session maintains ownership over the wrapped native session, so it cannot be closed
+ * using {@link APerformanceHint_closeSession}. The return value is valid until the Java object
+ * containing this value dies.
+ *
+ * The returned pointer is intended to be used by JNI calls to access native performance APIs using
+ * a Java hint session wrapper, and then immediately discarded. Using the pointer after the death of
+ * the Java container results in undefined behavior.
*
* @param env The Java environment where the PerformanceHintManager.Session lives.
* @param sessionObj The Java Session to unwrap.
@@ -502,7 +608,6 @@ APerformanceHintSession* _Nonnull APerformanceHint_borrowSessionFromJava(
ASessionCreationConfig* _Nonnull ASessionCreationConfig_create()
__INTRODUCED_IN(36);
-
/**
* Destroys a {@link ASessionCreationConfig} and frees all
* resources associated with it.
@@ -521,11 +626,8 @@ void ASessionCreationConfig_release(
* @param tids The list of tids to be associated with this session. They must be part of
* this process' thread group.
* @param size The size of the list of tids.
- *
- * @return 0 on success.
- * EINVAL if invalid array pointer or the value of size
*/
-int ASessionCreationConfig_setTids(
+void ASessionCreationConfig_setTids(
ASessionCreationConfig* _Nonnull config,
const pid_t* _Nonnull tids, size_t size) __INTRODUCED_IN(36);
@@ -534,15 +636,11 @@ int ASessionCreationConfig_setTids(
*
* @param config The {@link ASessionCreationConfig}
* created by calling {@link ASessionCreationConfig_create()}.
- * @param targetWorkDurationNanos The parameter to specify a target duration
- * in nanoseconds for the new session; this value must be positive to use
- * the work duration API.
- *
- * @return 0 on success.
- * ENOTSUP if unsupported
- * EINVAL if invalid value
+ * @param targetWorkDurationNanos The parameter to specify a target duration in nanoseconds for the
+ * new session; this value must be positive to use the work duration API, and may be ignored
+ * otherwise or set to zero. Negative values are invalid.
*/
-int ASessionCreationConfig_setTargetWorkDurationNanos(
+void ASessionCreationConfig_setTargetWorkDurationNanos(
ASessionCreationConfig* _Nonnull config,
int64_t targetWorkDurationNanos) __INTRODUCED_IN(36);
@@ -554,12 +652,8 @@ int ASessionCreationConfig_setTargetWorkDurationNanos(
* @param config The {@link ASessionCreationConfig}
* created by calling {@link ASessionCreationConfig_create()}.
* @param enabled Whether power efficiency mode will be enabled.
- *
- * @return 0 on success.
- * ENOTSUP if unsupported
- * EINVAL if invalid pointer to creation config
*/
-int ASessionCreationConfig_setPreferPowerEfficiency(
+void ASessionCreationConfig_setPreferPowerEfficiency(
ASessionCreationConfig* _Nonnull config, bool enabled) __INTRODUCED_IN(36);
/**
@@ -569,24 +663,31 @@ int ASessionCreationConfig_setPreferPowerEfficiency(
* buffer is fully finished drawing.
*
* It should include any threads on the critical path of that pipeline,
- * up to a limit accessible from {@link getMaxGraphicsPipelineThreadsCount()}.
+ * up to a limit accessible from {@link APerformanceHint_getMaxGraphicsPipelineThreadsCount()}.
*
* @param config The {@link ASessionCreationConfig}
* created by calling {@link ASessionCreationConfig_create()}.
* @param enabled Whether this session manages a graphics pipeline's critical path.
- *
- * @return 0 on success.
- * ENOTSUP if unsupported
- * EINVAL if invalid pointer to creation config or maximum threads for graphics
- pipeline is reached.
*/
-int ASessionCreationConfig_setGraphicsPipeline(
+void ASessionCreationConfig_setGraphicsPipeline(
ASessionCreationConfig* _Nonnull config, bool enabled) __INTRODUCED_IN(36);
/**
- * Associates a session with any {@link ASurfaceControl} or {@link ANativeWindow}
- * instances managed by this session. See {@link APerformanceHint_setNativeSurfaces}
- * for more details.
+ * Associates the created session with any {@link ASurfaceControl} or {@link ANativeWindow}
+ * instances it will be managing. Invalid or dead instances are ignored.
+ *
+ * This method is primarily intended for sessions that manage the timing of an entire
+ * graphics pipeline end-to-end for frame pacing, such as those using the
+ * {@link ASessionCreationConfig_setGraphicsPipeline} API. However, any session directly
+ * or indirectly managing a graphics pipeline should still associate themselves with
+ * directly relevant ASurfaceControl or ANativeWindow instances for better optimization.
+ * Additionally, if the surface associated with a session changes, this method should be called
+ * again to re-create the association.
+ *
+ * To see any benefit from this method, the client must make sure they are updating the frame rate
+ * of attached surfaces using methods such as {@link ANativeWindow_setFrameRate}, or by updating
+ * any associated ASurfaceControls with transactions that have {ASurfaceTransaction_setFrameRate}.
+ *
*
* @param config The {@link ASessionCreationConfig}
* created by calling {@link ASessionCreationConfig_create()}.
@@ -596,49 +697,46 @@ int ASessionCreationConfig_setGraphicsPipeline(
* @param surfaceControls A pointer to a list of ASurfaceControls associated with this session.
* nullptr can be passed to indicate there are no associated ASurfaceControls.
* @param surfaceControlsSize The number of ASurfaceControls in the list.
- *
- * @return 0 on success.
- * ENOTSUP if unsupported.
- * EINVAL if invalid or empty arguments passed.
*/
-int ASessionCreationConfig_setNativeSurfaces(
+void ASessionCreationConfig_setNativeSurfaces(
ASessionCreationConfig* _Nonnull config,
- ANativeWindow* _Nonnull* _Nullable nativeWindows, int nativeWindowsSize,
- ASurfaceControl* _Nonnull* _Nullable surfaceControls, int surfaceControlsSize)
+ ANativeWindow* _Nonnull* _Nullable nativeWindows, size_t nativeWindowsSize,
+ ASurfaceControl* _Nonnull* _Nullable surfaceControls, size_t surfaceControlsSize)
__INTRODUCED_IN(36);
/**
* Enable automatic timing mode for sessions using the GRAPHICS_PIPELINE API with an attached
- * surface. In this mode, sessions do not need to report actual durations and only need
- * to keep their thread list up-to-date, set a native surface, call
- * {@link ASessionCreationConfig_setGraphicsPipeline()} to signal that the session is in
- * "graphics pipeline" mode, and then set whether automatic timing is desired for the
- * CPU, GPU, or both, using this method.
+ * surface. In this mode, sessions do not need to report timing data for the CPU, GPU, or both
+ * depending on the configuration. To use this mode, sessions should set a native surface
+ * using {@ASessionCreationConfig_setNativeSurfaces}, enable graphics pipeline mode with
+ * {@link ASessionCreationConfig_setGraphicsPipeline()}, and then call this method to set whether
+ * automatic timing is desired for the CPU, GPU, or both. Trying to enable this without also
+ * enabling the graphics pipeline mode will cause session creation to fail.
*
* It is still be beneficial to set an accurate target time, as this may help determine
* timing information for some workloads where there is less information available from
* the framework, such as games. Additionally, reported CPU durations will be ignored
* while automatic CPU timing is enabled, and similarly GPU durations will be ignored
* when automatic GPU timing is enabled. When both are enabled, the entire
- * reportActualWorkDuration call will be ignored, and the session will be managed
- * completely automatically.
+ * {@link APerformanceHint_reportActualWorkDuration} call will be ignored, and the session will be
+ * managed completely automatically.
*
- * This mode will not work unless the client makes sure they are updating the framerate
- * of attached surfaces with methods such as {@link ANativeWindow_setFrameRate}, or updating
- * any associated ASurfaceControls with transactions that have {ASurfaceTransaction_setFrameRate}.
+ * If the client is manually controlling their frame rate for those surfaces, then they must make
+ * sure they are updating the frame rate with {@link ANativeWindow_setFrameRate}, or updating any
+ * associated ASurfaceControls with transactions that have {ASurfaceTransaction_setFrameRate} set.
+ *
+ * The user of this API should ensure this feature is supported by checking
+ * {@link APERF_HINT_AUTO_CPU} and {@link APERF_HINT_AUTO_GPU} with
+ * {@link APerformanceHint_isFeatureSupported} and falling back to manual timing if it is not.
+ * Trying to use automatic timing when it is unsupported will cause session creation to fail.
*
* @param config The {@link ASessionCreationConfig}
* created by calling {@link ASessionCreationConfig_create()}.
* @param cpu Whether to enable automatic timing for the CPU for this session.
* @param gpu Whether to enable automatic timing for the GPU for this session.
- *
- * @return 0 on success.
- * ENOTSUP if unsupported.
*/
-int ASessionCreationConfig_setUseAutoTiming(
- ASessionCreationConfig* _Nonnull config,
- bool cpu, bool gpu)
- __INTRODUCED_IN(36);
+void ASessionCreationConfig_setUseAutoTiming(
+ ASessionCreationConfig* _Nonnull config, bool cpu, bool gpu) __INTRODUCED_IN(36);
__END_DECLS
diff --git a/include/android/surface_control_input_receiver.h b/include/android/surface_control_input_receiver.h
index f0503f6324..59d3a31b30 100644
--- a/include/android/surface_control_input_receiver.h
+++ b/include/android/surface_control_input_receiver.h
@@ -39,11 +39,11 @@ __BEGIN_DECLS
*
* \param motionEvent The motion event. This must be released with AInputEvent_release.
*
+ * \return true if the event is handled by the client, false otherwise.
* Available since API level 35.
*/
typedef bool (*AInputReceiver_onMotionEvent)(void *_Null_unspecified context,
- AInputEvent *_Nonnull motionEvent)
- __INTRODUCED_IN(__ANDROID_API_V__);
+ AInputEvent *_Nonnull motionEvent);
/**
* The AInputReceiver_onKeyEvent callback is invoked when the registered input channel receives
* a key event.
@@ -53,11 +53,12 @@ typedef bool (*AInputReceiver_onMotionEvent)(void *_Null_unspecified context,
*
* \param keyEvent The key event. This must be released with AInputEvent_release.
*
+ * \return true if the event is handled by the client, false otherwise. System may generate
+ * a fallback key event if the event is not handled.
* Available since API level 35.
*/
typedef bool (*AInputReceiver_onKeyEvent)(void *_Null_unspecified context,
- AInputEvent *_Nonnull keyEvent)
- __INTRODUCED_IN(__ANDROID_API_V__);
+ AInputEvent *_Nonnull keyEvent);
typedef struct AInputReceiverCallbacks AInputReceiverCallbacks;
diff --git a/include/android/system_health.h b/include/android/system_health.h
index 69620df16e..bdb1413555 100644
--- a/include/android/system_health.h
+++ b/include/android/system_health.h
@@ -16,6 +16,31 @@
/**
* @defgroup SystemHealth
+*
+ * SystemHealth provides access to data about how various system resources are used by applications.
+ *
+ * CPU/GPU headroom APIs are designed to be best used by applications with consistent and intense
+ * workload such as games to query the remaining capacity headroom over a short period and perform
+ * optimization accordingly. Due to the nature of the fast job scheduling and frequency scaling of
+ * CPU and GPU, the headroom by nature will have "TOCTOU" problem which makes it less suitable for
+ * apps with inconsistent or low workload to take any useful action but simply monitoring. And to
+ * avoid oscillation it's not recommended to adjust workload too frequent (on each polling request)
+ * or too aggressively. As the headroom calculation is more based on reflecting past history usage
+ * than predicting future capacity. Take game as an example, if the API returns CPU headroom of 0 in
+ * one scenario (especially if it's constant across multiple calls), or some value significantly
+ * smaller than other scenarios, then it can reason that the recent performance result is more CPU
+ * bottlenecked. Then reducing the CPU workload intensity can help reserve some headroom to handle
+ * the load variance better, which can result in less frame drops or smooth FPS value. On the other
+ * hand, if the API returns large CPU headroom constantly, the app can be more confident to increase
+ * the workload and expect higher possibility of device meeting its performance expectation.
+ * App can also use thermal APIs to read the current thermal status and headroom first, then poll
+ * the CPU and GPU headroom if the device is (about to) getting thermal throttled. If the CPU/GPU
+ * headrooms provide enough significance such as one valued at 0 while the other at 100, then it can
+ * be used to infer that reducing CPU workload could be more efficient to cool down the device.
+ * There is a caveat that the power controller may scale down the frequency of the CPU and GPU due
+ * to thermal and other reasons, which can result in a higher than usual percentage usage of the
+ * capacity.
+ *
* @{
*/
@@ -70,55 +95,40 @@ typedef struct ACpuHeadroomParams ACpuHeadroomParams;
*/
typedef struct AGpuHeadroomParams AGpuHeadroomParams;
-/**
- * Creates a new instance of ACpuHeadroomParams.
- *
- * When the client finishes using {@link ACpuHeadroomParams},
- * {@link ACpuHeadroomParams_destroy()} must be called to destroy
- * and free up the resources associated with {@link ACpuHeadroomParams}.
- *
- * Available since API level 36.
- *
- * @return A new instance of ACpuHeadroomParams.
- */
-ACpuHeadroomParams *_Nonnull ACpuHeadroomParams_create()
-__INTRODUCED_IN(36);
-
-enum ACpuHeadroomCalculationType {
+typedef enum ACpuHeadroomCalculationType : int32_t {
/**
- * Use the minimum headroom value within the calculation window.
+ * The headroom calculation type bases on minimum value over a specified window.
* Introduced in API level 36.
*/
ACPU_HEADROOM_CALCULATION_TYPE_MIN = 0,
/**
- * Use the average headroom value within the calculation window.
+ * The headroom calculation type bases on average value over a specified window.
* Introduced in API level 36.
*/
ACPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1,
-};
-typedef enum ACpuHeadroomCalculationType ACpuHeadroomCalculationType;
+} ACpuHeadroomCalculationType;
-enum AGpuHeadroomCalculationType {
+typedef enum AGpuHeadroomCalculationType : int32_t {
/**
- * Use the minimum headroom value within the calculation window.
+ * The headroom calculation type bases on minimum value over a specified window.
* Introduced in API level 36.
*/
AGPU_HEADROOM_CALCULATION_TYPE_MIN = 0,
/**
- * Use the average headroom value within the calculation window.
+ * The headroom calculation type bases on average value over a specified window.
* Introduced in API level 36.
*/
AGPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1,
-};
-typedef enum AGpuHeadroomCalculationType AGpuHeadroomCalculationType;
+} AGpuHeadroomCalculationType;
/**
- * Sets the headroom calculation window size in ACpuHeadroomParams.
+ * Sets the CPU headroom calculation window size in milliseconds.
*
* Available since API level 36.
*
* @param params The params to be set.
- * @param windowMillis The window size in milliseconds ranged from [50, 10000]. The smaller the
+ * @param windowMillis The window size in milliseconds ranges from
+ * {@link ASystemHealth_getCpuHeadroomCalculationWindowRange}. The smaller the
* window size, the larger fluctuation in the headroom value should be expected.
* The default value can be retrieved from the
* {@link #ACpuHeadroomParams_getCalculationWindowMillis} if not set. The device
@@ -129,136 +139,210 @@ void ACpuHeadroomParams_setCalculationWindowMillis(ACpuHeadroomParams *_Nonnull
__INTRODUCED_IN(36);
/**
- * Gets the headroom calculation window size in ACpuHeadroomParams.
+ * Gets the CPU headroom calculation window size in milliseconds.
+ *
+ * This will return the default value chosen by the device if not set.
*
* Available since API level 36.
*
- * @param params The params to be set.
+ * @param params The params to read from.
* @return This will return the default value chosen by the device if the params is not set.
*/
-int ACpuHeadroomParams_getCalculationWindowMillis(ACpuHeadroomParams *_Nonnull params)
+int ACpuHeadroomParams_getCalculationWindowMillis(ACpuHeadroomParams* _Nonnull params)
__INTRODUCED_IN(36);
/**
- * Sets the headroom calculation window size in AGpuHeadroomParams.
+ * Sets the GPU headroom calculation window size in milliseconds.
*
* Available since API level 36.
*
* @param params The params to be set.
- * @param windowMillis The window size in milliseconds ranged from [50, 10000]. The smaller the
+ * @param windowMillis The window size in milliseconds ranges from
+ * {@link ASystemHealth_getGpuHeadroomCalculationWindowRange}. The smaller the
* window size, the larger fluctuation in the headroom value should be expected.
* The default value can be retrieved from the
* {@link #AGpuHeadroomParams_getCalculationWindowMillis} if not set. The device
* will try to use the closest feasible window size to this param.
*/
-void AGpuHeadroomParams_setCalculationWindowMillis(AGpuHeadroomParams *_Nonnull params,
+void AGpuHeadroomParams_setCalculationWindowMillis(AGpuHeadroomParams* _Nonnull params,
int windowMillis)
__INTRODUCED_IN(36);
/**
- * Gets the headroom calculation window size in AGpuHeadroomParams.
+ * Gets the GPU headroom calculation window size in milliseconds.
+ *
+ * This will return the default value chosen by the device if not set.
*
* Available since API level 36.
*
- * @param params The params to be set.
+ * @param params The params to read from.
* @return This will return the default value chosen by the device if the params is not set.
*/
-int AGpuHeadroomParams_getCalculationWindowMillis(AGpuHeadroomParams *_Nonnull params)
+int AGpuHeadroomParams_getCalculationWindowMillis(AGpuHeadroomParams* _Nonnull params)
__INTRODUCED_IN(36);
/**
- * Sets the headroom calculation type in ACpuHeadroomParams.
+ * Sets the CPU headroom calculation type in {@link ACpuHeadroomParams}.
*
* Available since API level 36.
*
* @param params The params to be set.
* @param calculationType The headroom calculation type.
*/
-void ACpuHeadroomParams_setCalculationType(ACpuHeadroomParams *_Nonnull params,
+void ACpuHeadroomParams_setCalculationType(ACpuHeadroomParams* _Nonnull params,
ACpuHeadroomCalculationType calculationType)
__INTRODUCED_IN(36);
/**
- * Gets the headroom calculation type in ACpuHeadroomParams.
+ * Gets the CPU headroom calculation type in {@link ACpuHeadroomParams}.
+ *
+ * This will return the default value chosen by the device if not set.
*
* Available since API level 36.
*
- * @param params The params to be set.
+ * @param params The params to read from.
* @return The headroom calculation type.
*/
ACpuHeadroomCalculationType
-ACpuHeadroomParams_getCalculationType(ACpuHeadroomParams *_Nonnull params)
+ACpuHeadroomParams_getCalculationType(ACpuHeadroomParams* _Nonnull params)
__INTRODUCED_IN(36);
/**
- * Sets the headroom calculation type in AGpuHeadroomParams.
+ * Sets the GPU headroom calculation type in {@link AGpuHeadroomParams}.
*
* Available since API level 36.
*
* @param params The params to be set.
* @param calculationType The headroom calculation type.
*/
-void AGpuHeadroomParams_setCalculationType(AGpuHeadroomParams *_Nonnull params,
+void AGpuHeadroomParams_setCalculationType(AGpuHeadroomParams* _Nonnull params,
AGpuHeadroomCalculationType calculationType)
__INTRODUCED_IN(36);
/**
- * Gets the headroom calculation type in AGpuHeadroomParams.
+ * Gets the GPU headroom calculation type in {@link AGpuHeadroomParams}.
+ *
+ * This will return the default value chosen by the device if not set.
*
* Available since API level 36.
*
- * @param params The params to be set.
+ * @param params The params to read from.
* @return The headroom calculation type.
*/
AGpuHeadroomCalculationType
-AGpuHeadroomParams_getCalculationType(AGpuHeadroomParams *_Nonnull params)
+AGpuHeadroomParams_getCalculationType(AGpuHeadroomParams* _Nonnull params)
__INTRODUCED_IN(36);
/**
- * Sets the thread TIDs to track in ACpuHeadroomParams.
+ * Sets the thread TIDs to track in {@link ACpuHeadroomParams}.
+ *
+ * The TIDs should belong to the same of the process that will make the headroom call. And they
+ * should not have different core affinity.
+ *
+ * If not set or set to empty, the headroom will be based on the PID of the process making the call.
*
* Available since API level 36.
*
* @param params The params to be set.
- * @param tids Non-null array of TIDs, maximum 5.
+ * @param tids Non-null array of TIDs, where maximum size can be read from
+ * {@link ASystemHealth_getMaxCpuHeadroomTidsSize}.
* @param tidsSize The size of the tids array.
*/
-void ACpuHeadroomParams_setTids(ACpuHeadroomParams *_Nonnull params, const int *_Nonnull tids,
- int tidsSize)
+void ACpuHeadroomParams_setTids(ACpuHeadroomParams* _Nonnull params, const int* _Nonnull tids,
+ size_t tidsSize)
__INTRODUCED_IN(36);
/**
- * Creates a new instance of AGpuHeadroomParams.
+ * Creates a new instance of {@link ACpuHeadroomParams}.
+ *
+ * When the client finishes using {@link ACpuHeadroomParams},
+ * {@link ACpuHeadroomParams_destroy} must be called to destroy
+ * and free up the resources associated with {@link ACpuHeadroomParams}.
+ *
+ * Available since API level 36.
+ *
+ * @return A new instance of {@link ACpuHeadroomParams}.
+ */
+ACpuHeadroomParams* _Nonnull ACpuHeadroomParams_create(void)
+__INTRODUCED_IN(36);
+
+/**
+ * Creates a new instance of {@link AGpuHeadroomParams}.
*
* When the client finishes using {@link AGpuHeadroomParams},
- * {@link AGpuHeadroomParams_destroy()} must be called to destroy
+ * {@link AGpuHeadroomParams_destroy} must be called to destroy
* and free up the resources associated with {@link AGpuHeadroomParams}.
*
* Available since API level 36.
*
- * @return A new instance of AGpuHeadroomParams.
+ * @return A new instance of {@link AGpuHeadroomParams}.
*/
-AGpuHeadroomParams *_Nonnull AGpuHeadroomParams_create()
+AGpuHeadroomParams* _Nonnull AGpuHeadroomParams_create(void)
__INTRODUCED_IN(36);
/**
- * Deletes the ACpuHeadroomParams instance.
+ * Deletes the {@link ACpuHeadroomParams} instance.
*
* Available since API level 36.
*
* @param params The params to be deleted.
*/
-void ACpuHeadroomParams_destroy(ACpuHeadroomParams *_Nonnull params)
+void ACpuHeadroomParams_destroy(ACpuHeadroomParams* _Nullable params)
__INTRODUCED_IN(36);
/**
- * Deletes the AGpuHeadroomParams instance.
+ * Deletes the {@link AGpuHeadroomParams} instance.
*
* Available since API level 36.
*
* @param params The params to be deleted.
*/
-void AGpuHeadroomParams_destroy(AGpuHeadroomParams *_Nonnull params)
+void AGpuHeadroomParams_destroy(AGpuHeadroomParams* _Nullable params)
+__INTRODUCED_IN(36);
+
+/**
+ * Gets the maximum number of TIDs this device supports for getting CPU headroom.
+ *
+ * See {@link ACpuHeadroomParams_setTids}.
+ *
+ * Available since API level 36.
+ *
+ * @param outSize Non-null output pointer to the max size.
+ * @return 0 on success.
+ * ENOTSUP if the CPU headroom API is unsupported.
+ */
+int ASystemHealth_getMaxCpuHeadroomTidsSize(size_t* _Nonnull outSize);
+
+/**
+ * Gets the range of the calculation window size for CPU headroom.
+ *
+ * In API version 36, the range will be a superset of [50, 10000].
+ *
+ * Available since API level 36.
+ *
+ * @param outMinMillis Non-null output pointer to be set to the minimum window size in milliseconds.
+ * @param outMaxMillis Non-null output pointer to be set to the maximum window size in milliseconds.
+ * @return 0 on success.
+ * ENOTSUP if API is unsupported.
+ */
+int ASystemHealth_getCpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis,
+ int32_t* _Nonnull outMaxMillis)
+__INTRODUCED_IN(36);
+
+/**
+ * Gets the range of the calculation window size for GPU headroom.
+ *
+ * In API version 36, the range will be a superset of [50, 10000].
+ *
+ * Available since API level 36.
+ *
+ * @param outMinMillis Non-null output pointer to be set to the minimum window size in milliseconds.
+ * @param outMaxMillis Non-null output pointer to be set to the maximum window size in milliseconds.
+ * @return 0 on success.
+ * ENOTSUP if API is unsupported.
+ */
+int ASystemHealth_getGpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis,
+ int32_t* _Nonnull outMaxMillis)
__INTRODUCED_IN(36);
/**
@@ -269,21 +353,27 @@ __INTRODUCED_IN(36);
* be used with the thermal status and headroom to determine if reducing the CPU bound workload can
* help reduce the device temperature to avoid thermal throttling.
*
+ * If the params are valid, each call will perform at least one synchronous binder transaction that
+ * can take more than 1ms. So it's not recommended to call or wait for this on critical threads.
+ * Some devices may implement this as an on-demand API with lazy initialization, so the caller
+ * should expect higher latency when making the first call (especially with non-default params)
+ * since app starts or after changing params, as the device may need to change its data collection.
+ *
* Available since API level 36.
*
- * @param params The params to customize the CPU headroom calculation, or nullptr to use the default
+ * @param params The params to customize the CPU headroom calculation, or nullptr to use default.
* @param outHeadroom Non-null output pointer to a single float, which will be set to the CPU
* headroom value. The value will be a single value or `Float.NaN` if it's
- * temporarily unavailable.
+ * temporarily unavailable due to server error or not enough user CPU workload.
* Each valid value ranges from [0, 100], where 0 indicates no more cpu resources
* can be granted.
- * @return 0 on success
+ * @return 0 on success.
* EPIPE if failed to get the CPU headroom.
* EPERM if the TIDs do not belong to the same process.
* ENOTSUP if API or requested params is unsupported.
*/
-int ASystemHealth_getCpuHeadroom(const ACpuHeadroomParams *_Nullable params,
- float *_Nonnull outHeadroom)
+int ASystemHealth_getCpuHeadroom(const ACpuHeadroomParams* _Nullable params,
+ float* _Nonnull outHeadroom)
__INTRODUCED_IN(36);
/**
@@ -294,52 +384,58 @@ __INTRODUCED_IN(36);
* be used with the thermal status and headroom to determine if reducing the GPU bound workload can
* help reduce the device temperature to avoid thermal throttling.
*
+ * If the params are valid, each call will perform at least one synchronous binder transaction that
+ * can take more than 1ms. So it's not recommended to call or wait for this on critical threads.
+ * Some devices may implement this as an on-demand API with lazy initialization, so the caller
+ * should expect higher latency when making the first call (especially with non-default params)
+ * since app starts or after changing params, as the device may need to change its data collection.
+ *
* Available since API level 36
*
- * @param params The params to customize the GPU headroom calculation, or nullptr to use the default
+ * @param params The params to customize the GPU headroom calculation, or nullptr to use default
* @param outHeadroom Non-null output pointer to a single float, which will be set to the GPU
* headroom value. The value will be a single value or `Float.NaN` if it's
* temporarily unavailable.
* Each valid value ranges from [0, 100], where 0 indicates no more gpu resources
* can be granted.
- * @return 0 on success
+ * @return 0 on success.
* EPIPE if failed to get the GPU headroom.
* ENOTSUP if API or requested params is unsupported.
*/
-int ASystemHealth_getGpuHeadroom(const AGpuHeadroomParams *_Nullable params,
- float *_Nonnull outHeadroom)
+int ASystemHealth_getGpuHeadroom(const AGpuHeadroomParams* _Nullable params,
+ float* _Nonnull outHeadroom)
__INTRODUCED_IN(36);
/**
* Gets minimum polling interval for calling {@link ASystemHealth_getCpuHeadroom} in milliseconds.
*
- * The getCpuHeadroom API may return cached result if called more frequently than the interval.
+ * The {@link ASystemHealth_getCpuHeadroom} API may return cached result if called more frequently
+ * than the interval.
*
* Available since API level 36.
*
* @param outMinIntervalMillis Non-null output pointer to a int64_t, which
* will be set to the minimum polling interval in milliseconds.
- * @return 0 on success
- * EPIPE if failed to get the minimum polling interval.
+ * @return 0 on success.
* ENOTSUP if API is unsupported.
*/
-int ASystemHealth_getCpuHeadroomMinIntervalMillis(int64_t *_Nonnull outMinIntervalMillis)
+int ASystemHealth_getCpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis)
__INTRODUCED_IN(36);
/**
* Gets minimum polling interval for calling {@link ASystemHealth_getGpuHeadroom} in milliseconds.
*
- * The getGpuHeadroom API may return cached result if called more frequent than the interval.
+ * The {@link ASystemHealth_getGpuHeadroom} API may return cached result if called more frequently
+ * than the interval.
*
* Available since API level 36.
*
* @param outMinIntervalMillis Non-null output pointer to a int64_t, which
* will be set to the minimum polling interval in milliseconds.
- * @return 0 on success
- * EPIPE if failed to get the minimum polling interval.
+ * @return 0 on success.
* ENOTSUP if API is unsupported.
*/
-int ASystemHealth_getGpuHeadroomMinIntervalMillis(int64_t *_Nonnull outMinIntervalMillis)
+int ASystemHealth_getGpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis)
__INTRODUCED_IN(36);
#ifdef __cplusplus
diff --git a/include/audiomanager/IAudioManager.h b/include/audiomanager/IAudioManager.h
index a35a145084..b0641b826e 100644
--- a/include/audiomanager/IAudioManager.h
+++ b/include/audiomanager/IAudioManager.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_IAUDIOMANAGER_H
#define ANDROID_IAUDIOMANAGER_H
+#include <android/media/IAudioManagerNative.h>
#include <audiomanager/AudioManager.h>
#include <utils/Errors.h>
#include <binder/IInterface.h>
@@ -34,20 +35,23 @@ public:
// These transaction IDs must be kept in sync with the method order from
// IAudioService.aidl.
enum {
- TRACK_PLAYER = IBinder::FIRST_CALL_TRANSACTION,
- PLAYER_ATTRIBUTES = IBinder::FIRST_CALL_TRANSACTION + 1,
- PLAYER_EVENT = IBinder::FIRST_CALL_TRANSACTION + 2,
- RELEASE_PLAYER = IBinder::FIRST_CALL_TRANSACTION + 3,
- TRACK_RECORDER = IBinder::FIRST_CALL_TRANSACTION + 4,
- RECORDER_EVENT = IBinder::FIRST_CALL_TRANSACTION + 5,
- RELEASE_RECORDER = IBinder::FIRST_CALL_TRANSACTION + 6,
- PLAYER_SESSION_ID = IBinder::FIRST_CALL_TRANSACTION + 7,
- PORT_EVENT = IBinder::FIRST_CALL_TRANSACTION + 8,
- PERMISSION_UPDATE_BARRIER = IBinder::FIRST_CALL_TRANSACTION + 9,
+ GET_NATIVE_INTERFACE = IBinder::FIRST_CALL_TRANSACTION,
+ TRACK_PLAYER = IBinder::FIRST_CALL_TRANSACTION + 1,
+ PLAYER_ATTRIBUTES = IBinder::FIRST_CALL_TRANSACTION + 2,
+ PLAYER_EVENT = IBinder::FIRST_CALL_TRANSACTION + 3,
+ RELEASE_PLAYER = IBinder::FIRST_CALL_TRANSACTION + 4,
+ TRACK_RECORDER = IBinder::FIRST_CALL_TRANSACTION + 5,
+ RECORDER_EVENT = IBinder::FIRST_CALL_TRANSACTION + 6,
+ RELEASE_RECORDER = IBinder::FIRST_CALL_TRANSACTION + 7,
+ PLAYER_SESSION_ID = IBinder::FIRST_CALL_TRANSACTION + 8,
+ PORT_EVENT = IBinder::FIRST_CALL_TRANSACTION + 9,
+ PERMISSION_UPDATE_BARRIER = IBinder::FIRST_CALL_TRANSACTION + 10,
};
DECLARE_META_INTERFACE(AudioManager)
+ virtual sp<media::IAudioManagerNative> getNativeInterface() = 0;
+
// The parcels created by these methods must be kept in sync with the
// corresponding methods from IAudioService.aidl and objects it imports.
virtual audio_unique_id_t trackPlayer(player_type_t playerType, audio_usage_t usage,
diff --git a/include/ftl/finalizer.h b/include/ftl/finalizer.h
new file mode 100644
index 0000000000..0251957ad0
--- /dev/null
+++ b/include/ftl/finalizer.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2024 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.
+ */
+
+#pragma once
+
+#include <cstddef>
+
+#include <functional>
+#include <type_traits>
+#include <utility>
+
+#include <ftl/function.h>
+
+namespace android::ftl {
+
+// An RAII wrapper that invokes a function object as a finalizer when destroyed.
+//
+// The function object must take no arguments, and must return void. If the function object needs
+// any context for the call, it must store it itself, for example with a lambda capture.
+//
+// The stored function object will be called once (unless canceled via the `cancel()` member
+// function) at the first of:
+//
+// - The Finalizer instance is destroyed.
+// - `operator()` is used to invoke the contained function.
+// - The Finalizer instance is move-assigned a new value. The function being replaced will be
+// invoked, and the replacement will be stored to be called later.
+//
+// The intent with this class is to keep cleanup code next to the code that requires that
+// cleanup be performed.
+//
+// bool read_file(std::string filename) {
+// FILE* f = fopen(filename.c_str(), "rb");
+// if (f == nullptr) return false;
+// const auto cleanup = ftl::Finalizer([f]() { fclose(f); });
+// // fread(...), etc
+// return true;
+// }
+//
+// The `FinalFunction` template argument to Finalizer<FinalFunction> allows a polymorphic function
+// type for storing the finalization function, such as `std::function` or `ftl::Function`.
+//
+// For convenience, this header defines a few useful aliases for using those types.
+//
+// - `FinalizerStd`, an alias for `Finalizer<std::function<void()>>`
+// - `FinalizerFtl`, an alias for `Finalizer<ftl::Function<void()>>`
+// - `FinalizerFtl1`, an alias for `Finalizer<ftl::Function<void(), 1>>`
+// - `FinalizerFtl2`, an alias for `Finalizer<ftl::Function<void(), 2>>`
+// - `FinalizerFtl3`, an alias for `Finalizer<ftl::Function<void(), 3>>`
+//
+// Clients of this header are free to define other aliases they need.
+//
+// A Finalizer that uses a polymorphic function type can be returned from a function call and/or
+// stored as member data (to be destroyed along with the containing class).
+//
+// auto register(Observer* observer) -> ftl::FinalizerStd<void()> {
+// const auto id = observers.add(observer);
+// return ftl::Finalizer([id]() { observers.remove(id); });
+// }
+//
+// {
+// const auto _ = register(observer);
+// // do the things that required the registered observer.
+// }
+// // the observer is removed.
+//
+// Cautions:
+//
+// 1. When a Finalizer is stored as member data, you will almost certainly want that cleanup to
+// happen first, before the rest of the other member data is destroyed. For safety you should
+// assume that the finalization function will access that data directly or indirectly.
+//
+// This means that Finalizers should be defined last, after all other normal member data in a
+// class.
+//
+// class MyClass {
+// public:
+// bool initialize() {
+// ready_ = true;
+// cleanup_ = ftl::Finalizer([this]() { ready_ = false; });
+// return true;
+// }
+//
+// bool ready_ = false;
+//
+// // Finalizers should be last so other class members can be accessed before being
+// // destroyed.
+// ftl::FinalizerStd<void()> cleanup_;
+// };
+//
+// 2. Care must be taken to use `ftl::Finalizer()` when constructing locally from a lambda. If you
+// forget to do so, you are just creating a lambda that won't be automatically invoked!
+//
+// const auto bad = [&counter](){ ++counter; }; // Just a lambda instance
+// const auto good = ftl::Finalizer([&counter](){ ++counter; });
+//
+template <typename FinalFunction>
+class Finalizer final {
+ // requires(std::is_invocable_r_v<void, FinalFunction>)
+ static_assert(std::is_invocable_r_v<void, FinalFunction>);
+
+ public:
+ // A default constructed Finalizer does nothing when destroyed.
+ // requires(std::is_default_constructible_v<FinalFunction>)
+ constexpr Finalizer() = default;
+
+ // Constructs a Finalizer from a function object.
+ // requires(std::is_invocable_v<F>)
+ template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
+ [[nodiscard]] explicit constexpr Finalizer(F&& function)
+ : Finalizer(std::forward<F>(function), false) {}
+
+ constexpr ~Finalizer() { maybe_invoke(); }
+
+ // Disallow copying.
+ Finalizer(const Finalizer& that) = delete;
+ auto operator=(const Finalizer& that) = delete;
+
+ // Move construction
+ // requires(std::is_move_constructible_v<FinalFunction>)
+ [[nodiscard]] constexpr Finalizer(Finalizer&& that)
+ : Finalizer(std::move(that.function_), std::exchange(that.canceled_, true)) {}
+
+ // Implicit conversion move construction
+ // requires(!std::is_same_v<Finalizer, Finalizer<F>>)
+ template <typename F, typename = std::enable_if_t<!std::is_same_v<Finalizer, Finalizer<F>>>>
+ // NOLINTNEXTLINE(google-explicit-constructor, cppcoreguidelines-rvalue-reference-param-not-moved)
+ [[nodiscard]] constexpr Finalizer(Finalizer<F>&& that)
+ : Finalizer(std::move(that.function_), std::exchange(that.canceled_, true)) {}
+
+ // Move assignment
+ // requires(std::is_move_assignable_v<FinalFunction>)
+ constexpr auto operator=(Finalizer&& that) -> Finalizer& {
+ maybe_invoke();
+
+ function_ = std::move(that.function_);
+ canceled_ = std::exchange(that.canceled_, true);
+
+ return *this;
+ }
+
+ // Implicit conversion move assignment
+ // requires(!std::is_same_v<Finalizer, Finalizer<F>>)
+ template <typename F, typename = std::enable_if_t<!std::is_same_v<Finalizer, Finalizer<F>>>>
+ // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
+ constexpr auto operator=(Finalizer<F>&& that) -> Finalizer& {
+ *this = Finalizer(std::move(that.function_), std::exchange(that.canceled_, true));
+ return *this;
+ }
+
+ // Cancels the final function, preventing it from being invoked.
+ constexpr void cancel() {
+ canceled_ = true;
+ maybe_nullify_function();
+ }
+
+ // Invokes the final function now, if not already invoked.
+ constexpr void operator()() { maybe_invoke(); }
+
+ private:
+ template <typename>
+ friend class Finalizer;
+
+ template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
+ [[nodiscard]] explicit constexpr Finalizer(F&& function, bool canceled)
+ : function_(std::forward<F>(function)), canceled_(canceled) {}
+
+ constexpr void maybe_invoke() {
+ if (!std::exchange(canceled_, true)) {
+ std::invoke(function_);
+ maybe_nullify_function();
+ }
+ }
+
+ constexpr void maybe_nullify_function() {
+ // Sets function_ to nullptr if that is supported for the backing type.
+ if constexpr (std::is_assignable_v<FinalFunction, nullptr_t>) {
+ function_ = nullptr;
+ }
+ }
+
+ FinalFunction function_;
+ bool canceled_ = true;
+};
+
+template <typename F>
+Finalizer(F&&) -> Finalizer<std::decay_t<F>>;
+
+// A standard alias for using `std::function` as the polymorphic function type.
+using FinalizerStd = Finalizer<std::function<void()>>;
+
+// Helpful aliases for using `ftl::Function` as the polymorphic function type.
+using FinalizerFtl = Finalizer<Function<void()>>;
+using FinalizerFtl1 = Finalizer<Function<void(), 1>>;
+using FinalizerFtl2 = Finalizer<Function<void(), 2>>;
+using FinalizerFtl3 = Finalizer<Function<void(), 3>>;
+
+} // namespace android::ftl \ No newline at end of file
diff --git a/include/ftl/ignore.h b/include/ftl/ignore.h
new file mode 100644
index 0000000000..1468fa2498
--- /dev/null
+++ b/include/ftl/ignore.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2025 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.
+ */
+
+#pragma once
+
+namespace android::ftl {
+
+// An alternative to `std::ignore` that makes it easy to ignore multiple values.
+//
+// Examples:
+//
+// void ftl_ignore_multiple(int arg1, const char* arg2, std::string arg3) {
+// // When invoked, all the arguments are ignored.
+// ftl::ignore(arg1, arg2, arg3);
+// }
+//
+// void ftl_ignore_single(int arg) {
+// // It can be used like std::ignore to ignore a single value
+// ftl::ignore = arg;
+// }
+//
+inline constexpr struct {
+ // NOLINTNEXTLINE(misc-unconventional-assign-operator, readability-named-parameter)
+ constexpr auto operator=(auto&&) const -> decltype(*this) { return *this; }
+ // NOLINTNEXTLINE(readability-named-parameter)
+ constexpr void operator()(auto&&...) const {}
+} ignore;
+
+} // namespace android::ftl \ No newline at end of file
diff --git a/include/ftl/small_map.h b/include/ftl/small_map.h
index 83d5967464..96d35cd21e 100644
--- a/include/ftl/small_map.h
+++ b/include/ftl/small_map.h
@@ -234,6 +234,12 @@ class SmallMap final {
//
bool erase(const key_type& key) { return erase(key, begin()); }
+ // Removes a mapping.
+ //
+ // The last() and end() iterators, as well as those to the erased mapping, are invalidated.
+ //
+ void erase(iterator it) { map_.unstable_erase(it); }
+
// Removes all mappings.
//
// All iterators are invalidated.
diff --git a/include/input/AccelerationCurve.h b/include/input/AccelerationCurve.h
index 0cf648a2f7..8a4a5d429b 100644
--- a/include/input/AccelerationCurve.h
+++ b/include/input/AccelerationCurve.h
@@ -46,4 +46,15 @@ struct AccelerationCurveSegment {
std::vector<AccelerationCurveSegment> createAccelerationCurveForPointerSensitivity(
int32_t sensitivity);
+/*
+ * Creates a flat acceleration curve for disabling pointer acceleration.
+ *
+ * This method generates a single AccelerationCurveSegment with specific values
+ * to effectively disable acceleration for both mice and touchpads.
+ * A flat acceleration curve ensures a constant gain, meaning that the output
+ * velocity is directly proportional to the input velocity, resulting in
+ * a 1:1 movement ratio between the input device and the on-screen pointer.
+ */
+std::vector<AccelerationCurveSegment> createFlatAccelerationCurve(int32_t sensitivity);
+
} // namespace android
diff --git a/include/input/BlockingQueue.h b/include/input/BlockingQueue.h
index f848c82c42..6e32de6d86 100644
--- a/include/input/BlockingQueue.h
+++ b/include/input/BlockingQueue.h
@@ -16,6 +16,7 @@
#pragma once
+#include <input/PrintTools.h>
#include <condition_variable>
#include <functional>
#include <list>
@@ -126,11 +127,21 @@ public:
* Primary used for debugging.
* Does not block.
*/
- size_t size() {
+ size_t size() const {
std::scoped_lock lock(mLock);
return mQueue.size();
}
+ bool empty() const {
+ std::scoped_lock lock(mLock);
+ return mQueue.empty();
+ }
+
+ std::string dump(std::string (*toString)(const T&) = constToString) const {
+ std::scoped_lock lock(mLock);
+ return dumpContainer(mQueue, toString);
+ }
+
private:
const std::optional<size_t> mCapacity;
/**
@@ -140,7 +151,7 @@ private:
/**
* Lock for accessing and waiting on elements.
*/
- std::mutex mLock;
+ mutable std::mutex mLock;
std::list<T> mQueue GUARDED_BY(mLock);
};
diff --git a/include/input/DisplayTopologyGraph.h b/include/input/DisplayTopologyGraph.h
index 90427bd76d..3ae865a33a 100644
--- a/include/input/DisplayTopologyGraph.h
+++ b/include/input/DisplayTopologyGraph.h
@@ -42,8 +42,10 @@ enum class DisplayTopologyPosition : int32_t {
*/
struct DisplayTopologyAdjacentDisplay {
ui::LogicalDisplayId displayId = ui::LogicalDisplayId::INVALID;
+ // Position of the adjacent display, relative to the source display.
DisplayTopologyPosition position;
- float offsetPx;
+ // The offset in DP of the adjacent display, relative to the source display.
+ float offsetDp;
};
/**
@@ -52,6 +54,7 @@ struct DisplayTopologyAdjacentDisplay {
struct DisplayTopologyGraph {
ui::LogicalDisplayId primaryDisplayId = ui::LogicalDisplayId::INVALID;
std::unordered_map<ui::LogicalDisplayId, std::vector<DisplayTopologyAdjacentDisplay>> graph;
+ std::unordered_map<ui::LogicalDisplayId, int> displaysDensity;
};
} // namespace android
diff --git a/include/input/Input.h b/include/input/Input.h
index 2cabd56204..002b3a7d15 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -92,11 +92,23 @@ enum {
static_cast<int32_t>(android::os::MotionEventFlag::NO_FOCUS_CHANGE),
/**
- * This event was generated or modified by accessibility service.
+ * This event was injected from some AccessibilityService, which may be either an
+ * Accessibility Tool OR a service using that API for purposes other than assisting users
+ * with disabilities.
*/
AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT =
static_cast<int32_t>(android::os::MotionEventFlag::IS_ACCESSIBILITY_EVENT),
+ /**
+ * This event was injected from an AccessibilityService with the
+ * AccessibilityServiceInfo#isAccessibilityTool property set to true. These services (known as
+ * "Accessibility Tools") are used to assist users with disabilities, so events from these
+ * services should be able to reach all Views including Views which set
+ * View#isAccessibilityDataSensitive to true.
+ */
+ AMOTION_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL =
+ static_cast<int32_t>(android::os::MotionEventFlag::INJECTED_FROM_ACCESSIBILITY_TOOL),
+
AMOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS =
static_cast<int32_t>(android::os::MotionEventFlag::TARGET_ACCESSIBILITY_FOCUS),
@@ -304,6 +316,19 @@ struct PointerProperties;
bool isStylusEvent(uint32_t source, const std::vector<PointerProperties>& properties);
+bool isStylusHoverEvent(uint32_t source, const std::vector<PointerProperties>& properties,
+ int32_t action);
+
+bool isFromMouse(uint32_t source, ToolType tooltype);
+
+bool isFromTouchpad(uint32_t source, ToolType tooltype);
+
+bool isFromDrawingTablet(uint32_t source, ToolType tooltype);
+
+bool isHoverAction(int32_t action);
+
+bool isMouseOrTouchpad(uint32_t sources);
+
/*
* Flags that flow alongside events in the input dispatch system to help with certain
* policy decisions such as waking from device sleep.
@@ -347,6 +372,9 @@ enum {
POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY =
android::os::IInputConstants::POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY,
+ POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL =
+ android::os::IInputConstants::POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL,
+
/* These flags are set by the input dispatcher. */
// Indicates that the input event was injected.
diff --git a/include/input/InputFlags.h b/include/input/InputFlags.h
new file mode 100644
index 0000000000..4b42f775dd
--- /dev/null
+++ b/include/input/InputFlags.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2025 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.
+ */
+
+#pragma once
+
+namespace android {
+
+class InputFlags {
+public:
+ /**
+ * Check if connected displays feature is enabled, either via the feature flag or settings
+ * override.
+ */
+ static bool connectedDisplaysCursorEnabled();
+
+ /**
+ * Check if both connectedDisplaysCursor and associatedDisplayCursorBugfix is enabled.
+ */
+ static bool connectedDisplaysCursorAndAssociatedDisplayCursorBugfixEnabled();
+};
+
+} // namespace android
diff --git a/include/input/InputVerifier.h b/include/input/InputVerifier.h
index 14dd463425..7d3fb469c6 100644
--- a/include/input/InputVerifier.h
+++ b/include/input/InputVerifier.h
@@ -47,9 +47,10 @@ public:
InputVerifier(const std::string& name);
android::base::Result<void> processMovement(int32_t deviceId, int32_t source, int32_t action,
- uint32_t pointerCount,
+ int32_t actionButton, uint32_t pointerCount,
const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords, int32_t flags);
+ const PointerCoords* pointerCoords, int32_t flags,
+ int32_t buttonState);
void resetDevice(int32_t deviceId);
diff --git a/include/input/PrintTools.h b/include/input/PrintTools.h
index 3470be4dce..71c215f723 100644
--- a/include/input/PrintTools.h
+++ b/include/input/PrintTools.h
@@ -19,13 +19,18 @@
#include <bitset>
#include <map>
#include <optional>
-#include <set>
+#include <ranges>
#include <sstream>
#include <string>
#include <vector>
namespace android {
+namespace internal {
+template <typename T>
+concept Container = std::ranges::range<T>;
+}
+
template <size_t N>
std::string bitsetToString(const std::bitset<N>& bitset) {
if (bitset.none()) {
@@ -72,10 +77,12 @@ inline std::string toString(const std::optional<T>& optional,
/**
* Convert a set of integral types to string.
*/
-template <typename T>
-std::string dumpSet(const std::set<T>& v, std::string (*toString)(const T&) = constToString) {
+template <internal::Container T>
+std::string dumpContainer(
+ const T& container,
+ std::string (*toString)(const std::ranges::range_value_t<T>&) = constToString) {
std::string out;
- for (const T& entry : v) {
+ for (const auto& entry : container) {
out += out.empty() ? "{" : ", ";
out += toString(entry);
}
diff --git a/include/private/performance_hint_private.h b/include/private/performance_hint_private.h
index e3f98badbe..a468313341 100644
--- a/include/private/performance_hint_private.h
+++ b/include/private/performance_hint_private.h
@@ -125,8 +125,10 @@ APerformanceHintSession* APerformanceHint_createSessionInternal(APerformanceHint
/**
* Creates a session using ASessionCreationConfig
*/
-APerformanceHintSession* APerformanceHint_createSessionUsingConfigInternal(
- APerformanceHintManager* manager, ASessionCreationConfig* sessionCreationConfig,
+int APerformanceHint_createSessionUsingConfigInternal(
+ APerformanceHintManager* manager,
+ ASessionCreationConfig* config,
+ APerformanceHintSession** sessionOut,
SessionTag tag);
/**
diff --git a/include/private/system_health_private.h b/include/private/system_health_private.h
new file mode 100644
index 0000000000..05a5a06c9c
--- /dev/null
+++ b/include/private/system_health_private.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#ifndef ANDROID_PRIVATE_NATIVE_SYSTEM_HEALTH_H
+#define ANDROID_PRIVATE_NATIVE_SYSTEM_HEALTH_H
+
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+/**
+ * For testing only.
+ */
+void ASystemHealth_setIHintManagerForTesting(void* iManager);
+
+__END_DECLS
+
+#endif // ANDROID_PRIVATE_NATIVE_SYSTEM_HEALTH_H
+