Loading core/java/android/app/appfunctions/AppFunctionAccessServiceInterface.java +5 −5 Original line number Diff line number Diff line Loading @@ -26,26 +26,26 @@ import java.util.List; */ public interface AppFunctionAccessServiceInterface { /** check access */ /** @see AppFunctionManager#checkAppFunctionAccess(String, String) */ boolean checkAppFunctionAccess(@NonNull String agentPackageName, int agentUserId, @NonNull String targetPackageName, int targetUserId); /** check access, but also informs if access is invalid */ /** @see AppFunctionManager#getAppFunctionAccessRequestState(String, String) */ @AppFunctionManager.AppFunctionAccessState int getAppFunctionAccessRequestState(@NonNull String agentPackageName, int agentUserId, @NonNull String targetPackageName, int targetUserId); /** get flags for a given target and agent */ /** @see AppFunctionManager#getAppFunctionAccessFlags(String, String) */ @AppFunctionManager.AppFunctionAccessFlags int getAppFunctionAccessFlags(@NonNull String agentPackageName, int agentUserId, @NonNull String targetPackageName, int targetUserId); /** update flags for a given target and agent */ /** @see AppFunctionManager#updateAppFunctionAccessFlags(String, String, int, int) */ boolean updateAppFunctionAccessFlags(@NonNull String agentPackageName, int agentUserId, @NonNull String targetPackageName, int targetUserId, @AppFunctionManager.AppFunctionAccessFlags int flagMask, @AppFunctionManager.AppFunctionAccessFlags int flags) throws IllegalArgumentException; /** update the agent allowlist */ /** Set the agent allowlist */ void setAgentAllowlist(@NonNull List<SignedPackage> agentAllowlist); } core/java/android/app/appfunctions/IAppFunctionManager.aidl +34 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.app.appfunctions.IExecuteAppFunctionCallback; import android.os.ICancellationSignal; import android.os.UserHandle; import java.util.List; /** * Defines the interface for apps to interact with the app function execution service * {@code AppFunctionManagerService} running in the system server process. Loading Loading @@ -50,4 +52,36 @@ interface IAppFunctionManager { int enabledState, in IAppFunctionEnabledCallback callback ); boolean checkAppFunctionAccess( in String agentPackageName, int agentUserId, in String targetPackageName, int targetUserId ); int getAppFunctionAccessRequestState( in String agentPackageName, int agentUserId, in String targetPackageName, int targetUserId ); int getAppFunctionAccessFlags( in String agentPackageName, int agentUserId, in String targetPackageName, int targetUserId ); void updateAppFunctionAccessFlags( in String agentPackageName, int agentUserId, in String targetPackageName, int targetUserId, int flagMask, int flags ); void revokeSelfAppFunctionAccess(in String targetPackageName); } services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +57 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.appfunctions; import static android.app.appfunctions.AppFunctionManager.ACCESS_REQUEST_STATE_UNREQUESTABLE; import static android.app.appfunctions.AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_METADATA_DB; import static android.app.appfunctions.AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_NAMESPACE; Loading Loading @@ -480,6 +481,62 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { }); } @Override public boolean checkAppFunctionAccess(String agentPackageName, int agentUserId, String targetPackageName, int targetUserId) throws RemoteException { if (!accessCheckFlagsEnabled()) { return false; } return mAppFunctionAccessService.checkAppFunctionAccess(agentPackageName, agentUserId, targetPackageName, targetUserId); } @Override public int getAppFunctionAccessFlags(String agentPackageName, int agentUserId, String targetPackageName, int targetUserId) throws RemoteException { if (!accessCheckFlagsEnabled()) { return 0; } return mAppFunctionAccessService.getAppFunctionAccessFlags(agentPackageName, agentUserId, targetPackageName, targetUserId); } @Override public void updateAppFunctionAccessFlags(String agentPackageName, int agentUserId, String targetPackageName, int targetUserId, int flagMask, int flags) throws RemoteException { if (!accessCheckFlagsEnabled()) { return; } mAppFunctionAccessService.updateAppFunctionAccessFlags(agentPackageName, agentUserId, targetPackageName, targetUserId, flagMask, flags); } @Override public void revokeSelfAppFunctionAccess(String targetPackageName) { if (!accessCheckFlagsEnabled()) { return; } // TODO: Call mAppFunctionAccessService.revokeSelfAppFunctionAccess(targetPackageName) // when ag/33428645 is in. } @Override public int getAppFunctionAccessRequestState(String agentPackageName, int agentUserId, String targetPackageName, int targetUserId) throws RemoteException { if (!accessCheckFlagsEnabled()) { return ACCESS_REQUEST_STATE_UNREQUESTABLE; } return mAppFunctionAccessService.getAppFunctionAccessRequestState(agentPackageName, agentUserId, targetPackageName, targetUserId); } private boolean accessCheckFlagsEnabled() { return android.permission.flags.Flags.appFunctionAccessApiEnabled() && android.permission.flags.Flags.appFunctionAccessServiceEnabled(); } private static void reportException( @NonNull IAppFunctionEnabledCallback callback, @NonNull Exception exception) { try { Loading services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceShellCommand.java +127 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,10 @@ package com.android.server.appfunctions; import static android.app.appfunctions.AppFunctionManager.ACCESS_FLAG_MASK_OTHER; import static android.app.appfunctions.AppFunctionManager.ACCESS_FLAG_OTHER_DENIED; import static android.app.appfunctions.AppFunctionManager.ACCESS_FLAG_OTHER_GRANTED; import android.annotation.NonNull; import android.app.ActivityManager; import android.app.appfunctions.AppFunctionException; Loading Loading @@ -48,7 +52,8 @@ import java.util.concurrent.TimeUnit; /** Shell command implementation for the {@link AppFunctionManagerService}. */ public class AppFunctionManagerServiceShellCommand extends ShellCommand { @NonNull private final IAppFunctionManager mService; @NonNull private final IAppFunctionManager mService; AppFunctionManagerServiceShellCommand(@NonNull IAppFunctionManager service) { mService = Objects.requireNonNull(service); Loading Loading @@ -85,6 +90,38 @@ public class AppFunctionManagerServiceShellCommand extends ShellCommand { pw.println( " --user <USER_ID> (optional): The user ID under which to set the function state" + ". Defaults to the current user."); pw.println(); pw.println( " grant-app-function-access --agent-package <AGENT_PACKAGE_NAME> " + "--target-package <TARGET_PACKAGE_NAME> [--agent-user <USER_ID>] " + "[--target-user <USER_ID>]"); pw.println(" Grants an agent package access to an app's functions."); pw.println(" --agent-package <AGENT_PACKAGE_NAME>: The agent package to grant access."); pw.println(" --target-package <TARGET_PACKAGE_NAME>: The target package."); pw.println( " --agent-user <USER_ID> (optional): The user ID for the agent package. " + "Defaults to the current user."); pw.println( " --target-user <USER_ID> (optional): The user ID for the target package. " + "Defaults to the current user."); pw.println(); pw.println( " revoke-app-function-access --agent-package <AGENT_PACKAGE_NAME> " + "--target-package <TARGET_PACKAGE_NAME> [--agent-user <USER_ID>] " + "[--target-user <USER_ID>]"); pw.println(" Revokes an agent package's access to an app's functions."); pw.println( " --agent-package <AGENT_PACKAGE_NAME>: The agent package to revoke access " + "from."); pw.println(" --target-package <TARGET_PACKAGE_NAME>: The target package."); pw.println( " --agent-user <USER_ID> (optional): The user ID for the agent package. " + "Defaults to the current user."); pw.println( " --target-user <USER_ID> (optional): The user ID for the target package. " + "Defaults to the current user."); pw.println(); } Loading @@ -100,6 +137,10 @@ public class AppFunctionManagerServiceShellCommand extends ShellCommand { return runExecuteAppFunction(); case "set-enabled": return runSetAppFunctionEnabled(); case "grant-app-function-access": return runGrantAppFunctionAccess(); case "revoke-app-function-access": return runRevokeAppFunctionAccess(); default: return handleDefaultCommands(cmd); } Loading Loading @@ -371,6 +412,91 @@ public class AppFunctionManagerServiceShellCommand extends ShellCommand { return builder.build(); } private int runGrantAppFunctionAccess() throws Exception { final PrintWriter pw = getOutPrintWriter(); String agentPackage = null; String targetPackage = null; int agentUserId = ActivityManager.getCurrentUser(); int targetUserId = ActivityManager.getCurrentUser(); String opt; while ((opt = getNextOption()) != null) { switch (opt) { case "--agent-package": agentPackage = getNextArgRequired(); break; case "--target-package": targetPackage = getNextArgRequired(); break; case "--agent-user": agentUserId = UserHandle.parseUserArg(getNextArgRequired()); break; case "--target-user": targetUserId = UserHandle.parseUserArg(getNextArgRequired()); break; default: pw.println("Unknown option: " + opt); return -1; } } if (agentPackage == null) { pw.println("Error: --agent-package must be specified."); return -1; } if (targetPackage == null) { pw.println("Error: --target-package must be specified."); return -1; } mService.updateAppFunctionAccessFlags(agentPackage, agentUserId, targetPackage, targetUserId, ACCESS_FLAG_MASK_OTHER, ACCESS_FLAG_OTHER_GRANTED); pw.println("Access granted successfully."); return 0; } private int runRevokeAppFunctionAccess() throws Exception { final PrintWriter pw = getOutPrintWriter(); String agentPackage = null; String targetPackage = null; int agentUserId = ActivityManager.getCurrentUser(); int targetUserId = ActivityManager.getCurrentUser(); String opt; while ((opt = getNextOption()) != null) { switch (opt) { case "--agent-package": agentPackage = getNextArgRequired(); break; case "--target-package": targetPackage = getNextArgRequired(); break; case "--agent-user": agentUserId = UserHandle.parseUserArg(getNextArgRequired()); break; case "--target-user": targetUserId = UserHandle.parseUserArg(getNextArgRequired()); break; default: pw.println("Unknown option: " + opt); return -1; } } if (agentPackage == null) { pw.println("Error: --agent-package must be specified."); return -1; } if (targetPackage == null) { pw.println("Error: --target-package must be specified."); return -1; } mService.updateAppFunctionAccessFlags(agentPackage, agentUserId, targetPackage, targetUserId, ACCESS_FLAG_MASK_OTHER, ACCESS_FLAG_OTHER_DENIED); pw.println("Access revoked successfully."); return 0; } private static String getCallingPackage() { return switch (Binder.getCallingUid()) { case Process.ROOT_UID -> "root"; Loading Loading
core/java/android/app/appfunctions/AppFunctionAccessServiceInterface.java +5 −5 Original line number Diff line number Diff line Loading @@ -26,26 +26,26 @@ import java.util.List; */ public interface AppFunctionAccessServiceInterface { /** check access */ /** @see AppFunctionManager#checkAppFunctionAccess(String, String) */ boolean checkAppFunctionAccess(@NonNull String agentPackageName, int agentUserId, @NonNull String targetPackageName, int targetUserId); /** check access, but also informs if access is invalid */ /** @see AppFunctionManager#getAppFunctionAccessRequestState(String, String) */ @AppFunctionManager.AppFunctionAccessState int getAppFunctionAccessRequestState(@NonNull String agentPackageName, int agentUserId, @NonNull String targetPackageName, int targetUserId); /** get flags for a given target and agent */ /** @see AppFunctionManager#getAppFunctionAccessFlags(String, String) */ @AppFunctionManager.AppFunctionAccessFlags int getAppFunctionAccessFlags(@NonNull String agentPackageName, int agentUserId, @NonNull String targetPackageName, int targetUserId); /** update flags for a given target and agent */ /** @see AppFunctionManager#updateAppFunctionAccessFlags(String, String, int, int) */ boolean updateAppFunctionAccessFlags(@NonNull String agentPackageName, int agentUserId, @NonNull String targetPackageName, int targetUserId, @AppFunctionManager.AppFunctionAccessFlags int flagMask, @AppFunctionManager.AppFunctionAccessFlags int flags) throws IllegalArgumentException; /** update the agent allowlist */ /** Set the agent allowlist */ void setAgentAllowlist(@NonNull List<SignedPackage> agentAllowlist); }
core/java/android/app/appfunctions/IAppFunctionManager.aidl +34 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.app.appfunctions.IExecuteAppFunctionCallback; import android.os.ICancellationSignal; import android.os.UserHandle; import java.util.List; /** * Defines the interface for apps to interact with the app function execution service * {@code AppFunctionManagerService} running in the system server process. Loading Loading @@ -50,4 +52,36 @@ interface IAppFunctionManager { int enabledState, in IAppFunctionEnabledCallback callback ); boolean checkAppFunctionAccess( in String agentPackageName, int agentUserId, in String targetPackageName, int targetUserId ); int getAppFunctionAccessRequestState( in String agentPackageName, int agentUserId, in String targetPackageName, int targetUserId ); int getAppFunctionAccessFlags( in String agentPackageName, int agentUserId, in String targetPackageName, int targetUserId ); void updateAppFunctionAccessFlags( in String agentPackageName, int agentUserId, in String targetPackageName, int targetUserId, int flagMask, int flags ); void revokeSelfAppFunctionAccess(in String targetPackageName); }
services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +57 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.appfunctions; import static android.app.appfunctions.AppFunctionManager.ACCESS_REQUEST_STATE_UNREQUESTABLE; import static android.app.appfunctions.AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_METADATA_DB; import static android.app.appfunctions.AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_NAMESPACE; Loading Loading @@ -480,6 +481,62 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { }); } @Override public boolean checkAppFunctionAccess(String agentPackageName, int agentUserId, String targetPackageName, int targetUserId) throws RemoteException { if (!accessCheckFlagsEnabled()) { return false; } return mAppFunctionAccessService.checkAppFunctionAccess(agentPackageName, agentUserId, targetPackageName, targetUserId); } @Override public int getAppFunctionAccessFlags(String agentPackageName, int agentUserId, String targetPackageName, int targetUserId) throws RemoteException { if (!accessCheckFlagsEnabled()) { return 0; } return mAppFunctionAccessService.getAppFunctionAccessFlags(agentPackageName, agentUserId, targetPackageName, targetUserId); } @Override public void updateAppFunctionAccessFlags(String agentPackageName, int agentUserId, String targetPackageName, int targetUserId, int flagMask, int flags) throws RemoteException { if (!accessCheckFlagsEnabled()) { return; } mAppFunctionAccessService.updateAppFunctionAccessFlags(agentPackageName, agentUserId, targetPackageName, targetUserId, flagMask, flags); } @Override public void revokeSelfAppFunctionAccess(String targetPackageName) { if (!accessCheckFlagsEnabled()) { return; } // TODO: Call mAppFunctionAccessService.revokeSelfAppFunctionAccess(targetPackageName) // when ag/33428645 is in. } @Override public int getAppFunctionAccessRequestState(String agentPackageName, int agentUserId, String targetPackageName, int targetUserId) throws RemoteException { if (!accessCheckFlagsEnabled()) { return ACCESS_REQUEST_STATE_UNREQUESTABLE; } return mAppFunctionAccessService.getAppFunctionAccessRequestState(agentPackageName, agentUserId, targetPackageName, targetUserId); } private boolean accessCheckFlagsEnabled() { return android.permission.flags.Flags.appFunctionAccessApiEnabled() && android.permission.flags.Flags.appFunctionAccessServiceEnabled(); } private static void reportException( @NonNull IAppFunctionEnabledCallback callback, @NonNull Exception exception) { try { Loading
services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceShellCommand.java +127 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,10 @@ package com.android.server.appfunctions; import static android.app.appfunctions.AppFunctionManager.ACCESS_FLAG_MASK_OTHER; import static android.app.appfunctions.AppFunctionManager.ACCESS_FLAG_OTHER_DENIED; import static android.app.appfunctions.AppFunctionManager.ACCESS_FLAG_OTHER_GRANTED; import android.annotation.NonNull; import android.app.ActivityManager; import android.app.appfunctions.AppFunctionException; Loading Loading @@ -48,7 +52,8 @@ import java.util.concurrent.TimeUnit; /** Shell command implementation for the {@link AppFunctionManagerService}. */ public class AppFunctionManagerServiceShellCommand extends ShellCommand { @NonNull private final IAppFunctionManager mService; @NonNull private final IAppFunctionManager mService; AppFunctionManagerServiceShellCommand(@NonNull IAppFunctionManager service) { mService = Objects.requireNonNull(service); Loading Loading @@ -85,6 +90,38 @@ public class AppFunctionManagerServiceShellCommand extends ShellCommand { pw.println( " --user <USER_ID> (optional): The user ID under which to set the function state" + ". Defaults to the current user."); pw.println(); pw.println( " grant-app-function-access --agent-package <AGENT_PACKAGE_NAME> " + "--target-package <TARGET_PACKAGE_NAME> [--agent-user <USER_ID>] " + "[--target-user <USER_ID>]"); pw.println(" Grants an agent package access to an app's functions."); pw.println(" --agent-package <AGENT_PACKAGE_NAME>: The agent package to grant access."); pw.println(" --target-package <TARGET_PACKAGE_NAME>: The target package."); pw.println( " --agent-user <USER_ID> (optional): The user ID for the agent package. " + "Defaults to the current user."); pw.println( " --target-user <USER_ID> (optional): The user ID for the target package. " + "Defaults to the current user."); pw.println(); pw.println( " revoke-app-function-access --agent-package <AGENT_PACKAGE_NAME> " + "--target-package <TARGET_PACKAGE_NAME> [--agent-user <USER_ID>] " + "[--target-user <USER_ID>]"); pw.println(" Revokes an agent package's access to an app's functions."); pw.println( " --agent-package <AGENT_PACKAGE_NAME>: The agent package to revoke access " + "from."); pw.println(" --target-package <TARGET_PACKAGE_NAME>: The target package."); pw.println( " --agent-user <USER_ID> (optional): The user ID for the agent package. " + "Defaults to the current user."); pw.println( " --target-user <USER_ID> (optional): The user ID for the target package. " + "Defaults to the current user."); pw.println(); } Loading @@ -100,6 +137,10 @@ public class AppFunctionManagerServiceShellCommand extends ShellCommand { return runExecuteAppFunction(); case "set-enabled": return runSetAppFunctionEnabled(); case "grant-app-function-access": return runGrantAppFunctionAccess(); case "revoke-app-function-access": return runRevokeAppFunctionAccess(); default: return handleDefaultCommands(cmd); } Loading Loading @@ -371,6 +412,91 @@ public class AppFunctionManagerServiceShellCommand extends ShellCommand { return builder.build(); } private int runGrantAppFunctionAccess() throws Exception { final PrintWriter pw = getOutPrintWriter(); String agentPackage = null; String targetPackage = null; int agentUserId = ActivityManager.getCurrentUser(); int targetUserId = ActivityManager.getCurrentUser(); String opt; while ((opt = getNextOption()) != null) { switch (opt) { case "--agent-package": agentPackage = getNextArgRequired(); break; case "--target-package": targetPackage = getNextArgRequired(); break; case "--agent-user": agentUserId = UserHandle.parseUserArg(getNextArgRequired()); break; case "--target-user": targetUserId = UserHandle.parseUserArg(getNextArgRequired()); break; default: pw.println("Unknown option: " + opt); return -1; } } if (agentPackage == null) { pw.println("Error: --agent-package must be specified."); return -1; } if (targetPackage == null) { pw.println("Error: --target-package must be specified."); return -1; } mService.updateAppFunctionAccessFlags(agentPackage, agentUserId, targetPackage, targetUserId, ACCESS_FLAG_MASK_OTHER, ACCESS_FLAG_OTHER_GRANTED); pw.println("Access granted successfully."); return 0; } private int runRevokeAppFunctionAccess() throws Exception { final PrintWriter pw = getOutPrintWriter(); String agentPackage = null; String targetPackage = null; int agentUserId = ActivityManager.getCurrentUser(); int targetUserId = ActivityManager.getCurrentUser(); String opt; while ((opt = getNextOption()) != null) { switch (opt) { case "--agent-package": agentPackage = getNextArgRequired(); break; case "--target-package": targetPackage = getNextArgRequired(); break; case "--agent-user": agentUserId = UserHandle.parseUserArg(getNextArgRequired()); break; case "--target-user": targetUserId = UserHandle.parseUserArg(getNextArgRequired()); break; default: pw.println("Unknown option: " + opt); return -1; } } if (agentPackage == null) { pw.println("Error: --agent-package must be specified."); return -1; } if (targetPackage == null) { pw.println("Error: --target-package must be specified."); return -1; } mService.updateAppFunctionAccessFlags(agentPackage, agentUserId, targetPackage, targetUserId, ACCESS_FLAG_MASK_OTHER, ACCESS_FLAG_OTHER_DENIED); pw.println("Access revoked successfully."); return 0; } private static String getCallingPackage() { return switch (Binder.getCallingUid()) { case Process.ROOT_UID -> "root"; Loading