AppFunctionAccessLevel


@ExperimentalAppFunctionsApi
@Target(allowedTargets = [AnnotationTarget.FUNCTION, AnnotationTarget.CLASS])
@Retention(value = AnnotationRetention.BINARY)
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(level: Int, isCompatEnforcementEnabled: Boolean)

Public properties

Boolean

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

Int

minimum access level required to invoke the function.

Public constructors

AppFunctionAccessLevel

Added in 1.0.0-alpha13
AppFunctionAccessLevel(level: Int, isCompatEnforcementEnabled: Boolean)
Parameters
level: Int

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: Boolean

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

Public properties

isCompatEnforcementEnabled

Added in 1.0.0-alpha13
val isCompatEnforcementEnabled: Boolean

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

level

val level: Int

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.