blob: 68c906948f12550546630c97846cabdabe5dc694 [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;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080041import android.util.ArraySet;
Terry Wangdbd1dca2020-11-03 17:03:56 -080042import android.util.Log;
Terry Wangfebbead2019-10-17 17:05:18 -070043
Cassie Wang15c86972021-02-09 13:43:25 -080044import com.android.internal.annotations.GuardedBy;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080045import com.android.internal.util.Preconditions;
Cassie Wang0c62d992021-01-15 14:39:30 -080046import com.android.server.LocalServices;
Terry Wangfebbead2019-10-17 17:05:18 -070047import com.android.server.SystemService;
Alexander Dorokhinef660d8f2020-10-29 22:37:00 -070048import com.android.server.appsearch.external.localstorage.AppSearchImpl;
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080049
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080050import java.util.ArrayList;
Alexander Dorokhine18465842020-01-21 01:08:57 -080051import java.util.List;
Alexander Dorokhineab789062021-01-11 21:00:00 -080052import java.util.Map;
Alexander Dorokhined18f8842021-01-20 15:26:13 -080053import java.util.Objects;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080054import java.util.Set;
Alexander Dorokhine18465842020-01-21 01:08:57 -080055
Cassie Wang0c62d992021-01-15 14:39:30 -080056/** TODO(b/142567528): add comments when implement this class */
Terry Wangfebbead2019-10-17 17:05:18 -070057public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070058 private static final String TAG = "AppSearchManagerService";
Cassie Wang0c62d992021-01-15 14:39:30 -080059 private PackageManagerInternal mPackageManagerInternal;
Cassie Wang21c2d6a2021-01-20 23:59:55 -080060 private ImplInstanceManager mImplInstanceManager;
Terry Wangfebbead2019-10-17 17:05:18 -070061
Cassie Wang15c86972021-02-09 13:43:25 -080062 // Cache of unlocked user ids so we don't have to query UserManager service each time. The
63 // "locked" suffix refers to the fact that access to the field should be locked; unrelated to
64 // the unlocked status of user ids.
65 @GuardedBy("mUnlockedUserIdsLocked")
66 private final Set<Integer> mUnlockedUserIdsLocked = new ArraySet<>();
Cassie Wang9ba9ae12021-02-01 16:39:37 -080067
Terry Wangfebbead2019-10-17 17:05:18 -070068 public AppSearchManagerService(Context context) {
69 super(context);
70 }
71
72 @Override
73 public void onStart() {
74 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
Cassie Wang0c62d992021-01-15 14:39:30 -080075 mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
Cassie Wang308304c2021-01-21 11:13:49 -080076 mImplInstanceManager = ImplInstanceManager.getInstance(getContext());
Terry Wangfebbead2019-10-17 17:05:18 -070077 }
78
Cassie Wang9ba9ae12021-02-01 16:39:37 -080079 @Override
80 public void onUserUnlocked(@NonNull TargetUser user) {
Cassie Wang15c86972021-02-09 13:43:25 -080081 synchronized (mUnlockedUserIdsLocked) {
82 mUnlockedUserIdsLocked.add(user.getUserIdentifier());
83 }
Cassie Wang9ba9ae12021-02-01 16:39:37 -080084 }
85
Terry Wangfebbead2019-10-17 17:05:18 -070086 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080087 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -080088 public void setSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -080089 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -070090 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070091 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080092 @NonNull List<String> schemasNotPlatformSurfaceable,
Alexander Dorokhineab789062021-01-11 21:00:00 -080093 @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -080094 boolean forceOverride,
Terry Wangf2093072020-11-30 04:47:19 -080095 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -080096 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -080097 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -070098 Preconditions.checkNotNull(databaseName);
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070099 Preconditions.checkNotNull(schemaBundles);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800100 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800101 int callingUid = Binder.getCallingUid();
102 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600103 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800104 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800105 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800106 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine6a99f942020-12-04 02:57:22 -0800107 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700108 for (int i = 0; i < schemaBundles.size(); i++) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700109 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700110 }
Alexander Dorokhineab789062021-01-11 21:00:00 -0800111 Map<String, List<PackageIdentifier>> schemasPackageAccessible =
112 new ArrayMap<>(schemasPackageAccessibleBundles.size());
113 for (Map.Entry<String, List<Bundle>> entry :
114 schemasPackageAccessibleBundles.entrySet()) {
115 List<PackageIdentifier> packageIdentifiers =
116 new ArrayList<>(entry.getValue().size());
Cassie Wange8569db2021-02-05 00:05:25 -0800117 for (int i = 0; i < entry.getValue().size(); i++) {
Alexander Dorokhineab789062021-01-11 21:00:00 -0800118 packageIdentifiers.add(new PackageIdentifier(entry.getValue().get(i)));
119 }
120 schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
121 }
Terry Wang9d8f4272021-02-04 21:01:10 -0800122 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhineab789062021-01-11 21:00:00 -0800123 impl.setSchema(
124 packageName,
125 databaseName,
126 schemas,
127 schemasNotPlatformSurfaceable,
128 schemasPackageAccessible,
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800129 forceOverride);
Cassie Wang0c62d992021-01-15 14:39:30 -0800130 invokeCallbackOnResult(
131 callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800132 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800133 invokeCallbackOnError(callback, t);
Alexander Dorokhine270d4f12020-01-15 17:24:35 -0800134 } finally {
135 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800136 }
137 }
138
139 @Override
Terry Wang83a24932020-12-09 21:00:18 -0800140 public void getSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800141 @NonNull String packageName,
Terry Wang83a24932020-12-09 21:00:18 -0800142 @NonNull String databaseName,
Terry Wangf2093072020-11-30 04:47:19 -0800143 @UserIdInt int userId,
Terry Wang83a24932020-12-09 21:00:18 -0800144 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800145 Preconditions.checkNotNull(packageName);
Terry Wang83a24932020-12-09 21:00:18 -0800146 Preconditions.checkNotNull(databaseName);
147 Preconditions.checkNotNull(callback);
148 int callingUid = Binder.getCallingUidOrThrow();
Terry Wangf2093072020-11-30 04:47:19 -0800149 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wang83a24932020-12-09 21:00:18 -0800150 final long callingIdentity = Binder.clearCallingIdentity();
151 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800152 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800153 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800154 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800155 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800156 List<AppSearchSchema> schemas = impl.getSchema(packageName, databaseName);
Terry Wang83a24932020-12-09 21:00:18 -0800157 List<Bundle> schemaBundles = new ArrayList<>(schemas.size());
158 for (int i = 0; i < schemas.size(); i++) {
159 schemaBundles.add(schemas.get(i).getBundle());
160 }
Cassie Wang0c62d992021-01-15 14:39:30 -0800161 invokeCallbackOnResult(
162 callback, AppSearchResult.newSuccessfulResult(schemaBundles));
Terry Wang83a24932020-12-09 21:00:18 -0800163 } catch (Throwable t) {
164 invokeCallbackOnError(callback, t);
165 } finally {
166 Binder.restoreCallingIdentity(callingIdentity);
167 }
168 }
169
170 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -0800171 public void putDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800172 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700173 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700174 @NonNull List<Bundle> documentBundles,
Terry Wangf2093072020-11-30 04:47:19 -0800175 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800176 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800177 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700178 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700179 Preconditions.checkNotNull(documentBundles);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800180 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800181 int callingUid = Binder.getCallingUid();
182 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600183 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800184 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800185 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800186 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800187 AppSearchBatchResult.Builder<String, Void> resultBuilder =
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800188 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800189 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800190 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700191 for (int i = 0; i < documentBundles.size(); i++) {
192 GenericDocument document = new GenericDocument(documentBundles.get(i));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800193 try {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800194 // TODO(b/173451571): reduce burden of binder thread by enqueue request onto
195 // a separate thread.
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800196 impl.putDocument(packageName, databaseName, document);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700197 resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800198 } catch (Throwable t) {
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800199 resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800200 }
201 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800202 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800203 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800204 invokeCallbackOnError(callback, t);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800205 } finally {
206 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800207 }
208 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800209
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800210 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800211 public void getDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800212 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800213 @NonNull String databaseName,
214 @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800215 @NonNull List<String> uris,
Alexander Dorokhine87cdd152021-01-20 15:41:25 -0800216 @NonNull Map<String, List<String>> typePropertyPaths,
Terry Wangf2093072020-11-30 04:47:19 -0800217 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800218 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800219 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700220 Preconditions.checkNotNull(databaseName);
221 Preconditions.checkNotNull(namespace);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800222 Preconditions.checkNotNull(uris);
223 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800224 int callingUid = Binder.getCallingUid();
225 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600226 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800227 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800228 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800229 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700230 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800231 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800232 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800233 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800234 for (int i = 0; i < uris.size(); i++) {
235 String uri = uris.get(i);
236 try {
Cassie Wang308304c2021-01-21 11:13:49 -0800237 GenericDocument document =
238 impl.getDocument(
239 packageName,
240 databaseName,
241 namespace,
242 uri,
243 typePropertyPaths);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700244 resultBuilder.setSuccess(uri, document.getBundle());
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800245 } catch (Throwable t) {
246 resultBuilder.setResult(uri, throwableToFailedResult(t));
247 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800248 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800249 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800250 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800251 invokeCallbackOnError(callback, t);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800252 } finally {
253 Binder.restoreCallingIdentity(callingIdentity);
254 }
255 }
256
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800257 // TODO(sidchhabra): Do this in a threadpool.
258 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800259 public void query(
Cassie Wang0c62d992021-01-15 14:39:30 -0800260 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700261 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700262 @NonNull String queryExpression,
263 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800264 @UserIdInt int userId,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700265 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800266 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700267 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700268 Preconditions.checkNotNull(queryExpression);
269 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800270 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800271 int callingUid = Binder.getCallingUid();
272 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600273 final long callingIdentity = Binder.clearCallingIdentity();
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800274 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800275 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800276 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800277 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800278 mImplInstanceManager.getAppSearchImpl(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800279 SearchResultPage searchResultPage =
280 impl.query(
281 packageName,
282 databaseName,
283 queryExpression,
284 new SearchSpec(searchSpecBundle));
285 invokeCallbackOnResult(
286 callback,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700287 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800288 } catch (Throwable t) {
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700289 invokeCallbackOnError(callback, t);
290 } finally {
291 Binder.restoreCallingIdentity(callingIdentity);
292 }
293 }
294
Terry Wangf2093072020-11-30 04:47:19 -0800295 @Override
Terry Wangbfbfcac2020-11-06 15:46:44 -0800296 public void globalQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800297 @NonNull String packageName,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800298 @NonNull String queryExpression,
299 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800300 @UserIdInt int userId,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800301 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800302 Preconditions.checkNotNull(packageName);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800303 Preconditions.checkNotNull(queryExpression);
304 Preconditions.checkNotNull(searchSpecBundle);
305 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800306 int callingUid = Binder.getCallingUid();
307 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800308 final long callingIdentity = Binder.clearCallingIdentity();
309 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800310 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800311 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800312 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800313 mImplInstanceManager.getAppSearchImpl(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800314 SearchResultPage searchResultPage =
315 impl.globalQuery(
316 queryExpression,
317 new SearchSpec(searchSpecBundle),
318 packageName,
319 callingUid);
Cassie Wang0c62d992021-01-15 14:39:30 -0800320 invokeCallbackOnResult(
321 callback,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800322 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
323 } catch (Throwable t) {
324 invokeCallbackOnError(callback, t);
325 } finally {
326 Binder.restoreCallingIdentity(callingIdentity);
327 }
328 }
329
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700330 @Override
Cassie Wang0c62d992021-01-15 14:39:30 -0800331 public void getNextPage(
332 long nextPageToken,
333 @UserIdInt int userId,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700334 @NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800335 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800336 int callingUid = Binder.getCallingUid();
337 int callingUserId = handleIncomingUser(userId, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700338 final long callingIdentity = Binder.clearCallingIdentity();
339 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
340 // opened it
341 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800342 verifyUserUnlocked(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800343 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800344 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700345 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
Cassie Wang0c62d992021-01-15 14:39:30 -0800346 invokeCallbackOnResult(
347 callback,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700348 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
349 } catch (Throwable t) {
350 invokeCallbackOnError(callback, t);
351 } finally {
352 Binder.restoreCallingIdentity(callingIdentity);
353 }
354 }
355
356 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800357 public void invalidateNextPageToken(long nextPageToken, @UserIdInt int userId) {
358 int callingUid = Binder.getCallingUid();
359 int callingUserId = handleIncomingUser(userId, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700360 final long callingIdentity = Binder.clearCallingIdentity();
361 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800362 verifyUserUnlocked(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800363 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800364 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700365 impl.invalidateNextPageToken(nextPageToken);
366 } catch (Throwable t) {
Terry Wang2da17852020-12-16 19:59:08 -0800367 Log.e(TAG, "Unable to invalidate the query page token", t);
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800368 } finally {
369 Binder.restoreCallingIdentity(callingIdentity);
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800370 }
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800371 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800372
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700373 @Override
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800374 public void reportUsage(
375 @NonNull String packageName,
376 @NonNull String databaseName,
377 @NonNull String namespace,
378 @NonNull String uri,
379 long usageTimeMillis,
380 @UserIdInt int userId,
381 @NonNull IAppSearchResultCallback callback) {
382 Objects.requireNonNull(databaseName);
383 Objects.requireNonNull(namespace);
384 Objects.requireNonNull(uri);
385 Objects.requireNonNull(callback);
386 int callingUid = Binder.getCallingUid();
387 int callingUserId = handleIncomingUser(userId, callingUid);
388 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);
Cassie Wang308304c2021-01-21 11:13:49 -0800393 impl.reportUsage(packageName, databaseName, namespace, uri, usageTimeMillis);
394 invokeCallbackOnResult(
395 callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800396 } catch (Throwable t) {
397 invokeCallbackOnError(callback, t);
398 } finally {
399 Binder.restoreCallingIdentity(callingIdentity);
400 }
401 }
402
403 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800404 public void removeByUri(
Cassie Wang0c62d992021-01-15 14:39:30 -0800405 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800406 @NonNull String databaseName,
407 @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800408 @NonNull List<String> uris,
Terry Wangf2093072020-11-30 04:47:19 -0800409 @UserIdInt int userId,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800410 @NonNull IAppSearchBatchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800411 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700412 Preconditions.checkNotNull(databaseName);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700413 Preconditions.checkNotNull(uris);
414 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800415 int callingUid = Binder.getCallingUid();
416 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600417 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700418 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800419 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800420 verifyCallingPackage(callingUid, packageName);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800421 AppSearchBatchResult.Builder<String, Void> resultBuilder =
422 new AppSearchBatchResult.Builder<>();
Cassie Wang308304c2021-01-21 11:13:49 -0800423 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800424 mImplInstanceManager.getAppSearchImpl(callingUserId);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700425 for (int i = 0; i < uris.size(); i++) {
426 String uri = uris.get(i);
427 try {
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800428 impl.remove(packageName, databaseName, namespace, uri);
Cassie Wang0c62d992021-01-15 14:39:30 -0800429 resultBuilder.setSuccess(uri, /*result= */ null);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700430 } catch (Throwable t) {
431 resultBuilder.setResult(uri, throwableToFailedResult(t));
432 }
433 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800434 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700435 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800436 invokeCallbackOnError(callback, t);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700437 } finally {
438 Binder.restoreCallingIdentity(callingIdentity);
439 }
440 }
441
442 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -0700443 public void removeByQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800444 @NonNull String packageName,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700445 @NonNull String databaseName,
446 @NonNull String queryExpression,
447 @NonNull Bundle searchSpecBundle,
Terry Wangf2093072020-11-30 04:47:19 -0800448 @UserIdInt int userId,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700449 @NonNull IAppSearchResultCallback callback) {
Cassie Wang0c62d992021-01-15 14:39:30 -0800450 Preconditions.checkNotNull(packageName);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700451 Preconditions.checkNotNull(databaseName);
452 Preconditions.checkNotNull(queryExpression);
453 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800454 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800455 int callingUid = Binder.getCallingUid();
456 int callingUserId = handleIncomingUser(userId, callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600457 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700458 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800459 verifyUserUnlocked(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800460 verifyCallingPackage(callingUid, packageName);
Cassie Wang308304c2021-01-21 11:13:49 -0800461 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800462 mImplInstanceManager.getAppSearchImpl(callingUserId);
Cassie Wang0c62d992021-01-15 14:39:30 -0800463 impl.removeByQuery(
464 packageName,
465 databaseName,
466 queryExpression,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700467 new SearchSpec(searchSpecBundle));
468 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700469 } catch (Throwable t) {
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700470 invokeCallbackOnError(callback, t);
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700471 } finally {
472 Binder.restoreCallingIdentity(callingIdentity);
473 }
474 }
475
Terry Wangdbd1dca2020-11-03 17:03:56 -0800476 @Override
Terry Wang2da17852020-12-16 19:59:08 -0800477 public void persistToDisk(@UserIdInt int userId) {
478 int callingUid = Binder.getCallingUidOrThrow();
479 int callingUserId = handleIncomingUser(userId, callingUid);
480 final long callingIdentity = Binder.clearCallingIdentity();
481 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800482 verifyUserUnlocked(callingUserId);
Cassie Wang308304c2021-01-21 11:13:49 -0800483 AppSearchImpl impl =
Terry Wang9d8f4272021-02-04 21:01:10 -0800484 mImplInstanceManager.getAppSearchImpl(callingUserId);
Terry Wang2da17852020-12-16 19:59:08 -0800485 impl.persistToDisk();
486 } catch (Throwable t) {
487 Log.e(TAG, "Unable to persist the data to disk", t);
488 } finally {
489 Binder.restoreCallingIdentity(callingIdentity);
490 }
491 }
492
493 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800494 public void initialize(@UserIdInt int userId, @NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800495 Preconditions.checkNotNull(callback);
Terry Wangf2093072020-11-30 04:47:19 -0800496 int callingUid = Binder.getCallingUid();
497 int callingUserId = handleIncomingUser(userId, callingUid);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800498 final long callingIdentity = Binder.clearCallingIdentity();
499 try {
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800500 verifyUserUnlocked(callingUserId);
Terry Wang9d8f4272021-02-04 21:01:10 -0800501 mImplInstanceManager.getOrCreateAppSearchImpl(getContext(), callingUserId);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800502 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
503 } catch (Throwable t) {
504 invokeCallbackOnError(callback, t);
505 } finally {
506 Binder.restoreCallingIdentity(callingIdentity);
507 }
508 }
509
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800510 private void verifyUserUnlocked(int callingUserId) {
Cassie Wang15c86972021-02-09 13:43:25 -0800511 synchronized (mUnlockedUserIdsLocked) {
512 if (!mUnlockedUserIdsLocked.contains(callingUserId)) {
513 throw new IllegalStateException(
514 "User " + callingUserId + " is locked or not running.");
515 }
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800516 }
517 }
518
Cassie Wang0c62d992021-01-15 14:39:30 -0800519 private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) {
520 Preconditions.checkNotNull(callingPackage);
521 if (mPackageManagerInternal.getPackageUid(
522 callingPackage, /*flags=*/ 0, UserHandle.getUserId(callingUid))
523 != callingUid) {
524 throw new SecurityException(
525 "Specified calling package ["
526 + callingPackage
527 + "] does not match the calling uid "
528 + callingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700529 }
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700530 }
531
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800532 /** Invokes the {@link IAppSearchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -0800533 private void invokeCallbackOnResult(
534 IAppSearchResultCallback callback, AppSearchResult<?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800535 try {
536 callback.onResult(result);
537 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800538 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800539 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800540 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800541
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800542 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -0800543 private void invokeCallbackOnResult(
544 IAppSearchBatchResultCallback callback, AppSearchBatchResult<?, ?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800545 try {
546 callback.onResult(result);
547 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800548 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800549 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800550 }
551
552 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800553 * Invokes the {@link IAppSearchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800554 *
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800555 * <p>The throwable is convert to a {@link AppSearchResult};
Terry Wangdbd1dca2020-11-03 17:03:56 -0800556 */
557 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
558 try {
559 callback.onResult(throwableToFailedResult(throwable));
560 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800561 Log.e(TAG, "Unable to send result to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800562 }
563 }
564
565 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800566 * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800567 *
568 * <p>The throwable is converted to {@link ParcelableException}.
569 */
Cassie Wang0c62d992021-01-15 14:39:30 -0800570 private void invokeCallbackOnError(
571 IAppSearchBatchResultCallback callback, Throwable throwable) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800572 try {
Terry Wang9d8f4272021-02-04 21:01:10 -0800573 //TODO(b/175067650) verify ParcelableException could propagate throwable correctly.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800574 callback.onSystemError(new ParcelableException(throwable));
575 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -0800576 Log.e(TAG, "Unable to send error to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800577 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800578 }
Terry Wangfebbead2019-10-17 17:05:18 -0700579 }
Terry Wangf2093072020-11-30 04:47:19 -0800580
Cassie Wang0c62d992021-01-15 14:39:30 -0800581 // TODO(b/173553485) verifying that the caller has permission to access target user's data
582 // TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast
583 // TODO(b/173553485) Implement SystemService.onUserStopping()
Terry Wangf2093072020-11-30 04:47:19 -0800584 private static int handleIncomingUser(@UserIdInt int userId, int callingUid) {
585 int callingPid = Binder.getCallingPid();
Cassie Wang0c62d992021-01-15 14:39:30 -0800586 return ActivityManager.handleIncomingUser(
587 callingPid,
588 callingUid,
589 userId,
590 /*allowAll=*/ false,
591 /*requireFull=*/ false,
592 /*name=*/ null,
593 /*callerPackage=*/ null);
Terry Wangf2093072020-11-30 04:47:19 -0800594 }
Terry Wangfebbead2019-10-17 17:05:18 -0700595}