Loading core/api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -772,6 +772,7 @@ package android.app.admin { package android.app.appfunctions { @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public final class AppFunctionManager { method @FlaggedApi("android.permission.flags.app_function_access_api_enabled") @NonNull public java.util.Set<java.lang.String> getDeviceSettingPackages(); field public static final int ACCESS_FLAG_MASK_ALL = 31; // 0x1f field public static final int ACCESS_FLAG_MASK_OTHER = 6; // 0x6 field public static final int ACCESS_FLAG_MASK_USER = 24; // 0x18 Loading core/java/android/app/appfunctions/AppFunctionManager.java +151 −109 Original line number Diff line number Diff line Loading @@ -42,16 +42,19 @@ import android.os.ParcelableException; import android.os.RemoteException; import android.os.SystemClock; import android.permission.flags.Flags; import android.util.ArraySet; import com.android.internal.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; /** * Provides access to App Functions. App Functions is currently a * beta/experimental preview feature. * Provides access to App Functions. App Functions is currently a beta/experimental preview feature. * * <p>An app function is a piece of functionality that apps expose to the system for cross-app * orchestration. Loading Loading @@ -82,8 +85,8 @@ import java.util.concurrent.Executor; * ExecuteAppFunctionRequest}. Then, invoke {@link #executeAppFunction} with the request to execute * the app function. Callers need the {@code android.permission.EXECUTE_APP_FUNCTIONS} permission to * execute app functions from other apps. An app can always execute its own app functions and * doesn't need these permissions. AppFunction SDK provides a convenient way to achieve this and * is the preferred method. * doesn't need these permissions. AppFunction SDK provides a convenient way to achieve this and is * the preferred method. * * <h3>Example</h3> * Loading @@ -100,12 +103,10 @@ public final class AppFunctionManager { /** * Activity action: Launch UI that shows list of all agents and provides management of App * Function access of those agents. * <p> * Input: Nothing. * </p> * <p> * Output: Nothing. * </p> * * <p>Input: Nothing. * * <p>Output: Nothing. */ @FlaggedApi(FLAG_APP_FUNCTION_ACCESS_UI_ENABLED) @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) Loading @@ -115,13 +116,11 @@ public final class AppFunctionManager { /** * Activity action: Launch UI that shows a list of all targets that the specified agent package * can access, and provides management of App Function access of those targets. * <p> * Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package whose access * will be managed by the launched UI. * </p> * <p> * Output: Nothing. * </p> * * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package whose * access will be managed by the launched UI. * * <p>Output: Nothing. * * @see android.content.Intent#EXTRA_PACKAGE_NAME */ Loading @@ -131,15 +130,13 @@ public final class AppFunctionManager { "android.app.appfunctions.action.MANAGE_AGENT_APP_FUNCTION_ACCESS"; /** * Activity action: Launch UI that shows list of all agents for a specific target and * provides management of App Function access by those agents. * <p> * Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package whose access * will be managed by the launched UI. * </p> * <p> * Output: Nothing. * </p> * Activity action: Launch UI that shows list of all agents for a specific target and provides * management of App Function access by those agents. * * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package whose * access will be managed by the launched UI. * * <p>Output: Nothing. * * @see android.content.Intent#EXTRA_PACKAGE_NAME */ Loading @@ -150,16 +147,13 @@ public final class AppFunctionManager { /** * Activity action: Launch UI to for an agent to request App Function access of a target. * <p> * Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package for which the * calling agent is requesting access of. * </p> * <p> * Output: Nothing. * </p> * * @see android.content.Intent#EXTRA_PACKAGE_NAME * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package for which * the calling agent is requesting access of. * * <p>Output: Nothing. * * @see android.content.Intent#EXTRA_PACKAGE_NAME * @hide */ @FlaggedApi(FLAG_APP_FUNCTION_ACCESS_UI_ENABLED) Loading Loading @@ -194,15 +188,15 @@ public final class AppFunctionManager { public static final int ACCESS_REQUEST_STATE_GRANTED = 0; /** * App Function access request state indicating that the access has been denied for a * particular agent and target * App Function access request state indicating that the access has been denied for a particular * agent and target */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) public static final int ACCESS_REQUEST_STATE_DENIED = 1; /** * App Function access request state indicating that the access is not able to be granted for * a particular agent and target, due to the agent not being granted the EXECUTE_APP_FUNCTIONS * App Function access request state indicating that the access is not able to be granted for a * particular agent and target, due to the agent not being granted the EXECUTE_APP_FUNCTIONS * permission, or the target not having an App Function Service, or the agent not being in the * device allowlist, or one or both apps not being installed. */ Loading @@ -210,7 +204,9 @@ public final class AppFunctionManager { public static final int ACCESS_REQUEST_STATE_UNREQUESTABLE = 2; /** @hide */ @IntDef(prefix = { "ACCESS_REQUEST_STATE_" }, value = { @IntDef( prefix = {"ACCESS_REQUEST_STATE_"}, value = { ACCESS_REQUEST_STATE_DENIED, ACCESS_REQUEST_STATE_GRANTED, ACCESS_REQUEST_STATE_UNREQUESTABLE Loading @@ -220,6 +216,7 @@ public final class AppFunctionManager { /** * A flag indicating the app function access state has been pregranted by the system * * @hide */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) Loading @@ -229,6 +226,7 @@ public final class AppFunctionManager { /** * A flag indicating the app function access is granted through a mechanism not tied to any * other flag (e.g. ADB) * * @hide */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) Loading @@ -238,6 +236,7 @@ public final class AppFunctionManager { /** * A flag indicating the app function access state has been denied by some other mechanism not * covered by another flag (e.g. ADB, self revoke) * * @hide */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) Loading @@ -246,6 +245,7 @@ public final class AppFunctionManager { /** * A flag indicating the user granted the app function access state through UI * * @hide */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) Loading @@ -254,6 +254,7 @@ public final class AppFunctionManager { /** * A flag indicating the app function access state has been denied by the user * * @hide */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) Loading @@ -262,13 +263,16 @@ public final class AppFunctionManager { /** * All USER flags * * @hide */ @TestApi public static final int ACCESS_FLAG_MASK_USER = ACCESS_FLAG_USER_GRANTED | ACCESS_FLAG_USER_DENIED; /** * All OTHER flags * * @hide */ @TestApi Loading @@ -277,15 +281,21 @@ public final class AppFunctionManager { /** * All access flags * * @hide */ @TestApi public static final int ACCESS_FLAG_MASK_ALL = ACCESS_FLAG_PREGRANTED | ACCESS_FLAG_OTHER_GRANTED | ACCESS_FLAG_OTHER_DENIED | ACCESS_FLAG_USER_GRANTED | ACCESS_FLAG_USER_DENIED; public static final int ACCESS_FLAG_MASK_ALL = ACCESS_FLAG_PREGRANTED | ACCESS_FLAG_OTHER_GRANTED | ACCESS_FLAG_OTHER_DENIED | ACCESS_FLAG_USER_GRANTED | ACCESS_FLAG_USER_DENIED; @IntDef(prefix = { "ACCESS_FLAG_" }, flag = true, value = { @IntDef( prefix = {"ACCESS_FLAG_"}, flag = true, value = { ACCESS_FLAG_PREGRANTED, ACCESS_FLAG_OTHER_GRANTED, ACCESS_FLAG_OTHER_DENIED, Loading Loading @@ -329,8 +339,8 @@ public final class AppFunctionManager { * Executes the app function. * * <p>Note: Applications can execute functions they define. To execute functions defined in * another component, apps would need to have the permission * {@code android.permission.EXECUTE_APP_FUNCTIONS}. * another component, apps would need to have the permission {@code * android.permission.EXECUTE_APP_FUNCTIONS}. * * @param request the request to execute the app function * @param executor the executor to run the callback Loading @@ -352,16 +362,16 @@ public final class AppFunctionManager { @NonNull ExecuteAppFunctionRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull CancellationSignal cancellationSignal, @NonNull OutcomeReceiver<ExecuteAppFunctionResponse, AppFunctionException> callback) { @NonNull OutcomeReceiver<ExecuteAppFunctionResponse, AppFunctionException> callback) { Objects.requireNonNull(request); Objects.requireNonNull(executor); Objects.requireNonNull(callback); ExecuteAppFunctionAidlRequest aidlRequest = new ExecuteAppFunctionAidlRequest( request, mContext.getUser(), mContext.getPackageName(), request, mContext.getUser(), mContext.getPackageName(), /* requestTime= */ SystemClock.elapsedRealtime()); try { Loading Loading @@ -402,8 +412,8 @@ public final class AppFunctionManager { * Returns a boolean through a callback, indicating whether the app function is enabled. * * <p>This method can only check app functions owned by the caller, or those where the caller * has visibility to the owner package and holds the * {@link Manifest.permission#EXECUTE_APP_FUNCTIONS} permission. * has visibility to the owner package and holds the {@link * Manifest.permission#EXECUTE_APP_FUNCTIONS} permission. * * <p>If the operation fails, the callback's {@link OutcomeReceiver#onError} is called with * errors: Loading Loading @@ -532,49 +542,53 @@ public final class AppFunctionManager { }; AppFunctionManagerHelper.isAppFunctionEnabled( functionIdentifier, targetPackage, appSearchManager, executor, functionIdentifier, targetPackage, appSearchManager, executor, callbackWithExceptionInterceptor); } /** * Checks whether the given agent has access to app functions of the given target app, or if * the access is not {@link #getAccessRequestState(String) valid}. Requires the * {@link Manifest.permission.MANAGE_APP_FUNCTION_ACCESS} permission if the * {@param agentPackageName} is not the calling app. * Checks whether the given agent has access to app functions of the given target app, or if the * access is not {@link #getAccessRequestState(String) valid}. Requires the {@link * Manifest.permission.MANAGE_APP_FUNCTION_ACCESS} permission if the {@param agentPackageName} * is not the calling app. * * @param agentPackageName The package name of the agent * @param targetPackageName The package name of the target * @return The state of the access, one of {@link #ACCESS_REQUEST_STATE_GRANTED}, * {@link #ACCESS_REQUEST_STATE_DENIED}, or {@link #ACCESS_REQUEST_STATE_UNREQUESTABLE} * @return The state of the access, one of {@link #ACCESS_REQUEST_STATE_GRANTED}, {@link * #ACCESS_REQUEST_STATE_DENIED}, or {@link #ACCESS_REQUEST_STATE_UNREQUESTABLE} * @hide */ @SystemApi @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) @RequiresPermission(value = MANAGE_APP_FUNCTION_ACCESS, conditional = true) @AppFunctionAccessState public int getAccessRequestState(@NonNull String agentPackageName, @NonNull String targetPackageName) { public int getAccessRequestState( @NonNull String agentPackageName, @NonNull String targetPackageName) { try { return mService.getAccessRequestState(agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId()); return mService.getAccessRequestState( agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Checks whether the calling app has access to app functions of the given target app, * for the given users, or if the access is invalid (not able to be requested). An access is * valid if: * Checks whether the calling app has access to app functions of the given target app, for the * given users, or if the access is invalid (not able to be requested). An access is valid if: * 1. The agent (calling app) and target apps are both installed, and the agent has visibility * of the target. * 2. The agent has the {@link Manifest.permission.EXECUTE_APP_FUNCTIONS} permission granted. * 3. The agent is allowlisted by the system. * 4. The target has an AppFunctionService. * of the target. 2. The agent has the {@link Manifest.permission.EXECUTE_APP_FUNCTIONS} * permission granted. 3. The agent is allowlisted by the system. 4. The target has an * AppFunctionService. * * @param targetPackageName The package name of the target * @return The state of the access, one of {@link #ACCESS_REQUEST_STATE_GRANTED}, * {@link #ACCESS_REQUEST_STATE_DENIED}, or {@link #ACCESS_REQUEST_STATE_UNREQUESTABLE} * @return The state of the access, one of {@link #ACCESS_REQUEST_STATE_GRANTED}, {@link * #ACCESS_REQUEST_STATE_DENIED}, or {@link #ACCESS_REQUEST_STATE_UNREQUESTABLE} */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) @AppFunctionAccessState Loading @@ -584,8 +598,8 @@ public final class AppFunctionManager { /** * Get the access flags for a given agent and target. These flags include extra information * about the access state (whether it is pregranted, if the user has set state, etc.). Returns * 0 if the access is not {@link #getAccessRequestState(String) valid}. * about the access state (whether it is pregranted, if the user has set state, etc.). Returns 0 * if the access is not {@link #getAccessRequestState(String) valid}. * * @param agentPackageName The package name of the agent * @param targetPackageName The package name of the target Loading @@ -596,40 +610,48 @@ public final class AppFunctionManager { @RequiresPermission(MANAGE_APP_FUNCTION_ACCESS) @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) @AppFunctionAccessFlags public int getAccessFlags(@NonNull String agentPackageName, @NonNull String targetPackageName) { public int getAccessFlags(@NonNull String agentPackageName, @NonNull String targetPackageName) { try { return mService.getAccessFlags(agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId()); return mService.getAccessFlags( agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Updates the access flags for the given agent and target. If the access is not * {@link #getAccessRequestState(String) valid}, this method is a no-op. * Updates the access flags for the given agent and target. If the access is not {@link * #getAccessRequestState(String) valid}, this method is a no-op. * * @param agentPackageName The package name of the agent * @param targetPackageName The package name of the target * @param flagMask The mask determining which flag values will be changed * @param flags The flag values to be changed * @throws IllegalArgumentException if an invalid flag is specified, opposing flags (e.g. * USER_GRANTED and USER_DENIED) are set together, or a flag with an opposite is set, without * its opposite being explicitly cleared (via being included in the flag mask, but not the flag * set). * USER_GRANTED and USER_DENIED) are set together, or a flag with an opposite is set, * without its opposite being explicitly cleared (via being included in the flag mask, but * not the flag set). * @hide */ @SystemApi @RequiresPermission(MANAGE_APP_FUNCTION_ACCESS) @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) public void updateAccessFlags(@NonNull String agentPackageName, @NonNull String targetPackageName, @AppFunctionAccessFlags int flagMask, public void updateAccessFlags( @NonNull String agentPackageName, @NonNull String targetPackageName, @AppFunctionAccessFlags int flagMask, @AppFunctionAccessFlags int flags) { try { mService.updateAccessFlags(agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId(), flagMask, flags); mService.updateAccessFlags( agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId(), flagMask, flags); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading @@ -637,6 +659,7 @@ public final class AppFunctionManager { /** * Revoke the App Function access for the calling app and the given target * * @param targetPackageName The app whose AppFunctionService the calling app should lose access * to. */ Loading @@ -649,9 +672,9 @@ public final class AppFunctionManager { } } /** * Gets all {@link #getAccessRequestState(String) valid} agents. * * @return A list of all valid agent package names * @hide */ Loading @@ -668,8 +691,9 @@ public final class AppFunctionManager { /** * Gets all {@link #getAccessRequestState(String) valid} target apps. * @return A list of all target app package names in the current user that the agent can * request access for * * @return A list of all target app package names in the current user that the agent can request * access for * @hide */ @SystemApi Loading @@ -683,6 +707,24 @@ public final class AppFunctionManager { } } /** * Gets the configured list of package names that should be grouped as Device Settings. * * <p>The list here is a configuration, the returned packages are not necessarily installed. The * package names here must refer to system apps. * * @hide */ @TestApi @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) @NonNull public Set<String> getDeviceSettingPackages() { final String[] deviceSettingPackages = mContext.getResources() .getStringArray(R.array.config_appFunctionDeviceSettingsPackages); return new ArraySet<>(deviceSettingPackages); } private static class CallbackWrapper extends IAppFunctionEnabledCallback.Stub { private final OutcomeReceiver<Void, Exception> mCallback; Loading core/res/res/values/config.xml +2 −2 Original line number Diff line number Diff line Loading @@ -7625,10 +7625,10 @@ <!-- Maximum number of devices that allows for audio sharing. --> <integer name="config_audio_sharing_maximum_sinks">2</integer> <!--For App Functions, this configuration lists package names grouped as "Device Settings". <!--For App Function, this configuration lists package names grouped as "Device Settings". Packages in this list share the same App Function access settings. In the UI, they are presented as a single "Device Settings" item rather than individually. --> <string-array name="config_appFunctionsDeviceSettingsPackages" translatable="false"> <string-array name="config_appFunctionDeviceSettingsPackages" translatable="false"> </string-array> <!-- Package name for developer verification service provider app [DO NOT TRANSLATE] --> Loading core/res/res/values/symbols.xml +3 −0 Original line number Diff line number Diff line Loading @@ -6267,4 +6267,7 @@ <!-- Package and class info to bind to ProximityProviderService --> <java-symbol type="string" name="proximity_provider_service_package_name" /> <java-symbol type="string" name="proximity_provider_service_class_name" /> <!-- For App Functions --> <java-symbol type="array" name="config_appFunctionDeviceSettingsPackages" /> </resources> Loading
core/api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -772,6 +772,7 @@ package android.app.admin { package android.app.appfunctions { @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public final class AppFunctionManager { method @FlaggedApi("android.permission.flags.app_function_access_api_enabled") @NonNull public java.util.Set<java.lang.String> getDeviceSettingPackages(); field public static final int ACCESS_FLAG_MASK_ALL = 31; // 0x1f field public static final int ACCESS_FLAG_MASK_OTHER = 6; // 0x6 field public static final int ACCESS_FLAG_MASK_USER = 24; // 0x18 Loading
core/java/android/app/appfunctions/AppFunctionManager.java +151 −109 Original line number Diff line number Diff line Loading @@ -42,16 +42,19 @@ import android.os.ParcelableException; import android.os.RemoteException; import android.os.SystemClock; import android.permission.flags.Flags; import android.util.ArraySet; import com.android.internal.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; /** * Provides access to App Functions. App Functions is currently a * beta/experimental preview feature. * Provides access to App Functions. App Functions is currently a beta/experimental preview feature. * * <p>An app function is a piece of functionality that apps expose to the system for cross-app * orchestration. Loading Loading @@ -82,8 +85,8 @@ import java.util.concurrent.Executor; * ExecuteAppFunctionRequest}. Then, invoke {@link #executeAppFunction} with the request to execute * the app function. Callers need the {@code android.permission.EXECUTE_APP_FUNCTIONS} permission to * execute app functions from other apps. An app can always execute its own app functions and * doesn't need these permissions. AppFunction SDK provides a convenient way to achieve this and * is the preferred method. * doesn't need these permissions. AppFunction SDK provides a convenient way to achieve this and is * the preferred method. * * <h3>Example</h3> * Loading @@ -100,12 +103,10 @@ public final class AppFunctionManager { /** * Activity action: Launch UI that shows list of all agents and provides management of App * Function access of those agents. * <p> * Input: Nothing. * </p> * <p> * Output: Nothing. * </p> * * <p>Input: Nothing. * * <p>Output: Nothing. */ @FlaggedApi(FLAG_APP_FUNCTION_ACCESS_UI_ENABLED) @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) Loading @@ -115,13 +116,11 @@ public final class AppFunctionManager { /** * Activity action: Launch UI that shows a list of all targets that the specified agent package * can access, and provides management of App Function access of those targets. * <p> * Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package whose access * will be managed by the launched UI. * </p> * <p> * Output: Nothing. * </p> * * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package whose * access will be managed by the launched UI. * * <p>Output: Nothing. * * @see android.content.Intent#EXTRA_PACKAGE_NAME */ Loading @@ -131,15 +130,13 @@ public final class AppFunctionManager { "android.app.appfunctions.action.MANAGE_AGENT_APP_FUNCTION_ACCESS"; /** * Activity action: Launch UI that shows list of all agents for a specific target and * provides management of App Function access by those agents. * <p> * Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package whose access * will be managed by the launched UI. * </p> * <p> * Output: Nothing. * </p> * Activity action: Launch UI that shows list of all agents for a specific target and provides * management of App Function access by those agents. * * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package whose * access will be managed by the launched UI. * * <p>Output: Nothing. * * @see android.content.Intent#EXTRA_PACKAGE_NAME */ Loading @@ -150,16 +147,13 @@ public final class AppFunctionManager { /** * Activity action: Launch UI to for an agent to request App Function access of a target. * <p> * Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package for which the * calling agent is requesting access of. * </p> * <p> * Output: Nothing. * </p> * * @see android.content.Intent#EXTRA_PACKAGE_NAME * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} specifies the package for which * the calling agent is requesting access of. * * <p>Output: Nothing. * * @see android.content.Intent#EXTRA_PACKAGE_NAME * @hide */ @FlaggedApi(FLAG_APP_FUNCTION_ACCESS_UI_ENABLED) Loading Loading @@ -194,15 +188,15 @@ public final class AppFunctionManager { public static final int ACCESS_REQUEST_STATE_GRANTED = 0; /** * App Function access request state indicating that the access has been denied for a * particular agent and target * App Function access request state indicating that the access has been denied for a particular * agent and target */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) public static final int ACCESS_REQUEST_STATE_DENIED = 1; /** * App Function access request state indicating that the access is not able to be granted for * a particular agent and target, due to the agent not being granted the EXECUTE_APP_FUNCTIONS * App Function access request state indicating that the access is not able to be granted for a * particular agent and target, due to the agent not being granted the EXECUTE_APP_FUNCTIONS * permission, or the target not having an App Function Service, or the agent not being in the * device allowlist, or one or both apps not being installed. */ Loading @@ -210,7 +204,9 @@ public final class AppFunctionManager { public static final int ACCESS_REQUEST_STATE_UNREQUESTABLE = 2; /** @hide */ @IntDef(prefix = { "ACCESS_REQUEST_STATE_" }, value = { @IntDef( prefix = {"ACCESS_REQUEST_STATE_"}, value = { ACCESS_REQUEST_STATE_DENIED, ACCESS_REQUEST_STATE_GRANTED, ACCESS_REQUEST_STATE_UNREQUESTABLE Loading @@ -220,6 +216,7 @@ public final class AppFunctionManager { /** * A flag indicating the app function access state has been pregranted by the system * * @hide */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) Loading @@ -229,6 +226,7 @@ public final class AppFunctionManager { /** * A flag indicating the app function access is granted through a mechanism not tied to any * other flag (e.g. ADB) * * @hide */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) Loading @@ -238,6 +236,7 @@ public final class AppFunctionManager { /** * A flag indicating the app function access state has been denied by some other mechanism not * covered by another flag (e.g. ADB, self revoke) * * @hide */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) Loading @@ -246,6 +245,7 @@ public final class AppFunctionManager { /** * A flag indicating the user granted the app function access state through UI * * @hide */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) Loading @@ -254,6 +254,7 @@ public final class AppFunctionManager { /** * A flag indicating the app function access state has been denied by the user * * @hide */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) Loading @@ -262,13 +263,16 @@ public final class AppFunctionManager { /** * All USER flags * * @hide */ @TestApi public static final int ACCESS_FLAG_MASK_USER = ACCESS_FLAG_USER_GRANTED | ACCESS_FLAG_USER_DENIED; /** * All OTHER flags * * @hide */ @TestApi Loading @@ -277,15 +281,21 @@ public final class AppFunctionManager { /** * All access flags * * @hide */ @TestApi public static final int ACCESS_FLAG_MASK_ALL = ACCESS_FLAG_PREGRANTED | ACCESS_FLAG_OTHER_GRANTED | ACCESS_FLAG_OTHER_DENIED | ACCESS_FLAG_USER_GRANTED | ACCESS_FLAG_USER_DENIED; public static final int ACCESS_FLAG_MASK_ALL = ACCESS_FLAG_PREGRANTED | ACCESS_FLAG_OTHER_GRANTED | ACCESS_FLAG_OTHER_DENIED | ACCESS_FLAG_USER_GRANTED | ACCESS_FLAG_USER_DENIED; @IntDef(prefix = { "ACCESS_FLAG_" }, flag = true, value = { @IntDef( prefix = {"ACCESS_FLAG_"}, flag = true, value = { ACCESS_FLAG_PREGRANTED, ACCESS_FLAG_OTHER_GRANTED, ACCESS_FLAG_OTHER_DENIED, Loading Loading @@ -329,8 +339,8 @@ public final class AppFunctionManager { * Executes the app function. * * <p>Note: Applications can execute functions they define. To execute functions defined in * another component, apps would need to have the permission * {@code android.permission.EXECUTE_APP_FUNCTIONS}. * another component, apps would need to have the permission {@code * android.permission.EXECUTE_APP_FUNCTIONS}. * * @param request the request to execute the app function * @param executor the executor to run the callback Loading @@ -352,16 +362,16 @@ public final class AppFunctionManager { @NonNull ExecuteAppFunctionRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull CancellationSignal cancellationSignal, @NonNull OutcomeReceiver<ExecuteAppFunctionResponse, AppFunctionException> callback) { @NonNull OutcomeReceiver<ExecuteAppFunctionResponse, AppFunctionException> callback) { Objects.requireNonNull(request); Objects.requireNonNull(executor); Objects.requireNonNull(callback); ExecuteAppFunctionAidlRequest aidlRequest = new ExecuteAppFunctionAidlRequest( request, mContext.getUser(), mContext.getPackageName(), request, mContext.getUser(), mContext.getPackageName(), /* requestTime= */ SystemClock.elapsedRealtime()); try { Loading Loading @@ -402,8 +412,8 @@ public final class AppFunctionManager { * Returns a boolean through a callback, indicating whether the app function is enabled. * * <p>This method can only check app functions owned by the caller, or those where the caller * has visibility to the owner package and holds the * {@link Manifest.permission#EXECUTE_APP_FUNCTIONS} permission. * has visibility to the owner package and holds the {@link * Manifest.permission#EXECUTE_APP_FUNCTIONS} permission. * * <p>If the operation fails, the callback's {@link OutcomeReceiver#onError} is called with * errors: Loading Loading @@ -532,49 +542,53 @@ public final class AppFunctionManager { }; AppFunctionManagerHelper.isAppFunctionEnabled( functionIdentifier, targetPackage, appSearchManager, executor, functionIdentifier, targetPackage, appSearchManager, executor, callbackWithExceptionInterceptor); } /** * Checks whether the given agent has access to app functions of the given target app, or if * the access is not {@link #getAccessRequestState(String) valid}. Requires the * {@link Manifest.permission.MANAGE_APP_FUNCTION_ACCESS} permission if the * {@param agentPackageName} is not the calling app. * Checks whether the given agent has access to app functions of the given target app, or if the * access is not {@link #getAccessRequestState(String) valid}. Requires the {@link * Manifest.permission.MANAGE_APP_FUNCTION_ACCESS} permission if the {@param agentPackageName} * is not the calling app. * * @param agentPackageName The package name of the agent * @param targetPackageName The package name of the target * @return The state of the access, one of {@link #ACCESS_REQUEST_STATE_GRANTED}, * {@link #ACCESS_REQUEST_STATE_DENIED}, or {@link #ACCESS_REQUEST_STATE_UNREQUESTABLE} * @return The state of the access, one of {@link #ACCESS_REQUEST_STATE_GRANTED}, {@link * #ACCESS_REQUEST_STATE_DENIED}, or {@link #ACCESS_REQUEST_STATE_UNREQUESTABLE} * @hide */ @SystemApi @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) @RequiresPermission(value = MANAGE_APP_FUNCTION_ACCESS, conditional = true) @AppFunctionAccessState public int getAccessRequestState(@NonNull String agentPackageName, @NonNull String targetPackageName) { public int getAccessRequestState( @NonNull String agentPackageName, @NonNull String targetPackageName) { try { return mService.getAccessRequestState(agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId()); return mService.getAccessRequestState( agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Checks whether the calling app has access to app functions of the given target app, * for the given users, or if the access is invalid (not able to be requested). An access is * valid if: * Checks whether the calling app has access to app functions of the given target app, for the * given users, or if the access is invalid (not able to be requested). An access is valid if: * 1. The agent (calling app) and target apps are both installed, and the agent has visibility * of the target. * 2. The agent has the {@link Manifest.permission.EXECUTE_APP_FUNCTIONS} permission granted. * 3. The agent is allowlisted by the system. * 4. The target has an AppFunctionService. * of the target. 2. The agent has the {@link Manifest.permission.EXECUTE_APP_FUNCTIONS} * permission granted. 3. The agent is allowlisted by the system. 4. The target has an * AppFunctionService. * * @param targetPackageName The package name of the target * @return The state of the access, one of {@link #ACCESS_REQUEST_STATE_GRANTED}, * {@link #ACCESS_REQUEST_STATE_DENIED}, or {@link #ACCESS_REQUEST_STATE_UNREQUESTABLE} * @return The state of the access, one of {@link #ACCESS_REQUEST_STATE_GRANTED}, {@link * #ACCESS_REQUEST_STATE_DENIED}, or {@link #ACCESS_REQUEST_STATE_UNREQUESTABLE} */ @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) @AppFunctionAccessState Loading @@ -584,8 +598,8 @@ public final class AppFunctionManager { /** * Get the access flags for a given agent and target. These flags include extra information * about the access state (whether it is pregranted, if the user has set state, etc.). Returns * 0 if the access is not {@link #getAccessRequestState(String) valid}. * about the access state (whether it is pregranted, if the user has set state, etc.). Returns 0 * if the access is not {@link #getAccessRequestState(String) valid}. * * @param agentPackageName The package name of the agent * @param targetPackageName The package name of the target Loading @@ -596,40 +610,48 @@ public final class AppFunctionManager { @RequiresPermission(MANAGE_APP_FUNCTION_ACCESS) @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) @AppFunctionAccessFlags public int getAccessFlags(@NonNull String agentPackageName, @NonNull String targetPackageName) { public int getAccessFlags(@NonNull String agentPackageName, @NonNull String targetPackageName) { try { return mService.getAccessFlags(agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId()); return mService.getAccessFlags( agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Updates the access flags for the given agent and target. If the access is not * {@link #getAccessRequestState(String) valid}, this method is a no-op. * Updates the access flags for the given agent and target. If the access is not {@link * #getAccessRequestState(String) valid}, this method is a no-op. * * @param agentPackageName The package name of the agent * @param targetPackageName The package name of the target * @param flagMask The mask determining which flag values will be changed * @param flags The flag values to be changed * @throws IllegalArgumentException if an invalid flag is specified, opposing flags (e.g. * USER_GRANTED and USER_DENIED) are set together, or a flag with an opposite is set, without * its opposite being explicitly cleared (via being included in the flag mask, but not the flag * set). * USER_GRANTED and USER_DENIED) are set together, or a flag with an opposite is set, * without its opposite being explicitly cleared (via being included in the flag mask, but * not the flag set). * @hide */ @SystemApi @RequiresPermission(MANAGE_APP_FUNCTION_ACCESS) @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) public void updateAccessFlags(@NonNull String agentPackageName, @NonNull String targetPackageName, @AppFunctionAccessFlags int flagMask, public void updateAccessFlags( @NonNull String agentPackageName, @NonNull String targetPackageName, @AppFunctionAccessFlags int flagMask, @AppFunctionAccessFlags int flags) { try { mService.updateAccessFlags(agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId(), flagMask, flags); mService.updateAccessFlags( agentPackageName, mContext.getUserId(), targetPackageName, mContext.getUserId(), flagMask, flags); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading @@ -637,6 +659,7 @@ public final class AppFunctionManager { /** * Revoke the App Function access for the calling app and the given target * * @param targetPackageName The app whose AppFunctionService the calling app should lose access * to. */ Loading @@ -649,9 +672,9 @@ public final class AppFunctionManager { } } /** * Gets all {@link #getAccessRequestState(String) valid} agents. * * @return A list of all valid agent package names * @hide */ Loading @@ -668,8 +691,9 @@ public final class AppFunctionManager { /** * Gets all {@link #getAccessRequestState(String) valid} target apps. * @return A list of all target app package names in the current user that the agent can * request access for * * @return A list of all target app package names in the current user that the agent can request * access for * @hide */ @SystemApi Loading @@ -683,6 +707,24 @@ public final class AppFunctionManager { } } /** * Gets the configured list of package names that should be grouped as Device Settings. * * <p>The list here is a configuration, the returned packages are not necessarily installed. The * package names here must refer to system apps. * * @hide */ @TestApi @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED) @NonNull public Set<String> getDeviceSettingPackages() { final String[] deviceSettingPackages = mContext.getResources() .getStringArray(R.array.config_appFunctionDeviceSettingsPackages); return new ArraySet<>(deviceSettingPackages); } private static class CallbackWrapper extends IAppFunctionEnabledCallback.Stub { private final OutcomeReceiver<Void, Exception> mCallback; Loading
core/res/res/values/config.xml +2 −2 Original line number Diff line number Diff line Loading @@ -7625,10 +7625,10 @@ <!-- Maximum number of devices that allows for audio sharing. --> <integer name="config_audio_sharing_maximum_sinks">2</integer> <!--For App Functions, this configuration lists package names grouped as "Device Settings". <!--For App Function, this configuration lists package names grouped as "Device Settings". Packages in this list share the same App Function access settings. In the UI, they are presented as a single "Device Settings" item rather than individually. --> <string-array name="config_appFunctionsDeviceSettingsPackages" translatable="false"> <string-array name="config_appFunctionDeviceSettingsPackages" translatable="false"> </string-array> <!-- Package name for developer verification service provider app [DO NOT TRANSLATE] --> Loading
core/res/res/values/symbols.xml +3 −0 Original line number Diff line number Diff line Loading @@ -6267,4 +6267,7 @@ <!-- Package and class info to bind to ProximityProviderService --> <java-symbol type="string" name="proximity_provider_service_package_name" /> <java-symbol type="string" name="proximity_provider_service_class_name" /> <!-- For App Functions --> <java-symbol type="array" name="config_appFunctionDeviceSettingsPackages" /> </resources>