Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c42d097 authored by Nate Myren's avatar Nate Myren Committed by Android (Google) Code Review
Browse files

Merge "Add app function access internal service" into main

parents 9ea3ea3a 91a0851f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -8954,6 +8954,9 @@ package android.app.appfunctions {
    method @RequiresPermission(value=android.Manifest.permission.EXECUTE_APP_FUNCTIONS, conditional=true) public void isAppFunctionEnabled(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,java.lang.Exception>);
    method public void isAppFunctionEnabled(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,java.lang.Exception>);
    method public void setAppFunctionEnabled(@NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,java.lang.Exception>);
    field @FlaggedApi("android.permission.flags.app_function_access_api_enabled") public static final int ACCESS_REQUEST_STATE_DENIED = 1; // 0x1
    field @FlaggedApi("android.permission.flags.app_function_access_api_enabled") public static final int ACCESS_REQUEST_STATE_GRANTED = 0; // 0x0
    field @FlaggedApi("android.permission.flags.app_function_access_api_enabled") public static final int ACCESS_REQUEST_STATE_UNREQUESTABLE = 2; // 0x2
    field @FlaggedApi("android.permission.flags.app_function_access_ui_enabled") public static final String ACTION_MANAGE_AGENT_APP_FUNCTION_ACCESS = "android.app.appfunctions.action.MANAGE_AGENT_APP_FUNCTION_ACCESS";
    field @FlaggedApi("android.permission.flags.app_function_access_ui_enabled") public static final String ACTION_MANAGE_APP_FUNCTION_ACCESS = "android.app.appfunctions.action.MANAGE_APP_FUNCTION_ACCESS";
    field @FlaggedApi("android.permission.flags.app_function_access_ui_enabled") public static final String ACTION_MANAGE_TARGET_APP_FUNCTION_ACCESS = "android.app.appfunctions.action.MANAGE_TARGET_APP_FUNCTION_ACCESS";
+6 −0
Original line number Diff line number Diff line
@@ -203,6 +203,7 @@ package android {
    field @Deprecated public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
    field public static final String MANAGE_ACTIVITY_TASKS = "android.permission.MANAGE_ACTIVITY_TASKS";
    field @FlaggedApi("android.security.aapm_api") public static final String MANAGE_ADVANCED_PROTECTION_MODE = "android.permission.MANAGE_ADVANCED_PROTECTION_MODE";
    field @FlaggedApi("android.permission.flags.app_function_access_api_enabled") public static final String MANAGE_APP_FUNCTION_ACCESS = "android.permission.MANAGE_APP_FUNCTION_ACCESS";
    field public static final String MANAGE_APP_HIBERNATION = "android.permission.MANAGE_APP_HIBERNATION";
    field public static final String MANAGE_APP_OPS_RESTRICTIONS = "android.permission.MANAGE_APP_OPS_RESTRICTIONS";
    field public static final String MANAGE_APP_PREDICTIONS = "android.permission.MANAGE_APP_PREDICTIONS";
@@ -1764,6 +1765,11 @@ package android.app.ambientcontext {
package android.app.appfunctions {
  @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public final class AppFunctionManager {
    field @FlaggedApi("android.permission.flags.app_function_access_api_enabled") public static final int ACCESS_FLAG_OTHER_DENIED = 4; // 0x4
    field @FlaggedApi("android.permission.flags.app_function_access_api_enabled") public static final int ACCESS_FLAG_OTHER_GRANTED = 2; // 0x2
    field @FlaggedApi("android.permission.flags.app_function_access_api_enabled") public static final int ACCESS_FLAG_PREGRANTED = 1; // 0x1
    field @FlaggedApi("android.permission.flags.app_function_access_api_enabled") public static final int ACCESS_FLAG_USER_DENIED = 16; // 0x10
    field @FlaggedApi("android.permission.flags.app_function_access_api_enabled") public static final int ACCESS_FLAG_USER_GRANTED = 8; // 0x8
    field @FlaggedApi("android.permission.flags.app_function_access_ui_enabled") public static final String ACTION_REQUEST_APP_FUNCTION_ACCESS = "android.app.appfunctions.action.REQUEST_APP_FUNCTION_ACCESS";
  }
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 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.
 */

package android.app.appfunctions;

import android.annotation.NonNull;
import android.content.pm.SignedPackage;

import java.util.List;

/**
 * @hide
 */
public interface AppFunctionAccessServiceInterface {

    /** check access */
    boolean checkAppFunctionAccess(@NonNull String agentPackageName, int agentUserId,
            @NonNull String targetPackageName, int targetUserId);

    /** check access, but also informs if access is invalid */
    @AppFunctionManager.AppFunctionAccessState
    int getAppFunctionAccessRequestState(@NonNull String agentPackageName, int agentUserId,
            @NonNull String targetPackageName, int targetUserId);

    /** get flags for a given target and agent */
    @AppFunctionManager.AppFunctionAccessFlags
    int getAppFunctionAccessFlags(@NonNull String agentPackageName, int agentUserId,
            @NonNull String targetPackageName, int targetUserId);

    /** update flags for a given target and agent */
    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 */
    void setAgentAllowlist(@NonNull List<SignedPackage> agentAllowlist);
}
+107 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.OutcomeReceiver;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.SystemClock;
import android.permission.flags.Flags;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -179,6 +180,112 @@ public final class AppFunctionManager {
     */
    public static final int APP_FUNCTION_STATE_DISABLED = 2;

    /**
     * App Function access request state indicating that the access has been granted for a
     * particular agent and target
     */
    @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED)
    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
     */
    @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
     * 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.
     */
    @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED)
    public static final int ACCESS_REQUEST_STATE_UNREQUESTABLE = 2;

    /** @hide */
    @IntDef(prefix = { "ACCESS_REQUEST_STATE_" }, value = {
            ACCESS_REQUEST_STATE_DENIED,
            ACCESS_REQUEST_STATE_GRANTED,
            ACCESS_REQUEST_STATE_UNREQUESTABLE
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface AppFunctionAccessState {}

    /**
     * A flag indicating the app function access state has been pregranted by the system
     * @hide
     */
    @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED)
    @SystemApi
    public static final int ACCESS_FLAG_PREGRANTED = 1;

    /**
     * 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)
    @SystemApi
    public static final int ACCESS_FLAG_OTHER_GRANTED = 1 << 1;

    /**
     * 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)
    @SystemApi
    public static final int ACCESS_FLAG_OTHER_DENIED = 1 << 2;

    /**
     * A flag indicating the user granted the app function access state through UI
     * @hide
     */
    @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED)
    @SystemApi
    public static final int ACCESS_FLAG_USER_GRANTED = 1 << 3;

    /**
     * A flag indicating the app function access state has been denied by the user
     * @hide
     */
    @FlaggedApi(Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED)
    @SystemApi
    public static final int ACCESS_FLAG_USER_DENIED = 1 << 4;

    /**
     * All USER flags
     * @hide
     */
    public static final int ACCESS_FLAG_MASK_USER =
            ACCESS_FLAG_USER_GRANTED | ACCESS_FLAG_USER_DENIED;
    /**
     * All OTHER flags
     * @hide
     */
    public static final int ACCESS_FLAG_MASK_OTHER =
            ACCESS_FLAG_OTHER_GRANTED | ACCESS_FLAG_OTHER_DENIED;

    /**
     * All access flags
     * @hide
     */
    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 = {
            ACCESS_FLAG_PREGRANTED,
            ACCESS_FLAG_OTHER_GRANTED,
            ACCESS_FLAG_OTHER_DENIED,
            ACCESS_FLAG_USER_GRANTED,
            ACCESS_FLAG_USER_DENIED
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface AppFunctionAccessFlags {}

    private final IAppFunctionManager mService;
    private final Context mContext;

+11 −0
Original line number Diff line number Diff line
@@ -9131,6 +9131,17 @@
        android:protectionLevel="signature"
        android:featureFlag="android.permission.flags.supervision_role_enabled" />

    <!-- @SystemApi
        @FlaggedApi(android.permission.flags.Flags.FLAG_APP_FUNCTION_ACCESS_API_ENABLED)
        This permission is required to set the access state flags on an agent, to access
        AppFunctions of other apps.
        <p> Protection level: signature|installer
        @hide
    -->
    <permission android:name="android.permission.MANAGE_APP_FUNCTION_ACCESS"
        android:protectionLevel="signature|installer"
        android:featureFlag="android.permission.flags.app_function_access_api_enabled"/>

    <!-- Allows an application to programmatically move and resize its tasks when the system is in
        a state that allows such operations, e.g. in a desktop-like environment. It is only
        extended to the {@link android.app.role.RoleManager#ROLE_BROWSER default browser}.
Loading