blob: d3f05b0eb607047a165bb12b3a118b0772d077cc [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;
Terry Wange201dc02021-04-16 01:03:20 -070019import static android.os.Process.INVALID_UID;
Terry Wangdbd1dca2020-11-03 17:03:56 -080020
Alexander Dorokhine5c416772021-06-04 09:05:00 -070021import android.Manifest;
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -080022import android.annotation.ElapsedRealtimeLong;
sidchhabraa7c8f8a2020-01-16 18:38:17 -080023import android.annotation.NonNull;
Alexander Dorokhine18465842020-01-21 01:08:57 -080024import android.app.appsearch.AppSearchBatchResult;
Terry Wang623e3b02021-02-02 20:27:33 -080025import android.app.appsearch.AppSearchMigrationHelper;
Alexander Dorokhine969f4462020-03-05 15:54:19 -080026import android.app.appsearch.AppSearchResult;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070027import android.app.appsearch.AppSearchSchema;
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070028import android.app.appsearch.GenericDocument;
Alexander Dorokhine9795b512021-03-23 22:06:59 -070029import android.app.appsearch.GetSchemaResponse;
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 Wang623e3b02021-02-02 20:27:33 -080033import android.app.appsearch.SetSchemaResponse;
Cassie Wang8f0df492021-03-24 09:23:18 -070034import android.app.appsearch.StorageInfo;
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -070035import android.app.appsearch.aidl.AppSearchBatchResultParcel;
36import android.app.appsearch.aidl.AppSearchResultParcel;
37import android.app.appsearch.aidl.IAppSearchBatchResultCallback;
38import android.app.appsearch.aidl.IAppSearchManager;
39import android.app.appsearch.aidl.IAppSearchResultCallback;
Alexander Dorokhine4d051632021-06-18 10:48:58 -070040import android.app.appsearch.exceptions.AppSearchException;
Terry Wang12dc6c02021-03-31 19:26:16 -070041import android.content.BroadcastReceiver;
Terry Wangfebbead2019-10-17 17:05:18 -070042import android.content.Context;
Terry Wang12dc6c02021-03-31 19:26:16 -070043import android.content.Intent;
44import android.content.IntentFilter;
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -070045import android.content.pm.PackageInfo;
Yang Yu0fcd51a2021-04-23 11:25:44 -070046import android.content.pm.PackageManager;
Yang Yu0fcd51a2021-04-23 11:25:44 -070047import android.content.pm.PackageStats;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080048import android.os.Binder;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070049import android.os.Bundle;
Terry Wang623e3b02021-02-02 20:27:33 -080050import android.os.ParcelFileDescriptor;
Terry Wangdbd1dca2020-11-03 17:03:56 -080051import android.os.RemoteException;
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -080052import android.os.SystemClock;
Cassie Wang0c62d992021-01-15 14:39:30 -080053import android.os.UserHandle;
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070054import android.os.UserManager;
Alexander Dorokhineab789062021-01-11 21:00:00 -080055import android.util.ArrayMap;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080056import android.util.ArraySet;
Terry Wangdbd1dca2020-11-03 17:03:56 -080057import android.util.Log;
Terry Wangfebbead2019-10-17 17:05:18 -070058
Cassie Wang15c86972021-02-09 13:43:25 -080059import com.android.internal.annotations.GuardedBy;
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -070060import com.android.server.LocalManagerRegistry;
Terry Wangfebbead2019-10-17 17:05:18 -070061import com.android.server.SystemService;
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -080062import com.android.server.appsearch.external.localstorage.stats.CallStats;
Alexander Dorokhine44c04972021-06-22 12:32:15 -070063import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
Alexander Dorokhine5c416772021-06-04 09:05:00 -070064import com.android.server.appsearch.util.PackageUtil;
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -070065import com.android.server.usage.StorageStatsManagerLocal;
66import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080067
Alexander Dorokhinec77f4442021-04-14 09:26:06 -070068import com.google.android.icing.proto.PersistType;
69
Terry Wang623e3b02021-02-02 20:27:33 -080070import java.io.DataInputStream;
71import java.io.DataOutputStream;
72import java.io.EOFException;
73import java.io.FileInputStream;
74import java.io.FileOutputStream;
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080075import java.util.ArrayList;
Alexander Dorokhine18465842020-01-21 01:08:57 -080076import java.util.List;
Alexander Dorokhineab789062021-01-11 21:00:00 -080077import java.util.Map;
Alexander Dorokhined18f8842021-01-20 15:26:13 -080078import java.util.Objects;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080079import java.util.Set;
Terry Wange04ceab2021-03-29 19:25:12 -070080import java.util.concurrent.Executor;
Terry Wangd2186e52021-04-14 13:19:45 -070081import java.util.concurrent.LinkedBlockingQueue;
Terry Wange04ceab2021-03-29 19:25:12 -070082import java.util.concurrent.ThreadPoolExecutor;
83import java.util.concurrent.TimeUnit;
Alexander Dorokhine18465842020-01-21 01:08:57 -080084
Alexander Dorokhine5d2bb0b2021-06-24 22:58:46 -070085/**
86 * The main service implementation which contains AppSearch's platform functionality.
87 * @hide
88 */
Terry Wangfebbead2019-10-17 17:05:18 -070089public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070090 private static final String TAG = "AppSearchManagerService";
Terry Wang12dc6c02021-03-31 19:26:16 -070091 private final Context mContext;
Yang Yu0fcd51a2021-04-23 11:25:44 -070092 private PackageManager mPackageManager;
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070093 private UserManager mUserManager;
Alexander Dorokhine4d051632021-06-18 10:48:58 -070094 private AppSearchUserInstanceManager mAppSearchUserInstanceManager;
Terry Wangfebbead2019-10-17 17:05:18 -070095
Terry Wange04ceab2021-03-29 19:25:12 -070096 // Never call shutdownNow(). It will cancel the futures it's returned. And since
97 // Executor#execute won't return anything, we will hang forever waiting for the execution.
98 // AppSearch multi-thread execution is guarded by Read & Write Lock in AppSearchImpl, all
99 // mutate requests will need to gain write lock and query requests need to gain read lock.
100 private static final Executor EXECUTOR = new ThreadPoolExecutor(/*corePoolSize=*/1,
101 Runtime.getRuntime().availableProcessors(), /*keepAliveTime*/ 60L, TimeUnit.SECONDS,
Terry Wangd2186e52021-04-14 13:19:45 -0700102 new LinkedBlockingQueue<>());
Terry Wange04ceab2021-03-29 19:25:12 -0700103
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700104 // Cache of unlocked users so we don't have to query UserManager service each time. The "locked"
105 // suffix refers to the fact that access to the field should be locked; unrelated to the
106 // unlocked status of users.
107 @GuardedBy("mUnlockedUsersLocked")
108 private final Set<UserHandle> mUnlockedUsersLocked = new ArraySet<>();
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800109
Terry Wangfebbead2019-10-17 17:05:18 -0700110 public AppSearchManagerService(Context context) {
111 super(context);
Terry Wang12dc6c02021-03-31 19:26:16 -0700112 mContext = context;
Terry Wangfebbead2019-10-17 17:05:18 -0700113 }
114
115 @Override
116 public void onStart() {
117 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
Yang Yu0fcd51a2021-04-23 11:25:44 -0700118 mPackageManager = getContext().getPackageManager();
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700119 mAppSearchUserInstanceManager = AppSearchUserInstanceManager.getInstance();
Terry Wang12dc6c02021-03-31 19:26:16 -0700120 mUserManager = mContext.getSystemService(UserManager.class);
121 registerReceivers();
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -0700122 LocalManagerRegistry.getManager(StorageStatsManagerLocal.class)
Yang Yu0fcd51a2021-04-23 11:25:44 -0700123 .registerStorageStatsAugmenter(new AppSearchStorageStatsAugmenter(), TAG);
Terry Wang12dc6c02021-03-31 19:26:16 -0700124 }
125
126 private void registerReceivers() {
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700127 mContext.registerReceiverForAllUsers(
128 new UserActionReceiver(),
129 new IntentFilter(Intent.ACTION_USER_REMOVED),
130 /*broadcastPermission=*/ null,
Terry Wang12dc6c02021-03-31 19:26:16 -0700131 /*scheduler=*/ null);
Terry Wange201dc02021-04-16 01:03:20 -0700132
133 //TODO(b/145759910) Add a direct callback when user clears the data instead of relying on
134 // broadcasts
135 IntentFilter packageChangedFilter = new IntentFilter();
136 packageChangedFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
137 packageChangedFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
138 packageChangedFilter.addDataScheme("package");
139 packageChangedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700140 mContext.registerReceiverForAllUsers(
141 new PackageChangedReceiver(),
142 packageChangedFilter,
143 /*broadcastPermission=*/ null,
Terry Wange201dc02021-04-16 01:03:20 -0700144 /*scheduler=*/ null);
Terry Wang12dc6c02021-03-31 19:26:16 -0700145 }
146
147 private class UserActionReceiver extends BroadcastReceiver {
148 @Override
149 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700150 Objects.requireNonNull(context);
151 Objects.requireNonNull(intent);
152
Terry Wang12dc6c02021-03-31 19:26:16 -0700153 switch (intent.getAction()) {
154 case Intent.ACTION_USER_REMOVED:
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700155 UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
156 if (userHandle == null) {
157 Log.e(TAG, "Extra "
158 + Intent.EXTRA_USER + " is missing in the intent: " + intent);
Terry Wang12dc6c02021-03-31 19:26:16 -0700159 return;
160 }
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700161 handleUserRemoved(userHandle);
Terry Wang12dc6c02021-03-31 19:26:16 -0700162 break;
163 default:
Terry Wange201dc02021-04-16 01:03:20 -0700164 Log.e(TAG, "Received unknown intent: " + intent);
Terry Wang12dc6c02021-03-31 19:26:16 -0700165 }
166 }
167 }
168
169 /**
170 * Handles user removed action.
171 *
172 * <p>Only need to clear the AppSearchImpl instance. The data of AppSearch is saved in the
173 * "credential encrypted" system directory of each user. That directory will be auto-deleted
174 * when a user is removed.
175 *
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700176 * @param userHandle The multi-user handle of the user that need to be removed.
Terry Wang12dc6c02021-03-31 19:26:16 -0700177 *
178 * @see android.os.Environment#getDataSystemCeDirectory
179 */
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700180 private void handleUserRemoved(@NonNull UserHandle userHandle) {
Terry Wang12dc6c02021-03-31 19:26:16 -0700181 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700182 mAppSearchUserInstanceManager.closeAndRemoveUserInstance(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700183 Log.i(TAG, "Removed AppSearchImpl instance for: " + userHandle);
Terry Wang12dc6c02021-03-31 19:26:16 -0700184 } catch (Throwable t) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700185 Log.e(TAG, "Unable to remove data for: " + userHandle, t);
Terry Wange201dc02021-04-16 01:03:20 -0700186 }
187 }
188
189 private class PackageChangedReceiver extends BroadcastReceiver {
190 @Override
191 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700192 Objects.requireNonNull(context);
193 Objects.requireNonNull(intent);
194
Terry Wange201dc02021-04-16 01:03:20 -0700195 switch (intent.getAction()) {
196 case Intent.ACTION_PACKAGE_FULLY_REMOVED:
197 case Intent.ACTION_PACKAGE_DATA_CLEARED:
198 String packageName = intent.getData().getSchemeSpecificPart();
199 if (packageName == null) {
200 Log.e(TAG, "Package name is missing in the intent: " + intent);
201 return;
202 }
203 int uid = intent.getIntExtra(Intent.EXTRA_UID, INVALID_UID);
204 if (uid == INVALID_UID) {
205 Log.e(TAG, "uid is missing in the intent: " + intent);
206 return;
207 }
208 handlePackageRemoved(packageName, uid);
209 break;
210 default:
211 Log.e(TAG, "Received unknown intent: " + intent);
212 }
213 }
214 }
215
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700216 private void handlePackageRemoved(@NonNull String packageName, int uid) {
217 UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
Terry Wange201dc02021-04-16 01:03:20 -0700218 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700219 if (isUserLocked(userHandle)) {
Terry Wanga9e6e212021-04-23 15:51:37 -0700220 // We cannot access a locked user's directry and remove package data from it.
221 // We should remove those uninstalled package data when the user is unlocking.
Terry Wange201dc02021-04-16 01:03:20 -0700222 return;
223 }
Terry Wanga9e6e212021-04-23 15:51:37 -0700224 // Only clear the package's data if AppSearch exists for this user.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700225 if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
226 AppSearchUserInstance instance =
227 mAppSearchUserInstanceManager.getOrCreateUserInstance(
228 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
Terry Wange201dc02021-04-16 01:03:20 -0700229 //TODO(b/145759910) clear visibility setting for package.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700230 instance.getAppSearchImpl().clearPackageData(packageName);
231 instance.getLogger().removeCachedUidForPackage(packageName);
Terry Wange201dc02021-04-16 01:03:20 -0700232 }
233 } catch (Throwable t) {
234 Log.e(TAG, "Unable to remove data for package: " + packageName, t);
Terry Wang12dc6c02021-03-31 19:26:16 -0700235 }
Terry Wangfebbead2019-10-17 17:05:18 -0700236 }
237
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800238 @Override
Pinyao Tingd5c2ed92021-03-18 14:51:54 -0700239 public void onUserUnlocking(@NonNull TargetUser user) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700240 Objects.requireNonNull(user);
Terry Wanga9e6e212021-04-23 15:51:37 -0700241 UserHandle userHandle = user.getUserHandle();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700242 synchronized (mUnlockedUsersLocked) {
Terry Wanga9e6e212021-04-23 15:51:37 -0700243 mUnlockedUsersLocked.add(userHandle);
Cassie Wang15c86972021-02-09 13:43:25 -0800244 }
Terry Wanga9e6e212021-04-23 15:51:37 -0700245 EXECUTOR.execute(() -> {
246 try {
247 // Only clear the package's data if AppSearch exists for this user.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700248 if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
249 AppSearchUserInstance instance =
250 mAppSearchUserInstanceManager.getOrCreateUserInstance(
251 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
Terry Wanga9e6e212021-04-23 15:51:37 -0700252 List<PackageInfo> installedPackageInfos = mContext
253 .createContextAsUser(userHandle, /*flags=*/0)
254 .getPackageManager()
255 .getInstalledPackages(/*flags=*/0);
256 Set<String> packagesToKeep = new ArraySet<>(installedPackageInfos.size());
257 for (int i = 0; i < installedPackageInfos.size(); i++) {
258 packagesToKeep.add(installedPackageInfos.get(i).packageName);
259 }
260 packagesToKeep.add(VisibilityStore.PACKAGE_NAME);
261 //TODO(b/145759910) clear visibility setting for package.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700262 instance.getAppSearchImpl().prunePackageData(packagesToKeep);
Terry Wanga9e6e212021-04-23 15:51:37 -0700263 }
264 } catch (Throwable t) {
265 Log.e(TAG, "Unable to prune packages for " + user, t);
266 }
267 });
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800268 }
269
Terry Wangde9f3382021-04-28 19:45:07 -0700270 @Override
271 public void onUserStopping(@NonNull TargetUser user) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700272 Objects.requireNonNull(user);
273
274 synchronized (mUnlockedUsersLocked) {
275 UserHandle userHandle = user.getUserHandle();
276 mUnlockedUsersLocked.remove(userHandle);
Terry Wangde9f3382021-04-28 19:45:07 -0700277 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700278 mAppSearchUserInstanceManager.closeAndRemoveUserInstance(userHandle);
Terry Wangde9f3382021-04-28 19:45:07 -0700279 } catch (Throwable t) {
280 Log.e(TAG, "Error handling user stopping.", t);
281 }
282 }
283 }
284
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700285 private void verifyUserUnlocked(@NonNull UserHandle callingUser) {
286 if (isUserLocked(callingUser)) {
287 throw new IllegalStateException(callingUser + " is locked or not running.");
Terry Wange201dc02021-04-16 01:03:20 -0700288 }
289 }
290
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700291 private boolean isUserLocked(@NonNull UserHandle callingUser) {
292 synchronized (mUnlockedUsersLocked) {
Yang Yu0fcd51a2021-04-23 11:25:44 -0700293 // First, check the local copy.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700294 if (mUnlockedUsersLocked.contains(callingUser)) {
Terry Wange201dc02021-04-16 01:03:20 -0700295 return false;
Yang Yu0fcd51a2021-04-23 11:25:44 -0700296 }
297 // If the local copy says the user is locked, check with UM for the actual state,
298 // since the user might just have been unlocked.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700299 return !mUserManager.isUserUnlockingOrUnlocked(callingUser);
Yang Yu0fcd51a2021-04-23 11:25:44 -0700300 }
301 }
302
Terry Wangfebbead2019-10-17 17:05:18 -0700303 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800304 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800305 public void setSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800306 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700307 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700308 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine315cca62021-03-04 12:34:41 -0800309 @NonNull List<String> schemasNotDisplayedBySystem,
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700310 @NonNull Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800311 boolean forceOverride,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700312 int schemaVersion,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700313 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700314 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800315 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700316 Objects.requireNonNull(packageName);
317 Objects.requireNonNull(databaseName);
318 Objects.requireNonNull(schemaBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700319 Objects.requireNonNull(schemasNotDisplayedBySystem);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700320 Objects.requireNonNull(schemasVisibleToPackagesBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700321 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700322 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700323
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700324 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800325 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700326 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700327 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700328 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700329 AppSearchUserInstance instance = null;
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700330 int operationSuccessCount = 0;
331 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700332 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700333 verifyUserUnlocked(callingUser);
334 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700335 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
336 for (int i = 0; i < schemaBundles.size(); i++) {
337 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhineab789062021-01-11 21:00:00 -0800338 }
Alexander Dorokhine15d0ae42021-06-18 14:28:34 -0700339 Map<String, List<PackageIdentifier>> schemasVisibleToPackages =
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700340 new ArrayMap<>(schemasVisibleToPackagesBundles.size());
Terry Wange04ceab2021-03-29 19:25:12 -0700341 for (Map.Entry<String, List<Bundle>> entry :
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700342 schemasVisibleToPackagesBundles.entrySet()) {
Terry Wange04ceab2021-03-29 19:25:12 -0700343 List<PackageIdentifier> packageIdentifiers =
344 new ArrayList<>(entry.getValue().size());
345 for (int i = 0; i < entry.getValue().size(); i++) {
346 packageIdentifiers.add(
347 new PackageIdentifier(entry.getValue().get(i)));
348 }
Alexander Dorokhine15d0ae42021-06-18 14:28:34 -0700349 schemasVisibleToPackages.put(entry.getKey(), packageIdentifiers);
Terry Wange04ceab2021-03-29 19:25:12 -0700350 }
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700351 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
352 SetSchemaResponse setSchemaResponse = instance.getAppSearchImpl().setSchema(
Terry Wange04ceab2021-03-29 19:25:12 -0700353 packageName,
354 databaseName,
355 schemas,
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700356 instance.getVisibilityStore(),
Terry Wange04ceab2021-03-29 19:25:12 -0700357 schemasNotDisplayedBySystem,
Alexander Dorokhine15d0ae42021-06-18 14:28:34 -0700358 schemasVisibleToPackages,
Terry Wange04ceab2021-03-29 19:25:12 -0700359 forceOverride,
360 schemaVersion);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700361 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700362 invokeCallbackOnResult(callback,
363 AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
364 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700365 ++operationFailureCount;
366 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700367 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700368 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700369 if (instance != null) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700370 int estimatedBinderLatencyMillis =
371 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
372 int totalLatencyMillis =
373 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700374 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700375 .setPackageName(packageName)
376 .setDatabase(databaseName)
377 .setStatusCode(statusCode)
378 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700379 .setCallType(CallStats.CALL_TYPE_SET_SCHEMA)
380 // TODO(b/173532925) check the existing binder call latency chart
381 // is good enough for us:
382 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
383 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
384 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700385 .setNumOperationsFailed(operationFailureCount)
386 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700387 }
Alexander Dorokhineab789062021-01-11 21:00:00 -0800388 }
Terry Wange04ceab2021-03-29 19:25:12 -0700389 });
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800390 }
391
392 @Override
Terry Wang83a24932020-12-09 21:00:18 -0800393 public void getSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800394 @NonNull String packageName,
Terry Wang83a24932020-12-09 21:00:18 -0800395 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700396 @NonNull UserHandle userHandle,
Terry Wang83a24932020-12-09 21:00:18 -0800397 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700398 Objects.requireNonNull(packageName);
399 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700400 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700401 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700402
Cassie Wangb0d60122021-03-30 12:38:46 -0700403 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700404 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700405 EXECUTOR.execute(() -> {
406 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700407 verifyUserUnlocked(callingUser);
408 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700409 AppSearchUserInstance instance =
410 mAppSearchUserInstanceManager.getUserInstance(callingUser);
411 GetSchemaResponse response =
412 instance.getAppSearchImpl().getSchema(packageName, databaseName);
Terry Wange04ceab2021-03-29 19:25:12 -0700413 invokeCallbackOnResult(
414 callback,
415 AppSearchResult.newSuccessfulResult(response.getBundle()));
416 } catch (Throwable t) {
417 invokeCallbackOnError(callback, t);
418 }
419 });
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700420 }
421
422 @Override
423 public void getNamespaces(
424 @NonNull String packageName,
425 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700426 @NonNull UserHandle userHandle,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700427 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700428 Objects.requireNonNull(packageName);
429 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700430 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700431 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700432
Cassie Wangb0d60122021-03-30 12:38:46 -0700433 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700434 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700435 EXECUTOR.execute(() -> {
436 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700437 verifyUserUnlocked(callingUser);
438 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700439 AppSearchUserInstance instance =
440 mAppSearchUserInstanceManager.getUserInstance(callingUser);
441 List<String> namespaces =
442 instance.getAppSearchImpl().getNamespaces(packageName, databaseName);
443 invokeCallbackOnResult(
444 callback, AppSearchResult.newSuccessfulResult(namespaces));
Terry Wange04ceab2021-03-29 19:25:12 -0700445 } catch (Throwable t) {
446 invokeCallbackOnError(callback, t);
447 }
448 });
Terry Wang83a24932020-12-09 21:00:18 -0800449 }
450
451 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -0800452 public void putDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800453 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700454 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700455 @NonNull List<Bundle> documentBundles,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700456 @NonNull UserHandle userHandle,
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800457 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800458 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700459 Objects.requireNonNull(packageName);
460 Objects.requireNonNull(databaseName);
461 Objects.requireNonNull(documentBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700462 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700463 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700464
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700465 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800466 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700467 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700468 EXECUTOR.execute(() -> {
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800469 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700470 AppSearchUserInstance instance = null;
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800471 int operationSuccessCount = 0;
472 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700473 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700474 verifyUserUnlocked(callingUser);
475 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700476 AppSearchBatchResult.Builder<String, Void> resultBuilder =
477 new AppSearchBatchResult.Builder<>();
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700478 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700479 for (int i = 0; i < documentBundles.size(); i++) {
480 GenericDocument document = new GenericDocument(documentBundles.get(i));
481 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700482 instance.getAppSearchImpl().putDocument(
483 packageName, databaseName, document, instance.getLogger());
484 resultBuilder.setSuccess(document.getId(), /*value=*/ null);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800485 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700486 } catch (Throwable t) {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700487 resultBuilder.setResult(document.getId(), throwableToFailedResult(t));
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800488 AppSearchResult<Void> result = throwableToFailedResult(t);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700489 resultBuilder.setResult(document.getId(), result);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700490 // Since we can only include one status code in the atom,
491 // for failures, we would just save the one for the last failure
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800492 statusCode = result.getResultCode();
493 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700494 }
Alexander Dorokhine18465842020-01-21 01:08:57 -0800495 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700496 // Now that the batch has been written. Persist the newly written data.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700497 instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
Terry Wange04ceab2021-03-29 19:25:12 -0700498 invokeCallbackOnResult(callback, resultBuilder.build());
499 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700500 ++operationFailureCount;
501 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700502 invokeCallbackOnError(callback, t);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800503 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700504 if (instance != null) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700505 int estimatedBinderLatencyMillis =
506 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
507 int totalLatencyMillis =
508 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700509 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700510 .setPackageName(packageName)
511 .setDatabase(databaseName)
512 .setStatusCode(statusCode)
513 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800514 .setCallType(CallStats.CALL_TYPE_PUT_DOCUMENTS)
515 // TODO(b/173532925) check the existing binder call latency chart
516 // is good enough for us:
517 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700518 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800519 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700520 .setNumOperationsFailed(operationFailureCount)
521 .build());
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800522 }
Alexander Dorokhine18465842020-01-21 01:08:57 -0800523 }
Terry Wange04ceab2021-03-29 19:25:12 -0700524 });
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800525 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800526
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800527 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800528 public void getDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800529 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800530 @NonNull String databaseName,
531 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700532 @NonNull List<String> ids,
Alexander Dorokhine87cdd152021-01-20 15:41:25 -0800533 @NonNull Map<String, List<String>> typePropertyPaths,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700534 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700535 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800536 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700537 Objects.requireNonNull(packageName);
538 Objects.requireNonNull(databaseName);
539 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700540 Objects.requireNonNull(ids);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700541 Objects.requireNonNull(typePropertyPaths);
542 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700543 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700544
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700545 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800546 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700547 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700548 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700549 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700550 AppSearchUserInstance instance = null;
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700551 int operationSuccessCount = 0;
552 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700553 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700554 verifyUserUnlocked(callingUser);
555 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700556 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
557 new AppSearchBatchResult.Builder<>();
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700558 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700559 for (int i = 0; i < ids.size(); i++) {
560 String id = ids.get(i);
Terry Wange04ceab2021-03-29 19:25:12 -0700561 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700562 GenericDocument document = instance.getAppSearchImpl().getDocument(
563 packageName,
564 databaseName,
565 namespace,
566 id,
567 typePropertyPaths);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700568 ++operationSuccessCount;
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700569 resultBuilder.setSuccess(id, document.getBundle());
Terry Wange04ceab2021-03-29 19:25:12 -0700570 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700571 // Since we can only include one status code in the atom,
572 // for failures, we would just save the one for the last failure
573 AppSearchResult<Bundle> result = throwableToFailedResult(t);
574 resultBuilder.setResult(id, result);
575 statusCode = result.getResultCode();
576 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700577 }
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800578 }
Terry Wange04ceab2021-03-29 19:25:12 -0700579 invokeCallbackOnResult(callback, resultBuilder.build());
580 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700581 ++operationFailureCount;
582 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700583 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700584 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700585 if (instance != null) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700586 int estimatedBinderLatencyMillis =
587 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
588 int totalLatencyMillis =
589 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700590 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700591 .setPackageName(packageName)
592 .setDatabase(databaseName)
593 .setStatusCode(statusCode)
594 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700595 .setCallType(CallStats.CALL_TYPE_GET_DOCUMENTS)
596 // TODO(b/173532925) check the existing binder call latency chart
597 // is good enough for us:
598 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
599 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
600 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700601 .setNumOperationsFailed(operationFailureCount)
602 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700603 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800604 }
Terry Wange04ceab2021-03-29 19:25:12 -0700605 });
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800606 }
607
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800608 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800609 public void query(
Cassie Wang0c62d992021-01-15 14:39:30 -0800610 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700611 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700612 @NonNull String queryExpression,
613 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700614 @NonNull UserHandle userHandle,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700615 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700616 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700617 Objects.requireNonNull(packageName);
618 Objects.requireNonNull(databaseName);
619 Objects.requireNonNull(queryExpression);
620 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700621 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700622 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700623
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700624 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800625 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700626 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700627 EXECUTOR.execute(() -> {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700628 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700629 AppSearchUserInstance instance = null;
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700630 int operationSuccessCount = 0;
631 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700632 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700633 verifyUserUnlocked(callingUser);
634 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700635 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
636 SearchResultPage searchResultPage = instance.getAppSearchImpl().query(
637 packageName,
638 databaseName,
639 queryExpression,
640 new SearchSpec(searchSpecBundle),
641 instance.getLogger());
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700642 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700643 invokeCallbackOnResult(
644 callback,
645 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
646 } catch (Throwable t) {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700647 ++operationFailureCount;
648 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700649 invokeCallbackOnError(callback, t);
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700650 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700651 if (instance != null) {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700652 int estimatedBinderLatencyMillis =
653 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
654 int totalLatencyMillis =
655 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700656 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700657 .setPackageName(packageName)
658 .setDatabase(databaseName)
659 .setStatusCode(statusCode)
660 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700661 .setCallType(CallStats.CALL_TYPE_SEARCH)
662 // TODO(b/173532925) check the existing binder call latency chart
663 // is good enough for us:
664 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
665 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
666 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700667 .setNumOperationsFailed(operationFailureCount)
668 .build());
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700669 }
Terry Wange04ceab2021-03-29 19:25:12 -0700670 }
671 });
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700672 }
673
Terry Wangf2093072020-11-30 04:47:19 -0800674 @Override
Terry Wangbfbfcac2020-11-06 15:46:44 -0800675 public void globalQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800676 @NonNull String packageName,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800677 @NonNull String queryExpression,
678 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700679 @NonNull UserHandle userHandle,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700680 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800681 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700682 Objects.requireNonNull(packageName);
683 Objects.requireNonNull(queryExpression);
684 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700685 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700686 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700687
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700688 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800689 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700690 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700691 EXECUTOR.execute(() -> {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700692 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700693 AppSearchUserInstance instance = null;
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700694 int operationSuccessCount = 0;
695 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700696 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700697 verifyUserUnlocked(callingUser);
698 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700699 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
700
701 boolean callerHasSystemAccess =
702 instance.getVisibilityStore().doesCallerHaveSystemAccess(packageName);
703 SearchResultPage searchResultPage = instance.getAppSearchImpl().globalQuery(
704 queryExpression,
705 new SearchSpec(searchSpecBundle),
706 packageName,
707 instance.getVisibilityStore(),
708 callingUid,
709 callerHasSystemAccess,
710 instance.getLogger());
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700711 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700712 invokeCallbackOnResult(
713 callback,
714 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700715 } catch (Throwable t) {
716 ++operationFailureCount;
717 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700718 invokeCallbackOnError(callback, t);
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700719 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700720 if (instance != null) {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700721 int estimatedBinderLatencyMillis =
722 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
723 int totalLatencyMillis =
724 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700725 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700726 .setPackageName(packageName)
727 .setStatusCode(statusCode)
728 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700729 .setCallType(CallStats.CALL_TYPE_GLOBAL_SEARCH)
730 // TODO(b/173532925) check the existing binder call latency chart
731 // is good enough for us:
732 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
733 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
734 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700735 .setNumOperationsFailed(operationFailureCount)
736 .build());
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700737 }
Terry Wange04ceab2021-03-29 19:25:12 -0700738 }
739 });
Terry Wangbfbfcac2020-11-06 15:46:44 -0800740 }
741
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700742 @Override
Cassie Wang0c62d992021-01-15 14:39:30 -0800743 public void getNextPage(
744 long nextPageToken,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700745 @NonNull UserHandle userHandle,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700746 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700747 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700748 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700749
Terry Wangf2093072020-11-30 04:47:19 -0800750 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700751 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700752 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
753 // opened it
Terry Wange04ceab2021-03-29 19:25:12 -0700754 EXECUTOR.execute(() -> {
755 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700756 verifyUserUnlocked(callingUser);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700757 AppSearchUserInstance instance =
758 mAppSearchUserInstanceManager.getUserInstance(callingUser);
759 SearchResultPage searchResultPage =
760 instance.getAppSearchImpl().getNextPage(nextPageToken);
Terry Wange04ceab2021-03-29 19:25:12 -0700761 invokeCallbackOnResult(
762 callback,
763 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
764 } catch (Throwable t) {
765 invokeCallbackOnError(callback, t);
766 }
767 });
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700768 }
769
770 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700771 public void invalidateNextPageToken(long nextPageToken, @NonNull UserHandle userHandle) {
772 Objects.requireNonNull(userHandle);
773
Terry Wangf2093072020-11-30 04:47:19 -0800774 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700775 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700776 EXECUTOR.execute(() -> {
777 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700778 verifyUserUnlocked(callingUser);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700779 AppSearchUserInstance instance =
780 mAppSearchUserInstanceManager.getUserInstance(callingUser);
781 instance.getAppSearchImpl().invalidateNextPageToken(nextPageToken);
Terry Wange04ceab2021-03-29 19:25:12 -0700782 } catch (Throwable t) {
783 Log.e(TAG, "Unable to invalidate the query page token", t);
784 }
785 });
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800786 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800787
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700788 @Override
Terry Wang623e3b02021-02-02 20:27:33 -0800789 public void writeQueryResultsToFile(
790 @NonNull String packageName,
791 @NonNull String databaseName,
792 @NonNull ParcelFileDescriptor fileDescriptor,
793 @NonNull String queryExpression,
794 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700795 @NonNull UserHandle userHandle,
Terry Wang623e3b02021-02-02 20:27:33 -0800796 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700797 Objects.requireNonNull(packageName);
798 Objects.requireNonNull(databaseName);
799 Objects.requireNonNull(fileDescriptor);
800 Objects.requireNonNull(queryExpression);
801 Objects.requireNonNull(searchSpecBundle);
802 Objects.requireNonNull(userHandle);
803 Objects.requireNonNull(callback);
804
Terry Wang623e3b02021-02-02 20:27:33 -0800805 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700806 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700807 EXECUTOR.execute(() -> {
808 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700809 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700810 AppSearchUserInstance instance =
811 mAppSearchUserInstanceManager.getUserInstance(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700812 // we don't need to append the file. The file is always brand new.
813 try (DataOutputStream outputStream = new DataOutputStream(
814 new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700815 SearchResultPage searchResultPage = instance.getAppSearchImpl().query(
Terry Wange04ceab2021-03-29 19:25:12 -0700816 packageName,
817 databaseName,
818 queryExpression,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700819 new SearchSpec(searchSpecBundle),
820 /*logger=*/ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700821 while (!searchResultPage.getResults().isEmpty()) {
822 for (int i = 0; i < searchResultPage.getResults().size(); i++) {
823 AppSearchMigrationHelper.writeBundleToOutputStream(
824 outputStream, searchResultPage.getResults().get(i)
825 .getGenericDocument().getBundle());
826 }
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700827 searchResultPage = instance.getAppSearchImpl().getNextPage(
Terry Wange04ceab2021-03-29 19:25:12 -0700828 searchResultPage.getNextPageToken());
Terry Wang623e3b02021-02-02 20:27:33 -0800829 }
Terry Wang623e3b02021-02-02 20:27:33 -0800830 }
Terry Wange04ceab2021-03-29 19:25:12 -0700831 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
832 } catch (Throwable t) {
833 invokeCallbackOnError(callback, t);
Terry Wang623e3b02021-02-02 20:27:33 -0800834 }
Terry Wange04ceab2021-03-29 19:25:12 -0700835 });
Terry Wang623e3b02021-02-02 20:27:33 -0800836 }
837
838 @Override
839 public void putDocumentsFromFile(
840 @NonNull String packageName,
841 @NonNull String databaseName,
842 @NonNull ParcelFileDescriptor fileDescriptor,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700843 @NonNull UserHandle userHandle,
Terry Wang623e3b02021-02-02 20:27:33 -0800844 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700845 Objects.requireNonNull(packageName);
846 Objects.requireNonNull(databaseName);
847 Objects.requireNonNull(fileDescriptor);
848 Objects.requireNonNull(userHandle);
849 Objects.requireNonNull(callback);
850
Terry Wang623e3b02021-02-02 20:27:33 -0800851 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700852 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700853 EXECUTOR.execute(() -> {
854 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700855 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700856 AppSearchUserInstance instance =
857 mAppSearchUserInstanceManager.getUserInstance(callingUser);
Terry Wang623e3b02021-02-02 20:27:33 -0800858
Terry Wange04ceab2021-03-29 19:25:12 -0700859 GenericDocument document;
860 ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
861 try (DataInputStream inputStream = new DataInputStream(
862 new FileInputStream(fileDescriptor.getFileDescriptor()))) {
863 while (true) {
864 try {
865 document = AppSearchMigrationHelper
866 .readDocumentFromInputStream(inputStream);
867 } catch (EOFException e) {
868 // nothing wrong, we just finish the reading.
869 break;
870 }
871 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700872 instance.getAppSearchImpl().putDocument(
873 packageName, databaseName, document, /*logger=*/ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700874 } catch (Throwable t) {
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700875 migrationFailureBundles.add(new SetSchemaResponse.MigrationFailure(
876 document.getNamespace(),
877 document.getId(),
878 document.getSchemaType(),
879 AppSearchResult.throwableToFailedResult(t))
880 .getBundle());
Terry Wange04ceab2021-03-29 19:25:12 -0700881 }
Terry Wang623e3b02021-02-02 20:27:33 -0800882 }
883 }
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700884 instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL);
Terry Wange04ceab2021-03-29 19:25:12 -0700885 invokeCallbackOnResult(callback,
886 AppSearchResult.newSuccessfulResult(migrationFailureBundles));
887 } catch (Throwable t) {
888 invokeCallbackOnError(callback, t);
Terry Wang623e3b02021-02-02 20:27:33 -0800889 }
Terry Wange04ceab2021-03-29 19:25:12 -0700890 });
Terry Wang623e3b02021-02-02 20:27:33 -0800891 }
892
893 @Override
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800894 public void reportUsage(
895 @NonNull String packageName,
896 @NonNull String databaseName,
897 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700898 @NonNull String documentId,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800899 long usageTimeMillis,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700900 boolean systemUsage,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700901 @NonNull UserHandle userHandle,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800902 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700903 Objects.requireNonNull(packageName);
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800904 Objects.requireNonNull(databaseName);
905 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700906 Objects.requireNonNull(documentId);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700907 Objects.requireNonNull(userHandle);
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800908 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700909
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800910 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700911 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700912 EXECUTOR.execute(() -> {
913 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700914 verifyUserUnlocked(callingUser);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700915 verifyCallingPackage(callingUser, callingUid, packageName);
916 AppSearchUserInstance instance =
917 mAppSearchUserInstanceManager.getUserInstance(callingUser);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700918
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700919 if (systemUsage
920 && !instance.getVisibilityStore()
921 .doesCallerHaveSystemAccess(packageName)) {
922 throw new AppSearchException(
923 AppSearchResult.RESULT_SECURITY_ERROR,
924 packageName + " does not have access to report system usage");
Terry Wange04ceab2021-03-29 19:25:12 -0700925 }
926
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700927 instance.getAppSearchImpl().reportUsage(
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700928 packageName, databaseName, namespace, documentId,
Terry Wange04ceab2021-03-29 19:25:12 -0700929 usageTimeMillis, systemUsage);
930 invokeCallbackOnResult(
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700931 callback, AppSearchResult.newSuccessfulResult(/*value=*/ null));
Terry Wange04ceab2021-03-29 19:25:12 -0700932 } catch (Throwable t) {
933 invokeCallbackOnError(callback, t);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700934 }
Terry Wange04ceab2021-03-29 19:25:12 -0700935 });
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800936 }
937
938 @Override
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700939 public void removeByDocumentId(
Cassie Wang0c62d992021-01-15 14:39:30 -0800940 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800941 @NonNull String databaseName,
942 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700943 @NonNull List<String> ids,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700944 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700945 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800946 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700947 Objects.requireNonNull(packageName);
948 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700949 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700950 Objects.requireNonNull(ids);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700951 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700952 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700953
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700954 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800955 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700956 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700957 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700958 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700959 AppSearchUserInstance instance = null;
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700960 int operationSuccessCount = 0;
961 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700962 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700963 verifyUserUnlocked(callingUser);
964 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700965 AppSearchBatchResult.Builder<String, Void> resultBuilder =
966 new AppSearchBatchResult.Builder<>();
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700967 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700968 for (int i = 0; i < ids.size(); i++) {
969 String id = ids.get(i);
Terry Wange04ceab2021-03-29 19:25:12 -0700970 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700971 instance.getAppSearchImpl().remove(
Alexander Dorokhinea4b5bab2021-05-20 14:24:50 -0700972 packageName,
973 databaseName,
974 namespace,
975 id,
976 /*removeStatsBuilder=*/ null);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700977 ++operationSuccessCount;
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700978 resultBuilder.setSuccess(id, /*result= */ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700979 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700980 AppSearchResult<Void> result = throwableToFailedResult(t);
981 resultBuilder.setResult(id, result);
982 // Since we can only include one status code in the atom,
983 // for failures, we would just save the one for the last failure
984 statusCode = result.getResultCode();
985 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700986 }
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700987 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700988 // Now that the batch has been written. Persist the newly written data.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700989 instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
Terry Wange04ceab2021-03-29 19:25:12 -0700990 invokeCallbackOnResult(callback, resultBuilder.build());
991 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700992 ++operationFailureCount;
993 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700994 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700995 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700996 if (instance != null) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700997 int estimatedBinderLatencyMillis =
998 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
999 int totalLatencyMillis =
1000 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001001 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001002 .setPackageName(packageName)
1003 .setDatabase(databaseName)
1004 .setStatusCode(statusCode)
1005 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001006 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID)
1007 // TODO(b/173532925) check the existing binder call latency chart
1008 // is good enough for us:
1009 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1010 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1011 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001012 .setNumOperationsFailed(operationFailureCount)
1013 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001014 }
Alexander Dorokhineff82fba2020-03-09 16:35:24 -07001015 }
Terry Wange04ceab2021-03-29 19:25:12 -07001016 });
Alexander Dorokhineff82fba2020-03-09 16:35:24 -07001017 }
1018
1019 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -07001020 public void removeByQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -08001021 @NonNull String packageName,
Terry Wang26b9e5c2020-10-23 02:05:01 -07001022 @NonNull String databaseName,
1023 @NonNull String queryExpression,
1024 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001025 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001026 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Alexander Dorokhine178366b2020-10-20 17:40:49 -07001027 @NonNull IAppSearchResultCallback callback) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001028 // TODO(b/173532925) log CallStats once we have CALL_TYPE_REMOVE_BY_QUERY added
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001029 Objects.requireNonNull(packageName);
1030 Objects.requireNonNull(databaseName);
1031 Objects.requireNonNull(queryExpression);
1032 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001033 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001034 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001035
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001036 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -08001037 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001038 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001039 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001040 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001041 AppSearchUserInstance instance = null;
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001042 int operationSuccessCount = 0;
1043 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001044 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001045 verifyUserUnlocked(callingUser);
1046 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001047 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
1048 instance.getAppSearchImpl().removeByQuery(
Terry Wange04ceab2021-03-29 19:25:12 -07001049 packageName,
1050 databaseName,
1051 queryExpression,
Alexander Dorokhinea4b5bab2021-05-20 14:24:50 -07001052 new SearchSpec(searchSpecBundle),
1053 /*removeStatsBuilder=*/ null);
Alexander Dorokhinec77f4442021-04-14 09:26:06 -07001054 // Now that the batch has been written. Persist the newly written data.
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001055 instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001056 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001057 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
1058 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001059 ++operationFailureCount;
1060 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001061 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001062 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001063 if (instance != null) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001064 int estimatedBinderLatencyMillis =
1065 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1066 int totalLatencyMillis =
1067 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001068 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001069 .setPackageName(packageName)
1070 .setDatabase(databaseName)
1071 .setStatusCode(statusCode)
1072 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001073 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH)
1074 // TODO(b/173532925) check the existing binder call latency chart
1075 // is good enough for us:
1076 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1077 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1078 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001079 .setNumOperationsFailed(operationFailureCount)
1080 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001081 }
Terry Wange04ceab2021-03-29 19:25:12 -07001082 }
1083 });
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -07001084 }
1085
Terry Wangdbd1dca2020-11-03 17:03:56 -08001086 @Override
Cassie Wang8f0df492021-03-24 09:23:18 -07001087 public void getStorageInfo(
1088 @NonNull String packageName,
1089 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001090 @NonNull UserHandle userHandle,
Cassie Wang8f0df492021-03-24 09:23:18 -07001091 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001092 Objects.requireNonNull(packageName);
1093 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001094 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001095 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001096
Cassie Wang8f0df492021-03-24 09:23:18 -07001097 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001098 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001099 EXECUTOR.execute(() -> {
1100 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001101 verifyUserUnlocked(callingUser);
1102 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001103 AppSearchUserInstance instance =
1104 mAppSearchUserInstanceManager.getUserInstance(callingUser);
1105 StorageInfo storageInfo = instance.getAppSearchImpl()
1106 .getStorageInfoForDatabase(packageName, databaseName);
Terry Wange04ceab2021-03-29 19:25:12 -07001107 Bundle storageInfoBundle = storageInfo.getBundle();
1108 invokeCallbackOnResult(
1109 callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
1110 } catch (Throwable t) {
1111 invokeCallbackOnError(callback, t);
1112 }
1113 });
Cassie Wang8f0df492021-03-24 09:23:18 -07001114 }
1115
1116 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001117 public void persistToDisk(
1118 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001119 @ElapsedRealtimeLong long binderCallStartTimeMillis) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001120 Objects.requireNonNull(userHandle);
1121
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001122 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Cassie Wangb0d60122021-03-30 12:38:46 -07001123 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001124 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001125 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001126 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001127 AppSearchUserInstance instance = null;
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001128 int operationSuccessCount = 0;
1129 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001130 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001131 verifyUserUnlocked(callingUser);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001132 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
1133 instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001134 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001135 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001136 ++operationFailureCount;
1137 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001138 Log.e(TAG, "Unable to persist the data to disk", t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001139 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001140 if (instance != null) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001141 int estimatedBinderLatencyMillis =
1142 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1143 int totalLatencyMillis =
1144 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001145 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001146 .setStatusCode(statusCode)
1147 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001148 .setCallType(CallStats.CALL_TYPE_FLUSH)
1149 // TODO(b/173532925) check the existing binder call latency chart
1150 // is good enough for us:
1151 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1152 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1153 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001154 .setNumOperationsFailed(operationFailureCount)
1155 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001156 }
Terry Wange04ceab2021-03-29 19:25:12 -07001157 }
1158 });
Terry Wang2da17852020-12-16 19:59:08 -08001159 }
1160
1161 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001162 public void initialize(
1163 @NonNull UserHandle userHandle,
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001164 @ElapsedRealtimeLong long binderCallStartTimeMillis,
1165 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001166 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001167 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001168
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001169 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -08001170 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001171 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001172 EXECUTOR.execute(() -> {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001173 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001174 AppSearchUserInstance instance = null;
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001175 int operationSuccessCount = 0;
1176 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001177 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001178 verifyUserUnlocked(callingUser);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001179 instance = mAppSearchUserInstanceManager.getOrCreateUserInstance(
1180 mContext, callingUser, AppSearchConfig.getInstance(EXECUTOR));
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001181 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001182 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
1183 } catch (Throwable t) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001184 ++operationFailureCount;
1185 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001186 invokeCallbackOnError(callback, t);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001187 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001188 if (instance != null) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001189 int estimatedBinderLatencyMillis =
1190 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1191 int totalLatencyMillis =
1192 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001193 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001194 .setStatusCode(statusCode)
1195 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001196 .setCallType(CallStats.CALL_TYPE_INITIALIZE)
1197 // TODO(b/173532925) check the existing binder call latency chart
1198 // is good enough for us:
1199 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1200 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1201 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001202 .setNumOperationsFailed(operationFailureCount)
1203 .build());
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001204 }
Terry Wange04ceab2021-03-29 19:25:12 -07001205 }
1206 });
Terry Wangdbd1dca2020-11-03 17:03:56 -08001207 }
1208
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001209 private void verifyCallingPackage(
1210 @NonNull UserHandle actualCallingUser,
1211 int actualCallingUid,
1212 @NonNull String claimedCallingPackage) {
1213 Objects.requireNonNull(actualCallingUser);
1214 Objects.requireNonNull(claimedCallingPackage);
1215
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001216 int claimedCallingUid = PackageUtil.getPackageUidAsUser(
1217 mContext, claimedCallingPackage, actualCallingUser);
1218 if (claimedCallingUid == INVALID_UID) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001219 throw new SecurityException(
1220 "Specified calling package [" + claimedCallingPackage + "] not found");
1221 }
1222 if (claimedCallingUid != actualCallingUid) {
Cassie Wang0c62d992021-01-15 14:39:30 -08001223 throw new SecurityException(
1224 "Specified calling package ["
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001225 + claimedCallingPackage
Cassie Wang0c62d992021-01-15 14:39:30 -08001226 + "] does not match the calling uid "
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001227 + actualCallingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -07001228 }
Alexander Dorokhineebd37742020-09-22 15:02:26 -07001229 }
1230
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001231 /** Invokes the {@link IAppSearchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -08001232 private void invokeCallbackOnResult(
1233 IAppSearchResultCallback callback, AppSearchResult<?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -08001234 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001235 callback.onResult(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001236 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001237 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001238 }
Terry Wangdbd1dca2020-11-03 17:03:56 -08001239 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001240
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001241 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -08001242 private void invokeCallbackOnResult(
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001243 IAppSearchBatchResultCallback callback, AppSearchBatchResult<String, ?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -08001244 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001245 callback.onResult(new AppSearchBatchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001246 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001247 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001248 }
Terry Wangdbd1dca2020-11-03 17:03:56 -08001249 }
1250
1251 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001252 * Invokes the {@link IAppSearchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001253 *
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001254 * <p>The throwable is convert to a {@link AppSearchResult};
Terry Wangdbd1dca2020-11-03 17:03:56 -08001255 */
1256 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001257 AppSearchResult<?> result = throwableToFailedResult(throwable);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001258 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001259 callback.onResult(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001260 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001261 Log.e(TAG, "Unable to send result to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001262 }
1263 }
1264
1265 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001266 * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001267 *
Alexander Dorokhineb5d34b12021-04-15 00:32:15 -07001268 * <p>The throwable is converted to {@link AppSearchResult}.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001269 */
Cassie Wang0c62d992021-01-15 14:39:30 -08001270 private void invokeCallbackOnError(
Alexander Dorokhineb5d34b12021-04-15 00:32:15 -07001271 @NonNull IAppSearchBatchResultCallback callback, @NonNull Throwable throwable) {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001272 AppSearchResult<?> result = throwableToFailedResult(throwable);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001273 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001274 callback.onSystemError(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001275 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001276 Log.e(TAG, "Unable to send error to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001277 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001278 }
Terry Wangfebbead2019-10-17 17:05:18 -07001279 }
Terry Wangf2093072020-11-30 04:47:19 -08001280
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001281 /**
1282 * Helper for dealing with incoming user arguments to system service calls.
1283 *
1284 * <p>Takes care of checking permissions and converting USER_CURRENT to the actual current user.
1285 *
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001286 * @param requestedUser The user which the caller is requesting to execute as.
1287 * @param callingUid The actual uid of the caller as determined by Binder.
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001288 * @return the user handle that the call should run as. Will always be a concrete user.
1289 */
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001290 @NonNull
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001291 private UserHandle handleIncomingUser(@NonNull UserHandle requestedUser, int callingUid) {
Terry Wangf2093072020-11-30 04:47:19 -08001292 int callingPid = Binder.getCallingPid();
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001293 UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid);
1294 if (callingUser.equals(requestedUser)) {
1295 return requestedUser;
1296 }
1297 // Duplicates UserController#ensureNotSpecialUser
1298 if (requestedUser.getIdentifier() < 0) {
1299 throw new IllegalArgumentException(
1300 "Call does not support special user " + requestedUser);
1301 }
1302 boolean canInteractAcrossUsers = mContext.checkPermission(
1303 Manifest.permission.INTERACT_ACROSS_USERS,
Cassie Wang0c62d992021-01-15 14:39:30 -08001304 callingPid,
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001305 callingUid) == PackageManager.PERMISSION_GRANTED;
1306 if (!canInteractAcrossUsers) {
1307 canInteractAcrossUsers = mContext.checkPermission(
1308 Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1309 callingPid,
1310 callingUid) == PackageManager.PERMISSION_GRANTED;
1311 }
1312 if (canInteractAcrossUsers) {
1313 return requestedUser;
1314 }
1315 throw new SecurityException(
1316 "Permission denied while calling from uid " + callingUid
1317 + " with " + requestedUser + "; Need to run as either the calling user ("
1318 + callingUser + "), or with one of the following permissions: "
1319 + Manifest.permission.INTERACT_ACROSS_USERS + " or "
1320 + Manifest.permission.INTERACT_ACROSS_USERS_FULL);
Terry Wangf2093072020-11-30 04:47:19 -08001321 }
Yang Yu0fcd51a2021-04-23 11:25:44 -07001322
1323 // TODO(b/179160886): Cache the previous storage stats.
1324 private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter {
1325 @Override
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001326 public void augmentStatsForPackageForUser(
Yang Yu0fcd51a2021-04-23 11:25:44 -07001327 @NonNull PackageStats stats,
1328 @NonNull String packageName,
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001329 @NonNull UserHandle userHandle,
1330 boolean canCallerAccessAllStats) {
Yang Yu0fcd51a2021-04-23 11:25:44 -07001331 Objects.requireNonNull(stats);
1332 Objects.requireNonNull(packageName);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001333 Objects.requireNonNull(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001334
Yang Yu0fcd51a2021-04-23 11:25:44 -07001335 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001336 verifyUserUnlocked(userHandle);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001337 AppSearchUserInstance instance =
1338 mAppSearchUserInstanceManager.getOrCreateUserInstance(
1339 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
1340 stats.dataSize += instance.getAppSearchImpl()
1341 .getStorageInfoForPackage(packageName).getSizeBytes();
Yang Yu0fcd51a2021-04-23 11:25:44 -07001342 } catch (Throwable t) {
1343 Log.e(
1344 TAG,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001345 "Unable to augment storage stats for "
1346 + userHandle
Yang Yu0fcd51a2021-04-23 11:25:44 -07001347 + " packageName "
1348 + packageName,
1349 t);
1350 }
1351 }
1352
1353 @Override
1354 public void augmentStatsForUid(
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001355 @NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats) {
Yang Yu0fcd51a2021-04-23 11:25:44 -07001356 Objects.requireNonNull(stats);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001357
1358 UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001359 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001360 verifyUserUnlocked(userHandle);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001361 String[] packagesForUid = mPackageManager.getPackagesForUid(uid);
1362 if (packagesForUid == null) {
1363 return;
1364 }
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001365 AppSearchUserInstance instance =
1366 mAppSearchUserInstanceManager.getOrCreateUserInstance(
1367 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001368 for (int i = 0; i < packagesForUid.length; i++) {
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001369 stats.dataSize += instance.getAppSearchImpl()
1370 .getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
Yang Yu0fcd51a2021-04-23 11:25:44 -07001371 }
1372 } catch (Throwable t) {
1373 Log.e(TAG, "Unable to augment storage stats for uid " + uid, t);
1374 }
1375 }
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001376
1377 @Override
1378 public void augmentStatsForUser(
1379 @NonNull PackageStats stats, @NonNull UserHandle userHandle) {
1380 // TODO(b/179160886): this implementation could incur many jni calls and a lot of
1381 // in-memory processing from getStorageInfoForPackage. Instead, we can just compute the
1382 // size of the icing dir (or use the overall StorageInfo without interpolating it).
1383 Objects.requireNonNull(stats);
1384 Objects.requireNonNull(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001385
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001386 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001387 verifyUserUnlocked(userHandle);
1388 List<PackageInfo> packagesForUser = mPackageManager.getInstalledPackagesAsUser(
1389 /*flags=*/0, userHandle.getIdentifier());
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001390 if (packagesForUser == null) {
1391 return;
1392 }
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001393 AppSearchUserInstance instance =
1394 mAppSearchUserInstanceManager.getOrCreateUserInstance(
1395 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001396 for (int i = 0; i < packagesForUser.size(); i++) {
1397 String packageName = packagesForUser.get(i).packageName;
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001398 stats.dataSize += instance.getAppSearchImpl()
1399 .getStorageInfoForPackage(packageName).getSizeBytes();
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001400 }
1401 } catch (Throwable t) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001402 Log.e(TAG, "Unable to augment storage stats for " + userHandle, t);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001403 }
1404 }
Yang Yu0fcd51a2021-04-23 11:25:44 -07001405 }
Terry Wangfebbead2019-10-17 17:05:18 -07001406}