blob: 400c24138060c7f3ddc019d57f0752f0722c702e [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 Dorokhine5c416772021-06-04 09:05:00 -070063import com.android.server.appsearch.util.PackageUtil;
Terry Wanga9e6e212021-04-23 15:51:37 -070064import com.android.server.appsearch.visibilitystore.VisibilityStore;
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
Cassie Wang0c62d992021-01-15 14:39:30 -080085/** TODO(b/142567528): add comments when implement this class */
Terry Wangfebbead2019-10-17 17:05:18 -070086public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070087 private static final String TAG = "AppSearchManagerService";
Terry Wang12dc6c02021-03-31 19:26:16 -070088 private final Context mContext;
Yang Yu0fcd51a2021-04-23 11:25:44 -070089 private PackageManager mPackageManager;
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070090 private UserManager mUserManager;
Alexander Dorokhine4d051632021-06-18 10:48:58 -070091 private AppSearchUserInstanceManager mAppSearchUserInstanceManager;
Terry Wangfebbead2019-10-17 17:05:18 -070092
Terry Wange04ceab2021-03-29 19:25:12 -070093 // Never call shutdownNow(). It will cancel the futures it's returned. And since
94 // Executor#execute won't return anything, we will hang forever waiting for the execution.
95 // AppSearch multi-thread execution is guarded by Read & Write Lock in AppSearchImpl, all
96 // mutate requests will need to gain write lock and query requests need to gain read lock.
97 private static final Executor EXECUTOR = new ThreadPoolExecutor(/*corePoolSize=*/1,
98 Runtime.getRuntime().availableProcessors(), /*keepAliveTime*/ 60L, TimeUnit.SECONDS,
Terry Wangd2186e52021-04-14 13:19:45 -070099 new LinkedBlockingQueue<>());
Terry Wange04ceab2021-03-29 19:25:12 -0700100
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700101 // Cache of unlocked users so we don't have to query UserManager service each time. The "locked"
102 // suffix refers to the fact that access to the field should be locked; unrelated to the
103 // unlocked status of users.
104 @GuardedBy("mUnlockedUsersLocked")
105 private final Set<UserHandle> mUnlockedUsersLocked = new ArraySet<>();
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800106
Terry Wangfebbead2019-10-17 17:05:18 -0700107 public AppSearchManagerService(Context context) {
108 super(context);
Terry Wang12dc6c02021-03-31 19:26:16 -0700109 mContext = context;
Terry Wangfebbead2019-10-17 17:05:18 -0700110 }
111
112 @Override
113 public void onStart() {
114 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
Yang Yu0fcd51a2021-04-23 11:25:44 -0700115 mPackageManager = getContext().getPackageManager();
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700116 mAppSearchUserInstanceManager = AppSearchUserInstanceManager.getInstance();
Terry Wang12dc6c02021-03-31 19:26:16 -0700117 mUserManager = mContext.getSystemService(UserManager.class);
118 registerReceivers();
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -0700119 LocalManagerRegistry.getManager(StorageStatsManagerLocal.class)
Yang Yu0fcd51a2021-04-23 11:25:44 -0700120 .registerStorageStatsAugmenter(new AppSearchStorageStatsAugmenter(), TAG);
Terry Wang12dc6c02021-03-31 19:26:16 -0700121 }
122
123 private void registerReceivers() {
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700124 mContext.registerReceiverForAllUsers(
125 new UserActionReceiver(),
126 new IntentFilter(Intent.ACTION_USER_REMOVED),
127 /*broadcastPermission=*/ null,
Terry Wang12dc6c02021-03-31 19:26:16 -0700128 /*scheduler=*/ null);
Terry Wange201dc02021-04-16 01:03:20 -0700129
130 //TODO(b/145759910) Add a direct callback when user clears the data instead of relying on
131 // broadcasts
132 IntentFilter packageChangedFilter = new IntentFilter();
133 packageChangedFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
134 packageChangedFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
135 packageChangedFilter.addDataScheme("package");
136 packageChangedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700137 mContext.registerReceiverForAllUsers(
138 new PackageChangedReceiver(),
139 packageChangedFilter,
140 /*broadcastPermission=*/ null,
Terry Wange201dc02021-04-16 01:03:20 -0700141 /*scheduler=*/ null);
Terry Wang12dc6c02021-03-31 19:26:16 -0700142 }
143
144 private class UserActionReceiver extends BroadcastReceiver {
145 @Override
146 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700147 Objects.requireNonNull(context);
148 Objects.requireNonNull(intent);
149
Terry Wang12dc6c02021-03-31 19:26:16 -0700150 switch (intent.getAction()) {
151 case Intent.ACTION_USER_REMOVED:
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700152 UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
153 if (userHandle == null) {
154 Log.e(TAG, "Extra "
155 + Intent.EXTRA_USER + " is missing in the intent: " + intent);
Terry Wang12dc6c02021-03-31 19:26:16 -0700156 return;
157 }
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700158 handleUserRemoved(userHandle);
Terry Wang12dc6c02021-03-31 19:26:16 -0700159 break;
160 default:
Terry Wange201dc02021-04-16 01:03:20 -0700161 Log.e(TAG, "Received unknown intent: " + intent);
Terry Wang12dc6c02021-03-31 19:26:16 -0700162 }
163 }
164 }
165
166 /**
167 * Handles user removed action.
168 *
169 * <p>Only need to clear the AppSearchImpl instance. The data of AppSearch is saved in the
170 * "credential encrypted" system directory of each user. That directory will be auto-deleted
171 * when a user is removed.
172 *
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700173 * @param userHandle The multi-user handle of the user that need to be removed.
Terry Wang12dc6c02021-03-31 19:26:16 -0700174 *
175 * @see android.os.Environment#getDataSystemCeDirectory
176 */
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700177 private void handleUserRemoved(@NonNull UserHandle userHandle) {
Terry Wang12dc6c02021-03-31 19:26:16 -0700178 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700179 mAppSearchUserInstanceManager.closeAndRemoveUserInstance(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700180 Log.i(TAG, "Removed AppSearchImpl instance for: " + userHandle);
Terry Wang12dc6c02021-03-31 19:26:16 -0700181 } catch (Throwable t) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700182 Log.e(TAG, "Unable to remove data for: " + userHandle, t);
Terry Wange201dc02021-04-16 01:03:20 -0700183 }
184 }
185
186 private class PackageChangedReceiver extends BroadcastReceiver {
187 @Override
188 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700189 Objects.requireNonNull(context);
190 Objects.requireNonNull(intent);
191
Terry Wange201dc02021-04-16 01:03:20 -0700192 switch (intent.getAction()) {
193 case Intent.ACTION_PACKAGE_FULLY_REMOVED:
194 case Intent.ACTION_PACKAGE_DATA_CLEARED:
195 String packageName = intent.getData().getSchemeSpecificPart();
196 if (packageName == null) {
197 Log.e(TAG, "Package name is missing in the intent: " + intent);
198 return;
199 }
200 int uid = intent.getIntExtra(Intent.EXTRA_UID, INVALID_UID);
201 if (uid == INVALID_UID) {
202 Log.e(TAG, "uid is missing in the intent: " + intent);
203 return;
204 }
205 handlePackageRemoved(packageName, uid);
206 break;
207 default:
208 Log.e(TAG, "Received unknown intent: " + intent);
209 }
210 }
211 }
212
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700213 private void handlePackageRemoved(@NonNull String packageName, int uid) {
214 UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
Terry Wange201dc02021-04-16 01:03:20 -0700215 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700216 if (isUserLocked(userHandle)) {
Terry Wanga9e6e212021-04-23 15:51:37 -0700217 // We cannot access a locked user's directry and remove package data from it.
218 // We should remove those uninstalled package data when the user is unlocking.
Terry Wange201dc02021-04-16 01:03:20 -0700219 return;
220 }
Terry Wanga9e6e212021-04-23 15:51:37 -0700221 // Only clear the package's data if AppSearch exists for this user.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700222 if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
223 AppSearchUserInstance instance =
224 mAppSearchUserInstanceManager.getOrCreateUserInstance(
225 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
Terry Wange201dc02021-04-16 01:03:20 -0700226 //TODO(b/145759910) clear visibility setting for package.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700227 instance.getAppSearchImpl().clearPackageData(packageName);
228 instance.getLogger().removeCachedUidForPackage(packageName);
Terry Wange201dc02021-04-16 01:03:20 -0700229 }
230 } catch (Throwable t) {
231 Log.e(TAG, "Unable to remove data for package: " + packageName, t);
Terry Wang12dc6c02021-03-31 19:26:16 -0700232 }
Terry Wangfebbead2019-10-17 17:05:18 -0700233 }
234
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800235 @Override
Pinyao Tingd5c2ed92021-03-18 14:51:54 -0700236 public void onUserUnlocking(@NonNull TargetUser user) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700237 Objects.requireNonNull(user);
Terry Wanga9e6e212021-04-23 15:51:37 -0700238 UserHandle userHandle = user.getUserHandle();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700239 synchronized (mUnlockedUsersLocked) {
Terry Wanga9e6e212021-04-23 15:51:37 -0700240 mUnlockedUsersLocked.add(userHandle);
Cassie Wang15c86972021-02-09 13:43:25 -0800241 }
Terry Wanga9e6e212021-04-23 15:51:37 -0700242 EXECUTOR.execute(() -> {
243 try {
244 // Only clear the package's data if AppSearch exists for this user.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700245 if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) {
246 AppSearchUserInstance instance =
247 mAppSearchUserInstanceManager.getOrCreateUserInstance(
248 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
Terry Wanga9e6e212021-04-23 15:51:37 -0700249 List<PackageInfo> installedPackageInfos = mContext
250 .createContextAsUser(userHandle, /*flags=*/0)
251 .getPackageManager()
252 .getInstalledPackages(/*flags=*/0);
253 Set<String> packagesToKeep = new ArraySet<>(installedPackageInfos.size());
254 for (int i = 0; i < installedPackageInfos.size(); i++) {
255 packagesToKeep.add(installedPackageInfos.get(i).packageName);
256 }
257 packagesToKeep.add(VisibilityStore.PACKAGE_NAME);
258 //TODO(b/145759910) clear visibility setting for package.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700259 instance.getAppSearchImpl().prunePackageData(packagesToKeep);
Terry Wanga9e6e212021-04-23 15:51:37 -0700260 }
261 } catch (Throwable t) {
262 Log.e(TAG, "Unable to prune packages for " + user, t);
263 }
264 });
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800265 }
266
Terry Wangde9f3382021-04-28 19:45:07 -0700267 @Override
268 public void onUserStopping(@NonNull TargetUser user) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700269 Objects.requireNonNull(user);
270
271 synchronized (mUnlockedUsersLocked) {
272 UserHandle userHandle = user.getUserHandle();
273 mUnlockedUsersLocked.remove(userHandle);
Terry Wangde9f3382021-04-28 19:45:07 -0700274 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700275 mAppSearchUserInstanceManager.closeAndRemoveUserInstance(userHandle);
Terry Wangde9f3382021-04-28 19:45:07 -0700276 } catch (Throwable t) {
277 Log.e(TAG, "Error handling user stopping.", t);
278 }
279 }
280 }
281
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700282 private void verifyUserUnlocked(@NonNull UserHandle callingUser) {
283 if (isUserLocked(callingUser)) {
284 throw new IllegalStateException(callingUser + " is locked or not running.");
Terry Wange201dc02021-04-16 01:03:20 -0700285 }
286 }
287
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700288 private boolean isUserLocked(@NonNull UserHandle callingUser) {
289 synchronized (mUnlockedUsersLocked) {
Yang Yu0fcd51a2021-04-23 11:25:44 -0700290 // First, check the local copy.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700291 if (mUnlockedUsersLocked.contains(callingUser)) {
Terry Wange201dc02021-04-16 01:03:20 -0700292 return false;
Yang Yu0fcd51a2021-04-23 11:25:44 -0700293 }
294 // If the local copy says the user is locked, check with UM for the actual state,
295 // since the user might just have been unlocked.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700296 return !mUserManager.isUserUnlockingOrUnlocked(callingUser);
Yang Yu0fcd51a2021-04-23 11:25:44 -0700297 }
298 }
299
Terry Wangfebbead2019-10-17 17:05:18 -0700300 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800301 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800302 public void setSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800303 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700304 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700305 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine315cca62021-03-04 12:34:41 -0800306 @NonNull List<String> schemasNotDisplayedBySystem,
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700307 @NonNull Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800308 boolean forceOverride,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700309 int schemaVersion,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700310 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700311 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800312 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700313 Objects.requireNonNull(packageName);
314 Objects.requireNonNull(databaseName);
315 Objects.requireNonNull(schemaBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700316 Objects.requireNonNull(schemasNotDisplayedBySystem);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700317 Objects.requireNonNull(schemasVisibleToPackagesBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700318 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700319 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700320
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700321 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800322 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700323 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700324 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700325 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700326 AppSearchUserInstance instance = null;
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700327 int operationSuccessCount = 0;
328 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700329 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700330 verifyUserUnlocked(callingUser);
331 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700332 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
333 for (int i = 0; i < schemaBundles.size(); i++) {
334 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhineab789062021-01-11 21:00:00 -0800335 }
Terry Wange04ceab2021-03-29 19:25:12 -0700336 Map<String, List<PackageIdentifier>> schemasPackageAccessible =
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700337 new ArrayMap<>(schemasVisibleToPackagesBundles.size());
Terry Wange04ceab2021-03-29 19:25:12 -0700338 for (Map.Entry<String, List<Bundle>> entry :
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700339 schemasVisibleToPackagesBundles.entrySet()) {
Terry Wange04ceab2021-03-29 19:25:12 -0700340 List<PackageIdentifier> packageIdentifiers =
341 new ArrayList<>(entry.getValue().size());
342 for (int i = 0; i < entry.getValue().size(); i++) {
343 packageIdentifiers.add(
344 new PackageIdentifier(entry.getValue().get(i)));
345 }
346 schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
347 }
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700348 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
349 SetSchemaResponse setSchemaResponse = instance.getAppSearchImpl().setSchema(
Terry Wange04ceab2021-03-29 19:25:12 -0700350 packageName,
351 databaseName,
352 schemas,
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700353 instance.getVisibilityStore(),
Terry Wange04ceab2021-03-29 19:25:12 -0700354 schemasNotDisplayedBySystem,
355 schemasPackageAccessible,
356 forceOverride,
357 schemaVersion);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700358 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700359 invokeCallbackOnResult(callback,
360 AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
361 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700362 ++operationFailureCount;
363 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700364 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700365 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700366 if (instance != null) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700367 int estimatedBinderLatencyMillis =
368 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
369 int totalLatencyMillis =
370 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700371 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700372 .setPackageName(packageName)
373 .setDatabase(databaseName)
374 .setStatusCode(statusCode)
375 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700376 .setCallType(CallStats.CALL_TYPE_SET_SCHEMA)
377 // TODO(b/173532925) check the existing binder call latency chart
378 // is good enough for us:
379 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
380 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
381 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700382 .setNumOperationsFailed(operationFailureCount)
383 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700384 }
Alexander Dorokhineab789062021-01-11 21:00:00 -0800385 }
Terry Wange04ceab2021-03-29 19:25:12 -0700386 });
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800387 }
388
389 @Override
Terry Wang83a24932020-12-09 21:00:18 -0800390 public void getSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800391 @NonNull String packageName,
Terry Wang83a24932020-12-09 21:00:18 -0800392 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700393 @NonNull UserHandle userHandle,
Terry Wang83a24932020-12-09 21:00:18 -0800394 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700395 Objects.requireNonNull(packageName);
396 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700397 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700398 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700399
Cassie Wangb0d60122021-03-30 12:38:46 -0700400 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700401 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700402 EXECUTOR.execute(() -> {
403 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700404 verifyUserUnlocked(callingUser);
405 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700406 AppSearchUserInstance instance =
407 mAppSearchUserInstanceManager.getUserInstance(callingUser);
408 GetSchemaResponse response =
409 instance.getAppSearchImpl().getSchema(packageName, databaseName);
Terry Wange04ceab2021-03-29 19:25:12 -0700410 invokeCallbackOnResult(
411 callback,
412 AppSearchResult.newSuccessfulResult(response.getBundle()));
413 } catch (Throwable t) {
414 invokeCallbackOnError(callback, t);
415 }
416 });
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700417 }
418
419 @Override
420 public void getNamespaces(
421 @NonNull String packageName,
422 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700423 @NonNull UserHandle userHandle,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700424 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700425 Objects.requireNonNull(packageName);
426 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700427 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700428 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700429
Cassie Wangb0d60122021-03-30 12:38:46 -0700430 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700431 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700432 EXECUTOR.execute(() -> {
433 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700434 verifyUserUnlocked(callingUser);
435 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700436 AppSearchUserInstance instance =
437 mAppSearchUserInstanceManager.getUserInstance(callingUser);
438 List<String> namespaces =
439 instance.getAppSearchImpl().getNamespaces(packageName, databaseName);
440 invokeCallbackOnResult(
441 callback, AppSearchResult.newSuccessfulResult(namespaces));
Terry Wange04ceab2021-03-29 19:25:12 -0700442 } catch (Throwable t) {
443 invokeCallbackOnError(callback, t);
444 }
445 });
Terry Wang83a24932020-12-09 21:00:18 -0800446 }
447
448 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -0800449 public void putDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800450 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700451 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700452 @NonNull List<Bundle> documentBundles,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700453 @NonNull UserHandle userHandle,
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800454 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800455 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700456 Objects.requireNonNull(packageName);
457 Objects.requireNonNull(databaseName);
458 Objects.requireNonNull(documentBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700459 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700460 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700461
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700462 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800463 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700464 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700465 EXECUTOR.execute(() -> {
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800466 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700467 AppSearchUserInstance instance = null;
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800468 int operationSuccessCount = 0;
469 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700470 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700471 verifyUserUnlocked(callingUser);
472 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700473 AppSearchBatchResult.Builder<String, Void> resultBuilder =
474 new AppSearchBatchResult.Builder<>();
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700475 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700476 for (int i = 0; i < documentBundles.size(); i++) {
477 GenericDocument document = new GenericDocument(documentBundles.get(i));
478 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700479 instance.getAppSearchImpl().putDocument(
480 packageName, databaseName, document, instance.getLogger());
481 resultBuilder.setSuccess(document.getId(), /*value=*/ null);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800482 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700483 } catch (Throwable t) {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700484 resultBuilder.setResult(document.getId(), throwableToFailedResult(t));
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800485 AppSearchResult<Void> result = throwableToFailedResult(t);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700486 resultBuilder.setResult(document.getId(), result);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700487 // Since we can only include one status code in the atom,
488 // for failures, we would just save the one for the last failure
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800489 statusCode = result.getResultCode();
490 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700491 }
Alexander Dorokhine18465842020-01-21 01:08:57 -0800492 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700493 // Now that the batch has been written. Persist the newly written data.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700494 instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
Terry Wange04ceab2021-03-29 19:25:12 -0700495 invokeCallbackOnResult(callback, resultBuilder.build());
496 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700497 ++operationFailureCount;
498 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700499 invokeCallbackOnError(callback, t);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800500 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700501 if (instance != null) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700502 int estimatedBinderLatencyMillis =
503 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
504 int totalLatencyMillis =
505 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700506 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700507 .setPackageName(packageName)
508 .setDatabase(databaseName)
509 .setStatusCode(statusCode)
510 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800511 .setCallType(CallStats.CALL_TYPE_PUT_DOCUMENTS)
512 // TODO(b/173532925) check the existing binder call latency chart
513 // is good enough for us:
514 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700515 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800516 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700517 .setNumOperationsFailed(operationFailureCount)
518 .build());
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800519 }
Alexander Dorokhine18465842020-01-21 01:08:57 -0800520 }
Terry Wange04ceab2021-03-29 19:25:12 -0700521 });
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800522 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800523
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800524 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800525 public void getDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800526 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800527 @NonNull String databaseName,
528 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700529 @NonNull List<String> ids,
Alexander Dorokhine87cdd152021-01-20 15:41:25 -0800530 @NonNull Map<String, List<String>> typePropertyPaths,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700531 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700532 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800533 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700534 Objects.requireNonNull(packageName);
535 Objects.requireNonNull(databaseName);
536 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700537 Objects.requireNonNull(ids);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700538 Objects.requireNonNull(typePropertyPaths);
539 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700540 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700541
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700542 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800543 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700544 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700545 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700546 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700547 AppSearchUserInstance instance = null;
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700548 int operationSuccessCount = 0;
549 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700550 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700551 verifyUserUnlocked(callingUser);
552 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700553 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
554 new AppSearchBatchResult.Builder<>();
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700555 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700556 for (int i = 0; i < ids.size(); i++) {
557 String id = ids.get(i);
Terry Wange04ceab2021-03-29 19:25:12 -0700558 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700559 GenericDocument document = instance.getAppSearchImpl().getDocument(
560 packageName,
561 databaseName,
562 namespace,
563 id,
564 typePropertyPaths);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700565 ++operationSuccessCount;
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700566 resultBuilder.setSuccess(id, document.getBundle());
Terry Wange04ceab2021-03-29 19:25:12 -0700567 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700568 // Since we can only include one status code in the atom,
569 // for failures, we would just save the one for the last failure
570 AppSearchResult<Bundle> result = throwableToFailedResult(t);
571 resultBuilder.setResult(id, result);
572 statusCode = result.getResultCode();
573 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700574 }
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800575 }
Terry Wange04ceab2021-03-29 19:25:12 -0700576 invokeCallbackOnResult(callback, resultBuilder.build());
577 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700578 ++operationFailureCount;
579 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700580 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700581 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700582 if (instance != null) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700583 int estimatedBinderLatencyMillis =
584 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
585 int totalLatencyMillis =
586 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700587 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700588 .setPackageName(packageName)
589 .setDatabase(databaseName)
590 .setStatusCode(statusCode)
591 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700592 .setCallType(CallStats.CALL_TYPE_GET_DOCUMENTS)
593 // TODO(b/173532925) check the existing binder call latency chart
594 // is good enough for us:
595 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
596 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
597 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700598 .setNumOperationsFailed(operationFailureCount)
599 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700600 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800601 }
Terry Wange04ceab2021-03-29 19:25:12 -0700602 });
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800603 }
604
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800605 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800606 public void query(
Cassie Wang0c62d992021-01-15 14:39:30 -0800607 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700608 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700609 @NonNull String queryExpression,
610 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700611 @NonNull UserHandle userHandle,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700612 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700613 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700614 Objects.requireNonNull(packageName);
615 Objects.requireNonNull(databaseName);
616 Objects.requireNonNull(queryExpression);
617 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700618 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700619 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700620
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700621 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800622 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700623 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700624 EXECUTOR.execute(() -> {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700625 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700626 AppSearchUserInstance instance = null;
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700627 int operationSuccessCount = 0;
628 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700629 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700630 verifyUserUnlocked(callingUser);
631 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700632 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
633 SearchResultPage searchResultPage = instance.getAppSearchImpl().query(
634 packageName,
635 databaseName,
636 queryExpression,
637 new SearchSpec(searchSpecBundle),
638 instance.getLogger());
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700639 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700640 invokeCallbackOnResult(
641 callback,
642 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
643 } catch (Throwable t) {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700644 ++operationFailureCount;
645 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700646 invokeCallbackOnError(callback, t);
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700647 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700648 if (instance != null) {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700649 int estimatedBinderLatencyMillis =
650 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
651 int totalLatencyMillis =
652 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700653 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700654 .setPackageName(packageName)
655 .setDatabase(databaseName)
656 .setStatusCode(statusCode)
657 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700658 .setCallType(CallStats.CALL_TYPE_SEARCH)
659 // TODO(b/173532925) check the existing binder call latency chart
660 // is good enough for us:
661 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
662 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
663 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700664 .setNumOperationsFailed(operationFailureCount)
665 .build());
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700666 }
Terry Wange04ceab2021-03-29 19:25:12 -0700667 }
668 });
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700669 }
670
Terry Wangf2093072020-11-30 04:47:19 -0800671 @Override
Terry Wangbfbfcac2020-11-06 15:46:44 -0800672 public void globalQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800673 @NonNull String packageName,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800674 @NonNull String queryExpression,
675 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700676 @NonNull UserHandle userHandle,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700677 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800678 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700679 Objects.requireNonNull(packageName);
680 Objects.requireNonNull(queryExpression);
681 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700682 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700683 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700684
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700685 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800686 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700687 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700688 EXECUTOR.execute(() -> {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700689 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700690 AppSearchUserInstance instance = null;
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700691 int operationSuccessCount = 0;
692 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700693 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700694 verifyUserUnlocked(callingUser);
695 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700696 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
697
698 boolean callerHasSystemAccess =
699 instance.getVisibilityStore().doesCallerHaveSystemAccess(packageName);
700 SearchResultPage searchResultPage = instance.getAppSearchImpl().globalQuery(
701 queryExpression,
702 new SearchSpec(searchSpecBundle),
703 packageName,
704 instance.getVisibilityStore(),
705 callingUid,
706 callerHasSystemAccess,
707 instance.getLogger());
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700708 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700709 invokeCallbackOnResult(
710 callback,
711 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700712 } catch (Throwable t) {
713 ++operationFailureCount;
714 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700715 invokeCallbackOnError(callback, t);
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700716 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700717 if (instance != null) {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700718 int estimatedBinderLatencyMillis =
719 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
720 int totalLatencyMillis =
721 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700722 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700723 .setPackageName(packageName)
724 .setStatusCode(statusCode)
725 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700726 .setCallType(CallStats.CALL_TYPE_GLOBAL_SEARCH)
727 // TODO(b/173532925) check the existing binder call latency chart
728 // is good enough for us:
729 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
730 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
731 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700732 .setNumOperationsFailed(operationFailureCount)
733 .build());
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700734 }
Terry Wange04ceab2021-03-29 19:25:12 -0700735 }
736 });
Terry Wangbfbfcac2020-11-06 15:46:44 -0800737 }
738
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700739 @Override
Cassie Wang0c62d992021-01-15 14:39:30 -0800740 public void getNextPage(
741 long nextPageToken,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700742 @NonNull UserHandle userHandle,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700743 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700744 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700745 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700746
Terry Wangf2093072020-11-30 04:47:19 -0800747 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700748 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700749 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
750 // opened it
Terry Wange04ceab2021-03-29 19:25:12 -0700751 EXECUTOR.execute(() -> {
752 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700753 verifyUserUnlocked(callingUser);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700754 AppSearchUserInstance instance =
755 mAppSearchUserInstanceManager.getUserInstance(callingUser);
756 SearchResultPage searchResultPage =
757 instance.getAppSearchImpl().getNextPage(nextPageToken);
Terry Wange04ceab2021-03-29 19:25:12 -0700758 invokeCallbackOnResult(
759 callback,
760 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
761 } catch (Throwable t) {
762 invokeCallbackOnError(callback, t);
763 }
764 });
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700765 }
766
767 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700768 public void invalidateNextPageToken(long nextPageToken, @NonNull UserHandle userHandle) {
769 Objects.requireNonNull(userHandle);
770
Terry Wangf2093072020-11-30 04:47:19 -0800771 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700772 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700773 EXECUTOR.execute(() -> {
774 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700775 verifyUserUnlocked(callingUser);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700776 AppSearchUserInstance instance =
777 mAppSearchUserInstanceManager.getUserInstance(callingUser);
778 instance.getAppSearchImpl().invalidateNextPageToken(nextPageToken);
Terry Wange04ceab2021-03-29 19:25:12 -0700779 } catch (Throwable t) {
780 Log.e(TAG, "Unable to invalidate the query page token", t);
781 }
782 });
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800783 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800784
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700785 @Override
Terry Wang623e3b02021-02-02 20:27:33 -0800786 public void writeQueryResultsToFile(
787 @NonNull String packageName,
788 @NonNull String databaseName,
789 @NonNull ParcelFileDescriptor fileDescriptor,
790 @NonNull String queryExpression,
791 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700792 @NonNull UserHandle userHandle,
Terry Wang623e3b02021-02-02 20:27:33 -0800793 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700794 Objects.requireNonNull(packageName);
795 Objects.requireNonNull(databaseName);
796 Objects.requireNonNull(fileDescriptor);
797 Objects.requireNonNull(queryExpression);
798 Objects.requireNonNull(searchSpecBundle);
799 Objects.requireNonNull(userHandle);
800 Objects.requireNonNull(callback);
801
Terry Wang623e3b02021-02-02 20:27:33 -0800802 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700803 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700804 EXECUTOR.execute(() -> {
805 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700806 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700807 AppSearchUserInstance instance =
808 mAppSearchUserInstanceManager.getUserInstance(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700809 // we don't need to append the file. The file is always brand new.
810 try (DataOutputStream outputStream = new DataOutputStream(
811 new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700812 SearchResultPage searchResultPage = instance.getAppSearchImpl().query(
Terry Wange04ceab2021-03-29 19:25:12 -0700813 packageName,
814 databaseName,
815 queryExpression,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700816 new SearchSpec(searchSpecBundle),
817 /*logger=*/ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700818 while (!searchResultPage.getResults().isEmpty()) {
819 for (int i = 0; i < searchResultPage.getResults().size(); i++) {
820 AppSearchMigrationHelper.writeBundleToOutputStream(
821 outputStream, searchResultPage.getResults().get(i)
822 .getGenericDocument().getBundle());
823 }
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700824 searchResultPage = instance.getAppSearchImpl().getNextPage(
Terry Wange04ceab2021-03-29 19:25:12 -0700825 searchResultPage.getNextPageToken());
Terry Wang623e3b02021-02-02 20:27:33 -0800826 }
Terry Wang623e3b02021-02-02 20:27:33 -0800827 }
Terry Wange04ceab2021-03-29 19:25:12 -0700828 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
829 } catch (Throwable t) {
830 invokeCallbackOnError(callback, t);
Terry Wang623e3b02021-02-02 20:27:33 -0800831 }
Terry Wange04ceab2021-03-29 19:25:12 -0700832 });
Terry Wang623e3b02021-02-02 20:27:33 -0800833 }
834
835 @Override
836 public void putDocumentsFromFile(
837 @NonNull String packageName,
838 @NonNull String databaseName,
839 @NonNull ParcelFileDescriptor fileDescriptor,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700840 @NonNull UserHandle userHandle,
Terry Wang623e3b02021-02-02 20:27:33 -0800841 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700842 Objects.requireNonNull(packageName);
843 Objects.requireNonNull(databaseName);
844 Objects.requireNonNull(fileDescriptor);
845 Objects.requireNonNull(userHandle);
846 Objects.requireNonNull(callback);
847
Terry Wang623e3b02021-02-02 20:27:33 -0800848 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700849 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700850 EXECUTOR.execute(() -> {
851 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700852 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700853 AppSearchUserInstance instance =
854 mAppSearchUserInstanceManager.getUserInstance(callingUser);
Terry Wang623e3b02021-02-02 20:27:33 -0800855
Terry Wange04ceab2021-03-29 19:25:12 -0700856 GenericDocument document;
857 ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
858 try (DataInputStream inputStream = new DataInputStream(
859 new FileInputStream(fileDescriptor.getFileDescriptor()))) {
860 while (true) {
861 try {
862 document = AppSearchMigrationHelper
863 .readDocumentFromInputStream(inputStream);
864 } catch (EOFException e) {
865 // nothing wrong, we just finish the reading.
866 break;
867 }
868 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700869 instance.getAppSearchImpl().putDocument(
870 packageName, databaseName, document, /*logger=*/ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700871 } catch (Throwable t) {
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700872 migrationFailureBundles.add(new SetSchemaResponse.MigrationFailure(
873 document.getNamespace(),
874 document.getId(),
875 document.getSchemaType(),
876 AppSearchResult.throwableToFailedResult(t))
877 .getBundle());
Terry Wange04ceab2021-03-29 19:25:12 -0700878 }
Terry Wang623e3b02021-02-02 20:27:33 -0800879 }
880 }
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700881 instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL);
Terry Wange04ceab2021-03-29 19:25:12 -0700882 invokeCallbackOnResult(callback,
883 AppSearchResult.newSuccessfulResult(migrationFailureBundles));
884 } catch (Throwable t) {
885 invokeCallbackOnError(callback, t);
Terry Wang623e3b02021-02-02 20:27:33 -0800886 }
Terry Wange04ceab2021-03-29 19:25:12 -0700887 });
Terry Wang623e3b02021-02-02 20:27:33 -0800888 }
889
890 @Override
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800891 public void reportUsage(
892 @NonNull String packageName,
893 @NonNull String databaseName,
894 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700895 @NonNull String documentId,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800896 long usageTimeMillis,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700897 boolean systemUsage,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700898 @NonNull UserHandle userHandle,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800899 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700900 Objects.requireNonNull(packageName);
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800901 Objects.requireNonNull(databaseName);
902 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700903 Objects.requireNonNull(documentId);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700904 Objects.requireNonNull(userHandle);
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800905 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700906
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800907 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700908 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700909 EXECUTOR.execute(() -> {
910 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700911 verifyUserUnlocked(callingUser);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700912 verifyCallingPackage(callingUser, callingUid, packageName);
913 AppSearchUserInstance instance =
914 mAppSearchUserInstanceManager.getUserInstance(callingUser);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700915
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700916 if (systemUsage
917 && !instance.getVisibilityStore()
918 .doesCallerHaveSystemAccess(packageName)) {
919 throw new AppSearchException(
920 AppSearchResult.RESULT_SECURITY_ERROR,
921 packageName + " does not have access to report system usage");
Terry Wange04ceab2021-03-29 19:25:12 -0700922 }
923
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700924 instance.getAppSearchImpl().reportUsage(
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700925 packageName, databaseName, namespace, documentId,
Terry Wange04ceab2021-03-29 19:25:12 -0700926 usageTimeMillis, systemUsage);
927 invokeCallbackOnResult(
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700928 callback, AppSearchResult.newSuccessfulResult(/*value=*/ null));
Terry Wange04ceab2021-03-29 19:25:12 -0700929 } catch (Throwable t) {
930 invokeCallbackOnError(callback, t);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700931 }
Terry Wange04ceab2021-03-29 19:25:12 -0700932 });
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800933 }
934
935 @Override
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700936 public void removeByDocumentId(
Cassie Wang0c62d992021-01-15 14:39:30 -0800937 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800938 @NonNull String databaseName,
939 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700940 @NonNull List<String> ids,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700941 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700942 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800943 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700944 Objects.requireNonNull(packageName);
945 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700946 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700947 Objects.requireNonNull(ids);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700948 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700949 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700950
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700951 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800952 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700953 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700954 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700955 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700956 AppSearchUserInstance instance = null;
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700957 int operationSuccessCount = 0;
958 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700959 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700960 verifyUserUnlocked(callingUser);
961 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700962 AppSearchBatchResult.Builder<String, Void> resultBuilder =
963 new AppSearchBatchResult.Builder<>();
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700964 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700965 for (int i = 0; i < ids.size(); i++) {
966 String id = ids.get(i);
Terry Wange04ceab2021-03-29 19:25:12 -0700967 try {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700968 instance.getAppSearchImpl().remove(
Alexander Dorokhinea4b5bab2021-05-20 14:24:50 -0700969 packageName,
970 databaseName,
971 namespace,
972 id,
973 /*removeStatsBuilder=*/ null);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700974 ++operationSuccessCount;
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700975 resultBuilder.setSuccess(id, /*result= */ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700976 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700977 AppSearchResult<Void> result = throwableToFailedResult(t);
978 resultBuilder.setResult(id, result);
979 // Since we can only include one status code in the atom,
980 // for failures, we would just save the one for the last failure
981 statusCode = result.getResultCode();
982 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700983 }
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700984 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700985 // Now that the batch has been written. Persist the newly written data.
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700986 instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
Terry Wange04ceab2021-03-29 19:25:12 -0700987 invokeCallbackOnResult(callback, resultBuilder.build());
988 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700989 ++operationFailureCount;
990 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700991 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700992 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700993 if (instance != null) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700994 int estimatedBinderLatencyMillis =
995 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
996 int totalLatencyMillis =
997 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -0700998 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700999 .setPackageName(packageName)
1000 .setDatabase(databaseName)
1001 .setStatusCode(statusCode)
1002 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001003 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID)
1004 // TODO(b/173532925) check the existing binder call latency chart
1005 // is good enough for us:
1006 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1007 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1008 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001009 .setNumOperationsFailed(operationFailureCount)
1010 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001011 }
Alexander Dorokhineff82fba2020-03-09 16:35:24 -07001012 }
Terry Wange04ceab2021-03-29 19:25:12 -07001013 });
Alexander Dorokhineff82fba2020-03-09 16:35:24 -07001014 }
1015
1016 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -07001017 public void removeByQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -08001018 @NonNull String packageName,
Terry Wang26b9e5c2020-10-23 02:05:01 -07001019 @NonNull String databaseName,
1020 @NonNull String queryExpression,
1021 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001022 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001023 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Alexander Dorokhine178366b2020-10-20 17:40:49 -07001024 @NonNull IAppSearchResultCallback callback) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001025 // TODO(b/173532925) log CallStats once we have CALL_TYPE_REMOVE_BY_QUERY added
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001026 Objects.requireNonNull(packageName);
1027 Objects.requireNonNull(databaseName);
1028 Objects.requireNonNull(queryExpression);
1029 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001030 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001031 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001032
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001033 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -08001034 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001035 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001036 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001037 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001038 AppSearchUserInstance instance = null;
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001039 int operationSuccessCount = 0;
1040 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001041 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001042 verifyUserUnlocked(callingUser);
1043 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001044 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
1045 instance.getAppSearchImpl().removeByQuery(
Terry Wange04ceab2021-03-29 19:25:12 -07001046 packageName,
1047 databaseName,
1048 queryExpression,
Alexander Dorokhinea4b5bab2021-05-20 14:24:50 -07001049 new SearchSpec(searchSpecBundle),
1050 /*removeStatsBuilder=*/ null);
Alexander Dorokhinec77f4442021-04-14 09:26:06 -07001051 // Now that the batch has been written. Persist the newly written data.
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001052 instance.getAppSearchImpl().persistToDisk(PersistType.Code.LITE);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001053 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001054 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
1055 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001056 ++operationFailureCount;
1057 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001058 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001059 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001060 if (instance != null) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001061 int estimatedBinderLatencyMillis =
1062 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1063 int totalLatencyMillis =
1064 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001065 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001066 .setPackageName(packageName)
1067 .setDatabase(databaseName)
1068 .setStatusCode(statusCode)
1069 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001070 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH)
1071 // TODO(b/173532925) check the existing binder call latency chart
1072 // is good enough for us:
1073 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1074 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1075 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001076 .setNumOperationsFailed(operationFailureCount)
1077 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001078 }
Terry Wange04ceab2021-03-29 19:25:12 -07001079 }
1080 });
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -07001081 }
1082
Terry Wangdbd1dca2020-11-03 17:03:56 -08001083 @Override
Cassie Wang8f0df492021-03-24 09:23:18 -07001084 public void getStorageInfo(
1085 @NonNull String packageName,
1086 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001087 @NonNull UserHandle userHandle,
Cassie Wang8f0df492021-03-24 09:23:18 -07001088 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001089 Objects.requireNonNull(packageName);
1090 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001091 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001092 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001093
Cassie Wang8f0df492021-03-24 09:23:18 -07001094 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001095 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001096 EXECUTOR.execute(() -> {
1097 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001098 verifyUserUnlocked(callingUser);
1099 verifyCallingPackage(callingUser, callingUid, packageName);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001100 AppSearchUserInstance instance =
1101 mAppSearchUserInstanceManager.getUserInstance(callingUser);
1102 StorageInfo storageInfo = instance.getAppSearchImpl()
1103 .getStorageInfoForDatabase(packageName, databaseName);
Terry Wange04ceab2021-03-29 19:25:12 -07001104 Bundle storageInfoBundle = storageInfo.getBundle();
1105 invokeCallbackOnResult(
1106 callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
1107 } catch (Throwable t) {
1108 invokeCallbackOnError(callback, t);
1109 }
1110 });
Cassie Wang8f0df492021-03-24 09:23:18 -07001111 }
1112
1113 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001114 public void persistToDisk(
1115 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001116 @ElapsedRealtimeLong long binderCallStartTimeMillis) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001117 Objects.requireNonNull(userHandle);
1118
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001119 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Cassie Wangb0d60122021-03-30 12:38:46 -07001120 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001121 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001122 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001123 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001124 AppSearchUserInstance instance = null;
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001125 int operationSuccessCount = 0;
1126 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001127 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001128 verifyUserUnlocked(callingUser);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001129 instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
1130 instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001131 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001132 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001133 ++operationFailureCount;
1134 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001135 Log.e(TAG, "Unable to persist the data to disk", t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001136 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001137 if (instance != null) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001138 int estimatedBinderLatencyMillis =
1139 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1140 int totalLatencyMillis =
1141 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001142 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001143 .setStatusCode(statusCode)
1144 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001145 .setCallType(CallStats.CALL_TYPE_FLUSH)
1146 // TODO(b/173532925) check the existing binder call latency chart
1147 // is good enough for us:
1148 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1149 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1150 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001151 .setNumOperationsFailed(operationFailureCount)
1152 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001153 }
Terry Wange04ceab2021-03-29 19:25:12 -07001154 }
1155 });
Terry Wang2da17852020-12-16 19:59:08 -08001156 }
1157
1158 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001159 public void initialize(
1160 @NonNull UserHandle userHandle,
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001161 @ElapsedRealtimeLong long binderCallStartTimeMillis,
1162 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001163 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001164 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001165
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001166 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -08001167 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001168 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001169 EXECUTOR.execute(() -> {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001170 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001171 AppSearchUserInstance instance = null;
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001172 int operationSuccessCount = 0;
1173 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001174 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001175 verifyUserUnlocked(callingUser);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001176 instance = mAppSearchUserInstanceManager.getOrCreateUserInstance(
1177 mContext, callingUser, AppSearchConfig.getInstance(EXECUTOR));
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001178 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001179 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
1180 } catch (Throwable t) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001181 ++operationFailureCount;
1182 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001183 invokeCallbackOnError(callback, t);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001184 } finally {
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001185 if (instance != null) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001186 int estimatedBinderLatencyMillis =
1187 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1188 int totalLatencyMillis =
1189 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001190 instance.getLogger().logStats(new CallStats.Builder()
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001191 .setStatusCode(statusCode)
1192 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001193 .setCallType(CallStats.CALL_TYPE_INITIALIZE)
1194 // TODO(b/173532925) check the existing binder call latency chart
1195 // is good enough for us:
1196 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1197 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1198 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001199 .setNumOperationsFailed(operationFailureCount)
1200 .build());
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001201 }
Terry Wange04ceab2021-03-29 19:25:12 -07001202 }
1203 });
Terry Wangdbd1dca2020-11-03 17:03:56 -08001204 }
1205
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001206 private void verifyCallingPackage(
1207 @NonNull UserHandle actualCallingUser,
1208 int actualCallingUid,
1209 @NonNull String claimedCallingPackage) {
1210 Objects.requireNonNull(actualCallingUser);
1211 Objects.requireNonNull(claimedCallingPackage);
1212
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001213 int claimedCallingUid = PackageUtil.getPackageUidAsUser(
1214 mContext, claimedCallingPackage, actualCallingUser);
1215 if (claimedCallingUid == INVALID_UID) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001216 throw new SecurityException(
1217 "Specified calling package [" + claimedCallingPackage + "] not found");
1218 }
1219 if (claimedCallingUid != actualCallingUid) {
Cassie Wang0c62d992021-01-15 14:39:30 -08001220 throw new SecurityException(
1221 "Specified calling package ["
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001222 + claimedCallingPackage
Cassie Wang0c62d992021-01-15 14:39:30 -08001223 + "] does not match the calling uid "
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001224 + actualCallingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -07001225 }
Alexander Dorokhineebd37742020-09-22 15:02:26 -07001226 }
1227
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001228 /** Invokes the {@link IAppSearchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -08001229 private void invokeCallbackOnResult(
1230 IAppSearchResultCallback callback, AppSearchResult<?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -08001231 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001232 callback.onResult(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001233 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001234 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001235 }
Terry Wangdbd1dca2020-11-03 17:03:56 -08001236 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001237
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001238 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -08001239 private void invokeCallbackOnResult(
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001240 IAppSearchBatchResultCallback callback, AppSearchBatchResult<String, ?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -08001241 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001242 callback.onResult(new AppSearchBatchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001243 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001244 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001245 }
Terry Wangdbd1dca2020-11-03 17:03:56 -08001246 }
1247
1248 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001249 * Invokes the {@link IAppSearchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001250 *
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001251 * <p>The throwable is convert to a {@link AppSearchResult};
Terry Wangdbd1dca2020-11-03 17:03:56 -08001252 */
1253 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001254 AppSearchResult<?> result = throwableToFailedResult(throwable);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001255 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001256 callback.onResult(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001257 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001258 Log.e(TAG, "Unable to send result to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001259 }
1260 }
1261
1262 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001263 * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001264 *
Alexander Dorokhineb5d34b12021-04-15 00:32:15 -07001265 * <p>The throwable is converted to {@link AppSearchResult}.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001266 */
Cassie Wang0c62d992021-01-15 14:39:30 -08001267 private void invokeCallbackOnError(
Alexander Dorokhineb5d34b12021-04-15 00:32:15 -07001268 @NonNull IAppSearchBatchResultCallback callback, @NonNull Throwable throwable) {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001269 AppSearchResult<?> result = throwableToFailedResult(throwable);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001270 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001271 callback.onSystemError(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001272 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001273 Log.e(TAG, "Unable to send error to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001274 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001275 }
Terry Wangfebbead2019-10-17 17:05:18 -07001276 }
Terry Wangf2093072020-11-30 04:47:19 -08001277
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001278 /**
1279 * Helper for dealing with incoming user arguments to system service calls.
1280 *
1281 * <p>Takes care of checking permissions and converting USER_CURRENT to the actual current user.
1282 *
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001283 * @param requestedUser The user which the caller is requesting to execute as.
1284 * @param callingUid The actual uid of the caller as determined by Binder.
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001285 * @return the user handle that the call should run as. Will always be a concrete user.
1286 */
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001287 @NonNull
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001288 private UserHandle handleIncomingUser(@NonNull UserHandle requestedUser, int callingUid) {
Terry Wangf2093072020-11-30 04:47:19 -08001289 int callingPid = Binder.getCallingPid();
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001290 UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid);
1291 if (callingUser.equals(requestedUser)) {
1292 return requestedUser;
1293 }
1294 // Duplicates UserController#ensureNotSpecialUser
1295 if (requestedUser.getIdentifier() < 0) {
1296 throw new IllegalArgumentException(
1297 "Call does not support special user " + requestedUser);
1298 }
1299 boolean canInteractAcrossUsers = mContext.checkPermission(
1300 Manifest.permission.INTERACT_ACROSS_USERS,
Cassie Wang0c62d992021-01-15 14:39:30 -08001301 callingPid,
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001302 callingUid) == PackageManager.PERMISSION_GRANTED;
1303 if (!canInteractAcrossUsers) {
1304 canInteractAcrossUsers = mContext.checkPermission(
1305 Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1306 callingPid,
1307 callingUid) == PackageManager.PERMISSION_GRANTED;
1308 }
1309 if (canInteractAcrossUsers) {
1310 return requestedUser;
1311 }
1312 throw new SecurityException(
1313 "Permission denied while calling from uid " + callingUid
1314 + " with " + requestedUser + "; Need to run as either the calling user ("
1315 + callingUser + "), or with one of the following permissions: "
1316 + Manifest.permission.INTERACT_ACROSS_USERS + " or "
1317 + Manifest.permission.INTERACT_ACROSS_USERS_FULL);
Terry Wangf2093072020-11-30 04:47:19 -08001318 }
Yang Yu0fcd51a2021-04-23 11:25:44 -07001319
1320 // TODO(b/179160886): Cache the previous storage stats.
1321 private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter {
1322 @Override
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001323 public void augmentStatsForPackageForUser(
Yang Yu0fcd51a2021-04-23 11:25:44 -07001324 @NonNull PackageStats stats,
1325 @NonNull String packageName,
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001326 @NonNull UserHandle userHandle,
1327 boolean canCallerAccessAllStats) {
Yang Yu0fcd51a2021-04-23 11:25:44 -07001328 Objects.requireNonNull(stats);
1329 Objects.requireNonNull(packageName);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001330 Objects.requireNonNull(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001331
Yang Yu0fcd51a2021-04-23 11:25:44 -07001332 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001333 verifyUserUnlocked(userHandle);
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001334 AppSearchUserInstance instance =
1335 mAppSearchUserInstanceManager.getOrCreateUserInstance(
1336 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
1337 stats.dataSize += instance.getAppSearchImpl()
1338 .getStorageInfoForPackage(packageName).getSizeBytes();
Yang Yu0fcd51a2021-04-23 11:25:44 -07001339 } catch (Throwable t) {
1340 Log.e(
1341 TAG,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001342 "Unable to augment storage stats for "
1343 + userHandle
Yang Yu0fcd51a2021-04-23 11:25:44 -07001344 + " packageName "
1345 + packageName,
1346 t);
1347 }
1348 }
1349
1350 @Override
1351 public void augmentStatsForUid(
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001352 @NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats) {
Yang Yu0fcd51a2021-04-23 11:25:44 -07001353 Objects.requireNonNull(stats);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001354
1355 UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001356 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001357 verifyUserUnlocked(userHandle);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001358 String[] packagesForUid = mPackageManager.getPackagesForUid(uid);
1359 if (packagesForUid == null) {
1360 return;
1361 }
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001362 AppSearchUserInstance instance =
1363 mAppSearchUserInstanceManager.getOrCreateUserInstance(
1364 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001365 for (int i = 0; i < packagesForUid.length; i++) {
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001366 stats.dataSize += instance.getAppSearchImpl()
1367 .getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
Yang Yu0fcd51a2021-04-23 11:25:44 -07001368 }
1369 } catch (Throwable t) {
1370 Log.e(TAG, "Unable to augment storage stats for uid " + uid, t);
1371 }
1372 }
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001373
1374 @Override
1375 public void augmentStatsForUser(
1376 @NonNull PackageStats stats, @NonNull UserHandle userHandle) {
1377 // TODO(b/179160886): this implementation could incur many jni calls and a lot of
1378 // in-memory processing from getStorageInfoForPackage. Instead, we can just compute the
1379 // size of the icing dir (or use the overall StorageInfo without interpolating it).
1380 Objects.requireNonNull(stats);
1381 Objects.requireNonNull(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001382
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001383 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001384 verifyUserUnlocked(userHandle);
1385 List<PackageInfo> packagesForUser = mPackageManager.getInstalledPackagesAsUser(
1386 /*flags=*/0, userHandle.getIdentifier());
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001387 if (packagesForUser == null) {
1388 return;
1389 }
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001390 AppSearchUserInstance instance =
1391 mAppSearchUserInstanceManager.getOrCreateUserInstance(
1392 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001393 for (int i = 0; i < packagesForUser.size(); i++) {
1394 String packageName = packagesForUser.get(i).packageName;
Alexander Dorokhine4d051632021-06-18 10:48:58 -07001395 stats.dataSize += instance.getAppSearchImpl()
1396 .getStorageInfoForPackage(packageName).getSizeBytes();
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001397 }
1398 } catch (Throwable t) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001399 Log.e(TAG, "Unable to augment storage stats for " + userHandle, t);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001400 }
1401 }
Yang Yu0fcd51a2021-04-23 11:25:44 -07001402 }
Terry Wangfebbead2019-10-17 17:05:18 -07001403}