AppFunctionAccessLevel


@ExperimentalAppFunctionsApi
@Target(allowedTargets = [AnnotationTarget.FUNCTION, AnnotationTarget.CLASS])
@Retention(value = AnnotationRetention.BINARY)
public annotation AppFunctionAccessLevel


Defines the caller access level of an app function.

If an app function is not annotated with AppFunctionAccessLevel, it defaults to AppFunctionMetadata.ACCESS_LEVEL_ANDROID_TRUSTED, meaning it is accessible to any caller holding the android.permission.EXECUTE_APP_FUNCTIONS permission.

The Android framework natively enforces access restrictions starting in Android 17.2 (android.os.Build.SdkVersionFull.CINNAMON_BUN_2). On earlier platform versions, setting isCompatEnforcementEnabled to true enables Jetpack to enforce access restrictions instead of the platform.

Backwards compatibility enforcement on platform versions prior to Android 17.2 is a best-effort verification mechanism using caller tokens and incurs an IPC verification overhead for foreign callers. Additionally, access-level-based state filtering on pre-17.2 platforms is only applied when callers query via Jetpack's AppFunctionManager.getAppFunctionStates; direct queries using platform framework APIs on pre-17.2 platforms will see all indexed functions when the caller has the android.permission.EXECUTE_APP_FUNCTIONS permission.

When isCompatEnforcementEnabled is set to false, access level checks are skipped on pre-17.2 platforms, allowing any caller certified for AppFunctions to execute the function, while devices running Android 17.2+ continue to enforce the declared level. To prevent a function from being exposed or executable on platforms prior to Android 17.2 when backwards compatibility enforcement is disabled, the function should only be enabled or registered at runtime on devices running Android 17.2+ (e.g., using androidx.appfunctions.AppFunctionManager.setAppFunctionEnabled or androidx.appfunctions.AppFunctionManager.registerAppFunction).

Example usage for service-based functions:

@AppFunctionDeclaration
@AppFunctionAccessLevel
(
level = AppFunctionMetadata.ACCESS_LEVEL_SELF,
isCompatEnforcementEnabled = true,
)

fun executeTask(params: TaskParams): TaskResult { ... }

Example usage for dynamically registered functions:

@AppFunctionSignature(
scope = AppFunctionMetadata.SCOPE_GLOBAL,
appFunctionXmlFileName = "dynamic_signature_definitions",
)

@AppFunctionAccessLevel(
level = AppFunctionMetadata.ACCESS_LEVEL_SELF,
isCompatEnforcementEnabled = true,
)

fun interface DynamicTaskSignature {
suspend fun executeTask(params: TaskParams): TaskResult
}

Summary

Public constructors

AppFunctionAccessLevel(int level, boolean isCompatEnforcementEnabled)

Public methods

final int

minimum access level required to invoke the function.

final boolean

whether Jetpack should enforce access restrictions on platform versions prior to Android 17.2.

Public constructors

AppFunctionAccessLevel

Added in 1.0.0-alpha13
public AppFunctionAccessLevel(int level, boolean isCompatEnforcementEnabled)
Parameters
int level

minimum access level required to invoke the function. Possible values are AppFunctionMetadata.ACCESS_LEVEL_SELF (strictly restricted to callers with the same UID as the hosting application), AppFunctionMetadata.ACCESS_LEVEL_SYSTEM, and AppFunctionMetadata.ACCESS_LEVEL_ANDROID_TRUSTED.

boolean isCompatEnforcementEnabled

whether Jetpack should enforce access restrictions on platform versions prior to Android 17.2.

Public methods

getLevel

public final int getLevel()

minimum access level required to invoke the function. Possible values are AppFunctionMetadata.ACCESS_LEVEL_SELF (strictly restricted to callers with the same UID as the hosting application), AppFunctionMetadata.ACCESS_LEVEL_SYSTEM, and AppFunctionMetadata.ACCESS_LEVEL_ANDROID_TRUSTED.

isCompatEnforcementEnabled

Added in 1.0.0-alpha13
public final boolean isCompatEnforcementEnabled()

whether Jetpack should enforce access restrictions on platform versions prior to Android 17.2.