blob: f2830e5b8e6d34181e8b123f8311fc60f6f43f8c [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
sidchhabraa7c8f8a2020-01-16 18:38:17 -080018import android.annotation.NonNull;
Alexander Dorokhine18465842020-01-21 01:08:57 -080019import android.app.appsearch.AppSearchBatchResult;
Alexander Dorokhine969f4462020-03-05 15:54:19 -080020import android.app.appsearch.AppSearchResult;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070021import android.app.appsearch.AppSearchSchema;
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070022import android.app.appsearch.GenericDocument;
Terry Wangfebbead2019-10-17 17:05:18 -070023import android.app.appsearch.IAppSearchManager;
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070024import android.app.appsearch.SearchResult;
25import android.app.appsearch.SearchResults;
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -070026import android.app.appsearch.SearchSpec;
Alexander Dorokhineebd37742020-09-22 15:02:26 -070027import android.app.appsearch.exceptions.AppSearchException;
Terry Wangfebbead2019-10-17 17:05:18 -070028import android.content.Context;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080029import android.os.Binder;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070030import android.os.Bundle;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080031import android.os.UserHandle;
Terry Wangfebbead2019-10-17 17:05:18 -070032
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080033import com.android.internal.infra.AndroidFuture;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080034import com.android.internal.util.Preconditions;
Terry Wangfebbead2019-10-17 17:05:18 -070035import com.android.server.SystemService;
Alexander Dorokhinef660d8f2020-10-29 22:37:00 -070036import com.android.server.appsearch.external.localstorage.AppSearchImpl;
37import com.android.server.appsearch.external.localstorage.converter.GenericDocumentToProtoConverter;
38import com.android.server.appsearch.external.localstorage.converter.SchemaToProtoConverter;
39import com.android.server.appsearch.external.localstorage.converter.SearchResultToProtoConverter;
40import com.android.server.appsearch.external.localstorage.converter.SearchSpecToProtoConverter;
Terry Wangfebbead2019-10-17 17:05:18 -070041
Alexander Dorokhinecc223452020-01-19 03:00:28 -080042import com.google.android.icing.proto.DocumentProto;
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080043import com.google.android.icing.proto.SchemaProto;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070044import com.google.android.icing.proto.SchemaTypeConfigProto;
sidchhabraa7c8f8a2020-01-16 18:38:17 -080045import com.google.android.icing.proto.SearchResultProto;
46import com.google.android.icing.proto.SearchSpecProto;
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080047
Alexander Dorokhine969f4462020-03-05 15:54:19 -080048import java.io.IOException;
Alexander Dorokhinef660d8f2020-10-29 22:37:00 -070049import java.util.ArrayList;
Alexander Dorokhine18465842020-01-21 01:08:57 -080050import java.util.List;
51
Terry Wangfebbead2019-10-17 17:05:18 -070052/**
53 * TODO(b/142567528): add comments when implement this class
54 */
55public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070056 private static final String TAG = "AppSearchManagerService";
Terry Wang6413aee2020-10-07 03:04:58 -070057 private static final char CALLING_NAME_DATABASE_DELIMITER = '$';
Terry Wangfebbead2019-10-17 17:05:18 -070058
59 public AppSearchManagerService(Context context) {
60 super(context);
61 }
62
63 @Override
64 public void onStart() {
65 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
66 }
67
68 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080069 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -080070 public void setSchema(
Terry Wang6413aee2020-10-07 03:04:58 -070071 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070072 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -080073 boolean forceOverride,
74 @NonNull AndroidFuture<AppSearchResult> callback) {
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070075 Preconditions.checkNotNull(schemaBundles);
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080076 Preconditions.checkNotNull(callback);
77 int callingUid = Binder.getCallingUidOrThrow();
78 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -060079 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080080 try {
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070081 SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder();
82 for (int i = 0; i < schemaBundles.size(); i++) {
83 AppSearchSchema schema = new AppSearchSchema(schemaBundles.get(i));
84 SchemaTypeConfigProto schemaTypeProto = SchemaToProtoConverter.convert(schema);
85 schemaProtoBuilder.addTypes(schemaTypeProto);
86 }
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080087 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -070088 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070089 impl.setSchema(databaseName, schemaProtoBuilder.build(), forceOverride);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070090 callback.complete(AppSearchResult.newSuccessfulResult(/*result=*/ null));
Alexander Dorokhine179c8b82020-01-11 00:17:48 -080091 } catch (Throwable t) {
Alexander Dorokhine969f4462020-03-05 15:54:19 -080092 callback.complete(throwableToFailedResult(t));
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080093 } finally {
94 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhine179c8b82020-01-11 00:17:48 -080095 }
96 }
97
98 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -080099 public void putDocuments(
Terry Wang6413aee2020-10-07 03:04:58 -0700100 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700101 @NonNull List<Bundle> documentBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800102 @NonNull AndroidFuture<AppSearchBatchResult> callback) {
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700103 Preconditions.checkNotNull(documentBundles);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800104 Preconditions.checkNotNull(callback);
105 int callingUid = Binder.getCallingUidOrThrow();
106 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600107 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800108 try {
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800109 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700110 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800111 AppSearchBatchResult.Builder<String, Void> resultBuilder =
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800112 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700113 for (int i = 0; i < documentBundles.size(); i++) {
114 GenericDocument document = new GenericDocument(documentBundles.get(i));
115 DocumentProto documentProto = GenericDocumentToProtoConverter.convert(document);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800116 try {
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700117 impl.putDocument(databaseName, documentProto);
118 resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800119 } catch (Throwable t) {
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800120 resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800121 }
122 }
123 callback.complete(resultBuilder.build());
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800124 } catch (Throwable t) {
125 callback.completeExceptionally(t);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800126 } finally {
127 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800128 }
129 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800130
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800131 @Override
Terry Wang6413aee2020-10-07 03:04:58 -0700132 public void getDocuments(@NonNull String databaseName, @NonNull String namespace,
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800133 @NonNull List<String> uris, @NonNull AndroidFuture<AppSearchBatchResult> callback) {
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800134 Preconditions.checkNotNull(uris);
135 Preconditions.checkNotNull(callback);
136 int callingUid = Binder.getCallingUidOrThrow();
137 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600138 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800139 try {
140 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700141 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700142 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800143 new AppSearchBatchResult.Builder<>();
144 for (int i = 0; i < uris.size(); i++) {
145 String uri = uris.get(i);
146 try {
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700147 DocumentProto documentProto = impl.getDocument(
Terry Wang6413aee2020-10-07 03:04:58 -0700148 databaseName, namespace, uri);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700149 if (documentProto == null) {
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800150 resultBuilder.setFailure(
151 uri, AppSearchResult.RESULT_NOT_FOUND, /*errorMessage=*/ null);
152 } else {
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700153 GenericDocument genericDocument =
154 GenericDocumentToProtoConverter.convert(documentProto);
155 resultBuilder.setSuccess(uri, genericDocument.getBundle());
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800156 }
157 } catch (Throwable t) {
158 resultBuilder.setResult(uri, throwableToFailedResult(t));
159 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800160 }
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800161 callback.complete(resultBuilder.build());
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800162 } catch (Throwable t) {
163 callback.completeExceptionally(t);
164 } finally {
165 Binder.restoreCallingIdentity(callingIdentity);
166 }
167 }
168
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800169 // TODO(sidchhabra): Do this in a threadpool.
170 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800171 public void query(
Terry Wang6413aee2020-10-07 03:04:58 -0700172 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700173 @NonNull String queryExpression,
174 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800175 @NonNull AndroidFuture<AppSearchResult> callback) {
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700176 Preconditions.checkNotNull(queryExpression);
177 Preconditions.checkNotNull(searchSpecBundle);
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800178 Preconditions.checkNotNull(callback);
179 int callingUid = Binder.getCallingUidOrThrow();
180 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600181 final long callingIdentity = Binder.clearCallingIdentity();
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800182 try {
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700183 SearchSpec searchSpec = new SearchSpec(searchSpecBundle);
184 SearchSpecProto searchSpecProto =
185 SearchSpecToProtoConverter.toSearchSpecProto(searchSpec);
186 searchSpecProto = searchSpecProto.toBuilder()
187 .setQuery(queryExpression).build();
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800188 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700189 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700190 // TODO(adorokhine): handle pagination
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700191 SearchResultProto searchResultProto = impl.query(
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700192 databaseName,
193 searchSpecProto,
194 SearchSpecToProtoConverter.toResultSpecProto(searchSpec),
195 SearchSpecToProtoConverter.toScoringSpecProto(searchSpec));
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700196 List<SearchResult> searchResultList =
Alexander Dorokhinef660d8f2020-10-29 22:37:00 -0700197 new ArrayList<>(searchResultProto.getResultsCount());
198 for (int i = 0; i < searchResultProto.getResultsCount(); i++) {
199 SearchResult result = SearchResultToProtoConverter.convertSearchResult(
200 searchResultProto.getResults(i));
201 searchResultList.add(result);
202 }
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700203 SearchResults searchResults =
204 new SearchResults(searchResultList, searchResultProto.getNextPageToken());
205 callback.complete(AppSearchResult.newSuccessfulResult(searchResults));
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800206 } catch (Throwable t) {
207 callback.complete(throwableToFailedResult(t));
208 } finally {
209 Binder.restoreCallingIdentity(callingIdentity);
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800210 }
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800211 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800212
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700213 @Override
Terry Wang6413aee2020-10-07 03:04:58 -0700214 public void delete(@NonNull String databaseName, @NonNull String namespace,
215 List<String> uris, AndroidFuture<AppSearchBatchResult> callback) {
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700216 Preconditions.checkNotNull(uris);
217 Preconditions.checkNotNull(callback);
218 int callingUid = Binder.getCallingUidOrThrow();
219 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600220 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700221 try {
222 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700223 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700224 AppSearchBatchResult.Builder<String, Void> resultBuilder =
225 new AppSearchBatchResult.Builder<>();
226 for (int i = 0; i < uris.size(); i++) {
227 String uri = uris.get(i);
228 try {
Terry Wang6413aee2020-10-07 03:04:58 -0700229 impl.remove(databaseName, namespace, uri);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700230 resultBuilder.setSuccess(uri, /*result= */null);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700231 } catch (Throwable t) {
232 resultBuilder.setResult(uri, throwableToFailedResult(t));
233 }
234 }
235 callback.complete(resultBuilder.build());
236 } catch (Throwable t) {
237 callback.completeExceptionally(t);
238 } finally {
239 Binder.restoreCallingIdentity(callingIdentity);
240 }
241 }
242
243 @Override
Terry Wang6413aee2020-10-07 03:04:58 -0700244 public void deleteByTypes(@NonNull String databaseName,
Alexander Dorokhine7f46d6f2020-04-14 14:40:21 -0700245 List<String> schemaTypes, AndroidFuture<AppSearchBatchResult> callback) {
246 Preconditions.checkNotNull(schemaTypes);
247 Preconditions.checkNotNull(callback);
248 int callingUid = Binder.getCallingUidOrThrow();
249 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600250 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine7f46d6f2020-04-14 14:40:21 -0700251 try {
252 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700253 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhine7f46d6f2020-04-14 14:40:21 -0700254 AppSearchBatchResult.Builder<String, Void> resultBuilder =
255 new AppSearchBatchResult.Builder<>();
256 for (int i = 0; i < schemaTypes.size(); i++) {
257 String schemaType = schemaTypes.get(i);
258 try {
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700259 impl.removeByType(databaseName, schemaType);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700260 resultBuilder.setSuccess(schemaType, /*result=*/ null);
Alexander Dorokhine7f46d6f2020-04-14 14:40:21 -0700261 } catch (Throwable t) {
262 resultBuilder.setResult(schemaType, throwableToFailedResult(t));
263 }
264 }
265 callback.complete(resultBuilder.build());
266 } catch (Throwable t) {
267 callback.completeExceptionally(t);
268 } finally {
269 Binder.restoreCallingIdentity(callingIdentity);
270 }
271 }
272
273 @Override
Terry Wang6413aee2020-10-07 03:04:58 -0700274 public void deleteAll(@NonNull String databaseName,
275 @NonNull AndroidFuture<AppSearchResult> callback) {
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700276 Preconditions.checkNotNull(callback);
277 int callingUid = Binder.getCallingUidOrThrow();
278 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600279 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700280 try {
281 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700282 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700283 impl.removeAll(databaseName);
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700284 callback.complete(AppSearchResult.newSuccessfulResult(null));
285 } catch (Throwable t) {
286 callback.complete(throwableToFailedResult(t));
287 } finally {
288 Binder.restoreCallingIdentity(callingIdentity);
289 }
290 }
291
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700292 /**
Terry Wang6413aee2020-10-07 03:04:58 -0700293 * Rewrites the database name by adding a prefix of unique name for the given uid.
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700294 *
295 * <p>The current implementation returns the package name of the app with this uid in a
296 * format like {@code com.example.package} or {@code com.example.sharedname:5678}.
297 */
298 @NonNull
Terry Wang6413aee2020-10-07 03:04:58 -0700299 private String rewriteDatabaseNameWithUid(String databaseName, int callingUid) {
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700300 // For regular apps, this call will return the package name. If callingUid is an
301 // android:sharedUserId, this value may be another type of name and have a :uid suffix.
302 String callingUidName = getContext().getPackageManager().getNameForUid(callingUid);
303 if (callingUidName == null) {
304 // Not sure how this is possible --- maybe app was uninstalled?
305 throw new IllegalStateException(
306 "Failed to look up package name for uid " + callingUid);
307 }
Terry Wang6413aee2020-10-07 03:04:58 -0700308 return callingUidName + CALLING_NAME_DATABASE_DELIMITER + databaseName;
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700309 }
310
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800311 private <ValueType> AppSearchResult<ValueType> throwableToFailedResult(
312 @NonNull Throwable t) {
313 if (t instanceof AppSearchException) {
314 return ((AppSearchException) t).toAppSearchResult();
315 }
316
317 @AppSearchResult.ResultCode int resultCode;
318 if (t instanceof IllegalStateException) {
319 resultCode = AppSearchResult.RESULT_INTERNAL_ERROR;
320 } else if (t instanceof IllegalArgumentException) {
321 resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT;
322 } else if (t instanceof IOException) {
323 resultCode = AppSearchResult.RESULT_IO_ERROR;
324 } else {
325 resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR;
326 }
327 return AppSearchResult.newFailedResult(resultCode, t.getMessage());
328 }
Terry Wangfebbead2019-10-17 17:05:18 -0700329 }
330}