blob: 551347c5c202ed385fca9c1806e35ad85fbcd6d3 [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 Wang6413aee2020-10-07 03:04:58 -070050 private static final char CALLING_NAME_DATABASE_DELIMITER = '$';
Terry Wangfebbead2019-10-17 17:05:18 -070051
52 public AppSearchManagerService(Context context) {
53 super(context);
54 }
55
56 @Override
57 public void onStart() {
58 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
59 }
60
61 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080062 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -080063 public void setSchema(
Terry Wang6413aee2020-10-07 03:04:58 -070064 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070065 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080066 @NonNull List<String> schemasNotPlatformSurfaceable,
Alexander Dorokhine969f4462020-03-05 15:54:19 -080067 boolean forceOverride,
Terry Wangdbd1dca2020-11-03 17:03:56 -080068 @NonNull IAppSearchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -070069 Preconditions.checkNotNull(databaseName);
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070070 Preconditions.checkNotNull(schemaBundles);
Terry Wangbfbfcac2020-11-06 15:46:44 -080071 Preconditions.checkNotNull(callback);
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080072 int callingUid = Binder.getCallingUidOrThrow();
73 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -060074 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080075 try {
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080076 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070077 for (int i = 0; i < schemaBundles.size(); i++) {
Terry Wang26b9e5c2020-10-23 02:05:01 -070078 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070079 }
Terry Wang0d393872020-12-11 22:17:09 +000080 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -070081 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080082 impl.setSchema(databaseName, schemas, schemasNotPlatformSurfaceable, 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
Alexander Dorokhine18465842020-01-21 01:08:57 -080093 public void putDocuments(
Terry Wang6413aee2020-10-07 03:04:58 -070094 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070095 @NonNull List<Bundle> documentBundles,
Terry Wangdbd1dca2020-11-03 17:03:56 -080096 @NonNull IAppSearchBatchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -070097 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070098 Preconditions.checkNotNull(documentBundles);
Alexander Dorokhinecc223452020-01-19 03:00:28 -080099 Preconditions.checkNotNull(callback);
100 int callingUid = Binder.getCallingUidOrThrow();
101 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600102 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800103 try {
Alexander Dorokhine18465842020-01-21 01:08:57 -0800104 AppSearchBatchResult.Builder<String, Void> resultBuilder =
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800105 new AppSearchBatchResult.Builder<>();
Terry Wang0d393872020-12-11 22:17:09 +0000106 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800107 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700108 for (int i = 0; i < documentBundles.size(); i++) {
109 GenericDocument document = new GenericDocument(documentBundles.get(i));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800110 try {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800111 // TODO(b/173451571): reduce burden of binder thread by enqueue request onto
112 // a separate thread.
Terry Wang26b9e5c2020-10-23 02:05:01 -0700113 impl.putDocument(databaseName, document);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700114 resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800115 } catch (Throwable t) {
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800116 resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800117 }
118 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800119 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800120 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800121 invokeCallbackOnError(callback, t);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800122 } finally {
123 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800124 }
125 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800126
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800127 @Override
Terry Wang6413aee2020-10-07 03:04:58 -0700128 public void getDocuments(@NonNull String databaseName, @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800129 @NonNull List<String> uris,
130 @NonNull IAppSearchBatchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700131 Preconditions.checkNotNull(databaseName);
132 Preconditions.checkNotNull(namespace);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800133 Preconditions.checkNotNull(uris);
134 Preconditions.checkNotNull(callback);
135 int callingUid = Binder.getCallingUidOrThrow();
136 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600137 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800138 try {
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700139 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800140 new AppSearchBatchResult.Builder<>();
Terry Wang0d393872020-12-11 22:17:09 +0000141 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800142 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800143 for (int i = 0; i < uris.size(); i++) {
144 String uri = uris.get(i);
145 try {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700146 GenericDocument document = impl.getDocument(databaseName, namespace, uri);
147 resultBuilder.setSuccess(uri, document.getBundle());
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800148 } catch (Throwable t) {
149 resultBuilder.setResult(uri, throwableToFailedResult(t));
150 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800151 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800152 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800153 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800154 invokeCallbackOnError(callback, t);
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800155 } finally {
156 Binder.restoreCallingIdentity(callingIdentity);
157 }
158 }
159
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800160 // TODO(sidchhabra): Do this in a threadpool.
161 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800162 public void query(
Terry Wang6413aee2020-10-07 03:04:58 -0700163 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700164 @NonNull String queryExpression,
165 @NonNull Bundle searchSpecBundle,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700166 @NonNull IAppSearchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700167 Preconditions.checkNotNull(databaseName);
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700168 Preconditions.checkNotNull(queryExpression);
169 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800170 Preconditions.checkNotNull(callback);
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800171 int callingUid = Binder.getCallingUidOrThrow();
172 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600173 final long callingIdentity = Binder.clearCallingIdentity();
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800174 try {
Terry Wang0d393872020-12-11 22:17:09 +0000175 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700176 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Terry Wang26b9e5c2020-10-23 02:05:01 -0700177 SearchResultPage searchResultPage = impl.query(
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700178 databaseName,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700179 queryExpression,
180 new SearchSpec(searchSpecBundle));
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700181 invokeCallbackOnResult(callback,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700182 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800183 } catch (Throwable t) {
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700184 invokeCallbackOnError(callback, t);
185 } finally {
186 Binder.restoreCallingIdentity(callingIdentity);
187 }
188 }
189
Terry Wangbfbfcac2020-11-06 15:46:44 -0800190 public void globalQuery(
191 @NonNull String queryExpression,
192 @NonNull Bundle searchSpecBundle,
193 @NonNull IAppSearchResultCallback callback) {
194 Preconditions.checkNotNull(queryExpression);
195 Preconditions.checkNotNull(searchSpecBundle);
196 Preconditions.checkNotNull(callback);
197 int callingUid = Binder.getCallingUidOrThrow();
198 int callingUserId = UserHandle.getUserId(callingUid);
199 final long callingIdentity = Binder.clearCallingIdentity();
200 try {
Terry Wang0d393872020-12-11 22:17:09 +0000201 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800202 SearchResultPage searchResultPage = impl.globalQuery(
203 queryExpression,
204 new SearchSpec(searchSpecBundle));
205 invokeCallbackOnResult(callback,
206 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
207 } catch (Throwable t) {
208 invokeCallbackOnError(callback, t);
209 } finally {
210 Binder.restoreCallingIdentity(callingIdentity);
211 }
212 }
213
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700214 @Override
215 public void getNextPage(long nextPageToken,
216 @NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800217 Preconditions.checkNotNull(callback);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700218 int callingUid = Binder.getCallingUidOrThrow();
219 int callingUserId = UserHandle.getUserId(callingUid);
220 final long callingIdentity = Binder.clearCallingIdentity();
221 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
222 // opened it
223 try {
Terry Wang0d393872020-12-11 22:17:09 +0000224 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700225 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
226 invokeCallbackOnResult(callback,
227 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
228 } catch (Throwable t) {
229 invokeCallbackOnError(callback, t);
230 } finally {
231 Binder.restoreCallingIdentity(callingIdentity);
232 }
233 }
234
235 @Override
236 public void invalidateNextPageToken(long nextPageToken) {
237 int callingUid = Binder.getCallingUidOrThrow();
238 int callingUserId = UserHandle.getUserId(callingUid);
239 final long callingIdentity = Binder.clearCallingIdentity();
240 try {
Terry Wang0d393872020-12-11 22:17:09 +0000241 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700242 impl.invalidateNextPageToken(nextPageToken);
243 } catch (Throwable t) {
244 Log.d(TAG, "Unable to invalidate the query page token", t);
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800245 } finally {
246 Binder.restoreCallingIdentity(callingIdentity);
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800247 }
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800248 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800249
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700250 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -0700251 public void removeByUri(@NonNull String databaseName, @NonNull String namespace,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800252 @NonNull List<String> uris,
253 @NonNull IAppSearchBatchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700254 Preconditions.checkNotNull(databaseName);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700255 Preconditions.checkNotNull(uris);
256 Preconditions.checkNotNull(callback);
257 int callingUid = Binder.getCallingUidOrThrow();
258 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600259 final long callingIdentity = Binder.clearCallingIdentity();
Terry Wang0d393872020-12-11 22:17:09 +0000260 AppSearchBatchResult.Builder<String, Void> resultBuilder =
261 new AppSearchBatchResult.Builder<>();
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700262 try {
Terry Wang0d393872020-12-11 22:17:09 +0000263 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700264 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700265 for (int i = 0; i < uris.size(); i++) {
266 String uri = uris.get(i);
267 try {
Terry Wang6413aee2020-10-07 03:04:58 -0700268 impl.remove(databaseName, namespace, uri);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700269 resultBuilder.setSuccess(uri, /*result= */null);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700270 } catch (Throwable t) {
271 resultBuilder.setResult(uri, throwableToFailedResult(t));
272 }
273 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800274 invokeCallbackOnResult(callback, resultBuilder.build());
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700275 } catch (Throwable t) {
Terry Wangdbd1dca2020-11-03 17:03:56 -0800276 invokeCallbackOnError(callback, t);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700277 } finally {
278 Binder.restoreCallingIdentity(callingIdentity);
279 }
280 }
281
282 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -0700283 public void removeByQuery(
284 @NonNull String databaseName,
285 @NonNull String queryExpression,
286 @NonNull Bundle searchSpecBundle,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700287 @NonNull IAppSearchResultCallback callback) {
Terry Wang26b9e5c2020-10-23 02:05:01 -0700288 Preconditions.checkNotNull(databaseName);
289 Preconditions.checkNotNull(queryExpression);
290 Preconditions.checkNotNull(searchSpecBundle);
Terry Wangbfbfcac2020-11-06 15:46:44 -0800291 Preconditions.checkNotNull(callback);
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700292 int callingUid = Binder.getCallingUidOrThrow();
293 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600294 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700295 try {
Terry Wang0d393872020-12-11 22:17:09 +0000296 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700297 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700298 impl.removeByQuery(databaseName, queryExpression,
299 new SearchSpec(searchSpecBundle));
300 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700301 } catch (Throwable t) {
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700302 invokeCallbackOnError(callback, t);
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700303 } finally {
304 Binder.restoreCallingIdentity(callingIdentity);
305 }
306 }
307
Terry Wangdbd1dca2020-11-03 17:03:56 -0800308 @Override
309 public void initialize(@NonNull IAppSearchResultCallback callback) {
Terry Wangbfbfcac2020-11-06 15:46:44 -0800310 Preconditions.checkNotNull(callback);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800311 int callingUid = Binder.getCallingUidOrThrow();
312 int callingUserId = UserHandle.getUserId(callingUid);
313 final long callingIdentity = Binder.clearCallingIdentity();
314 try {
Terry Wang0d393872020-12-11 22:17:09 +0000315 ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wangdbd1dca2020-11-03 17:03:56 -0800316 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
317 } catch (Throwable t) {
318 invokeCallbackOnError(callback, t);
319 } finally {
320 Binder.restoreCallingIdentity(callingIdentity);
321 }
322 }
323
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700324 /**
Terry Wang6413aee2020-10-07 03:04:58 -0700325 * Rewrites the database name by adding a prefix of unique name for the given uid.
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700326 *
327 * <p>The current implementation returns the package name of the app with this uid in a
328 * format like {@code com.example.package} or {@code com.example.sharedname:5678}.
329 */
330 @NonNull
Terry Wang6413aee2020-10-07 03:04:58 -0700331 private String rewriteDatabaseNameWithUid(String databaseName, int callingUid) {
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700332 // For regular apps, this call will return the package name. If callingUid is an
333 // android:sharedUserId, this value may be another type of name and have a :uid suffix.
334 String callingUidName = getContext().getPackageManager().getNameForUid(callingUid);
335 if (callingUidName == null) {
336 // Not sure how this is possible --- maybe app was uninstalled?
337 throw new IllegalStateException(
338 "Failed to look up package name for uid " + callingUid);
339 }
Terry Wang6413aee2020-10-07 03:04:58 -0700340 return callingUidName + CALLING_NAME_DATABASE_DELIMITER + databaseName;
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700341 }
342
Terry Wangdbd1dca2020-11-03 17:03:56 -0800343 /** Invokes the {@link IAppSearchResultCallback} with the result. */
344 private void invokeCallbackOnResult(IAppSearchResultCallback callback,
345 AppSearchResult result) {
346 try {
347 callback.onResult(result);
348 } catch (RemoteException e) {
349 Log.d(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800350 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800351 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800352
Terry Wangdbd1dca2020-11-03 17:03:56 -0800353 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
354 private void invokeCallbackOnResult(IAppSearchBatchResultCallback callback,
355 AppSearchBatchResult result) {
356 try {
357 callback.onResult(result);
358 } catch (RemoteException e) {
359 Log.d(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800360 }
Terry Wangdbd1dca2020-11-03 17:03:56 -0800361 }
362
363 /**
364 * Invokes the {@link IAppSearchResultCallback} with an throwable.
365 *
366 * <p>The throwable is convert to a {@link AppSearchResult};
367 */
368 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
369 try {
370 callback.onResult(throwableToFailedResult(throwable));
371 } catch (RemoteException e) {
372 Log.d(TAG, "Unable to send result to the callback", e);
373 }
374 }
375
376 /**
Terry Wang0d393872020-12-11 22:17:09 +0000377 * Invokes the {@link IAppSearchBatchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -0800378 *
379 * <p>The throwable is converted to {@link ParcelableException}.
380 */
381 private void invokeCallbackOnError(IAppSearchBatchResultCallback callback,
382 Throwable throwable) {
383 try {
384 callback.onSystemError(new ParcelableException(throwable));
385 } catch (RemoteException e) {
386 Log.d(TAG, "Unable to send error to the callback", e);
387 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800388 }
Terry Wangfebbead2019-10-17 17:05:18 -0700389 }
390}