blob: 7cd6ee24cb20f7a04d308d354c3c6527798e881b [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 Dorokhineebd37742020-09-22 15:02:26 -070036import com.android.server.appsearch.external.localbackend.AppSearchImpl;
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070037import com.android.server.appsearch.external.localbackend.converter.GenericDocumentToProtoConverter;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070038import com.android.server.appsearch.external.localbackend.converter.SchemaToProtoConverter;
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070039import com.android.server.appsearch.external.localbackend.converter.SearchResultToProtoConverter;
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -070040import com.android.server.appsearch.external.localbackend.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 Dorokhine18465842020-01-21 01:08:57 -080049import java.util.List;
50
Terry Wangfebbead2019-10-17 17:05:18 -070051/**
52 * TODO(b/142567528): add comments when implement this class
53 */
54public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070055 private static final String TAG = "AppSearchManagerService";
Terry Wang6413aee2020-10-07 03:04:58 -070056 private static final char CALLING_NAME_DATABASE_DELIMITER = '$';
Terry Wangfebbead2019-10-17 17:05:18 -070057
58 public AppSearchManagerService(Context context) {
59 super(context);
60 }
61
62 @Override
63 public void onStart() {
64 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
65 }
66
67 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080068 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -080069 public void setSchema(
Terry Wang6413aee2020-10-07 03:04:58 -070070 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070071 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -080072 boolean forceOverride,
73 @NonNull AndroidFuture<AppSearchResult> callback) {
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070074 Preconditions.checkNotNull(schemaBundles);
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080075 Preconditions.checkNotNull(callback);
76 int callingUid = Binder.getCallingUidOrThrow();
77 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -060078 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080079 try {
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070080 SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder();
81 for (int i = 0; i < schemaBundles.size(); i++) {
82 AppSearchSchema schema = new AppSearchSchema(schemaBundles.get(i));
83 SchemaTypeConfigProto schemaTypeProto = SchemaToProtoConverter.convert(schema);
84 schemaProtoBuilder.addTypes(schemaTypeProto);
85 }
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080086 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -070087 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070088 impl.setSchema(databaseName, schemaProtoBuilder.build(), forceOverride);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070089 callback.complete(AppSearchResult.newSuccessfulResult(/*result=*/ null));
Alexander Dorokhine179c8b82020-01-11 00:17:48 -080090 } catch (Throwable t) {
Alexander Dorokhine969f4462020-03-05 15:54:19 -080091 callback.complete(throwableToFailedResult(t));
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080092 } finally {
93 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhine179c8b82020-01-11 00:17:48 -080094 }
95 }
96
97 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -080098 public void putDocuments(
Terry Wang6413aee2020-10-07 03:04:58 -070099 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700100 @NonNull List<Bundle> documentBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800101 @NonNull AndroidFuture<AppSearchBatchResult> callback) {
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700102 Preconditions.checkNotNull(documentBundles);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800103 Preconditions.checkNotNull(callback);
104 int callingUid = Binder.getCallingUidOrThrow();
105 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600106 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800107 try {
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800108 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700109 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800110 AppSearchBatchResult.Builder<String, Void> resultBuilder =
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800111 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700112 for (int i = 0; i < documentBundles.size(); i++) {
113 GenericDocument document = new GenericDocument(documentBundles.get(i));
114 DocumentProto documentProto = GenericDocumentToProtoConverter.convert(document);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800115 try {
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700116 impl.putDocument(databaseName, documentProto);
117 resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
Alexander Dorokhine18465842020-01-21 01:08:57 -0800118 } catch (Throwable t) {
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800119 resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
Alexander Dorokhine18465842020-01-21 01:08:57 -0800120 }
121 }
122 callback.complete(resultBuilder.build());
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800123 } catch (Throwable t) {
124 callback.completeExceptionally(t);
Alexander Dorokhinecc223452020-01-19 03:00:28 -0800125 } finally {
126 Binder.restoreCallingIdentity(callingIdentity);
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800127 }
128 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800129
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800130 @Override
Terry Wang6413aee2020-10-07 03:04:58 -0700131 public void getDocuments(@NonNull String databaseName, @NonNull String namespace,
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800132 @NonNull List<String> uris, @NonNull AndroidFuture<AppSearchBatchResult> callback) {
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 {
139 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700140 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700141 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800142 new AppSearchBatchResult.Builder<>();
143 for (int i = 0; i < uris.size(); i++) {
144 String uri = uris.get(i);
145 try {
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700146 DocumentProto documentProto = impl.getDocument(
Terry Wang6413aee2020-10-07 03:04:58 -0700147 databaseName, namespace, uri);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700148 if (documentProto == null) {
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800149 resultBuilder.setFailure(
150 uri, AppSearchResult.RESULT_NOT_FOUND, /*errorMessage=*/ null);
151 } else {
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700152 GenericDocument genericDocument =
153 GenericDocumentToProtoConverter.convert(documentProto);
154 resultBuilder.setSuccess(uri, genericDocument.getBundle());
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800155 }
156 } catch (Throwable t) {
157 resultBuilder.setResult(uri, throwableToFailedResult(t));
158 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800159 }
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800160 callback.complete(resultBuilder.build());
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800161 } catch (Throwable t) {
162 callback.completeExceptionally(t);
163 } finally {
164 Binder.restoreCallingIdentity(callingIdentity);
165 }
166 }
167
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800168 // TODO(sidchhabra): Do this in a threadpool.
169 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800170 public void query(
Terry Wang6413aee2020-10-07 03:04:58 -0700171 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700172 @NonNull String queryExpression,
173 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800174 @NonNull AndroidFuture<AppSearchResult> callback) {
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700175 Preconditions.checkNotNull(queryExpression);
176 Preconditions.checkNotNull(searchSpecBundle);
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800177 Preconditions.checkNotNull(callback);
178 int callingUid = Binder.getCallingUidOrThrow();
179 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600180 final long callingIdentity = Binder.clearCallingIdentity();
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800181 try {
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700182 SearchSpec searchSpec = new SearchSpec(searchSpecBundle);
183 SearchSpecProto searchSpecProto =
184 SearchSpecToProtoConverter.toSearchSpecProto(searchSpec);
185 searchSpecProto = searchSpecProto.toBuilder()
186 .setQuery(queryExpression).build();
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800187 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700188 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700189 // TODO(adorokhine): handle pagination
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700190 SearchResultProto searchResultProto = impl.query(
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700191 databaseName,
192 searchSpecProto,
193 SearchSpecToProtoConverter.toResultSpecProto(searchSpec),
194 SearchSpecToProtoConverter.toScoringSpecProto(searchSpec));
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700195 List<SearchResult> searchResultList =
196 SearchResultToProtoConverter.convert(searchResultProto);
197 SearchResults searchResults =
198 new SearchResults(searchResultList, searchResultProto.getNextPageToken());
199 callback.complete(AppSearchResult.newSuccessfulResult(searchResults));
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800200 } catch (Throwable t) {
201 callback.complete(throwableToFailedResult(t));
202 } finally {
203 Binder.restoreCallingIdentity(callingIdentity);
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800204 }
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800205 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800206
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700207 @Override
Terry Wang6413aee2020-10-07 03:04:58 -0700208 public void delete(@NonNull String databaseName, @NonNull String namespace,
209 List<String> uris, AndroidFuture<AppSearchBatchResult> callback) {
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700210 Preconditions.checkNotNull(uris);
211 Preconditions.checkNotNull(callback);
212 int callingUid = Binder.getCallingUidOrThrow();
213 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600214 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700215 try {
216 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700217 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700218 AppSearchBatchResult.Builder<String, Void> resultBuilder =
219 new AppSearchBatchResult.Builder<>();
220 for (int i = 0; i < uris.size(); i++) {
221 String uri = uris.get(i);
222 try {
Terry Wang6413aee2020-10-07 03:04:58 -0700223 impl.remove(databaseName, namespace, uri);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700224 resultBuilder.setSuccess(uri, /*result= */null);
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700225 } catch (Throwable t) {
226 resultBuilder.setResult(uri, throwableToFailedResult(t));
227 }
228 }
229 callback.complete(resultBuilder.build());
230 } catch (Throwable t) {
231 callback.completeExceptionally(t);
232 } finally {
233 Binder.restoreCallingIdentity(callingIdentity);
234 }
235 }
236
237 @Override
Terry Wang6413aee2020-10-07 03:04:58 -0700238 public void deleteByTypes(@NonNull String databaseName,
Alexander Dorokhine7f46d6f2020-04-14 14:40:21 -0700239 List<String> schemaTypes, AndroidFuture<AppSearchBatchResult> callback) {
240 Preconditions.checkNotNull(schemaTypes);
241 Preconditions.checkNotNull(callback);
242 int callingUid = Binder.getCallingUidOrThrow();
243 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600244 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhine7f46d6f2020-04-14 14:40:21 -0700245 try {
246 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700247 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhine7f46d6f2020-04-14 14:40:21 -0700248 AppSearchBatchResult.Builder<String, Void> resultBuilder =
249 new AppSearchBatchResult.Builder<>();
250 for (int i = 0; i < schemaTypes.size(); i++) {
251 String schemaType = schemaTypes.get(i);
252 try {
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700253 impl.removeByType(databaseName, schemaType);
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700254 resultBuilder.setSuccess(schemaType, /*result=*/ null);
Alexander Dorokhine7f46d6f2020-04-14 14:40:21 -0700255 } catch (Throwable t) {
256 resultBuilder.setResult(schemaType, throwableToFailedResult(t));
257 }
258 }
259 callback.complete(resultBuilder.build());
260 } catch (Throwable t) {
261 callback.completeExceptionally(t);
262 } finally {
263 Binder.restoreCallingIdentity(callingIdentity);
264 }
265 }
266
267 @Override
Terry Wang6413aee2020-10-07 03:04:58 -0700268 public void deleteAll(@NonNull String databaseName,
269 @NonNull AndroidFuture<AppSearchResult> callback) {
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700270 Preconditions.checkNotNull(callback);
271 int callingUid = Binder.getCallingUidOrThrow();
272 int callingUserId = UserHandle.getUserId(callingUid);
Jeff Sharkeyea5328c2020-10-06 11:18:09 -0600273 final long callingIdentity = Binder.clearCallingIdentity();
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700274 try {
275 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
Terry Wang6413aee2020-10-07 03:04:58 -0700276 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700277 impl.removeAll(databaseName);
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700278 callback.complete(AppSearchResult.newSuccessfulResult(null));
279 } catch (Throwable t) {
280 callback.complete(throwableToFailedResult(t));
281 } finally {
282 Binder.restoreCallingIdentity(callingIdentity);
283 }
284 }
285
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700286 /**
Terry Wang6413aee2020-10-07 03:04:58 -0700287 * Rewrites the database name by adding a prefix of unique name for the given uid.
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700288 *
289 * <p>The current implementation returns the package name of the app with this uid in a
290 * format like {@code com.example.package} or {@code com.example.sharedname:5678}.
291 */
292 @NonNull
Terry Wang6413aee2020-10-07 03:04:58 -0700293 private String rewriteDatabaseNameWithUid(String databaseName, int callingUid) {
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700294 // For regular apps, this call will return the package name. If callingUid is an
295 // android:sharedUserId, this value may be another type of name and have a :uid suffix.
296 String callingUidName = getContext().getPackageManager().getNameForUid(callingUid);
297 if (callingUidName == null) {
298 // Not sure how this is possible --- maybe app was uninstalled?
299 throw new IllegalStateException(
300 "Failed to look up package name for uid " + callingUid);
301 }
Terry Wang6413aee2020-10-07 03:04:58 -0700302 return callingUidName + CALLING_NAME_DATABASE_DELIMITER + databaseName;
Alexander Dorokhineebd37742020-09-22 15:02:26 -0700303 }
304
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800305 private <ValueType> AppSearchResult<ValueType> throwableToFailedResult(
306 @NonNull Throwable t) {
307 if (t instanceof AppSearchException) {
308 return ((AppSearchException) t).toAppSearchResult();
309 }
310
311 @AppSearchResult.ResultCode int resultCode;
312 if (t instanceof IllegalStateException) {
313 resultCode = AppSearchResult.RESULT_INTERNAL_ERROR;
314 } else if (t instanceof IllegalArgumentException) {
315 resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT;
316 } else if (t instanceof IOException) {
317 resultCode = AppSearchResult.RESULT_IO_ERROR;
318 } else {
319 resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR;
320 }
321 return AppSearchResult.newFailedResult(resultCode, t.getMessage());
322 }
Terry Wangfebbead2019-10-17 17:05:18 -0700323 }
324}