blob: d81b79414359d89f1d4db6f19ce42f7f71ee0cd7 [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;
Alexander Dorokhine18465842020-01-21 01:08:57 -080021import android.app.appsearch.AppSearchBatchResult;
Alexander Dorokhine969f4462020-03-05 15:54:19 -080022import android.app.appsearch.AppSearchResult;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070023import android.app.appsearch.AppSearchSchema;
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070024import android.app.appsearch.GenericDocument;
Terry Wangdbd1dca2020-11-03 17:03:56 -080025import android.app.appsearch.IAppSearchBatchResultCallback;
Terry Wangfebbead2019-10-17 17:05:18 -070026import android.app.appsearch.IAppSearchManager;
Terry Wangdbd1dca2020-11-03 17:03:56 -080027import android.app.appsearch.IAppSearchResultCallback;
Terry Wang26b9e5c2020-10-23 02:05:01 -070028import android.app.appsearch.SearchResultPage;
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -070029import android.app.appsearch.SearchSpec;
Terry Wangfebbead2019-10-17 17:05:18 -070030import android.content.Context;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080031import android.os.Binder;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070032import android.os.Bundle;
Terry Wangdbd1dca2020-11-03 17:03:56 -080033import android.os.ParcelableException;
34import android.os.RemoteException;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080035import android.os.UserHandle;
Terry Wangdbd1dca2020-11-03 17:03:56 -080036import android.util.Log;
Terry Wangfebbead2019-10-17 17:05:18 -070037
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080038import com.android.internal.util.Preconditions;
Terry Wangfebbead2019-10-17 17:05:18 -070039import com.android.server.SystemService;
Alexander Dorokhinef660d8f2020-10-29 22:37:00 -070040import com.android.server.appsearch.external.localstorage.AppSearchImpl;
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080041
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080042import java.util.ArrayList;
Alexander Dorokhine18465842020-01-21 01:08:57 -080043import java.util.List;
44
Terry Wangfebbead2019-10-17 17:05:18 -070045/**
46 * TODO(b/142567528): add comments when implement this class
47 */
48public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070049 private static final String TAG = "AppSearchManagerService";
Terry Wangfebbead2019-10-17 17:05:18 -070050
51 public AppSearchManagerService(Context context) {
52 super(context);
53 }
54
55 @Override
56 public void onStart() {
57 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
58 }
59
60 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080061 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -080062 public void setSchema(
Terry Wang6413aee2020-10-07 03:04:58 -070063 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070064 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080065 @NonNull List<String> schemasNotPlatformSurfaceable,
Alexander Dorokhine969f4462020-03-05 15:54:19 -080066 boolean forceOverride,
Terry Wangdbd1dca2020-11-03 17:03:56 -080067 @NonNull IAppSearchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -070068 Preconditions.checkNotNull(databaseName);
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070069 Preconditions.checkNotNull(schemaBundles);
Terry Wangbfbfcac2020-11-06 15:46:44 -080070 Preconditions.checkNotNull(callback);
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080071 int callingUid = Binder.getCallingUidOrThrow();
72 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -060073 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080074 try {
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080075 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070076 for (int i = 0; i < schemaBundles.size(); i++) {
Terry Wang26b9e5c2020-10-23 02:05:01 -070077 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070078 }
Terry Wang0d393872020-12-11 22:17:09 +000079 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -080080 String packageName = convertUidToPackageName(callingUid);
81 impl.setSchema(packageName, databaseName, schemas, schemasNotPlatformSurfaceable,
82 forceOverride);
Terry Wangdbd1dca2020-11-03 17:03:56 -080083 invokeCallbackOnResult(callback,
84 AppSearchResult.newSuccessfulResult(/*result=*/ null));
Alexander Dorokhine179c8b82020-01-11 00:17:48 -080085 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -080086 invokeCallbackOnError(callback, t);
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080087 } finally {
88 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhine179c8b82020-01-11 00:17:48 -080089 }
90 }
91
92 @Override
Terry Wang83a24932020-12-09 21:00:18 -080093 public void getSchema(
94 @NonNull String databaseName,
95 @NonNull IAppSearchResultCallback callback) {
96 Preconditions.checkNotNull(databaseName);
97 Preconditions.checkNotNull(callback);
98 int callingUid = Binder.getCallingUidOrThrow();
99 int callingUserId = UserHandle.getUserId(callingUid);
100 final long callingIdentity = Binder.clearCallingIdentity();
101 try {
102 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800103 String packageName = convertUidToPackageName(callingUid);
104 List<AppSearchSchema> schemas = impl.getSchema(packageName, databaseName);
Terry Wang83a24932020-12-09 21:00:18 -0800105 List<Bundle> schemaBundles = new ArrayList<>(schemas.size());
106 for (int i = 0; i < schemas.size(); i++) {
107 schemaBundles.add(schemas.get(i).getBundle());
108 }
109 invokeCallbackOnResult(callback,
110 AppSearchResult.newSuccessfulResult(schemaBundles));
111 } catch (Throwable t) {
112 invokeCallbackOnError(callback, t);
113 } finally {
114 Binder.restoreCallingIdentity(callingIdentity);
115 }
116 }
117
118 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -0800119 public void putDocuments(
Terry Wang6413aee2020-10-07 03:04:58 -0700120 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700121 @NonNull List<Bundle> documentBundles,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800122 @NonNull IAppSearchBatchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700123 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700124 Preconditions.checkNotNull(documentBundles);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800125 Preconditions.checkNotNull(callback);
126 int callingUid = Binder.getCallingUidOrThrow();
127 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600128 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800129 try {
Alexander Dorokhine18465842020-01-21 01:08:57 -0800130 AppSearchBatchResult.Builder<String, Void> resultBuilder =
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800131 new AppSearchBatchResult.Builder<>();
Terry Wang0d393872020-12-11 22:17:09 +0000132 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800133 String packageName = convertUidToPackageName(callingUid);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700134 for (int i = 0; i < documentBundles.size(); i++) {
135 GenericDocument document = new GenericDocument(documentBundles.get(i));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800136 try {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800137 // TODO(b/173451571): reduce burden of binder thread by enqueue request onto
138 // a separate thread.
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800139 impl.putDocument(packageName, databaseName, document);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700140 resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800141 } catch (Throwable t) {
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800142 resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800143 }
144 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800145 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800146 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800147 invokeCallbackOnError(callback, t);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800148 } finally {
149 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800150 }
151 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800152
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800153 @Override
Terry Wang6413aee2020-10-07 03:04:58 -0700154 public void getDocuments(@NonNull String databaseName, @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800155 @NonNull List<String> uris,
156 @NonNull IAppSearchBatchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700157 Preconditions.checkNotNull(databaseName);
158 Preconditions.checkNotNull(namespace);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800159 Preconditions.checkNotNull(uris);
160 Preconditions.checkNotNull(callback);
161 int callingUid = Binder.getCallingUidOrThrow();
162 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600163 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800164 try {
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700165 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800166 new AppSearchBatchResult.Builder<>();
Terry Wang0d393872020-12-11 22:17:09 +0000167 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800168 String packageName = convertUidToPackageName(callingUid);
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800169 for (int i = 0; i < uris.size(); i++) {
170 String uri = uris.get(i);
171 try {
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800172 GenericDocument document = impl.getDocument(packageName, databaseName,
173 namespace, uri);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700174 resultBuilder.setSuccess(uri, document.getBundle());
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800175 } catch (Throwable t) {
176 resultBuilder.setResult(uri, throwableToFailedResult(t));
177 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800178 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800179 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800180 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800181 invokeCallbackOnError(callback, t);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800182 } finally {
183 Binder.restoreCallingIdentity(callingIdentity);
184 }
185 }
186
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800187 // TODO(sidchhabra): Do this in a threadpool.
188 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800189 public void query(
Terry Wang6413aee2020-10-07 03:04:58 -0700190 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700191 @NonNull String queryExpression,
192 @NonNull Bundle searchSpecBundle,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700193 @NonNull IAppSearchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700194 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700195 Preconditions.checkNotNull(queryExpression);
196 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800197 Preconditions.checkNotNull(callback);
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800198 int callingUid = Binder.getCallingUidOrThrow();
199 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600200 final long callingIdentity = Binder.clearCallingIdentity();
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800201 try {
Terry Wang0d393872020-12-11 22:17:09 +0000202 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800203 String packageName = convertUidToPackageName(callingUid);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700204 SearchResultPage searchResultPage = impl.query(
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800205 packageName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700206 databaseName,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700207 queryExpression,
208 new SearchSpec(searchSpecBundle));
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700209 invokeCallbackOnResult(callback,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700210 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800211 } catch (Throwable t) {
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700212 invokeCallbackOnError(callback, t);
213 } finally {
214 Binder.restoreCallingIdentity(callingIdentity);
215 }
216 }
217
Terry Wangbfbfcac2020-11-06 15:46:44 -0800218 public void globalQuery(
219 @NonNull String queryExpression,
220 @NonNull Bundle searchSpecBundle,
221 @NonNull IAppSearchResultCallback callback) {
222 Preconditions.checkNotNull(queryExpression);
223 Preconditions.checkNotNull(searchSpecBundle);
224 Preconditions.checkNotNull(callback);
225 int callingUid = Binder.getCallingUidOrThrow();
226 int callingUserId = UserHandle.getUserId(callingUid);
227 final long callingIdentity = Binder.clearCallingIdentity();
228 try {
Terry Wang0d393872020-12-11 22:17:09 +0000229 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800230 SearchResultPage searchResultPage = impl.globalQuery(
231 queryExpression,
232 new SearchSpec(searchSpecBundle));
233 invokeCallbackOnResult(callback,
234 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
235 } catch (Throwable t) {
236 invokeCallbackOnError(callback, t);
237 } finally {
238 Binder.restoreCallingIdentity(callingIdentity);
239 }
240 }
241
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700242 @Override
243 public void getNextPage(long nextPageToken,
244 @NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800245 Preconditions.checkNotNull(callback);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700246 int callingUid = Binder.getCallingUidOrThrow();
247 int callingUserId = UserHandle.getUserId(callingUid);
248 final long callingIdentity = Binder.clearCallingIdentity();
249 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
250 // opened it
251 try {
Terry Wang0d393872020-12-11 22:17:09 +0000252 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700253 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
254 invokeCallbackOnResult(callback,
255 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
256 } catch (Throwable t) {
257 invokeCallbackOnError(callback, t);
258 } finally {
259 Binder.restoreCallingIdentity(callingIdentity);
260 }
261 }
262
263 @Override
264 public void invalidateNextPageToken(long nextPageToken) {
265 int callingUid = Binder.getCallingUidOrThrow();
266 int callingUserId = UserHandle.getUserId(callingUid);
267 final long callingIdentity = Binder.clearCallingIdentity();
268 try {
Terry Wang0d393872020-12-11 22:17:09 +0000269 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700270 impl.invalidateNextPageToken(nextPageToken);
271 } catch (Throwable t) {
272 Log.d(TAG, "Unable to invalidate the query page token", t);
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800273 } finally {
274 Binder.restoreCallingIdentity(callingIdentity);
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800275 }
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800276 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800277
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700278 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -0700279 public void removeByUri(@NonNull String databaseName, @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800280 @NonNull List<String> uris,
281 @NonNull IAppSearchBatchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700282 Preconditions.checkNotNull(databaseName);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700283 Preconditions.checkNotNull(uris);
284 Preconditions.checkNotNull(callback);
285 int callingUid = Binder.getCallingUidOrThrow();
286 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600287 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700288 try {
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800289 AppSearchBatchResult.Builder<String, Void> resultBuilder =
290 new AppSearchBatchResult.Builder<>();
Terry Wang0d393872020-12-11 22:17:09 +0000291 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800292 String packageName = convertUidToPackageName(callingUid);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700293 for (int i = 0; i < uris.size(); i++) {
294 String uri = uris.get(i);
295 try {
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800296 impl.remove(packageName, databaseName, namespace, uri);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700297 resultBuilder.setSuccess(uri, /*result= */null);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700298 } catch (Throwable t) {
299 resultBuilder.setResult(uri, throwableToFailedResult(t));
300 }
301 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800302 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700303 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800304 invokeCallbackOnError(callback, t);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700305 } finally {
306 Binder.restoreCallingIdentity(callingIdentity);
307 }
308 }
309
310 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -0700311 public void removeByQuery(
312 @NonNull String databaseName,
313 @NonNull String queryExpression,
314 @NonNull Bundle searchSpecBundle,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700315 @NonNull IAppSearchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700316 Preconditions.checkNotNull(databaseName);
317 Preconditions.checkNotNull(queryExpression);
318 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800319 Preconditions.checkNotNull(callback);
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700320 int callingUid = Binder.getCallingUidOrThrow();
321 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600322 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700323 try {
Terry Wang0d393872020-12-11 22:17:09 +0000324 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800325 String packageName = convertUidToPackageName(callingUid);
326 impl.removeByQuery(packageName, databaseName, queryExpression,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700327 new SearchSpec(searchSpecBundle));
328 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700329 } catch (Throwable t) {
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700330 invokeCallbackOnError(callback, t);
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700331 } finally {
332 Binder.restoreCallingIdentity(callingIdentity);
333 }
334 }
335
Terry Wangdbd1dca2020-11-03 17:03:56 -0800336 @Override
337 public void initialize(@NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800338 Preconditions.checkNotNull(callback);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800339 int callingUid = Binder.getCallingUidOrThrow();
340 int callingUserId = UserHandle.getUserId(callingUid);
341 final long callingIdentity = Binder.clearCallingIdentity();
342 try {
Terry Wang0d393872020-12-11 22:17:09 +0000343 ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800344 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
345 } catch (Throwable t) {
346 invokeCallbackOnError(callback, t);
347 } finally {
348 Binder.restoreCallingIdentity(callingIdentity);
349 }
350 }
351
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700352 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800353 * Returns a package name for the given uid.
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700354 *
355 * <p>The current implementation returns the package name of the app with this uid in a
356 * format like {@code com.example.package} or {@code com.example.sharedname:5678}.
357 */
358 @NonNull
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800359 private String convertUidToPackageName(int callingUid) {
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700360 // For regular apps, this call will return the package name. If callingUid is an
361 // android:sharedUserId, this value may be another type of name and have a :uid suffix.
362 String callingUidName = getContext().getPackageManager().getNameForUid(callingUid);
363 if (callingUidName == null) {
364 // Not sure how this is possible --- maybe app was uninstalled?
365 throw new IllegalStateException(
366 "Failed to look up package name for uid " + callingUid);
367 }
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800368 return callingUidName;
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700369 }
370
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800371 /** Invokes the {@link IAppSearchResultCallback} with the result. */
Terry Wangdbd1dca2020-11-03 17:03:56 -0800372 private void invokeCallbackOnResult(IAppSearchResultCallback callback,
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800373 AppSearchResult<?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800374 try {
375 callback.onResult(result);
376 } catch (RemoteException e) {
377 Log.d(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800378 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800379 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800380
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800381 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
Terry Wangdbd1dca2020-11-03 17:03:56 -0800382 private void invokeCallbackOnResult(IAppSearchBatchResultCallback callback,
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800383 AppSearchBatchResult<?, ?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800384 try {
385 callback.onResult(result);
386 } catch (RemoteException e) {
387 Log.d(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800388 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800389 }
390
391 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800392 * Invokes the {@link IAppSearchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800393 *
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800394 * <p>The throwable is convert to a {@link AppSearchResult};
Terry Wangdbd1dca2020-11-03 17:03:56 -0800395 */
396 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
397 try {
398 callback.onResult(throwableToFailedResult(throwable));
399 } catch (RemoteException e) {
400 Log.d(TAG, "Unable to send result to the callback", e);
401 }
402 }
403
404 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -0800405 * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800406 *
407 * <p>The throwable is converted to {@link ParcelableException}.
408 */
409 private void invokeCallbackOnError(IAppSearchBatchResultCallback callback,
410 Throwable throwable) {
411 try {
412 callback.onSystemError(new ParcelableException(throwable));
413 } catch (RemoteException e) {
414 Log.d(TAG, "Unable to send error to the callback", e);
415 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800416 }
Terry Wangfebbead2019-10-17 17:05:18 -0700417 }
418}