1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.extensions.appfunctions;
18 
19 import android.content.Context;
20 import android.os.CancellationSignal;
21 import android.os.OutcomeReceiver;
22 
23 import androidx.annotation.IntDef;
24 import androidx.annotation.RestrictTo;
25 
26 import org.jspecify.annotations.NonNull;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 import java.util.concurrent.Executor;
31 
32 /**
33  * Provides access to app functions.
34  *
35  * <p>An app function is a piece of functionality that apps expose to the system for cross-app
36  * orchestration.
37  *
38  * <p>**Building App Functions:**
39  *
40  * <p>Most developers should build app functions through the AppFunctions SDK. This SDK library
41  * offers a more convenient and type-safe way to build app functions. The SDK provides predefined
42  * function schemas for common use cases and associated data classes for function parameters and
43  * return values. Apps only have to implement the provided interfaces. Internally, the SDK converts
44  * these data classes into {@link ExecuteAppFunctionRequest#getParameters()} and {@link
45  * ExecuteAppFunctionResponse#getResultDocument()}.
46  *
47  * <p>**Discovering App Functions:**
48  *
49  * <p>When there is a package change or the device starts up, the metadata of available functions is
50  * indexed on-device by AppSearch. AppSearch stores the indexed information as an
51  * {@code AppFunctionStaticMetadata} document. This document contains the {@code functionIdentifier}
52  * and the schema information that the app function implements. This allows other apps and the app
53  * itself to discover these functions using the AppSearch search APIs. Visibility to this metadata
54  * document is based on the packages that have visibility to the app providing the app functions.
55  * AppFunction SDK provides a convenient way to achieve this and is the preferred method.
56  *
57  * <p>**Executing App Functions:**
58  *
59  * <p>To execute an app function, the caller app can retrieve the {@code functionIdentifier} from
60  * the {@code AppFunctionStaticMetadata} document and use it to build an {@link
61  * ExecuteAppFunctionRequest}. Then, invoke {@link #executeAppFunction} with the request to execute
62  * the app function. Callers need the {@code android.permission.EXECUTE_APP_FUNCTIONS} or {@code
63  * android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED} permission to execute app functions from other
64  * apps. An app can always execute its own app functions and doesn't need these permissions.
65  * AppFunction SDK provides a convenient way to achieve this and is the preferred method.
66  *
67  * <p>**Example:**
68  *
69  * <p>An assistant app is trying to fulfill the user request "Save XYZ into my note". The assistant
70  * app should first list all available app functions as {@code AppFunctionStaticMetadata} documents
71  * from AppSearch. Then, it should identify an app function that implements the {@code CreateNote}
72  * schema. Finally, the assistant app can invoke {@link #executeAppFunction} with the {@code
73  * functionIdentifier} of the chosen function.
74  */
75 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
76 public final class AppFunctionManager {
77     /**
78      * The default state of the app function. Call {@link #setAppFunctionEnabled} with this to reset
79      * enabled state to the default value.
80      */
81     public static final int APP_FUNCTION_STATE_DEFAULT = 0;
82 
83     /**
84      * The app function is enabled. To enable an app function, call {@link #setAppFunctionEnabled}
85      * with this value.
86      */
87     public static final int APP_FUNCTION_STATE_ENABLED = 1;
88 
89     /**
90      * The app function is disabled. To disable an app function, call {@link #setAppFunctionEnabled}
91      * with this value.
92      */
93     public static final int APP_FUNCTION_STATE_DISABLED = 2;
94 
95     /**
96      * The enabled state of the app function.
97      */
98     @IntDef(
99             value = {
100                     APP_FUNCTION_STATE_DEFAULT,
101                     APP_FUNCTION_STATE_ENABLED,
102                     APP_FUNCTION_STATE_DISABLED
103             })
104     @Retention(RetentionPolicy.SOURCE)
105     public @interface EnabledState {
106     }
107 
108     /**
109      * Creates an instance.
110      *
111      * @param context A {@link Context}.
112      */
AppFunctionManager(@onNull Context context)113     public AppFunctionManager(@NonNull Context context) {
114         throw new RuntimeException("Stub!");
115     }
116 
117     /**
118      * Executes the app function.
119      *
120      * <p>Proxies request and response to the underlying
121      * {@link AppFunctionManager#executeAppFunction}, converting the request and
122      * response in the appropriate type required by the function.
123      *
124      * <p>See {@link AppFunctionManager#executeAppFunction} for the
125      * documented behaviour of this method.
126      */
executeAppFunction( @onNull ExecuteAppFunctionRequest sidecarRequest, @NonNull Executor executor, @NonNull CancellationSignal cancellationSignal, @NonNull OutcomeReceiver<ExecuteAppFunctionResponse, AppFunctionException> callback)127     public void executeAppFunction(
128             @NonNull ExecuteAppFunctionRequest sidecarRequest,
129             @NonNull Executor executor,
130             @NonNull CancellationSignal cancellationSignal,
131             @NonNull
132             OutcomeReceiver<ExecuteAppFunctionResponse, AppFunctionException>
133                     callback) {
134         throw new RuntimeException("Stub!");
135     }
136 
137     /**
138      * Returns a boolean through a callback, indicating whether the app function is enabled.
139      *
140      * <p>See {@link AppFunctionManager#isAppFunctionEnabled} for the documented behaviour of
141      * this method.
142      */
isAppFunctionEnabled( @onNull String functionIdentifier, @NonNull String targetPackage, @NonNull Executor executor, @NonNull OutcomeReceiver<Boolean, Exception> callback)143     public void isAppFunctionEnabled(
144             @NonNull String functionIdentifier,
145             @NonNull String targetPackage,
146             @NonNull Executor executor,
147             @NonNull OutcomeReceiver<Boolean, Exception> callback) {
148         throw new RuntimeException("Stub!");
149     }
150 
151     /**
152      * Returns a boolean through a callback, indicating whether the app function is enabled.
153      *
154      * <p>See {@link AppFunctionManager#isAppFunctionEnabled} for the documented behaviour of
155      * this method.
156      */
isAppFunctionEnabled( @onNull String functionIdentifier, @NonNull Executor executor, @NonNull OutcomeReceiver<Boolean, Exception> callback)157     public void isAppFunctionEnabled(
158             @NonNull String functionIdentifier,
159             @NonNull Executor executor,
160             @NonNull OutcomeReceiver<Boolean, Exception> callback) {
161         throw new RuntimeException("Stub!");
162     }
163 
164     /**
165      * Sets the enabled state of the app function owned by the calling package.
166      *
167      * <p>See {@link AppFunctionManager#isAppFunctionEnabled} for the documented behaviour of
168      * this method.
169      */
setAppFunctionEnabled( @onNull String functionIdentifier, @EnabledState int newEnabledState, @NonNull Executor executor, @NonNull OutcomeReceiver<Void, Exception> callback)170     public void setAppFunctionEnabled(
171             @NonNull String functionIdentifier,
172             @EnabledState int newEnabledState,
173             @NonNull Executor executor,
174             @NonNull OutcomeReceiver<Void, Exception> callback) {
175         throw new RuntimeException("Stub!");
176     }
177 }
178