blob: 6e3fb82ba213779e32bedb5572e7ec3b7629867a [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;
Alexander Dorokhine9795b512021-03-23 22:06:59 -070027import android.app.appsearch.GetSchemaResponse;
Terry Wangdbd1dca2020-11-03 17:03:56 -080028import android.app.appsearch.IAppSearchBatchResultCallback;
Terry Wangfebbead2019-10-17 17:05:18 -070029import android.app.appsearch.IAppSearchManager;
Terry Wangdbd1dca2020-11-03 17:03:56 -080030import android.app.appsearch.IAppSearchResultCallback;
Alexander Dorokhineab789062021-01-11 21:00:00 -080031import android.app.appsearch.PackageIdentifier;
Terry Wang26b9e5c2020-10-23 02:05:01 -070032import android.app.appsearch.SearchResultPage;
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -070033import android.app.appsearch.SearchSpec;
Terry Wangfebbead2019-10-17 17:05:18 -070034import android.content.Context;
Cassie Wang0c62d992021-01-15 14:39:30 -080035import android.content.pm.PackageManagerInternal;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080036import android.os.Binder;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070037import android.os.Bundle;
Terry Wangdbd1dca2020-11-03 17:03:56 -080038import android.os.ParcelableException;
39import android.os.RemoteException;
Cassie Wang0c62d992021-01-15 14:39:30 -080040import android.os.UserHandle;
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070041import android.os.UserManager;
Alexander Dorokhineab789062021-01-11 21:00:00 -080042import android.util.ArrayMap;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080043import android.util.ArraySet;
Terry Wangdbd1dca2020-11-03 17:03:56 -080044import android.util.Log;
Terry Wangfebbead2019-10-17 17:05:18 -070045
Cassie Wang15c86972021-02-09 13:43:25 -080046import com.android.internal.annotations.GuardedBy;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080047import com.android.internal.util.Preconditions;
Cassie Wang0c62d992021-01-15 14:39:30 -080048import com.android.server.LocalServices;
Terry Wangfebbead2019-10-17 17:05:18 -070049import com.android.server.SystemService;
Alexander Dorokhinef660d8f2020-10-29 22:37:00 -070050import com.android.server.appsearch.external.localstorage.AppSearchImpl;
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080051
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080052import java.util.ArrayList;
Alexander Dorokhine18465842020-01-21 01:08:57 -080053import java.util.List;
Alexander Dorokhineab789062021-01-11 21:00:00 -080054import java.util.Map;
Alexander Dorokhined18f8842021-01-20 15:26:13 -080055import java.util.Objects;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080056import java.util.Set;
Alexander Dorokhine18465842020-01-21 01:08:57 -080057
Cassie Wang0c62d992021-01-15 14:39:30 -080058/** TODO(b/142567528): add comments when implement this class */
Terry Wangfebbead2019-10-17 17:05:18 -070059public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070060 private static final String TAG = "AppSearchManagerService";
Cassie Wang0c62d992021-01-15 14:39:30 -080061 private PackageManagerInternal mPackageManagerInternal;
Cassie Wang21c2d6a2021-01-20 23:59:55 -080062 private ImplInstanceManager mImplInstanceManager;
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070063 private UserManager mUserManager;
Terry Wangfebbead2019-10-17 17:05:18 -070064
Cassie Wang15c86972021-02-09 13:43:25 -080065 // Cache of unlocked user ids so we don't have to query UserManager service each time. The
66 // "locked" suffix refers to the fact that access to the field should be locked; unrelated to
67 // the unlocked status of user ids.
68 @GuardedBy("mUnlockedUserIdsLocked")
69 private final Set<Integer> mUnlockedUserIdsLocked = new ArraySet<>();
Cassie Wang9ba9ae12021-02-01 16:39:37 -080070
Terry Wangfebbead2019-10-17 17:05:18 -070071 public AppSearchManagerService(Context context) {
72 super(context);
73 }
74
75 @Override
76 public void onStart() {
77 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
Cassie Wang0c62d992021-01-15 14:39:30 -080078 mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
Cassie Wang308304c2021-01-21 11:13:49 -080079 mImplInstanceManager = ImplInstanceManager.getInstance(getContext());
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070080 mUserManager = getContext().getSystemService(UserManager.class);
Terry Wangfebbead2019-10-17 17:05:18 -070081 }
82
Cassie Wang9ba9ae12021-02-01 16:39:37 -080083 @Override
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070084 public void onUserUnlocking(@NonNull TargetUser user) {
Cassie Wang15c86972021-02-09 13:43:25 -080085 synchronized (mUnlockedUserIdsLocked) {
86 mUnlockedUserIdsLocked.add(user.getUserIdentifier());
87 }
Cassie Wang9ba9ae12021-02-01 16:39:37 -080088 }
89
Terry Wangfebbead2019-10-17 17:05:18 -070090 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080091 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -080092 public void setSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -080093 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -070094 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070095 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine315cca62021-03-04 12:34:41 -080096 @NonNull List<String> schemasNotDisplayedBySystem,
Alexander Dorokhineab789062021-01-11 21:00:00 -080097 @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -080098 boolean forceOverride,
Terry Wangf2093072020-11-30 04:47:19 -080099 @UserIdInt int userId,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700100 int schemaVersion,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800101 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800102 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700103 Preconditions.checkNotNull(databaseName);
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700104 Preconditions.checkNotNull(schemaBundles);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800105 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800106 int callingUid = Binder.getCallingUid();
107 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600108 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800109 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800110 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800111 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine6a99f942020-12-04 02:57:22 -0800112 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700113 for (int i = 0; i < schemaBundles.size(); i++) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700114 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700115 }
Alexander Dorokhineab789062021-01-11 21:00:00 -0800116 Map<String, List<PackageIdentifier>> schemasPackageAccessible =
117 new ArrayMap<>(schemasPackageAccessibleBundles.size());
118 for (Map.Entry<String, List<Bundle>> entry :
119 schemasPackageAccessibleBundles.entrySet()) {
120 List<PackageIdentifier> packageIdentifiers =
121 new ArrayList<>(entry.getValue().size());
Cassie Wange8569db2021-02-05 00:05:25 -0800122 for (int i = 0; i < entry.getValue().size(); i++) {
Alexander Dorokhineab789062021-01-11 21:00:00 -0800123 packageIdentifiers.add(new PackageIdentifier(entry.getValue().get(i)));
124 }
125 schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
126 }
Terry Wang9d8f4272021-02-04 21:01:10 -0800127 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhineab789062021-01-11 21:00:00 -0800128 impl.setSchema(
129 packageName,
130 databaseName,
131 schemas,
Alexander Dorokhine315cca62021-03-04 12:34:41 -0800132 schemasNotDisplayedBySystem,
Alexander Dorokhineab789062021-01-11 21:00:00 -0800133 schemasPackageAccessible,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700134 forceOverride,
135 schemaVersion);
Cassie Wang0c62d992021-01-15 14:39:30 -0800136 invokeCallbackOnResult(
137 callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800138 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800139 invokeCallbackOnError(callback, t);
Alexander Dorokhine270d4f12020-01-15 17:24:35 -0800140 } finally {
141 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800142 }
143 }
144
145 @Override
Terry Wang83a24932020-12-09 21:00:18 -0800146 public void getSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800147 @NonNull String packageName,
Terry Wang83a24932020-12-09 21:00:18 -0800148 @NonNull String databaseName,
Terry Wangf2093072020-11-30 04:47:19 -0800149 @UserIdInt int userId,
Terry Wang83a24932020-12-09 21:00:18 -0800150 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800151 Preconditions.checkNotNull(packageName);
Terry Wang83a24932020-12-09 21:00:18 -0800152 Preconditions.checkNotNull(databaseName);
153 Preconditions.checkNotNull(callback);
154 int callingUid = Binder.getCallingUidOrThrow();
Terry Wangf2093072020-11-30 04:47:19 -0800155 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wang83a24932020-12-09 21:00:18 -0800156 final long callingIdentity = Binder.clearCallingIdentity();
157 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800158 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800159 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800160 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800161 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700162 GetSchemaResponse response = impl.getSchema(packageName, databaseName);
Cassie Wang0c62d992021-01-15 14:39:30 -0800163 invokeCallbackOnResult(
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700164 callback, AppSearchResult.newSuccessfulResult(response.getBundle()));
165 } catch (Throwable t) {
166 invokeCallbackOnError(callback, t);
167 } finally {
168 Binder.restoreCallingIdentity(callingIdentity);
169 }
170 }
171
172 @Override
173 public void getNamespaces(
174 @NonNull String packageName,
175 @NonNull String databaseName,
176 @UserIdInt int userId,
177 @NonNull IAppSearchResultCallback callback) {
178 Preconditions.checkNotNull(packageName);
179 Preconditions.checkNotNull(databaseName);
180 Preconditions.checkNotNull(callback);
181 int callingUid = Binder.getCallingUidOrThrow();
182 int callingUserId = handleIncomingUser(userId, callingUid);
183 final long callingIdentity = Binder.clearCallingIdentity();
184 try {
185 verifyUserUnlocked(callingUserId);
186 verifyCallingPackage(callingUid, packageName);
187 AppSearchImpl impl =
188 mImplInstanceManager.getAppSearchImpl(callingUserId);
189 List<String> namespaces = impl.getNamespaces(packageName, databaseName);
190 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(namespaces));
Terry Wang83a24932020-12-09 21:00:18 -0800191 } catch (Throwable t) {
192 invokeCallbackOnError(callback, t);
193 } finally {
194 Binder.restoreCallingIdentity(callingIdentity);
195 }
196 }
197
198 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -0800199 public void putDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800200 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700201 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700202 @NonNull List<Bundle> documentBundles,
Terry Wangf2093072020-11-30 04:47:19 -0800203 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800204 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800205 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700206 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700207 Preconditions.checkNotNull(documentBundles);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800208 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800209 int callingUid = Binder.getCallingUid();
210 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600211 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800212 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800213 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800214 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800215 AppSearchBatchResult.Builder<String, Void> resultBuilder =
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800216 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800217 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800218 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700219 for (int i = 0; i < documentBundles.size(); i++) {
220 GenericDocument document = new GenericDocument(documentBundles.get(i));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800221 try {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800222 // TODO(b/173451571): reduce burden of binder thread by enqueue request onto
223 // a separate thread.
Alexander Dorokhine3488b9a2021-03-16 23:57:49 -0700224 impl.putDocument(packageName, databaseName, document, /*logger=*/ null);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700225 resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800226 } catch (Throwable t) {
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800227 resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800228 }
229 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800230 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800231 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800232 invokeCallbackOnError(callback, t);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800233 } finally {
234 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800235 }
236 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800237
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800238 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800239 public void getDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800240 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800241 @NonNull String databaseName,
242 @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800243 @NonNull List<String> uris,
Alexander Dorokhine87cdd152021-01-20 15:41:25 -0800244 @NonNull Map<String, List<String>> typePropertyPaths,
Terry Wangf2093072020-11-30 04:47:19 -0800245 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800246 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800247 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700248 Preconditions.checkNotNull(databaseName);
249 Preconditions.checkNotNull(namespace);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800250 Preconditions.checkNotNull(uris);
251 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();
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800255 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800256 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800257 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700258 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800259 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800260 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800261 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800262 for (int i = 0; i < uris.size(); i++) {
263 String uri = uris.get(i);
264 try {
Cassie Wang308304c2021-01-21 11:13:49 -0800265 GenericDocument document =
266 impl.getDocument(
267 packageName,
268 databaseName,
269 namespace,
270 uri,
271 typePropertyPaths);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700272 resultBuilder.setSuccess(uri, document.getBundle());
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800273 } catch (Throwable t) {
274 resultBuilder.setResult(uri, throwableToFailedResult(t));
275 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800276 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800277 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800278 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800279 invokeCallbackOnError(callback, t);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800280 } finally {
281 Binder.restoreCallingIdentity(callingIdentity);
282 }
283 }
284
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800285 // TODO(sidchhabra): Do this in a threadpool.
286 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800287 public void query(
Cassie Wang0c62d992021-01-15 14:39:30 -0800288 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700289 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700290 @NonNull String queryExpression,
291 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800292 @UserIdInt int userId,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700293 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800294 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700295 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700296 Preconditions.checkNotNull(queryExpression);
297 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800298 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800299 int callingUid = Binder.getCallingUid();
300 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600301 final long callingIdentity = Binder.clearCallingIdentity();
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800302 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800303 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800304 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800305 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800306 mImplInstanceManager.getAppSearchImpl(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800307 SearchResultPage searchResultPage =
308 impl.query(
309 packageName,
310 databaseName,
311 queryExpression,
312 new SearchSpec(searchSpecBundle));
313 invokeCallbackOnResult(
314 callback,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700315 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800316 } catch (Throwable t) {
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700317 invokeCallbackOnError(callback, t);
318 } finally {
319 Binder.restoreCallingIdentity(callingIdentity);
320 }
321 }
322
Terry Wangf2093072020-11-30 04:47:19 -0800323 @Override
Terry Wangbfbfcac2020-11-06 15:46:44 -0800324 public void globalQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800325 @NonNull String packageName,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800326 @NonNull String queryExpression,
327 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800328 @UserIdInt int userId,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800329 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800330 Preconditions.checkNotNull(packageName);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800331 Preconditions.checkNotNull(queryExpression);
332 Preconditions.checkNotNull(searchSpecBundle);
333 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800334 int callingUid = Binder.getCallingUid();
335 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800336 final long callingIdentity = Binder.clearCallingIdentity();
337 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800338 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800339 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800340 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800341 mImplInstanceManager.getAppSearchImpl(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800342 SearchResultPage searchResultPage =
343 impl.globalQuery(
344 queryExpression,
345 new SearchSpec(searchSpecBundle),
346 packageName,
347 callingUid);
Cassie Wang0c62d992021-01-15 14:39:30 -0800348 invokeCallbackOnResult(
349 callback,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800350 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
351 } catch (Throwable t) {
352 invokeCallbackOnError(callback, t);
353 } finally {
354 Binder.restoreCallingIdentity(callingIdentity);
355 }
356 }
357
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700358 @Override
Cassie Wang0c62d992021-01-15 14:39:30 -0800359 public void getNextPage(
360 long nextPageToken,
361 @UserIdInt int userId,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700362 @NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800363 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800364 int callingUid = Binder.getCallingUid();
365 int callingUserId = handleIncomingUser(userId, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700366 final long callingIdentity = Binder.clearCallingIdentity();
367 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
368 // opened it
369 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800370 verifyUserUnlocked(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800371 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800372 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700373 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
Cassie Wang0c62d992021-01-15 14:39:30 -0800374 invokeCallbackOnResult(
375 callback,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700376 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
377 } catch (Throwable t) {
378 invokeCallbackOnError(callback, t);
379 } finally {
380 Binder.restoreCallingIdentity(callingIdentity);
381 }
382 }
383
384 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800385 public void invalidateNextPageToken(long nextPageToken, @UserIdInt int userId) {
386 int callingUid = Binder.getCallingUid();
387 int callingUserId = handleIncomingUser(userId, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700388 final long callingIdentity = Binder.clearCallingIdentity();
389 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800390 verifyUserUnlocked(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800391 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800392 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700393 impl.invalidateNextPageToken(nextPageToken);
394 } catch (Throwable t) {
Terry Wang2da17852020-12-16 19:59:08 -0800395 Log.e(TAG, "Unable to invalidate the query page token", t);
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800396 } finally {
397 Binder.restoreCallingIdentity(callingIdentity);
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800398 }
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800399 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800400
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700401 @Override
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800402 public void reportUsage(
403 @NonNull String packageName,
404 @NonNull String databaseName,
405 @NonNull String namespace,
406 @NonNull String uri,
407 long usageTimeMillis,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700408 boolean systemUsage,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800409 @UserIdInt int userId,
410 @NonNull IAppSearchResultCallback callback) {
411 Objects.requireNonNull(databaseName);
412 Objects.requireNonNull(namespace);
413 Objects.requireNonNull(uri);
414 Objects.requireNonNull(callback);
415 int callingUid = Binder.getCallingUid();
416 int callingUserId = handleIncomingUser(userId, callingUid);
417 final long callingIdentity = Binder.clearCallingIdentity();
418 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800419 verifyUserUnlocked(callingUserId);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700420
421 if (systemUsage) {
422 // TODO(b/183031844): Validate that the call comes from the system
423 }
424
Cassie Wang308304c2021-01-21 11:13:49 -0800425 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800426 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700427 impl.reportUsage(
428 packageName, databaseName, namespace, uri,
429 usageTimeMillis, systemUsage);
Cassie Wang308304c2021-01-21 11:13:49 -0800430 invokeCallbackOnResult(
431 callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800432 } catch (Throwable t) {
433 invokeCallbackOnError(callback, t);
434 } finally {
435 Binder.restoreCallingIdentity(callingIdentity);
436 }
437 }
438
439 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800440 public void removeByUri(
Cassie Wang0c62d992021-01-15 14:39:30 -0800441 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800442 @NonNull String databaseName,
443 @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800444 @NonNull List<String> uris,
Terry Wangf2093072020-11-30 04:47:19 -0800445 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800446 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800447 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700448 Preconditions.checkNotNull(databaseName);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700449 Preconditions.checkNotNull(uris);
450 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800451 int callingUid = Binder.getCallingUid();
452 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600453 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700454 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800455 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800456 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800457 AppSearchBatchResult.Builder<String, Void> resultBuilder =
458 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800459 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800460 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700461 for (int i = 0; i < uris.size(); i++) {
462 String uri = uris.get(i);
463 try {
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800464 impl.remove(packageName, databaseName, namespace, uri);
Cassie Wang0c62d992021-01-15 14:39:30 -0800465 resultBuilder.setSuccess(uri, /*result= */ null);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700466 } catch (Throwable t) {
467 resultBuilder.setResult(uri, throwableToFailedResult(t));
468 }
469 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800470 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700471 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800472 invokeCallbackOnError(callback, t);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700473 } finally {
474 Binder.restoreCallingIdentity(callingIdentity);
475 }
476 }
477
478 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -0700479 public void removeByQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800480 @NonNull String packageName,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700481 @NonNull String databaseName,
482 @NonNull String queryExpression,
483 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800484 @UserIdInt int userId,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700485 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800486 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700487 Preconditions.checkNotNull(databaseName);
488 Preconditions.checkNotNull(queryExpression);
489 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800490 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800491 int callingUid = Binder.getCallingUid();
492 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600493 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700494 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800495 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800496 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800497 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800498 mImplInstanceManager.getAppSearchImpl(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800499 impl.removeByQuery(
500 packageName,
501 databaseName,
502 queryExpression,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700503 new SearchSpec(searchSpecBundle));
504 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700505 } catch (Throwable t) {
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700506 invokeCallbackOnError(callback, t);
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700507 } finally {
508 Binder.restoreCallingIdentity(callingIdentity);
509 }
510 }
511
Terry Wangdbd1dca2020-11-03 17:03:56 -0800512 @Override
Terry Wang2da17852020-12-16 19:59:08 -0800513 public void persistToDisk(@UserIdInt int userId) {
514 int callingUid = Binder.getCallingUidOrThrow();
515 int callingUserId = handleIncomingUser(userId, callingUid);
516 final long callingIdentity = Binder.clearCallingIdentity();
517 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800518 verifyUserUnlocked(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800519 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800520 mImplInstanceManager.getAppSearchImpl(callingUserId);
Terry Wang2da17852020-12-16 19:59:08 -0800521 impl.persistToDisk();
522 } catch (Throwable t) {
523 Log.e(TAG, "Unable to persist the data to disk", t);
524 } finally {
525 Binder.restoreCallingIdentity(callingIdentity);
526 }
527 }
528
529 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800530 public void initialize(@UserIdInt int userId, @NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800531 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800532 int callingUid = Binder.getCallingUid();
533 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800534 final long callingIdentity = Binder.clearCallingIdentity();
535 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800536 verifyUserUnlocked(callingUserId);
Terry Wang9d8f4272021-02-04 21:01:10 -0800537 mImplInstanceManager.getOrCreateAppSearchImpl(getContext(), callingUserId);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800538 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
539 } catch (Throwable t) {
540 invokeCallbackOnError(callback, t);
541 } finally {
542 Binder.restoreCallingIdentity(callingIdentity);
543 }
544 }
545
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800546 private void verifyUserUnlocked(int callingUserId) {
Cassie Wang15c86972021-02-09 13:43:25 -0800547 synchronized (mUnlockedUserIdsLocked) {
Pinyao Tingd5c2ed92021-03-18 14:51:54 -0700548 // First, check the local copy.
549 if (mUnlockedUserIdsLocked.contains(callingUserId)) {
550 return;
551 }
552 // If the local copy says the user is locked, check with UM for the actual state,
553 // since the user might just have been unlocked.
554 if (!mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(callingUserId))) {
Cassie Wang15c86972021-02-09 13:43:25 -0800555 throw new IllegalStateException(
556 "User " + callingUserId + " is locked or not running.");
557 }
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800558 }
559 }
560
Cassie Wang0c62d992021-01-15 14:39:30 -0800561 private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) {
562 Preconditions.checkNotNull(callingPackage);
563 if (mPackageManagerInternal.getPackageUid(
564 callingPackage, /*flags=*/ 0, UserHandle.getUserId(callingUid))
565 != callingUid) {
566 throw new SecurityException(
567 "Specified calling package ["
568 + callingPackage
569 + "] does not match the calling uid "
570 + callingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700571 }
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700572 }
573
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800574 /** Invokes the {@link IAppSearchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -0800575 private void invokeCallbackOnResult(
576 IAppSearchResultCallback callback, AppSearchResult<?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800577 try {
578 callback.onResult(result);
579 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800580 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800581 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800582 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800583
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800584 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -0800585 private void invokeCallbackOnResult(
586 IAppSearchBatchResultCallback callback, AppSearchBatchResult<?, ?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800587 try {
588 callback.onResult(result);
589 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800590 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800591 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800592 }
593
594 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800595 * Invokes the {@link IAppSearchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800596 *
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800597 * <p>The throwable is convert to a {@link AppSearchResult};
Terry Wangdbd1dca2020-11-03 17:03:56 -0800598 */
599 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
600 try {
601 callback.onResult(throwableToFailedResult(throwable));
602 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800603 Log.e(TAG, "Unable to send result to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800604 }
605 }
606
607 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800608 * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800609 *
610 * <p>The throwable is converted to {@link ParcelableException}.
611 */
Cassie Wang0c62d992021-01-15 14:39:30 -0800612 private void invokeCallbackOnError(
613 IAppSearchBatchResultCallback callback, Throwable throwable) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800614 try {
Terry Wang9d8f4272021-02-04 21:01:10 -0800615 //TODO(b/175067650) verify ParcelableException could propagate throwable correctly.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800616 callback.onSystemError(new ParcelableException(throwable));
617 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800618 Log.e(TAG, "Unable to send error to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800619 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800620 }
Terry Wangfebbead2019-10-17 17:05:18 -0700621 }
Terry Wangf2093072020-11-30 04:47:19 -0800622
Cassie Wang0c62d992021-01-15 14:39:30 -0800623 // TODO(b/173553485) verifying that the caller has permission to access target user's data
624 // TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast
625 // TODO(b/173553485) Implement SystemService.onUserStopping()
Terry Wangf2093072020-11-30 04:47:19 -0800626 private static int handleIncomingUser(@UserIdInt int userId, int callingUid) {
627 int callingPid = Binder.getCallingPid();
Cassie Wang0c62d992021-01-15 14:39:30 -0800628 return ActivityManager.handleIncomingUser(
629 callingPid,
630 callingUid,
631 userId,
632 /*allowAll=*/ false,
633 /*requireFull=*/ false,
634 /*name=*/ null,
635 /*callerPackage=*/ null);
Terry Wangf2093072020-11-30 04:47:19 -0800636 }
Terry Wangfebbead2019-10-17 17:05:18 -0700637}