• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.app.appfunctions;
18 
19 import static android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER;
20 
21 import android.annotation.FlaggedApi;
22 import android.annotation.NonNull;
23 import android.app.appsearch.GenericDocument;
24 import android.os.Bundle;
25 import android.os.Parcel;
26 import android.os.Parcelable;
27 
28 import java.util.Objects;
29 
30 /**
31  * A request to execute an app function.
32  *
33  * <p>The {@link ExecuteAppFunctionRequest#getParameters()} contains the parameters for the function
34  * to be executed in a GenericDocument. Structured classes defined in the AppFunction SDK can be
35  * converted into GenericDocuments.
36  *
37  * <p>The {@link ExecuteAppFunctionRequest#getExtras()} provides any extra metadata for the request.
38  * Structured APIs can be exposed in the SDK by packing and unpacking this Bundle.
39  */
40 @FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER)
41 public final class ExecuteAppFunctionRequest implements Parcelable {
42     @NonNull
43     public static final Creator<ExecuteAppFunctionRequest> CREATOR =
44             new Creator<>() {
45                 @Override
46                 public ExecuteAppFunctionRequest createFromParcel(Parcel parcel) {
47                     String targetPackageName = parcel.readString8();
48                     String functionIdentifier = parcel.readString8();
49                     GenericDocumentWrapper parameters =
50                             GenericDocumentWrapper.CREATOR.createFromParcel(parcel);
51                     Bundle extras = parcel.readBundle(Bundle.class.getClassLoader());
52                     return new ExecuteAppFunctionRequest(
53                             targetPackageName, functionIdentifier, extras, parameters);
54                 }
55 
56                 @Override
57                 public ExecuteAppFunctionRequest[] newArray(int size) {
58                     return new ExecuteAppFunctionRequest[size];
59                 }
60             };
61 
62     /** Returns the package name of the app that hosts/owns the function. */
63     @NonNull private final String mTargetPackageName;
64 
65     /**
66      * The unique string identifier of the app function to be executed. This identifier is used to
67      * execute a specific app function.
68      */
69     @NonNull private final String mFunctionIdentifier;
70 
71     /** Returns additional metadata relevant to this function execution request. */
72     @NonNull private final Bundle mExtras;
73 
74     /**
75      * Returns the parameters required to invoke this function. Within this [GenericDocument], the
76      * property names are the names of the function parameters and the property values are the
77      * values of those parameters.
78      *
79      * <p>The document may have missing parameters. Developers are advised to implement defensive
80      * handling measures.
81      */
82     @NonNull private final GenericDocumentWrapper mParameters;
83 
ExecuteAppFunctionRequest( @onNull String targetPackageName, @NonNull String functionIdentifier, @NonNull Bundle extras, @NonNull GenericDocumentWrapper parameters)84     private ExecuteAppFunctionRequest(
85             @NonNull String targetPackageName,
86             @NonNull String functionIdentifier,
87             @NonNull Bundle extras,
88             @NonNull GenericDocumentWrapper parameters) {
89         mTargetPackageName = Objects.requireNonNull(targetPackageName);
90         mFunctionIdentifier = Objects.requireNonNull(functionIdentifier);
91         mExtras = Objects.requireNonNull(extras);
92         mParameters = Objects.requireNonNull(parameters);
93     }
94 
95     /** Returns the package name of the app that hosts the function. */
96     @NonNull
getTargetPackageName()97     public String getTargetPackageName() {
98         return mTargetPackageName;
99     }
100 
101     /**
102      * Returns the unique string identifier of the app function to be executed.
103      *
104      * <p>When there is a package change or the device starts up, the metadata of available
105      * functions is indexed by AppSearch. AppSearch stores the indexed information as {@code
106      * AppFunctionStaticMetadata} document.
107      *
108      * <p>The ID can be obtained by querying the {@code AppFunctionStaticMetadata} documents from
109      * AppSearch.
110      *
111      * <p>If the {@code functionId} provided is invalid, the caller will get an invalid argument
112      * response.
113      */
114     @NonNull
getFunctionIdentifier()115     public String getFunctionIdentifier() {
116         return mFunctionIdentifier;
117     }
118 
119     /**
120      * Returns the function parameters. The key is the parameter name, and the value is the
121      * parameter value.
122      *
123      * <p>The {@link GenericDocument} may have missing parameters. Developers are advised to
124      * implement defensive handling measures.
125      *
126      * @see AppFunctionManager on how to determine the expected parameters.
127      */
128     @NonNull
getParameters()129     public GenericDocument getParameters() {
130         return mParameters.getValue();
131     }
132 
133     /** Returns the additional metadata for this function execution request. */
134     @NonNull
getExtras()135     public Bundle getExtras() {
136         return mExtras;
137     }
138 
139     /**
140      * Returns the size of the request in bytes.
141      *
142      * @hide
143      */
getRequestDataSize()144     public int getRequestDataSize() {
145         return mTargetPackageName.getBytes().length + mFunctionIdentifier.getBytes().length
146                 + mParameters.getDataSize() + mExtras.getSize();
147     }
148 
149     @Override
writeToParcel(@onNull Parcel dest, int flags)150     public void writeToParcel(@NonNull Parcel dest, int flags) {
151         dest.writeString8(mTargetPackageName);
152         dest.writeString8(mFunctionIdentifier);
153         mParameters.writeToParcel(dest, flags);
154         dest.writeBundle(mExtras);
155     }
156 
157     @Override
describeContents()158     public int describeContents() {
159         return 0;
160     }
161 
162     /** Builder for {@link ExecuteAppFunctionRequest}. */
163     public static final class Builder {
164         @NonNull private final String mTargetPackageName;
165         @NonNull private final String mFunctionIdentifier;
166         @NonNull private Bundle mExtras = Bundle.EMPTY;
167 
168         @NonNull
169         private GenericDocument mParameters = new GenericDocument.Builder<>("", "", "").build();
170 
171         /**
172          * Creates a new instance of this builder class.
173          *
174          * @param targetPackageName The package name of the target app providing the app function to
175          *     invoke.
176          * @param functionIdentifier The identifier used by the {@link AppFunctionService} from the
177          *     target app to uniquely identify the function to be invoked.
178          */
Builder(@onNull String targetPackageName, @NonNull String functionIdentifier)179         public Builder(@NonNull String targetPackageName, @NonNull String functionIdentifier) {
180             mTargetPackageName = Objects.requireNonNull(targetPackageName);
181             mFunctionIdentifier = Objects.requireNonNull(functionIdentifier);
182         }
183 
184         /** Sets the additional metadata for this function execution request. */
185         @NonNull
setExtras(@onNull Bundle extras)186         public Builder setExtras(@NonNull Bundle extras) {
187             mExtras = Objects.requireNonNull(extras);
188             return this;
189         }
190 
191         /**
192          * Sets the function parameters.
193          *
194          * @see #ExecuteAppFunctionRequest#getParameters()
195          */
196         @NonNull
setParameters(@onNull GenericDocument parameters)197         public Builder setParameters(@NonNull GenericDocument parameters) {
198             Objects.requireNonNull(parameters);
199             mParameters = parameters;
200             return this;
201         }
202 
203         /** Builds the {@link ExecuteAppFunctionRequest}. */
204         @NonNull
build()205         public ExecuteAppFunctionRequest build() {
206             return new ExecuteAppFunctionRequest(
207                     mTargetPackageName,
208                     mFunctionIdentifier,
209                     mExtras,
210                     new GenericDocumentWrapper(mParameters));
211         }
212     }
213 }
214