blob: 3bbc945c8b87b4ab0174778708f78af5299be377 [file] [log] [blame]
Terry Wangfebbead2019-10-17 17:05:18 -07001/*
sidchhabraa7c8f8a2020-01-16 18:38:17 -08002 * Copyright (C) 2020 The Android Open Source Project
Terry Wangfebbead2019-10-17 17:05:18 -07003 *
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 */
16package com.android.server.appsearch;
17
Terry Wangdbd1dca2020-11-03 17:03:56 -080018import static android.app.appsearch.AppSearchResult.throwableToFailedResult;
19
sidchhabraa7c8f8a2020-01-16 18:38:17 -080020import android.annotation.NonNull;
Terry Wangf2093072020-11-30 04:47:19 -080021import android.annotation.UserIdInt;
22import android.app.ActivityManager;
Alexander Dorokhine18465842020-01-21 01:08:57 -080023import android.app.appsearch.AppSearchBatchResult;
Alexander Dorokhine969f4462020-03-05 15:54:19 -080024import android.app.appsearch.AppSearchResult;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070025import android.app.appsearch.AppSearchSchema;
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070026import android.app.appsearch.GenericDocument;
Terry Wangdbd1dca2020-11-03 17:03:56 -080027import android.app.appsearch.IAppSearchBatchResultCallback;
Terry Wangfebbead2019-10-17 17:05:18 -070028import android.app.appsearch.IAppSearchManager;
Terry Wangdbd1dca2020-11-03 17:03:56 -080029import android.app.appsearch.IAppSearchResultCallback;
Alexander Dorokhineab789062021-01-11 21:00:00 -080030import android.app.appsearch.PackageIdentifier;
Terry Wang26b9e5c2020-10-23 02:05:01 -070031import android.app.appsearch.SearchResultPage;
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -070032import android.app.appsearch.SearchSpec;
Terry Wangfebbead2019-10-17 17:05:18 -070033import android.content.Context;
Cassie Wang0c62d992021-01-15 14:39:30 -080034import android.content.pm.PackageManagerInternal;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080035import android.os.Binder;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070036import android.os.Bundle;
Terry Wangdbd1dca2020-11-03 17:03:56 -080037import android.os.ParcelableException;
38import android.os.RemoteException;
Cassie Wang0c62d992021-01-15 14:39:30 -080039import android.os.UserHandle;
Alexander Dorokhineab789062021-01-11 21:00:00 -080040import android.util.ArrayMap;
Terry Wangdbd1dca2020-11-03 17:03:56 -080041import android.util.Log;
Terry Wangfebbead2019-10-17 17:05:18 -070042
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080043import com.android.internal.util.Preconditions;
Cassie Wang0c62d992021-01-15 14:39:30 -080044import com.android.server.LocalServices;
Terry Wangfebbead2019-10-17 17:05:18 -070045import com.android.server.SystemService;
Alexander Dorokhinef660d8f2020-10-29 22:37:00 -070046import com.android.server.appsearch.external.localstorage.AppSearchImpl;
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080047
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080048import java.util.ArrayList;
Alexander Dorokhine18465842020-01-21 01:08:57 -080049import java.util.List;
Alexander Dorokhineab789062021-01-11 21:00:00 -080050import java.util.Map;
Alexander Dorokhined18f8842021-01-20 15:26:13 -080051import java.util.Objects;
Alexander Dorokhine18465842020-01-21 01:08:57 -080052
Cassie Wang0c62d992021-01-15 14:39:30 -080053/** TODO(b/142567528): add comments when implement this class */
Terry Wangfebbead2019-10-17 17:05:18 -070054public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070055 private static final String TAG = "AppSearchManagerService";
Cassie Wang0c62d992021-01-15 14:39:30 -080056 private PackageManagerInternal mPackageManagerInternal;
Cassie Wang21c2d6a2021-01-20 23:59:55 -080057 private ImplInstanceManager mImplInstanceManager;
Terry Wangfebbead2019-10-17 17:05:18 -070058
59 public AppSearchManagerService(Context context) {
60 super(context);
61 }
62
63 @Override
64 public void onStart() {
65 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
Cassie Wang0c62d992021-01-15 14:39:30 -080066 mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
Cassie Wang308304c2021-01-21 11:13:49 -080067 mImplInstanceManager = ImplInstanceManager.getInstance(getContext());
Terry Wangfebbead2019-10-17 17:05:18 -070068 }
69
70 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080071 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -080072 public void setSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -080073 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -070074 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070075 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080076 @NonNull List<String> schemasNotPlatformSurfaceable,
Alexander Dorokhineab789062021-01-11 21:00:00 -080077 @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -080078 boolean forceOverride,
Terry Wangf2093072020-11-30 04:47:19 -080079 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -080080 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -080081 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -070082 Preconditions.checkNotNull(databaseName);
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070083 Preconditions.checkNotNull(schemaBundles);
Terry Wangbfbfcac2020-11-06 15:46:44 -080084 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -080085 int callingUid = Binder.getCallingUid();
86 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -060087 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080088 try {
Cassie Wang0c62d992021-01-15 14:39:30 -080089 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080090 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070091 for (int i = 0; i < schemaBundles.size(); i++) {
Terry Wang26b9e5c2020-10-23 02:05:01 -070092 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070093 }
Alexander Dorokhineab789062021-01-11 21:00:00 -080094 Map<String, List<PackageIdentifier>> schemasPackageAccessible =
95 new ArrayMap<>(schemasPackageAccessibleBundles.size());
96 for (Map.Entry<String, List<Bundle>> entry :
97 schemasPackageAccessibleBundles.entrySet()) {
98 List<PackageIdentifier> packageIdentifiers =
99 new ArrayList<>(entry.getValue().size());
100 for (int i = 0; i < packageIdentifiers.size(); i++) {
101 packageIdentifiers.add(new PackageIdentifier(entry.getValue().get(i)));
102 }
103 schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
104 }
Cassie Wang308304c2021-01-21 11:13:49 -0800105 AppSearchImpl impl =
106 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Alexander Dorokhineab789062021-01-11 21:00:00 -0800107 impl.setSchema(
108 packageName,
109 databaseName,
110 schemas,
111 schemasNotPlatformSurfaceable,
112 schemasPackageAccessible,
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800113 forceOverride);
Cassie Wang0c62d992021-01-15 14:39:30 -0800114 invokeCallbackOnResult(
115 callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800116 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800117 invokeCallbackOnError(callback, t);
Alexander Dorokhine270d4f12020-01-15 17:24:35 -0800118 } finally {
119 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800120 }
121 }
122
123 @Override
Terry Wang83a24932020-12-09 21:00:18 -0800124 public void getSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800125 @NonNull String packageName,
Terry Wang83a24932020-12-09 21:00:18 -0800126 @NonNull String databaseName,
Terry Wangf2093072020-11-30 04:47:19 -0800127 @UserIdInt int userId,
Terry Wang83a24932020-12-09 21:00:18 -0800128 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800129 Preconditions.checkNotNull(packageName);
Terry Wang83a24932020-12-09 21:00:18 -0800130 Preconditions.checkNotNull(databaseName);
131 Preconditions.checkNotNull(callback);
132 int callingUid = Binder.getCallingUidOrThrow();
Terry Wangf2093072020-11-30 04:47:19 -0800133 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wang83a24932020-12-09 21:00:18 -0800134 final long callingIdentity = Binder.clearCallingIdentity();
135 try {
Cassie Wang0c62d992021-01-15 14:39:30 -0800136 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800137 AppSearchImpl impl =
138 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800139 List<AppSearchSchema> schemas = impl.getSchema(packageName, databaseName);
Terry Wang83a24932020-12-09 21:00:18 -0800140 List<Bundle> schemaBundles = new ArrayList<>(schemas.size());
141 for (int i = 0; i < schemas.size(); i++) {
142 schemaBundles.add(schemas.get(i).getBundle());
143 }
Cassie Wang0c62d992021-01-15 14:39:30 -0800144 invokeCallbackOnResult(
145 callback, AppSearchResult.newSuccessfulResult(schemaBundles));
Terry Wang83a24932020-12-09 21:00:18 -0800146 } catch (Throwable t) {
147 invokeCallbackOnError(callback, t);
148 } finally {
149 Binder.restoreCallingIdentity(callingIdentity);
150 }
151 }
152
153 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -0800154 public void putDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800155 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700156 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700157 @NonNull List<Bundle> documentBundles,
Terry Wangf2093072020-11-30 04:47:19 -0800158 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800159 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800160 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700161 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700162 Preconditions.checkNotNull(documentBundles);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800163 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800164 int callingUid = Binder.getCallingUid();
165 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600166 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800167 try {
Cassie Wang0c62d992021-01-15 14:39:30 -0800168 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800169 AppSearchBatchResult.Builder<String, Void> resultBuilder =
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800170 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800171 AppSearchImpl impl =
172 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700173 for (int i = 0; i < documentBundles.size(); i++) {
174 GenericDocument document = new GenericDocument(documentBundles.get(i));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800175 try {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800176 // TODO(b/173451571): reduce burden of binder thread by enqueue request onto
177 // a separate thread.
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800178 impl.putDocument(packageName, databaseName, document);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700179 resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800180 } catch (Throwable t) {
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800181 resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800182 }
183 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800184 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800185 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800186 invokeCallbackOnError(callback, t);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800187 } finally {
188 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800189 }
190 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800191
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800192 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800193 public void getDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800194 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800195 @NonNull String databaseName,
196 @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800197 @NonNull List<String> uris,
Alexander Dorokhine87cdd152021-01-20 15:41:25 -0800198 @NonNull Map<String, List<String>> typePropertyPaths,
Terry Wangf2093072020-11-30 04:47:19 -0800199 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800200 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800201 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700202 Preconditions.checkNotNull(databaseName);
203 Preconditions.checkNotNull(namespace);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800204 Preconditions.checkNotNull(uris);
205 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800206 int callingUid = Binder.getCallingUid();
207 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600208 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800209 try {
Cassie Wang0c62d992021-01-15 14:39:30 -0800210 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700211 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800212 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800213 AppSearchImpl impl =
214 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800215 for (int i = 0; i < uris.size(); i++) {
216 String uri = uris.get(i);
217 try {
Cassie Wang308304c2021-01-21 11:13:49 -0800218 GenericDocument document =
219 impl.getDocument(
220 packageName,
221 databaseName,
222 namespace,
223 uri,
224 typePropertyPaths);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700225 resultBuilder.setSuccess(uri, document.getBundle());
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800226 } catch (Throwable t) {
227 resultBuilder.setResult(uri, throwableToFailedResult(t));
228 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800229 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800230 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800231 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800232 invokeCallbackOnError(callback, t);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800233 } finally {
234 Binder.restoreCallingIdentity(callingIdentity);
235 }
236 }
237
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800238 // TODO(sidchhabra): Do this in a threadpool.
239 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800240 public void query(
Cassie Wang0c62d992021-01-15 14:39:30 -0800241 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700242 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700243 @NonNull String queryExpression,
244 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800245 @UserIdInt int userId,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700246 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800247 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700248 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700249 Preconditions.checkNotNull(queryExpression);
250 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800251 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800252 int callingUid = Binder.getCallingUid();
253 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600254 final long callingIdentity = Binder.clearCallingIdentity();
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800255 try {
Cassie Wang0c62d992021-01-15 14:39:30 -0800256 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800257 AppSearchImpl impl =
258 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800259 SearchResultPage searchResultPage =
260 impl.query(
261 packageName,
262 databaseName,
263 queryExpression,
264 new SearchSpec(searchSpecBundle));
265 invokeCallbackOnResult(
266 callback,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700267 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800268 } catch (Throwable t) {
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700269 invokeCallbackOnError(callback, t);
270 } finally {
271 Binder.restoreCallingIdentity(callingIdentity);
272 }
273 }
274
Terry Wangf2093072020-11-30 04:47:19 -0800275 @Override
Terry Wangbfbfcac2020-11-06 15:46:44 -0800276 public void globalQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800277 @NonNull String packageName,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800278 @NonNull String queryExpression,
279 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800280 @UserIdInt int userId,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800281 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800282 Preconditions.checkNotNull(packageName);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800283 Preconditions.checkNotNull(queryExpression);
284 Preconditions.checkNotNull(searchSpecBundle);
285 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800286 int callingUid = Binder.getCallingUid();
287 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800288 final long callingIdentity = Binder.clearCallingIdentity();
289 try {
Cassie Wang0c62d992021-01-15 14:39:30 -0800290 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800291 AppSearchImpl impl =
292 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
293 SearchResultPage searchResultPage =
294 impl.globalQuery(
295 queryExpression,
296 new SearchSpec(searchSpecBundle),
297 packageName,
298 callingUid);
Cassie Wang0c62d992021-01-15 14:39:30 -0800299 invokeCallbackOnResult(
300 callback,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800301 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
302 } catch (Throwable t) {
303 invokeCallbackOnError(callback, t);
304 } finally {
305 Binder.restoreCallingIdentity(callingIdentity);
306 }
307 }
308
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700309 @Override
Cassie Wang0c62d992021-01-15 14:39:30 -0800310 public void getNextPage(
311 long nextPageToken,
312 @UserIdInt int userId,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700313 @NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800314 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800315 int callingUid = Binder.getCallingUid();
316 int callingUserId = handleIncomingUser(userId, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700317 final long callingIdentity = Binder.clearCallingIdentity();
318 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
319 // opened it
320 try {
Cassie Wang308304c2021-01-21 11:13:49 -0800321 AppSearchImpl impl =
322 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700323 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
Cassie Wang0c62d992021-01-15 14:39:30 -0800324 invokeCallbackOnResult(
325 callback,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700326 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
327 } catch (Throwable t) {
328 invokeCallbackOnError(callback, t);
329 } finally {
330 Binder.restoreCallingIdentity(callingIdentity);
331 }
332 }
333
334 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800335 public void invalidateNextPageToken(long nextPageToken, @UserIdInt int userId) {
336 int callingUid = Binder.getCallingUid();
337 int callingUserId = handleIncomingUser(userId, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700338 final long callingIdentity = Binder.clearCallingIdentity();
339 try {
Cassie Wang308304c2021-01-21 11:13:49 -0800340 AppSearchImpl impl =
341 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700342 impl.invalidateNextPageToken(nextPageToken);
343 } catch (Throwable t) {
Terry Wang2da17852020-12-16 19:59:08 -0800344 Log.e(TAG, "Unable to invalidate the query page token", t);
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800345 } finally {
346 Binder.restoreCallingIdentity(callingIdentity);
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800347 }
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800348 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800349
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700350 @Override
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800351 public void reportUsage(
352 @NonNull String packageName,
353 @NonNull String databaseName,
354 @NonNull String namespace,
355 @NonNull String uri,
356 long usageTimeMillis,
357 @UserIdInt int userId,
358 @NonNull IAppSearchResultCallback callback) {
359 Objects.requireNonNull(databaseName);
360 Objects.requireNonNull(namespace);
361 Objects.requireNonNull(uri);
362 Objects.requireNonNull(callback);
363 int callingUid = Binder.getCallingUid();
364 int callingUserId = handleIncomingUser(userId, callingUid);
365 final long callingIdentity = Binder.clearCallingIdentity();
366 try {
Cassie Wang308304c2021-01-21 11:13:49 -0800367 AppSearchImpl impl =
368 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
369 impl.reportUsage(packageName, databaseName, namespace, uri, usageTimeMillis);
370 invokeCallbackOnResult(
371 callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800372 } catch (Throwable t) {
373 invokeCallbackOnError(callback, t);
374 } finally {
375 Binder.restoreCallingIdentity(callingIdentity);
376 }
377 }
378
379 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800380 public void removeByUri(
Cassie Wang0c62d992021-01-15 14:39:30 -0800381 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800382 @NonNull String databaseName,
383 @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800384 @NonNull List<String> uris,
Terry Wangf2093072020-11-30 04:47:19 -0800385 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800386 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800387 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700388 Preconditions.checkNotNull(databaseName);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700389 Preconditions.checkNotNull(uris);
390 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800391 int callingUid = Binder.getCallingUid();
392 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600393 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700394 try {
Cassie Wang0c62d992021-01-15 14:39:30 -0800395 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800396 AppSearchBatchResult.Builder<String, Void> resultBuilder =
397 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800398 AppSearchImpl impl =
399 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700400 for (int i = 0; i < uris.size(); i++) {
401 String uri = uris.get(i);
402 try {
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800403 impl.remove(packageName, databaseName, namespace, uri);
Cassie Wang0c62d992021-01-15 14:39:30 -0800404 resultBuilder.setSuccess(uri, /*result= */ null);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700405 } catch (Throwable t) {
406 resultBuilder.setResult(uri, throwableToFailedResult(t));
407 }
408 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800409 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700410 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800411 invokeCallbackOnError(callback, t);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700412 } finally {
413 Binder.restoreCallingIdentity(callingIdentity);
414 }
415 }
416
417 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -0700418 public void removeByQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800419 @NonNull String packageName,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700420 @NonNull String databaseName,
421 @NonNull String queryExpression,
422 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800423 @UserIdInt int userId,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700424 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800425 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700426 Preconditions.checkNotNull(databaseName);
427 Preconditions.checkNotNull(queryExpression);
428 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800429 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800430 int callingUid = Binder.getCallingUid();
431 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600432 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700433 try {
Cassie Wang0c62d992021-01-15 14:39:30 -0800434 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800435 AppSearchImpl impl =
436 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800437 impl.removeByQuery(
438 packageName,
439 databaseName,
440 queryExpression,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700441 new SearchSpec(searchSpecBundle));
442 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700443 } catch (Throwable t) {
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700444 invokeCallbackOnError(callback, t);
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700445 } finally {
446 Binder.restoreCallingIdentity(callingIdentity);
447 }
448 }
449
Terry Wangdbd1dca2020-11-03 17:03:56 -0800450 @Override
Terry Wang2da17852020-12-16 19:59:08 -0800451 public void persistToDisk(@UserIdInt int userId) {
452 int callingUid = Binder.getCallingUidOrThrow();
453 int callingUserId = handleIncomingUser(userId, callingUid);
454 final long callingIdentity = Binder.clearCallingIdentity();
455 try {
Cassie Wang308304c2021-01-21 11:13:49 -0800456 AppSearchImpl impl =
457 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Terry Wang2da17852020-12-16 19:59:08 -0800458 impl.persistToDisk();
459 } catch (Throwable t) {
460 Log.e(TAG, "Unable to persist the data to disk", t);
461 } finally {
462 Binder.restoreCallingIdentity(callingIdentity);
463 }
464 }
465
466 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800467 public void initialize(@UserIdInt int userId, @NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800468 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800469 int callingUid = Binder.getCallingUid();
470 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800471 final long callingIdentity = Binder.clearCallingIdentity();
472 try {
Cassie Wang308304c2021-01-21 11:13:49 -0800473 mImplInstanceManager.getAppSearchImpl(getContext(), callingUserId);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800474 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
475 } catch (Throwable t) {
476 invokeCallbackOnError(callback, t);
477 } finally {
478 Binder.restoreCallingIdentity(callingIdentity);
479 }
480 }
481
Cassie Wang0c62d992021-01-15 14:39:30 -0800482 private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) {
483 Preconditions.checkNotNull(callingPackage);
484 if (mPackageManagerInternal.getPackageUid(
485 callingPackage, /*flags=*/ 0, UserHandle.getUserId(callingUid))
486 != callingUid) {
487 throw new SecurityException(
488 "Specified calling package ["
489 + callingPackage
490 + "] does not match the calling uid "
491 + callingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700492 }
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700493 }
494
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800495 /** Invokes the {@link IAppSearchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -0800496 private void invokeCallbackOnResult(
497 IAppSearchResultCallback callback, AppSearchResult<?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800498 try {
499 callback.onResult(result);
500 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800501 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800502 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800503 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800504
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800505 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -0800506 private void invokeCallbackOnResult(
507 IAppSearchBatchResultCallback callback, AppSearchBatchResult<?, ?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800508 try {
509 callback.onResult(result);
510 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800511 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800512 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800513 }
514
515 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800516 * Invokes the {@link IAppSearchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800517 *
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800518 * <p>The throwable is convert to a {@link AppSearchResult};
Terry Wangdbd1dca2020-11-03 17:03:56 -0800519 */
520 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
521 try {
522 callback.onResult(throwableToFailedResult(throwable));
523 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800524 Log.e(TAG, "Unable to send result to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800525 }
526 }
527
528 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800529 * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800530 *
531 * <p>The throwable is converted to {@link ParcelableException}.
532 */
Cassie Wang0c62d992021-01-15 14:39:30 -0800533 private void invokeCallbackOnError(
534 IAppSearchBatchResultCallback callback, Throwable throwable) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800535 try {
536 callback.onSystemError(new ParcelableException(throwable));
537 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800538 Log.e(TAG, "Unable to send error to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800539 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800540 }
Terry Wangfebbead2019-10-17 17:05:18 -0700541 }
Terry Wangf2093072020-11-30 04:47:19 -0800542
Cassie Wang0c62d992021-01-15 14:39:30 -0800543 // TODO(b/173553485) verifying that the caller has permission to access target user's data
544 // TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast
545 // TODO(b/173553485) Implement SystemService.onUserStopping()
Terry Wangf2093072020-11-30 04:47:19 -0800546 private static int handleIncomingUser(@UserIdInt int userId, int callingUid) {
547 int callingPid = Binder.getCallingPid();
Cassie Wang0c62d992021-01-15 14:39:30 -0800548 return ActivityManager.handleIncomingUser(
549 callingPid,
550 callingUid,
551 userId,
552 /*allowAll=*/ false,
553 /*requireFull=*/ false,
554 /*name=*/ null,
555 /*callerPackage=*/ null);
Terry Wangf2093072020-11-30 04:47:19 -0800556 }
Terry Wangfebbead2019-10-17 17:05:18 -0700557}