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.appsearch.functions;
18 
19 import android.annotation.CallbackExecutor;
20 import android.annotation.FlaggedApi;
21 import android.annotation.NonNull;
22 import android.annotation.SystemApi;
23 import android.annotation.UserHandleAware;
24 import android.app.appsearch.AppSearchManager;
25 import android.app.appsearch.AppSearchResult;
26 import android.app.appsearch.SearchSessionUtil;
27 import android.app.appsearch.aidl.AppSearchAttributionSource;
28 import android.app.appsearch.aidl.AppSearchResultParcel;
29 import android.app.appsearch.aidl.ExecuteAppFunctionAidlRequest;
30 import android.app.appsearch.aidl.IAppSearchManager;
31 import android.app.appsearch.aidl.IAppSearchResultCallback;
32 import android.content.Context;
33 import android.os.Process;
34 import android.os.RemoteException;
35 import android.os.SystemClock;
36 
37 import com.android.appsearch.flags.Flags;
38 
39 import java.util.Objects;
40 import java.util.concurrent.Executor;
41 import java.util.function.Consumer;
42 
43 /**
44  * Provides app functions related functionalities.
45  *
46  * <p>App function is a specific piece of functionality that an app offers to the system. These
47  * functionalities can be integrated into various system features.
48  *
49  * <p>You can obtain an instance using {@link AppSearchManager#getAppFunctionManager()}.
50  */
51 @FlaggedApi(Flags.FLAG_ENABLE_APP_FUNCTIONS)
52 public final class AppFunctionManager {
53     /**
54      * Allows system applications to execute app functions provided by apps through AppSearch.
55      *
56      * <p>Protection level: internal|role.
57      *
58      * @hide
59      */
60     @SystemApi
61     public static final String PERMISSION_EXECUTE_APP_FUNCTION =
62             "android.permission.EXECUTE_APP_FUNCTION";
63 
64     /**
65      * Must be required by a {@link android.app.appsearch.functions.AppFunctionService}, to ensure
66      * that only the system can bind to it.
67      *
68      * <p>Protection level: signature.
69      */
70     public static final String PERMISSION_BIND_APP_FUNCTION_SERVICE =
71             "android.permission.BIND_APP_FUNCTION_SERVICE";
72 
73     private final IAppSearchManager mService;
74     private final Context mContext;
75 
76     /** @hide */
AppFunctionManager(@onNull Context context, @NonNull IAppSearchManager service)77     public AppFunctionManager(@NonNull Context context, @NonNull IAppSearchManager service) {
78         mContext = Objects.requireNonNull(context);
79         mService = Objects.requireNonNull(service);
80     }
81 
82     /**
83      * Executes an app function provided by {@link AppFunctionService} through the system.
84      *
85      * @param request The request.
86      * @param executor Executor on which to invoke the callback.
87      * @param callback A callback to receive the function execution result.
88      */
89     @UserHandleAware
executeAppFunction( @onNull ExecuteAppFunctionRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<AppSearchResult<ExecuteAppFunctionResponse>> callback)90     public void executeAppFunction(
91             @NonNull ExecuteAppFunctionRequest request,
92             @NonNull @CallbackExecutor Executor executor,
93             @NonNull Consumer<AppSearchResult<ExecuteAppFunctionResponse>> callback) {
94         Objects.requireNonNull(request);
95         Objects.requireNonNull(callback);
96 
97         ExecuteAppFunctionAidlRequest aidlRequest =
98                 new ExecuteAppFunctionAidlRequest(
99                         request,
100                         AppSearchAttributionSource.createAttributionSource(
101                                 mContext, /* callingPid= */ Process.myPid()),
102                         mContext.getUser(),
103                         SystemClock.elapsedRealtime());
104         try {
105             mService.executeAppFunction(
106                     aidlRequest,
107                     new IAppSearchResultCallback.Stub() {
108                         @Override
109                         public void onResult(AppSearchResultParcel result) {
110                             SearchSessionUtil.safeExecute(
111                                     executor, callback, () -> callback.accept(result.getResult()));
112                         }
113                     });
114         } catch (RemoteException ex) {
115             ex.rethrowFromSystemServer();
116         }
117     }
118 }
119