Split the isAppFunctionEnabled method into two overloads
Flag: android.app.appfunctions.flags.enable_app_function_manager
Test: CTS
Bug: 376426049
Change-Id: I94c7a73983fea746dbf0815c77cc5e3705974c5d
diff --git a/core/api/current.txt b/core/api/current.txt
index 27c3cc5..fa2060c 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8783,7 +8783,8 @@
@FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public final class AppFunctionManager {
method @RequiresPermission(anyOf={"android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED", "android.permission.EXECUTE_APP_FUNCTIONS"}, conditional=true) public void executeAppFunction(@NonNull android.app.appfunctions.ExecuteAppFunctionRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<android.app.appfunctions.ExecuteAppFunctionResponse>);
- method public void isAppFunctionEnabled(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,java.lang.Exception>);
+ method @RequiresPermission(anyOf={"android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED", "android.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 public static final int APP_FUNCTION_STATE_DEFAULT = 0; // 0x0
field public static final int APP_FUNCTION_STATE_DISABLED = 2; // 0x2
diff --git a/core/java/android/app/appfunctions/AppFunctionManager.java b/core/java/android/app/appfunctions/AppFunctionManager.java
index 74cae07..5ddb590 100644
--- a/core/java/android/app/appfunctions/AppFunctionManager.java
+++ b/core/java/android/app/appfunctions/AppFunctionManager.java
@@ -53,8 +53,8 @@
* offers a more convenient and type-safe way to build app functions. The SDK provides predefined
* function schemas for common use cases and associated data classes for function parameters and
* return values. Apps only have to implement the provided interfaces. Internally, the SDK converts
- * these data classes into {@link ExecuteAppFunctionRequest#getParameters()} and
- * {@link ExecuteAppFunctionResponse#getResultDocument()}.
+ * these data classes into {@link ExecuteAppFunctionRequest#getParameters()} and {@link
+ * ExecuteAppFunctionResponse#getResultDocument()}.
*
* <p>**Discovering App Functions:**
*
@@ -69,13 +69,12 @@
* <p>**Executing App Functions:**
*
* <p>To execute an app function, the caller app can retrieve the {@code functionIdentifier} from
- * the {@code AppFunctionStaticMetadata} document and use it to build an
- * {@link ExecuteAppFunctionRequest}. Then, invoke {@link #executeAppFunction} with the request
- * to execute the app function. Callers need the {@code android.permission.EXECUTE_APP_FUNCTIONS}
- * or {@code android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED} 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.
+ * the {@code AppFunctionStaticMetadata} document and use it to build an {@link
+ * ExecuteAppFunctionRequest}. Then, invoke {@link #executeAppFunction} with the request to execute
+ * the app function. Callers need the {@code android.permission.EXECUTE_APP_FUNCTIONS} or {@code
+ * android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED} 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.
*
* <p>**Example:**
*
@@ -213,12 +212,13 @@
/**
* 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
+ * <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 either the {@link
* Manifest.permission#EXECUTE_APP_FUNCTIONS} or {@link
* Manifest.permission#EXECUTE_APP_FUNCTIONS_TRUSTED} permission.
*
- * <p>If operation fails, the callback's {@link OutcomeReceiver#onError} is called with errors:
+ * <p>If the operation fails, the callback's {@link OutcomeReceiver#onError} is called with
+ * errors:
*
* <ul>
* <li>{@link IllegalArgumentException}, if the function is not found or the caller does not
@@ -232,23 +232,47 @@
* @param executor the executor to run the request
* @param callback the callback to receive the function enabled check result
*/
+ @RequiresPermission(
+ anyOf = {
+ Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED,
+ Manifest.permission.EXECUTE_APP_FUNCTIONS
+ },
+ conditional = true)
public void isAppFunctionEnabled(
@NonNull String functionIdentifier,
@NonNull String targetPackage,
@NonNull Executor executor,
@NonNull OutcomeReceiver<Boolean, Exception> callback) {
- Objects.requireNonNull(functionIdentifier);
- Objects.requireNonNull(targetPackage);
- Objects.requireNonNull(executor);
- Objects.requireNonNull(callback);
- AppSearchManager appSearchManager = mContext.getSystemService(AppSearchManager.class);
- if (appSearchManager == null) {
- callback.onError(new IllegalStateException("Failed to get AppSearchManager."));
- return;
- }
+ isAppFunctionEnabledInternal(functionIdentifier, targetPackage, executor, callback);
+ }
- AppFunctionManagerHelper.isAppFunctionEnabled(
- functionIdentifier, targetPackage, appSearchManager, executor, callback);
+ /**
+ * 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, unlike {@link
+ * #isAppFunctionEnabled(String, String, Executor, OutcomeReceiver)}, which allows specifying a
+ * different target package.
+ *
+ * <p>If the operation fails, the callback's {@link OutcomeReceiver#onError} is called with
+ * errors:
+ *
+ * <ul>
+ * <li>{@link IllegalArgumentException}, if the function is not found or the caller does not
+ * have access to it.
+ * </ul>
+ *
+ * @param functionIdentifier the identifier of the app function to check (unique within the
+ * target package) and in most cases, these are automatically generated by the AppFunctions
+ * SDK
+ * @param executor the executor to run the request
+ * @param callback the callback to receive the function enabled check result
+ */
+ public void isAppFunctionEnabled(
+ @NonNull String functionIdentifier,
+ @NonNull Executor executor,
+ @NonNull OutcomeReceiver<Boolean, Exception> callback) {
+ isAppFunctionEnabledInternal(
+ functionIdentifier, mContext.getPackageName(), executor, callback);
}
/**
@@ -291,6 +315,25 @@
}
}
+ private void isAppFunctionEnabledInternal(
+ @NonNull String functionIdentifier,
+ @NonNull String targetPackage,
+ @NonNull Executor executor,
+ @NonNull OutcomeReceiver<Boolean, Exception> callback) {
+ Objects.requireNonNull(functionIdentifier);
+ Objects.requireNonNull(targetPackage);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ AppSearchManager appSearchManager = mContext.getSystemService(AppSearchManager.class);
+ if (appSearchManager == null) {
+ callback.onError(new IllegalStateException("Failed to get AppSearchManager."));
+ return;
+ }
+
+ AppFunctionManagerHelper.isAppFunctionEnabled(
+ functionIdentifier, targetPackage, appSearchManager, executor, callback);
+ }
+
private static class CallbackWrapper extends IAppFunctionEnabledCallback.Stub {
private final OutcomeReceiver<Void, Exception> mCallback;
diff --git a/libs/appfunctions/api/current.txt b/libs/appfunctions/api/current.txt
index 6c42bd3..89cdba8 100644
--- a/libs/appfunctions/api/current.txt
+++ b/libs/appfunctions/api/current.txt
@@ -3,8 +3,9 @@
public final class AppFunctionManager {
ctor public AppFunctionManager(android.content.Context);
- method public void executeAppFunction(@NonNull com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<com.google.android.appfunctions.sidecar.ExecuteAppFunctionResponse>);
- method public void isAppFunctionEnabled(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,java.lang.Exception>);
+ method @RequiresPermission(anyOf={android.Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED, android.Manifest.permission.EXECUTE_APP_FUNCTIONS}, conditional=true) public void executeAppFunction(@NonNull com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<com.google.android.appfunctions.sidecar.ExecuteAppFunctionResponse>);
+ method @RequiresPermission(anyOf={android.Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED, 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 public static final int APP_FUNCTION_STATE_DEFAULT = 0; // 0x0
field public static final int APP_FUNCTION_STATE_DISABLED = 2; // 0x2
diff --git a/libs/appfunctions/java/com/google/android/appfunctions/sidecar/AppFunctionManager.java b/libs/appfunctions/java/com/google/android/appfunctions/sidecar/AppFunctionManager.java
index 6870446..2075104 100644
--- a/libs/appfunctions/java/com/google/android/appfunctions/sidecar/AppFunctionManager.java
+++ b/libs/appfunctions/java/com/google/android/appfunctions/sidecar/AppFunctionManager.java
@@ -16,9 +16,11 @@
package com.google.android.appfunctions.sidecar;
+import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.UserHandleAware;
import android.content.Context;
@@ -103,6 +105,12 @@
* <p>See {@link android.app.appfunctions.AppFunctionManager#executeAppFunction} for the
* documented behaviour of this method.
*/
+ @RequiresPermission(
+ anyOf = {
+ Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED,
+ Manifest.permission.EXECUTE_APP_FUNCTIONS
+ },
+ conditional = true)
public void executeAppFunction(
@NonNull ExecuteAppFunctionRequest sidecarRequest,
@NonNull @CallbackExecutor Executor executor,
@@ -131,6 +139,12 @@
* <p>See {@link android.app.appfunctions.AppFunctionManager#isAppFunctionEnabled} for the
* documented behaviour of this method.
*/
+ @RequiresPermission(
+ anyOf = {
+ Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED,
+ Manifest.permission.EXECUTE_APP_FUNCTIONS
+ },
+ conditional = true)
public void isAppFunctionEnabled(
@NonNull String functionIdentifier,
@NonNull String targetPackage,
@@ -140,6 +154,19 @@
}
/**
+ * Returns a boolean through a callback, indicating whether the app function is enabled.
+ *
+ * <p>See {@link android.app.appfunctions.AppFunctionManager#isAppFunctionEnabled} for the
+ * documented behaviour of this method.
+ */
+ public void isAppFunctionEnabled(
+ @NonNull String functionIdentifier,
+ @NonNull Executor executor,
+ @NonNull OutcomeReceiver<Boolean, Exception> callback) {
+ mManager.isAppFunctionEnabled(functionIdentifier, executor, callback);
+ }
+
+ /**
* Sets the enabled state of the app function owned by the calling package.
*
* <p>See {@link android.app.appfunctions.AppFunctionManager#setAppFunctionEnabled} for the