blob: 991dda7cacd2d2866aa477efdb4ef9bb1ab27927 [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;
Terry Wang623e3b02021-02-02 20:27:33 -080024import android.app.appsearch.AppSearchMigrationHelper;
Alexander Dorokhine969f4462020-03-05 15:54:19 -080025import android.app.appsearch.AppSearchResult;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070026import android.app.appsearch.AppSearchSchema;
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070027import android.app.appsearch.GenericDocument;
Alexander Dorokhine9795b512021-03-23 22:06:59 -070028import android.app.appsearch.GetSchemaResponse;
Terry Wangdbd1dca2020-11-03 17:03:56 -080029import android.app.appsearch.IAppSearchBatchResultCallback;
Terry Wangfebbead2019-10-17 17:05:18 -070030import android.app.appsearch.IAppSearchManager;
Terry Wangdbd1dca2020-11-03 17:03:56 -080031import android.app.appsearch.IAppSearchResultCallback;
Alexander Dorokhineab789062021-01-11 21:00:00 -080032import android.app.appsearch.PackageIdentifier;
Terry Wang26b9e5c2020-10-23 02:05:01 -070033import android.app.appsearch.SearchResultPage;
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -070034import android.app.appsearch.SearchSpec;
Terry Wang623e3b02021-02-02 20:27:33 -080035import android.app.appsearch.SetSchemaResponse;
Cassie Wang8f0df492021-03-24 09:23:18 -070036import android.app.appsearch.StorageInfo;
Terry Wangfebbead2019-10-17 17:05:18 -070037import android.content.Context;
Cassie Wang0c62d992021-01-15 14:39:30 -080038import android.content.pm.PackageManagerInternal;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080039import android.os.Binder;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070040import android.os.Bundle;
Terry Wang623e3b02021-02-02 20:27:33 -080041import android.os.ParcelFileDescriptor;
Terry Wangdbd1dca2020-11-03 17:03:56 -080042import android.os.ParcelableException;
43import android.os.RemoteException;
Cassie Wang0c62d992021-01-15 14:39:30 -080044import android.os.UserHandle;
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070045import android.os.UserManager;
Alexander Dorokhineab789062021-01-11 21:00:00 -080046import android.util.ArrayMap;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080047import android.util.ArraySet;
Terry Wangdbd1dca2020-11-03 17:03:56 -080048import android.util.Log;
Terry Wangfebbead2019-10-17 17:05:18 -070049
Cassie Wang15c86972021-02-09 13:43:25 -080050import com.android.internal.annotations.GuardedBy;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080051import com.android.internal.util.Preconditions;
Cassie Wang0c62d992021-01-15 14:39:30 -080052import com.android.server.LocalServices;
Terry Wangfebbead2019-10-17 17:05:18 -070053import com.android.server.SystemService;
Alexander Dorokhinef660d8f2020-10-29 22:37:00 -070054import com.android.server.appsearch.external.localstorage.AppSearchImpl;
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080055
Terry Wang623e3b02021-02-02 20:27:33 -080056import java.io.DataInputStream;
57import java.io.DataOutputStream;
58import java.io.EOFException;
59import java.io.FileInputStream;
60import java.io.FileOutputStream;
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080061import java.util.ArrayList;
Alexander Dorokhine18465842020-01-21 01:08:57 -080062import java.util.List;
Alexander Dorokhineab789062021-01-11 21:00:00 -080063import java.util.Map;
Alexander Dorokhined18f8842021-01-20 15:26:13 -080064import java.util.Objects;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080065import java.util.Set;
Alexander Dorokhine18465842020-01-21 01:08:57 -080066
Cassie Wang0c62d992021-01-15 14:39:30 -080067/** TODO(b/142567528): add comments when implement this class */
Terry Wangfebbead2019-10-17 17:05:18 -070068public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070069 private static final String TAG = "AppSearchManagerService";
Cassie Wang0c62d992021-01-15 14:39:30 -080070 private PackageManagerInternal mPackageManagerInternal;
Cassie Wang21c2d6a2021-01-20 23:59:55 -080071 private ImplInstanceManager mImplInstanceManager;
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070072 private UserManager mUserManager;
Terry Wangfebbead2019-10-17 17:05:18 -070073
Cassie Wang15c86972021-02-09 13:43:25 -080074 // Cache of unlocked user ids so we don't have to query UserManager service each time. The
75 // "locked" suffix refers to the fact that access to the field should be locked; unrelated to
76 // the unlocked status of user ids.
77 @GuardedBy("mUnlockedUserIdsLocked")
78 private final Set<Integer> mUnlockedUserIdsLocked = new ArraySet<>();
Cassie Wang9ba9ae12021-02-01 16:39:37 -080079
Terry Wangfebbead2019-10-17 17:05:18 -070080 public AppSearchManagerService(Context context) {
81 super(context);
82 }
83
84 @Override
85 public void onStart() {
86 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
Cassie Wang0c62d992021-01-15 14:39:30 -080087 mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
Cassie Wang308304c2021-01-21 11:13:49 -080088 mImplInstanceManager = ImplInstanceManager.getInstance(getContext());
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070089 mUserManager = getContext().getSystemService(UserManager.class);
Terry Wangfebbead2019-10-17 17:05:18 -070090 }
91
Cassie Wang9ba9ae12021-02-01 16:39:37 -080092 @Override
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070093 public void onUserUnlocking(@NonNull TargetUser user) {
Cassie Wang15c86972021-02-09 13:43:25 -080094 synchronized (mUnlockedUserIdsLocked) {
95 mUnlockedUserIdsLocked.add(user.getUserIdentifier());
96 }
Cassie Wang9ba9ae12021-02-01 16:39:37 -080097 }
98
Terry Wangfebbead2019-10-17 17:05:18 -070099 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800100 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800101 public void setSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800102 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700103 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700104 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine315cca62021-03-04 12:34:41 -0800105 @NonNull List<String> schemasNotDisplayedBySystem,
Alexander Dorokhineab789062021-01-11 21:00:00 -0800106 @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800107 boolean forceOverride,
Terry Wangf2093072020-11-30 04:47:19 -0800108 @UserIdInt int userId,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700109 int schemaVersion,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800110 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800111 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700112 Preconditions.checkNotNull(databaseName);
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700113 Preconditions.checkNotNull(schemaBundles);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800114 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800115 int callingUid = Binder.getCallingUid();
116 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600117 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800118 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800119 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800120 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine6a99f942020-12-04 02:57:22 -0800121 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700122 for (int i = 0; i < schemaBundles.size(); i++) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700123 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700124 }
Alexander Dorokhineab789062021-01-11 21:00:00 -0800125 Map<String, List<PackageIdentifier>> schemasPackageAccessible =
126 new ArrayMap<>(schemasPackageAccessibleBundles.size());
127 for (Map.Entry<String, List<Bundle>> entry :
128 schemasPackageAccessibleBundles.entrySet()) {
129 List<PackageIdentifier> packageIdentifiers =
130 new ArrayList<>(entry.getValue().size());
Cassie Wange8569db2021-02-05 00:05:25 -0800131 for (int i = 0; i < entry.getValue().size(); i++) {
Alexander Dorokhineab789062021-01-11 21:00:00 -0800132 packageIdentifiers.add(new PackageIdentifier(entry.getValue().get(i)));
133 }
134 schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
135 }
Terry Wang9d8f4272021-02-04 21:01:10 -0800136 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUserId);
Terry Wang623e3b02021-02-02 20:27:33 -0800137 SetSchemaResponse setSchemaResponse = impl.setSchema(
Alexander Dorokhineab789062021-01-11 21:00:00 -0800138 packageName,
139 databaseName,
140 schemas,
Alexander Dorokhine315cca62021-03-04 12:34:41 -0800141 schemasNotDisplayedBySystem,
Alexander Dorokhineab789062021-01-11 21:00:00 -0800142 schemasPackageAccessible,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700143 forceOverride,
144 schemaVersion);
Terry Wang623e3b02021-02-02 20:27:33 -0800145 invokeCallbackOnResult(callback,
146 AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800147 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800148 invokeCallbackOnError(callback, t);
Alexander Dorokhine270d4f12020-01-15 17:24:35 -0800149 } finally {
150 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800151 }
152 }
153
154 @Override
Terry Wang83a24932020-12-09 21:00:18 -0800155 public void getSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800156 @NonNull String packageName,
Terry Wang83a24932020-12-09 21:00:18 -0800157 @NonNull String databaseName,
Terry Wangf2093072020-11-30 04:47:19 -0800158 @UserIdInt int userId,
Terry Wang83a24932020-12-09 21:00:18 -0800159 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800160 Preconditions.checkNotNull(packageName);
Terry Wang83a24932020-12-09 21:00:18 -0800161 Preconditions.checkNotNull(databaseName);
162 Preconditions.checkNotNull(callback);
163 int callingUid = Binder.getCallingUidOrThrow();
Terry Wangf2093072020-11-30 04:47:19 -0800164 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wang83a24932020-12-09 21:00:18 -0800165 final long callingIdentity = Binder.clearCallingIdentity();
166 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800167 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800168 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800169 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800170 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700171 GetSchemaResponse response = impl.getSchema(packageName, databaseName);
Cassie Wang0c62d992021-01-15 14:39:30 -0800172 invokeCallbackOnResult(
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700173 callback, AppSearchResult.newSuccessfulResult(response.getBundle()));
174 } catch (Throwable t) {
175 invokeCallbackOnError(callback, t);
176 } finally {
177 Binder.restoreCallingIdentity(callingIdentity);
178 }
179 }
180
181 @Override
182 public void getNamespaces(
183 @NonNull String packageName,
184 @NonNull String databaseName,
185 @UserIdInt int userId,
186 @NonNull IAppSearchResultCallback callback) {
187 Preconditions.checkNotNull(packageName);
188 Preconditions.checkNotNull(databaseName);
189 Preconditions.checkNotNull(callback);
190 int callingUid = Binder.getCallingUidOrThrow();
191 int callingUserId = handleIncomingUser(userId, callingUid);
192 final long callingIdentity = Binder.clearCallingIdentity();
193 try {
194 verifyUserUnlocked(callingUserId);
195 verifyCallingPackage(callingUid, packageName);
196 AppSearchImpl impl =
197 mImplInstanceManager.getAppSearchImpl(callingUserId);
198 List<String> namespaces = impl.getNamespaces(packageName, databaseName);
199 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(namespaces));
Terry Wang83a24932020-12-09 21:00:18 -0800200 } catch (Throwable t) {
201 invokeCallbackOnError(callback, t);
202 } finally {
203 Binder.restoreCallingIdentity(callingIdentity);
204 }
205 }
206
207 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -0800208 public void putDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800209 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700210 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700211 @NonNull List<Bundle> documentBundles,
Terry Wangf2093072020-11-30 04:47:19 -0800212 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800213 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800214 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700215 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700216 Preconditions.checkNotNull(documentBundles);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800217 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800218 int callingUid = Binder.getCallingUid();
219 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600220 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800221 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800222 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800223 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800224 AppSearchBatchResult.Builder<String, Void> resultBuilder =
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800225 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800226 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800227 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700228 for (int i = 0; i < documentBundles.size(); i++) {
229 GenericDocument document = new GenericDocument(documentBundles.get(i));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800230 try {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800231 // TODO(b/173451571): reduce burden of binder thread by enqueue request onto
232 // a separate thread.
Alexander Dorokhine3488b9a2021-03-16 23:57:49 -0700233 impl.putDocument(packageName, databaseName, document, /*logger=*/ null);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700234 resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800235 } catch (Throwable t) {
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800236 resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800237 }
238 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800239 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800240 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800241 invokeCallbackOnError(callback, t);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800242 } finally {
243 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800244 }
245 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800246
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800247 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800248 public void getDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800249 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800250 @NonNull String databaseName,
251 @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800252 @NonNull List<String> uris,
Alexander Dorokhine87cdd152021-01-20 15:41:25 -0800253 @NonNull Map<String, List<String>> typePropertyPaths,
Terry Wangf2093072020-11-30 04:47:19 -0800254 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800255 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800256 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700257 Preconditions.checkNotNull(databaseName);
258 Preconditions.checkNotNull(namespace);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800259 Preconditions.checkNotNull(uris);
260 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800261 int callingUid = Binder.getCallingUid();
262 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600263 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800264 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800265 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800266 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700267 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800268 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800269 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800270 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800271 for (int i = 0; i < uris.size(); i++) {
272 String uri = uris.get(i);
273 try {
Cassie Wang308304c2021-01-21 11:13:49 -0800274 GenericDocument document =
275 impl.getDocument(
276 packageName,
277 databaseName,
278 namespace,
279 uri,
280 typePropertyPaths);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700281 resultBuilder.setSuccess(uri, document.getBundle());
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800282 } catch (Throwable t) {
283 resultBuilder.setResult(uri, throwableToFailedResult(t));
284 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800285 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800286 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800287 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800288 invokeCallbackOnError(callback, t);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800289 } finally {
290 Binder.restoreCallingIdentity(callingIdentity);
291 }
292 }
293
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800294 // TODO(sidchhabra): Do this in a threadpool.
295 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800296 public void query(
Cassie Wang0c62d992021-01-15 14:39:30 -0800297 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700298 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700299 @NonNull String queryExpression,
300 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800301 @UserIdInt int userId,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700302 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800303 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700304 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700305 Preconditions.checkNotNull(queryExpression);
306 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800307 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800308 int callingUid = Binder.getCallingUid();
309 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600310 final long callingIdentity = Binder.clearCallingIdentity();
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800311 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800312 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800313 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800314 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800315 mImplInstanceManager.getAppSearchImpl(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800316 SearchResultPage searchResultPage =
317 impl.query(
318 packageName,
319 databaseName,
320 queryExpression,
321 new SearchSpec(searchSpecBundle));
322 invokeCallbackOnResult(
323 callback,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700324 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800325 } catch (Throwable t) {
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700326 invokeCallbackOnError(callback, t);
327 } finally {
328 Binder.restoreCallingIdentity(callingIdentity);
329 }
330 }
331
Terry Wangf2093072020-11-30 04:47:19 -0800332 @Override
Terry Wangbfbfcac2020-11-06 15:46:44 -0800333 public void globalQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800334 @NonNull String packageName,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800335 @NonNull String queryExpression,
336 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800337 @UserIdInt int userId,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800338 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800339 Preconditions.checkNotNull(packageName);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800340 Preconditions.checkNotNull(queryExpression);
341 Preconditions.checkNotNull(searchSpecBundle);
342 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800343 int callingUid = Binder.getCallingUid();
344 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800345 final long callingIdentity = Binder.clearCallingIdentity();
346 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800347 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800348 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800349 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800350 mImplInstanceManager.getAppSearchImpl(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800351 SearchResultPage searchResultPage =
352 impl.globalQuery(
353 queryExpression,
354 new SearchSpec(searchSpecBundle),
355 packageName,
356 callingUid);
Cassie Wang0c62d992021-01-15 14:39:30 -0800357 invokeCallbackOnResult(
358 callback,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800359 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
360 } catch (Throwable t) {
361 invokeCallbackOnError(callback, t);
362 } finally {
363 Binder.restoreCallingIdentity(callingIdentity);
364 }
365 }
366
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700367 @Override
Cassie Wang0c62d992021-01-15 14:39:30 -0800368 public void getNextPage(
369 long nextPageToken,
370 @UserIdInt int userId,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700371 @NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800372 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800373 int callingUid = Binder.getCallingUid();
374 int callingUserId = handleIncomingUser(userId, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700375 final long callingIdentity = Binder.clearCallingIdentity();
376 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
377 // opened it
378 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800379 verifyUserUnlocked(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800380 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800381 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700382 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
Cassie Wang0c62d992021-01-15 14:39:30 -0800383 invokeCallbackOnResult(
384 callback,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700385 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
386 } catch (Throwable t) {
387 invokeCallbackOnError(callback, t);
388 } finally {
389 Binder.restoreCallingIdentity(callingIdentity);
390 }
391 }
392
393 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800394 public void invalidateNextPageToken(long nextPageToken, @UserIdInt int userId) {
395 int callingUid = Binder.getCallingUid();
396 int callingUserId = handleIncomingUser(userId, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700397 final long callingIdentity = Binder.clearCallingIdentity();
398 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800399 verifyUserUnlocked(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800400 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800401 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700402 impl.invalidateNextPageToken(nextPageToken);
403 } catch (Throwable t) {
Terry Wang2da17852020-12-16 19:59:08 -0800404 Log.e(TAG, "Unable to invalidate the query page token", t);
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800405 } finally {
406 Binder.restoreCallingIdentity(callingIdentity);
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800407 }
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800408 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800409
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700410 @Override
Terry Wang623e3b02021-02-02 20:27:33 -0800411 public void writeQueryResultsToFile(
412 @NonNull String packageName,
413 @NonNull String databaseName,
414 @NonNull ParcelFileDescriptor fileDescriptor,
415 @NonNull String queryExpression,
416 @NonNull Bundle searchSpecBundle,
417 @UserIdInt int userId,
418 @NonNull IAppSearchResultCallback callback) {
419 int callingUid = Binder.getCallingUid();
420 int callingUserId = handleIncomingUser(userId, callingUid);
421 final long callingIdentity = Binder.clearCallingIdentity();
422 try {
423 verifyCallingPackage(callingUid, packageName);
424 AppSearchImpl impl =
425 mImplInstanceManager.getAppSearchImpl(callingUserId);
426 // we don't need to append the file. The file is always brand new.
427 try (DataOutputStream outputStream = new DataOutputStream(
428 new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
429 SearchResultPage searchResultPage = impl.query(
430 packageName,
431 databaseName,
432 queryExpression,
433 new SearchSpec(searchSpecBundle));
434 while (!searchResultPage.getResults().isEmpty()) {
435 for (int i = 0; i < searchResultPage.getResults().size(); i++) {
436 AppSearchMigrationHelper.writeBundleToOutputStream(
437 outputStream, searchResultPage.getResults().get(i)
438 .getGenericDocument().getBundle());
439 }
440 searchResultPage = impl.getNextPage(searchResultPage.getNextPageToken());
441 }
442 }
443 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
444 } catch (Throwable t) {
445 invokeCallbackOnError(callback, t);
446 } finally {
447 Binder.restoreCallingIdentity(callingIdentity);
448 }
449 }
450
451 @Override
452 public void putDocumentsFromFile(
453 @NonNull String packageName,
454 @NonNull String databaseName,
455 @NonNull ParcelFileDescriptor fileDescriptor,
456 @UserIdInt int userId,
457 @NonNull IAppSearchResultCallback callback) {
458 int callingUid = Binder.getCallingUid();
459 int callingUserId = handleIncomingUser(userId, callingUid);
460 final long callingIdentity = Binder.clearCallingIdentity();
461 try {
462 verifyCallingPackage(callingUid, packageName);
463 AppSearchImpl impl =
464 mImplInstanceManager.getAppSearchImpl(callingUserId);
465
466 GenericDocument document;
467 ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
468 try (DataInputStream inputStream = new DataInputStream(
469 new FileInputStream(fileDescriptor.getFileDescriptor()))) {
470 while (true) {
471 try {
472 document = AppSearchMigrationHelper
473 .readDocumentFromInputStream(inputStream);
474 } catch (EOFException e) {
475 // nothing wrong, we just finish the reading.
476 break;
477 }
478 try {
479 impl.putDocument(packageName, databaseName, document, /*logger=*/ null);
480 } catch (Throwable t) {
481 migrationFailureBundles.add(
482 new SetSchemaResponse.MigrationFailure.Builder()
483 .setNamespace(document.getNamespace())
484 .setSchemaType(document.getSchemaType())
485 .setUri(document.getUri())
486 .setAppSearchResult(
487 AppSearchResult.throwableToFailedResult(t))
488 .build().getBundle());
489 }
490 }
491 }
492 impl.persistToDisk();
493 invokeCallbackOnResult(callback,
494 AppSearchResult.newSuccessfulResult(migrationFailureBundles));
495 } catch (Throwable t) {
496 invokeCallbackOnError(callback, t);
497 } finally {
498 Binder.restoreCallingIdentity(callingIdentity);
499 }
500 }
501
502 @Override
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800503 public void reportUsage(
504 @NonNull String packageName,
505 @NonNull String databaseName,
506 @NonNull String namespace,
507 @NonNull String uri,
508 long usageTimeMillis,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700509 boolean systemUsage,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800510 @UserIdInt int userId,
511 @NonNull IAppSearchResultCallback callback) {
512 Objects.requireNonNull(databaseName);
513 Objects.requireNonNull(namespace);
514 Objects.requireNonNull(uri);
515 Objects.requireNonNull(callback);
516 int callingUid = Binder.getCallingUid();
517 int callingUserId = handleIncomingUser(userId, callingUid);
518 final long callingIdentity = Binder.clearCallingIdentity();
519 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800520 verifyUserUnlocked(callingUserId);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700521
522 if (systemUsage) {
523 // TODO(b/183031844): Validate that the call comes from the system
524 }
525
Cassie Wang308304c2021-01-21 11:13:49 -0800526 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800527 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700528 impl.reportUsage(
529 packageName, databaseName, namespace, uri,
530 usageTimeMillis, systemUsage);
Cassie Wang308304c2021-01-21 11:13:49 -0800531 invokeCallbackOnResult(
532 callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800533 } catch (Throwable t) {
534 invokeCallbackOnError(callback, t);
535 } finally {
536 Binder.restoreCallingIdentity(callingIdentity);
537 }
538 }
539
540 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800541 public void removeByUri(
Cassie Wang0c62d992021-01-15 14:39:30 -0800542 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800543 @NonNull String databaseName,
544 @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800545 @NonNull List<String> uris,
Terry Wangf2093072020-11-30 04:47:19 -0800546 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800547 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800548 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700549 Preconditions.checkNotNull(databaseName);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700550 Preconditions.checkNotNull(uris);
551 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800552 int callingUid = Binder.getCallingUid();
553 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600554 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700555 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800556 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800557 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800558 AppSearchBatchResult.Builder<String, Void> resultBuilder =
559 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800560 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800561 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700562 for (int i = 0; i < uris.size(); i++) {
563 String uri = uris.get(i);
564 try {
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800565 impl.remove(packageName, databaseName, namespace, uri);
Cassie Wang0c62d992021-01-15 14:39:30 -0800566 resultBuilder.setSuccess(uri, /*result= */ null);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700567 } catch (Throwable t) {
568 resultBuilder.setResult(uri, throwableToFailedResult(t));
569 }
570 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800571 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700572 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800573 invokeCallbackOnError(callback, t);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700574 } finally {
575 Binder.restoreCallingIdentity(callingIdentity);
576 }
577 }
578
579 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -0700580 public void removeByQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800581 @NonNull String packageName,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700582 @NonNull String databaseName,
583 @NonNull String queryExpression,
584 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800585 @UserIdInt int userId,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700586 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800587 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700588 Preconditions.checkNotNull(databaseName);
589 Preconditions.checkNotNull(queryExpression);
590 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800591 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800592 int callingUid = Binder.getCallingUid();
593 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600594 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700595 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800596 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800597 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800598 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800599 mImplInstanceManager.getAppSearchImpl(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800600 impl.removeByQuery(
601 packageName,
602 databaseName,
603 queryExpression,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700604 new SearchSpec(searchSpecBundle));
605 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700606 } catch (Throwable t) {
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700607 invokeCallbackOnError(callback, t);
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700608 } finally {
609 Binder.restoreCallingIdentity(callingIdentity);
610 }
611 }
612
Terry Wangdbd1dca2020-11-03 17:03:56 -0800613 @Override
Cassie Wang8f0df492021-03-24 09:23:18 -0700614 public void getStorageInfo(
615 @NonNull String packageName,
616 @NonNull String databaseName,
617 @UserIdInt int userId,
618 @NonNull IAppSearchResultCallback callback) {
619 Preconditions.checkNotNull(packageName);
620 Preconditions.checkNotNull(databaseName);
621 Preconditions.checkNotNull(callback);
622 int callingUid = Binder.getCallingUid();
623 int callingUserId = handleIncomingUser(userId, callingUid);
624 final long callingIdentity = Binder.clearCallingIdentity();
625 try {
626 verifyUserUnlocked(callingUserId);
627 verifyCallingPackage(callingUid, packageName);
628 AppSearchImpl impl =
629 mImplInstanceManager.getAppSearchImpl(callingUserId);
630 StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName, databaseName);
631 Bundle storageInfoBundle = storageInfo.getBundle();
632 invokeCallbackOnResult(
633 callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
634 } catch (Throwable t) {
635 invokeCallbackOnError(callback, t);
636 } finally {
637 Binder.restoreCallingIdentity(callingIdentity);
638 }
639 }
640
641 @Override
Terry Wang2da17852020-12-16 19:59:08 -0800642 public void persistToDisk(@UserIdInt int userId) {
643 int callingUid = Binder.getCallingUidOrThrow();
644 int callingUserId = handleIncomingUser(userId, callingUid);
645 final long callingIdentity = Binder.clearCallingIdentity();
646 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800647 verifyUserUnlocked(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800648 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800649 mImplInstanceManager.getAppSearchImpl(callingUserId);
Terry Wang2da17852020-12-16 19:59:08 -0800650 impl.persistToDisk();
651 } catch (Throwable t) {
652 Log.e(TAG, "Unable to persist the data to disk", t);
653 } finally {
654 Binder.restoreCallingIdentity(callingIdentity);
655 }
656 }
657
658 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800659 public void initialize(@UserIdInt int userId, @NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800660 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800661 int callingUid = Binder.getCallingUid();
662 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800663 final long callingIdentity = Binder.clearCallingIdentity();
664 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800665 verifyUserUnlocked(callingUserId);
Terry Wang9d8f4272021-02-04 21:01:10 -0800666 mImplInstanceManager.getOrCreateAppSearchImpl(getContext(), callingUserId);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800667 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
668 } catch (Throwable t) {
669 invokeCallbackOnError(callback, t);
670 } finally {
671 Binder.restoreCallingIdentity(callingIdentity);
672 }
673 }
674
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800675 private void verifyUserUnlocked(int callingUserId) {
Cassie Wang15c86972021-02-09 13:43:25 -0800676 synchronized (mUnlockedUserIdsLocked) {
Pinyao Tingd5c2ed92021-03-18 14:51:54 -0700677 // First, check the local copy.
678 if (mUnlockedUserIdsLocked.contains(callingUserId)) {
679 return;
680 }
681 // If the local copy says the user is locked, check with UM for the actual state,
682 // since the user might just have been unlocked.
683 if (!mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(callingUserId))) {
Cassie Wang15c86972021-02-09 13:43:25 -0800684 throw new IllegalStateException(
685 "User " + callingUserId + " is locked or not running.");
686 }
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800687 }
688 }
689
Cassie Wang0c62d992021-01-15 14:39:30 -0800690 private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) {
691 Preconditions.checkNotNull(callingPackage);
692 if (mPackageManagerInternal.getPackageUid(
693 callingPackage, /*flags=*/ 0, UserHandle.getUserId(callingUid))
694 != callingUid) {
695 throw new SecurityException(
696 "Specified calling package ["
697 + callingPackage
698 + "] does not match the calling uid "
699 + callingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700700 }
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700701 }
702
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800703 /** Invokes the {@link IAppSearchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -0800704 private void invokeCallbackOnResult(
705 IAppSearchResultCallback callback, AppSearchResult<?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800706 try {
707 callback.onResult(result);
708 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800709 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800710 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800711 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800712
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800713 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -0800714 private void invokeCallbackOnResult(
715 IAppSearchBatchResultCallback callback, AppSearchBatchResult<?, ?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800716 try {
717 callback.onResult(result);
718 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800719 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800720 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800721 }
722
723 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800724 * Invokes the {@link IAppSearchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800725 *
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800726 * <p>The throwable is convert to a {@link AppSearchResult};
Terry Wangdbd1dca2020-11-03 17:03:56 -0800727 */
728 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
729 try {
730 callback.onResult(throwableToFailedResult(throwable));
731 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800732 Log.e(TAG, "Unable to send result to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800733 }
734 }
735
736 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800737 * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800738 *
739 * <p>The throwable is converted to {@link ParcelableException}.
740 */
Cassie Wang0c62d992021-01-15 14:39:30 -0800741 private void invokeCallbackOnError(
742 IAppSearchBatchResultCallback callback, Throwable throwable) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800743 try {
Terry Wang9d8f4272021-02-04 21:01:10 -0800744 //TODO(b/175067650) verify ParcelableException could propagate throwable correctly.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800745 callback.onSystemError(new ParcelableException(throwable));
746 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800747 Log.e(TAG, "Unable to send error to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800748 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800749 }
Terry Wangfebbead2019-10-17 17:05:18 -0700750 }
Terry Wangf2093072020-11-30 04:47:19 -0800751
Cassie Wang0c62d992021-01-15 14:39:30 -0800752 // TODO(b/173553485) verifying that the caller has permission to access target user's data
753 // TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast
754 // TODO(b/173553485) Implement SystemService.onUserStopping()
Terry Wangf2093072020-11-30 04:47:19 -0800755 private static int handleIncomingUser(@UserIdInt int userId, int callingUid) {
756 int callingPid = Binder.getCallingPid();
Cassie Wang0c62d992021-01-15 14:39:30 -0800757 return ActivityManager.handleIncomingUser(
758 callingPid,
759 callingUid,
760 userId,
761 /*allowAll=*/ false,
762 /*requireFull=*/ false,
763 /*name=*/ null,
764 /*callerPackage=*/ null);
Terry Wangf2093072020-11-30 04:47:19 -0800765 }
Terry Wangfebbead2019-10-17 17:05:18 -0700766}