blob: 754cc41960fc0c87ddc01ef5bed226048ac551c6 [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 Wang12dc6c02021-03-31 19:26:16 -070020import static android.os.UserHandle.USER_NULL;
Terry Wangdbd1dca2020-11-03 17:03:56 -080021
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -080022import android.annotation.ElapsedRealtimeLong;
sidchhabraa7c8f8a2020-01-16 18:38:17 -080023import android.annotation.NonNull;
Terry Wangf2093072020-11-30 04:47:19 -080024import android.app.ActivityManager;
Alexander Dorokhine18465842020-01-21 01:08:57 -080025import android.app.appsearch.AppSearchBatchResult;
Terry Wang623e3b02021-02-02 20:27:33 -080026import android.app.appsearch.AppSearchMigrationHelper;
Alexander Dorokhine969f4462020-03-05 15:54:19 -080027import android.app.appsearch.AppSearchResult;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070028import android.app.appsearch.AppSearchSchema;
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -070029import android.app.appsearch.GenericDocument;
Alexander Dorokhine9795b512021-03-23 22:06:59 -070030import android.app.appsearch.GetSchemaResponse;
Alexander Dorokhineab789062021-01-11 21:00:00 -080031import android.app.appsearch.PackageIdentifier;
Terry Wang26b9e5c2020-10-23 02:05:01 -070032import android.app.appsearch.SearchResultPage;
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -070033import android.app.appsearch.SearchSpec;
Terry Wang623e3b02021-02-02 20:27:33 -080034import android.app.appsearch.SetSchemaResponse;
Cassie Wang8f0df492021-03-24 09:23:18 -070035import android.app.appsearch.StorageInfo;
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -070036import android.app.appsearch.aidl.AppSearchBatchResultParcel;
37import android.app.appsearch.aidl.AppSearchResultParcel;
38import android.app.appsearch.aidl.IAppSearchBatchResultCallback;
39import android.app.appsearch.aidl.IAppSearchManager;
40import android.app.appsearch.aidl.IAppSearchResultCallback;
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;
Alexander Dorokhinef660d8f2020-10-29 22:37:00 -070062import com.android.server.appsearch.external.localstorage.AppSearchImpl;
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -080063import com.android.server.appsearch.external.localstorage.stats.CallStats;
64import com.android.server.appsearch.stats.LoggerInstanceManager;
65import com.android.server.appsearch.stats.PlatformLogger;
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -070066import com.android.server.usage.StorageStatsManagerLocal;
67import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080068
Alexander Dorokhinec77f4442021-04-14 09:26:06 -070069import com.google.android.icing.proto.PersistType;
70
Terry Wang623e3b02021-02-02 20:27:33 -080071import java.io.DataInputStream;
72import java.io.DataOutputStream;
73import java.io.EOFException;
74import java.io.FileInputStream;
75import java.io.FileOutputStream;
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080076import java.util.ArrayList;
Alexander Dorokhine18465842020-01-21 01:08:57 -080077import java.util.List;
Alexander Dorokhineab789062021-01-11 21:00:00 -080078import java.util.Map;
Alexander Dorokhined18f8842021-01-20 15:26:13 -080079import java.util.Objects;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080080import java.util.Set;
Terry Wange04ceab2021-03-29 19:25:12 -070081import java.util.concurrent.Executor;
Terry Wangd2186e52021-04-14 13:19:45 -070082import java.util.concurrent.LinkedBlockingQueue;
Terry Wange04ceab2021-03-29 19:25:12 -070083import java.util.concurrent.ThreadPoolExecutor;
84import java.util.concurrent.TimeUnit;
Alexander Dorokhine18465842020-01-21 01:08:57 -080085
Cassie Wang0c62d992021-01-15 14:39:30 -080086/** TODO(b/142567528): add comments when implement this class */
Terry Wangfebbead2019-10-17 17:05:18 -070087public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070088 private static final String TAG = "AppSearchManagerService";
Terry Wang12dc6c02021-03-31 19:26:16 -070089 private final Context mContext;
Yang Yu0fcd51a2021-04-23 11:25:44 -070090 private PackageManager mPackageManager;
Cassie Wang21c2d6a2021-01-20 23:59:55 -080091 private ImplInstanceManager mImplInstanceManager;
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070092 private UserManager mUserManager;
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -080093 private LoggerInstanceManager mLoggerInstanceManager;
Terry Wangfebbead2019-10-17 17:05:18 -070094
Terry Wange04ceab2021-03-29 19:25:12 -070095 // Never call shutdownNow(). It will cancel the futures it's returned. And since
96 // Executor#execute won't return anything, we will hang forever waiting for the execution.
97 // AppSearch multi-thread execution is guarded by Read & Write Lock in AppSearchImpl, all
98 // mutate requests will need to gain write lock and query requests need to gain read lock.
99 private static final Executor EXECUTOR = new ThreadPoolExecutor(/*corePoolSize=*/1,
100 Runtime.getRuntime().availableProcessors(), /*keepAliveTime*/ 60L, TimeUnit.SECONDS,
Terry Wangd2186e52021-04-14 13:19:45 -0700101 new LinkedBlockingQueue<>());
Terry Wange04ceab2021-03-29 19:25:12 -0700102
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700103 // Cache of unlocked users so we don't have to query UserManager service each time. The "locked"
104 // suffix refers to the fact that access to the field should be locked; unrelated to the
105 // unlocked status of users.
106 @GuardedBy("mUnlockedUsersLocked")
107 private final Set<UserHandle> mUnlockedUsersLocked = new ArraySet<>();
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800108
Terry Wangfebbead2019-10-17 17:05:18 -0700109 public AppSearchManagerService(Context context) {
110 super(context);
Terry Wang12dc6c02021-03-31 19:26:16 -0700111 mContext = context;
Terry Wangfebbead2019-10-17 17:05:18 -0700112 }
113
114 @Override
115 public void onStart() {
116 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
Yang Yu0fcd51a2021-04-23 11:25:44 -0700117 mPackageManager = getContext().getPackageManager();
Terry Wang12dc6c02021-03-31 19:26:16 -0700118 mImplInstanceManager = ImplInstanceManager.getInstance(mContext);
119 mUserManager = mContext.getSystemService(UserManager.class);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800120 mLoggerInstanceManager = LoggerInstanceManager.getInstance();
Terry Wang12dc6c02021-03-31 19:26:16 -0700121 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() {
127 mContext.registerReceiverAsUser(new UserActionReceiver(), UserHandle.ALL,
128 new IntentFilter(Intent.ACTION_USER_REMOVED), /*broadcastPermission=*/ null,
129 /*scheduler=*/ null);
Terry Wange201dc02021-04-16 01:03:20 -0700130
131 //TODO(b/145759910) Add a direct callback when user clears the data instead of relying on
132 // broadcasts
133 IntentFilter packageChangedFilter = new IntentFilter();
134 packageChangedFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
135 packageChangedFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
136 packageChangedFilter.addDataScheme("package");
137 packageChangedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
138 mContext.registerReceiverAsUser(new PackageChangedReceiver(), UserHandle.ALL,
139 packageChangedFilter, /*broadcastPermission=*/ null,
140 /*scheduler=*/ null);
Terry Wang12dc6c02021-03-31 19:26:16 -0700141 }
142
143 private class UserActionReceiver extends BroadcastReceiver {
144 @Override
145 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700146 Objects.requireNonNull(context);
147 Objects.requireNonNull(intent);
148
Terry Wang12dc6c02021-03-31 19:26:16 -0700149 switch (intent.getAction()) {
150 case Intent.ACTION_USER_REMOVED:
Terry Wange201dc02021-04-16 01:03:20 -0700151 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
Terry Wang12dc6c02021-03-31 19:26:16 -0700152 if (userId == USER_NULL) {
Terry Wange201dc02021-04-16 01:03:20 -0700153 Log.e(TAG, "userId is missing in the intent: " + intent);
Terry Wang12dc6c02021-03-31 19:26:16 -0700154 return;
155 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700156 handleUserRemoved(UserHandle.of(userId));
Terry Wang12dc6c02021-03-31 19:26:16 -0700157 break;
158 default:
Terry Wange201dc02021-04-16 01:03:20 -0700159 Log.e(TAG, "Received unknown intent: " + intent);
Terry Wang12dc6c02021-03-31 19:26:16 -0700160 }
161 }
162 }
163
164 /**
165 * Handles user removed action.
166 *
167 * <p>Only need to clear the AppSearchImpl instance. The data of AppSearch is saved in the
168 * "credential encrypted" system directory of each user. That directory will be auto-deleted
169 * when a user is removed.
170 *
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700171 * @param userHandle The multi-user handle of the user that need to be removed.
Terry Wang12dc6c02021-03-31 19:26:16 -0700172 *
173 * @see android.os.Environment#getDataSystemCeDirectory
174 */
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700175 private void handleUserRemoved(@NonNull UserHandle userHandle) {
Terry Wang12dc6c02021-03-31 19:26:16 -0700176 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700177 mImplInstanceManager.removeAppSearchImplForUser(userHandle);
178 mLoggerInstanceManager.removePlatformLoggerForUser(userHandle);
179 Log.i(TAG, "Removed AppSearchImpl instance for: " + userHandle);
Terry Wang12dc6c02021-03-31 19:26:16 -0700180 } catch (Throwable t) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700181 Log.e(TAG, "Unable to remove data for: " + userHandle, t);
Terry Wange201dc02021-04-16 01:03:20 -0700182 }
183 }
184
185 private class PackageChangedReceiver extends BroadcastReceiver {
186 @Override
187 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700188 Objects.requireNonNull(context);
189 Objects.requireNonNull(intent);
190
Terry Wange201dc02021-04-16 01:03:20 -0700191 switch (intent.getAction()) {
192 case Intent.ACTION_PACKAGE_FULLY_REMOVED:
193 case Intent.ACTION_PACKAGE_DATA_CLEARED:
194 String packageName = intent.getData().getSchemeSpecificPart();
195 if (packageName == null) {
196 Log.e(TAG, "Package name is missing in the intent: " + intent);
197 return;
198 }
199 int uid = intent.getIntExtra(Intent.EXTRA_UID, INVALID_UID);
200 if (uid == INVALID_UID) {
201 Log.e(TAG, "uid is missing in the intent: " + intent);
202 return;
203 }
204 handlePackageRemoved(packageName, uid);
205 break;
206 default:
207 Log.e(TAG, "Received unknown intent: " + intent);
208 }
209 }
210 }
211
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700212 private void handlePackageRemoved(@NonNull String packageName, int uid) {
213 UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
Terry Wange201dc02021-04-16 01:03:20 -0700214 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700215 if (isUserLocked(userHandle)) {
Terry Wange201dc02021-04-16 01:03:20 -0700216 //TODO(b/186151459) clear the uninstalled package data when user is unlocked.
217 return;
218 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700219 if (ImplInstanceManager.getAppSearchDir(userHandle).exists()) {
Terry Wange201dc02021-04-16 01:03:20 -0700220 // Only clear the package's data if AppSearch exists for this user.
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700221 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700222 userHandle);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700223 AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700224 userHandle, logger);
Terry Wange201dc02021-04-16 01:03:20 -0700225 //TODO(b/145759910) clear visibility setting for package.
226 impl.clearPackageData(packageName);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700227 logger.removeCachedUidForPackage(packageName);
Terry Wange201dc02021-04-16 01:03:20 -0700228 }
229 } catch (Throwable t) {
230 Log.e(TAG, "Unable to remove data for package: " + packageName, t);
Terry Wang12dc6c02021-03-31 19:26:16 -0700231 }
Terry Wangfebbead2019-10-17 17:05:18 -0700232 }
233
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800234 @Override
Pinyao Tingd5c2ed92021-03-18 14:51:54 -0700235 public void onUserUnlocking(@NonNull TargetUser user) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700236 Objects.requireNonNull(user);
237 synchronized (mUnlockedUsersLocked) {
238 mUnlockedUsersLocked.add(user.getUserHandle());
Cassie Wang15c86972021-02-09 13:43:25 -0800239 }
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800240 }
241
Terry Wangde9f3382021-04-28 19:45:07 -0700242 @Override
243 public void onUserStopping(@NonNull TargetUser user) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700244 Objects.requireNonNull(user);
245
246 synchronized (mUnlockedUsersLocked) {
247 UserHandle userHandle = user.getUserHandle();
248 mUnlockedUsersLocked.remove(userHandle);
Terry Wangde9f3382021-04-28 19:45:07 -0700249 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700250 mImplInstanceManager.closeAndRemoveAppSearchImplForUser(userHandle);
Terry Wangde9f3382021-04-28 19:45:07 -0700251 } catch (Throwable t) {
252 Log.e(TAG, "Error handling user stopping.", t);
253 }
254 }
255 }
256
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700257 private void verifyUserUnlocked(@NonNull UserHandle callingUser) {
258 if (isUserLocked(callingUser)) {
259 throw new IllegalStateException(callingUser + " is locked or not running.");
Terry Wange201dc02021-04-16 01:03:20 -0700260 }
261 }
262
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700263 private boolean isUserLocked(@NonNull UserHandle callingUser) {
264 synchronized (mUnlockedUsersLocked) {
Yang Yu0fcd51a2021-04-23 11:25:44 -0700265 // First, check the local copy.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700266 if (mUnlockedUsersLocked.contains(callingUser)) {
Terry Wange201dc02021-04-16 01:03:20 -0700267 return false;
Yang Yu0fcd51a2021-04-23 11:25:44 -0700268 }
269 // If the local copy says the user is locked, check with UM for the actual state,
270 // since the user might just have been unlocked.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700271 return !mUserManager.isUserUnlockingOrUnlocked(callingUser);
Yang Yu0fcd51a2021-04-23 11:25:44 -0700272 }
273 }
274
Terry Wangfebbead2019-10-17 17:05:18 -0700275 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800276 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800277 public void setSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800278 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700279 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700280 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine315cca62021-03-04 12:34:41 -0800281 @NonNull List<String> schemasNotDisplayedBySystem,
Alexander Dorokhineab789062021-01-11 21:00:00 -0800282 @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800283 boolean forceOverride,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700284 int schemaVersion,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700285 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700286 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800287 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700288 Objects.requireNonNull(packageName);
289 Objects.requireNonNull(databaseName);
290 Objects.requireNonNull(schemaBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700291 Objects.requireNonNull(schemasNotDisplayedBySystem);
292 Objects.requireNonNull(schemasPackageAccessibleBundles);
293 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700294 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700295
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700296 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800297 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700298 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700299 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700300 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
301 PlatformLogger logger = null;
302 int operationSuccessCount = 0;
303 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700304 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700305 verifyUserUnlocked(callingUser);
306 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700307 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
308 for (int i = 0; i < schemaBundles.size(); i++) {
309 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhineab789062021-01-11 21:00:00 -0800310 }
Terry Wange04ceab2021-03-29 19:25:12 -0700311 Map<String, List<PackageIdentifier>> schemasPackageAccessible =
312 new ArrayMap<>(schemasPackageAccessibleBundles.size());
313 for (Map.Entry<String, List<Bundle>> entry :
314 schemasPackageAccessibleBundles.entrySet()) {
315 List<PackageIdentifier> packageIdentifiers =
316 new ArrayList<>(entry.getValue().size());
317 for (int i = 0; i < entry.getValue().size(); i++) {
318 packageIdentifiers.add(
319 new PackageIdentifier(entry.getValue().get(i)));
320 }
321 schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
322 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700323 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
324 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700325 SetSchemaResponse setSchemaResponse = impl.setSchema(
326 packageName,
327 databaseName,
328 schemas,
329 schemasNotDisplayedBySystem,
330 schemasPackageAccessible,
331 forceOverride,
332 schemaVersion);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700333 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700334 invokeCallbackOnResult(callback,
335 AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
336 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700337 ++operationFailureCount;
338 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700339 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700340 } finally {
341 if (logger != null) {
342 int estimatedBinderLatencyMillis =
343 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
344 int totalLatencyMillis =
345 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
346 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
347 databaseName)
348 .setCallType(CallStats.CALL_TYPE_SET_SCHEMA)
349 // TODO(b/173532925) check the existing binder call latency chart
350 // is good enough for us:
351 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
352 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
353 .setNumOperationsSucceeded(operationSuccessCount)
354 .setNumOperationsFailed(operationFailureCount);
355 cBuilder.getGeneralStatsBuilder()
356 .setStatusCode(statusCode)
357 .setTotalLatencyMillis(totalLatencyMillis);
358 logger.logStats(cBuilder.build());
359 }
Alexander Dorokhineab789062021-01-11 21:00:00 -0800360 }
Terry Wange04ceab2021-03-29 19:25:12 -0700361 });
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800362 }
363
364 @Override
Terry Wang83a24932020-12-09 21:00:18 -0800365 public void getSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800366 @NonNull String packageName,
Terry Wang83a24932020-12-09 21:00:18 -0800367 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700368 @NonNull UserHandle userHandle,
Terry Wang83a24932020-12-09 21:00:18 -0800369 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700370 Objects.requireNonNull(packageName);
371 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700372 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700373 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700374
Cassie Wangb0d60122021-03-30 12:38:46 -0700375 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700376 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700377 EXECUTOR.execute(() -> {
378 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700379 verifyUserUnlocked(callingUser);
380 verifyCallingPackage(callingUser, callingUid, packageName);
381 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700382 GetSchemaResponse response = impl.getSchema(packageName, databaseName);
383 invokeCallbackOnResult(
384 callback,
385 AppSearchResult.newSuccessfulResult(response.getBundle()));
386 } catch (Throwable t) {
387 invokeCallbackOnError(callback, t);
388 }
389 });
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700390 }
391
392 @Override
393 public void getNamespaces(
394 @NonNull String packageName,
395 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700396 @NonNull UserHandle userHandle,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700397 @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);
409 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700410 List<String> namespaces = impl.getNamespaces(packageName, databaseName);
411 invokeCallbackOnResult(callback,
412 AppSearchResult.newSuccessfulResult(namespaces));
413 } catch (Throwable t) {
414 invokeCallbackOnError(callback, t);
415 }
416 });
Terry Wang83a24932020-12-09 21:00:18 -0800417 }
418
419 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -0800420 public void putDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800421 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700422 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700423 @NonNull List<Bundle> documentBundles,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700424 @NonNull UserHandle userHandle,
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800425 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800426 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700427 Objects.requireNonNull(packageName);
428 Objects.requireNonNull(databaseName);
429 Objects.requireNonNull(documentBundles);
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
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700433 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800434 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700435 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700436 EXECUTOR.execute(() -> {
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800437 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
438 PlatformLogger logger = null;
439 int operationSuccessCount = 0;
440 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700441 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700442 verifyUserUnlocked(callingUser);
443 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700444 AppSearchBatchResult.Builder<String, Void> resultBuilder =
445 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700446 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
447 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700448 for (int i = 0; i < documentBundles.size(); i++) {
449 GenericDocument document = new GenericDocument(documentBundles.get(i));
450 try {
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800451 impl.putDocument(packageName, databaseName, document, logger);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700452 resultBuilder.setSuccess(document.getId(), /*result=*/ null);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800453 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700454 } catch (Throwable t) {
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700455 resultBuilder.setResult(document.getId(),
Terry Wange04ceab2021-03-29 19:25:12 -0700456 throwableToFailedResult(t));
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800457 AppSearchResult<Void> result = throwableToFailedResult(t);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700458 resultBuilder.setResult(document.getId(), result);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700459 // Since we can only include one status code in the atom,
460 // for failures, we would just save the one for the last failure
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800461 statusCode = result.getResultCode();
462 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700463 }
Alexander Dorokhine18465842020-01-21 01:08:57 -0800464 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700465 // Now that the batch has been written. Persist the newly written data.
466 impl.persistToDisk(PersistType.Code.LITE);
Terry Wange04ceab2021-03-29 19:25:12 -0700467 invokeCallbackOnResult(callback, resultBuilder.build());
468 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700469 ++operationFailureCount;
470 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700471 invokeCallbackOnError(callback, t);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800472 } finally {
473 if (logger != null) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700474 int estimatedBinderLatencyMillis =
475 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
476 int totalLatencyMillis =
477 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800478 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
479 databaseName)
480 .setCallType(CallStats.CALL_TYPE_PUT_DOCUMENTS)
481 // TODO(b/173532925) check the existing binder call latency chart
482 // is good enough for us:
483 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700484 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800485 .setNumOperationsSucceeded(operationSuccessCount)
486 .setNumOperationsFailed(operationFailureCount);
487 cBuilder.getGeneralStatsBuilder()
488 .setStatusCode(statusCode)
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700489 .setTotalLatencyMillis(totalLatencyMillis);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800490 logger.logStats(cBuilder.build());
491 }
Alexander Dorokhine18465842020-01-21 01:08:57 -0800492 }
Terry Wange04ceab2021-03-29 19:25:12 -0700493 });
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800494 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800495
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800496 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800497 public void getDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800498 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800499 @NonNull String databaseName,
500 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700501 @NonNull List<String> ids,
Alexander Dorokhine87cdd152021-01-20 15:41:25 -0800502 @NonNull Map<String, List<String>> typePropertyPaths,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700503 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700504 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800505 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700506 Objects.requireNonNull(packageName);
507 Objects.requireNonNull(databaseName);
508 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700509 Objects.requireNonNull(ids);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700510 Objects.requireNonNull(typePropertyPaths);
511 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700512 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700513
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700514 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800515 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700516 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700517 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700518 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
519 PlatformLogger logger = null;
520 int operationSuccessCount = 0;
521 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700522 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700523 verifyUserUnlocked(callingUser);
524 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700525 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
526 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700527 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
528 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700529 for (int i = 0; i < ids.size(); i++) {
530 String id = ids.get(i);
Terry Wange04ceab2021-03-29 19:25:12 -0700531 try {
532 GenericDocument document =
533 impl.getDocument(
534 packageName,
535 databaseName,
536 namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700537 id,
Terry Wange04ceab2021-03-29 19:25:12 -0700538 typePropertyPaths);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700539 ++operationSuccessCount;
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700540 resultBuilder.setSuccess(id, document.getBundle());
Terry Wange04ceab2021-03-29 19:25:12 -0700541 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700542 // Since we can only include one status code in the atom,
543 // for failures, we would just save the one for the last failure
544 AppSearchResult<Bundle> result = throwableToFailedResult(t);
545 resultBuilder.setResult(id, result);
546 statusCode = result.getResultCode();
547 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700548 }
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800549 }
Terry Wange04ceab2021-03-29 19:25:12 -0700550 invokeCallbackOnResult(callback, resultBuilder.build());
551 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700552 ++operationFailureCount;
553 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700554 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700555 } finally {
556 if (logger != null) {
557 int estimatedBinderLatencyMillis =
558 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
559 int totalLatencyMillis =
560 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
561 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
562 databaseName)
563 .setCallType(CallStats.CALL_TYPE_GET_DOCUMENTS)
564 // TODO(b/173532925) check the existing binder call latency chart
565 // is good enough for us:
566 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
567 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
568 .setNumOperationsSucceeded(operationSuccessCount)
569 .setNumOperationsFailed(operationFailureCount);
570 cBuilder.getGeneralStatsBuilder()
571 .setStatusCode(statusCode)
572 .setTotalLatencyMillis(totalLatencyMillis);
573 logger.logStats(cBuilder.build());
574 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800575 }
Terry Wange04ceab2021-03-29 19:25:12 -0700576 });
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800577 }
578
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800579 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800580 public void query(
Cassie Wang0c62d992021-01-15 14:39:30 -0800581 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700582 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700583 @NonNull String queryExpression,
584 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700585 @NonNull UserHandle userHandle,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700586 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700587 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700588 Objects.requireNonNull(packageName);
589 Objects.requireNonNull(databaseName);
590 Objects.requireNonNull(queryExpression);
591 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700592 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700593 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700594
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700595 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800596 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700597 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700598 EXECUTOR.execute(() -> {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700599 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
600 PlatformLogger logger = null;
601 int operationSuccessCount = 0;
602 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700603 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700604 verifyUserUnlocked(callingUser);
605 verifyCallingPackage(callingUser, callingUid, packageName);
606 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
607 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700608 SearchResultPage searchResultPage =
609 impl.query(
610 packageName,
611 databaseName,
612 queryExpression,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700613 new SearchSpec(searchSpecBundle),
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700614 logger);
615 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700616 invokeCallbackOnResult(
617 callback,
618 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
619 } catch (Throwable t) {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700620 ++operationFailureCount;
621 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700622 invokeCallbackOnError(callback, t);
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700623 } finally {
624 if (logger != null) {
625 int estimatedBinderLatencyMillis =
626 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
627 int totalLatencyMillis =
628 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
629 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
630 databaseName)
631 .setCallType(CallStats.CALL_TYPE_SEARCH)
632 // TODO(b/173532925) check the existing binder call latency chart
633 // is good enough for us:
634 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
635 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
636 .setNumOperationsSucceeded(operationSuccessCount)
637 .setNumOperationsFailed(operationFailureCount);
638 cBuilder.getGeneralStatsBuilder()
639 .setStatusCode(statusCode)
640 .setTotalLatencyMillis(totalLatencyMillis);
641 logger.logStats(cBuilder.build());
642 }
Terry Wange04ceab2021-03-29 19:25:12 -0700643 }
644 });
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700645 }
646
Terry Wangf2093072020-11-30 04:47:19 -0800647 @Override
Terry Wangbfbfcac2020-11-06 15:46:44 -0800648 public void globalQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800649 @NonNull String packageName,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800650 @NonNull String queryExpression,
651 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700652 @NonNull UserHandle userHandle,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700653 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800654 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700655 Objects.requireNonNull(packageName);
656 Objects.requireNonNull(queryExpression);
657 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700658 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700659 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700660
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700661 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800662 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700663 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700664 EXECUTOR.execute(() -> {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700665 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
666 PlatformLogger logger = null;
667 int operationSuccessCount = 0;
668 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700669 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700670 verifyUserUnlocked(callingUser);
671 verifyCallingPackage(callingUser, callingUid, packageName);
672 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
673 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700674 SearchResultPage searchResultPage =
675 impl.globalQuery(
676 queryExpression,
677 new SearchSpec(searchSpecBundle),
678 packageName,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700679 callingUid,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700680 logger);
681 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700682 invokeCallbackOnResult(
683 callback,
684 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700685 } catch (Throwable t) {
686 ++operationFailureCount;
687 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700688 invokeCallbackOnError(callback, t);
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700689 } finally {
690 if (logger != null) {
691 int estimatedBinderLatencyMillis =
692 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
693 int totalLatencyMillis =
694 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
695 // TODO(b/173532925) database would be nulluable once we remove generalStats
696 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
697 /*database=*/ "")
698 .setCallType(CallStats.CALL_TYPE_GLOBAL_SEARCH)
699 // TODO(b/173532925) check the existing binder call latency chart
700 // is good enough for us:
701 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
702 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
703 .setNumOperationsSucceeded(operationSuccessCount)
704 .setNumOperationsFailed(operationFailureCount);
705 cBuilder.getGeneralStatsBuilder()
706 .setStatusCode(statusCode)
707 .setTotalLatencyMillis(totalLatencyMillis);
708 logger.logStats(cBuilder.build());
709 }
Terry Wange04ceab2021-03-29 19:25:12 -0700710 }
711 });
Terry Wangbfbfcac2020-11-06 15:46:44 -0800712 }
713
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700714 @Override
Cassie Wang0c62d992021-01-15 14:39:30 -0800715 public void getNextPage(
716 long nextPageToken,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700717 @NonNull UserHandle userHandle,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700718 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700719 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700720 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700721
Terry Wangf2093072020-11-30 04:47:19 -0800722 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700723 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700724 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
725 // opened it
Terry Wange04ceab2021-03-29 19:25:12 -0700726 EXECUTOR.execute(() -> {
727 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700728 verifyUserUnlocked(callingUser);
729 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700730 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
731 invokeCallbackOnResult(
732 callback,
733 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
734 } catch (Throwable t) {
735 invokeCallbackOnError(callback, t);
736 }
737 });
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700738 }
739
740 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700741 public void invalidateNextPageToken(long nextPageToken, @NonNull UserHandle userHandle) {
742 Objects.requireNonNull(userHandle);
743
Terry Wangf2093072020-11-30 04:47:19 -0800744 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700745 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700746 EXECUTOR.execute(() -> {
747 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700748 verifyUserUnlocked(callingUser);
749 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700750 impl.invalidateNextPageToken(nextPageToken);
751 } catch (Throwable t) {
752 Log.e(TAG, "Unable to invalidate the query page token", t);
753 }
754 });
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800755 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800756
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700757 @Override
Terry Wang623e3b02021-02-02 20:27:33 -0800758 public void writeQueryResultsToFile(
759 @NonNull String packageName,
760 @NonNull String databaseName,
761 @NonNull ParcelFileDescriptor fileDescriptor,
762 @NonNull String queryExpression,
763 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700764 @NonNull UserHandle userHandle,
Terry Wang623e3b02021-02-02 20:27:33 -0800765 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700766 Objects.requireNonNull(packageName);
767 Objects.requireNonNull(databaseName);
768 Objects.requireNonNull(fileDescriptor);
769 Objects.requireNonNull(queryExpression);
770 Objects.requireNonNull(searchSpecBundle);
771 Objects.requireNonNull(userHandle);
772 Objects.requireNonNull(callback);
773
Terry Wang623e3b02021-02-02 20:27:33 -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 verifyCallingPackage(callingUser, callingUid, packageName);
779 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700780 // we don't need to append the file. The file is always brand new.
781 try (DataOutputStream outputStream = new DataOutputStream(
782 new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
783 SearchResultPage searchResultPage = impl.query(
784 packageName,
785 databaseName,
786 queryExpression,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700787 new SearchSpec(searchSpecBundle),
788 /*logger=*/ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700789 while (!searchResultPage.getResults().isEmpty()) {
790 for (int i = 0; i < searchResultPage.getResults().size(); i++) {
791 AppSearchMigrationHelper.writeBundleToOutputStream(
792 outputStream, searchResultPage.getResults().get(i)
793 .getGenericDocument().getBundle());
794 }
795 searchResultPage = impl.getNextPage(
796 searchResultPage.getNextPageToken());
Terry Wang623e3b02021-02-02 20:27:33 -0800797 }
Terry Wang623e3b02021-02-02 20:27:33 -0800798 }
Terry Wange04ceab2021-03-29 19:25:12 -0700799 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
800 } catch (Throwable t) {
801 invokeCallbackOnError(callback, t);
Terry Wang623e3b02021-02-02 20:27:33 -0800802 }
Terry Wange04ceab2021-03-29 19:25:12 -0700803 });
Terry Wang623e3b02021-02-02 20:27:33 -0800804 }
805
806 @Override
807 public void putDocumentsFromFile(
808 @NonNull String packageName,
809 @NonNull String databaseName,
810 @NonNull ParcelFileDescriptor fileDescriptor,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700811 @NonNull UserHandle userHandle,
Terry Wang623e3b02021-02-02 20:27:33 -0800812 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700813 Objects.requireNonNull(packageName);
814 Objects.requireNonNull(databaseName);
815 Objects.requireNonNull(fileDescriptor);
816 Objects.requireNonNull(userHandle);
817 Objects.requireNonNull(callback);
818
Terry Wang623e3b02021-02-02 20:27:33 -0800819 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700820 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700821 EXECUTOR.execute(() -> {
822 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700823 verifyCallingPackage(callingUser, callingUid, packageName);
824 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wang623e3b02021-02-02 20:27:33 -0800825
Terry Wange04ceab2021-03-29 19:25:12 -0700826 GenericDocument document;
827 ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
828 try (DataInputStream inputStream = new DataInputStream(
829 new FileInputStream(fileDescriptor.getFileDescriptor()))) {
830 while (true) {
831 try {
832 document = AppSearchMigrationHelper
833 .readDocumentFromInputStream(inputStream);
834 } catch (EOFException e) {
835 // nothing wrong, we just finish the reading.
836 break;
837 }
838 try {
839 impl.putDocument(packageName, databaseName, document,
840 /*logger=*/ null);
841 } catch (Throwable t) {
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700842 migrationFailureBundles.add(new SetSchemaResponse.MigrationFailure(
843 document.getNamespace(),
844 document.getId(),
845 document.getSchemaType(),
846 AppSearchResult.throwableToFailedResult(t))
847 .getBundle());
Terry Wange04ceab2021-03-29 19:25:12 -0700848 }
Terry Wang623e3b02021-02-02 20:27:33 -0800849 }
850 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700851 impl.persistToDisk(PersistType.Code.FULL);
Terry Wange04ceab2021-03-29 19:25:12 -0700852 invokeCallbackOnResult(callback,
853 AppSearchResult.newSuccessfulResult(migrationFailureBundles));
854 } catch (Throwable t) {
855 invokeCallbackOnError(callback, t);
Terry Wang623e3b02021-02-02 20:27:33 -0800856 }
Terry Wange04ceab2021-03-29 19:25:12 -0700857 });
Terry Wang623e3b02021-02-02 20:27:33 -0800858 }
859
860 @Override
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800861 public void reportUsage(
862 @NonNull String packageName,
863 @NonNull String databaseName,
864 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700865 @NonNull String documentId,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800866 long usageTimeMillis,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700867 boolean systemUsage,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700868 @NonNull UserHandle userHandle,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800869 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700870 Objects.requireNonNull(packageName);
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800871 Objects.requireNonNull(databaseName);
872 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700873 Objects.requireNonNull(documentId);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700874 Objects.requireNonNull(userHandle);
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800875 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700876
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800877 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700878 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700879 EXECUTOR.execute(() -> {
880 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700881 verifyUserUnlocked(callingUser);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700882
Terry Wange04ceab2021-03-29 19:25:12 -0700883 if (systemUsage) {
884 // TODO(b/183031844): Validate that the call comes from the system
885 }
886
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700887 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700888 impl.reportUsage(
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700889 packageName, databaseName, namespace, documentId,
Terry Wange04ceab2021-03-29 19:25:12 -0700890 usageTimeMillis, systemUsage);
891 invokeCallbackOnResult(
892 callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
893 } catch (Throwable t) {
894 invokeCallbackOnError(callback, t);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700895 }
Terry Wange04ceab2021-03-29 19:25:12 -0700896 });
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800897 }
898
899 @Override
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700900 public void removeByDocumentId(
Cassie Wang0c62d992021-01-15 14:39:30 -0800901 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800902 @NonNull String databaseName,
903 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700904 @NonNull List<String> ids,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700905 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700906 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800907 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700908 Objects.requireNonNull(packageName);
909 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700910 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700911 Objects.requireNonNull(ids);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700912 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700913 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700914
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700915 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800916 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700917 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700918 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700919 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
920 PlatformLogger logger = null;
921 int operationSuccessCount = 0;
922 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700923 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700924 verifyUserUnlocked(callingUser);
925 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700926 AppSearchBatchResult.Builder<String, Void> resultBuilder =
927 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700928 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
929 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700930 for (int i = 0; i < ids.size(); i++) {
931 String id = ids.get(i);
Terry Wange04ceab2021-03-29 19:25:12 -0700932 try {
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700933 impl.remove(packageName, databaseName, namespace, id);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700934 ++operationSuccessCount;
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700935 resultBuilder.setSuccess(id, /*result= */ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700936 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700937 AppSearchResult<Void> result = throwableToFailedResult(t);
938 resultBuilder.setResult(id, result);
939 // Since we can only include one status code in the atom,
940 // for failures, we would just save the one for the last failure
941 statusCode = result.getResultCode();
942 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700943 }
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700944 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700945 // Now that the batch has been written. Persist the newly written data.
946 impl.persistToDisk(PersistType.Code.LITE);
Terry Wange04ceab2021-03-29 19:25:12 -0700947 invokeCallbackOnResult(callback, resultBuilder.build());
948 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700949 ++operationFailureCount;
950 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700951 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700952 } finally {
953 if (logger != null) {
954 int estimatedBinderLatencyMillis =
955 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
956 int totalLatencyMillis =
957 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
958 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
959 databaseName)
960 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID)
961 // TODO(b/173532925) check the existing binder call latency chart
962 // is good enough for us:
963 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
964 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
965 .setNumOperationsSucceeded(operationSuccessCount)
966 .setNumOperationsFailed(operationFailureCount);
967 cBuilder.getGeneralStatsBuilder()
968 .setStatusCode(statusCode)
969 .setTotalLatencyMillis(totalLatencyMillis);
970 logger.logStats(cBuilder.build());
971 }
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700972 }
Terry Wange04ceab2021-03-29 19:25:12 -0700973 });
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700974 }
975
976 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -0700977 public void removeByQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800978 @NonNull String packageName,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700979 @NonNull String databaseName,
980 @NonNull String queryExpression,
981 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700982 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700983 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700984 @NonNull IAppSearchResultCallback callback) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700985 // TODO(b/173532925) log CallStats once we have CALL_TYPE_REMOVE_BY_QUERY added
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700986 Objects.requireNonNull(packageName);
987 Objects.requireNonNull(databaseName);
988 Objects.requireNonNull(queryExpression);
989 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700990 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700991 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700992
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700993 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800994 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700995 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700996 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700997 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
998 PlatformLogger logger = null;
999 int operationSuccessCount = 0;
1000 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001001 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001002 verifyUserUnlocked(callingUser);
1003 verifyCallingPackage(callingUser, callingUid, packageName);
1004 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
1005 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -07001006 impl.removeByQuery(
1007 packageName,
1008 databaseName,
1009 queryExpression,
1010 new SearchSpec(searchSpecBundle));
Alexander Dorokhinec77f4442021-04-14 09:26:06 -07001011 // Now that the batch has been written. Persist the newly written data.
1012 impl.persistToDisk(PersistType.Code.LITE);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001013 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001014 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
1015 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001016 ++operationFailureCount;
1017 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001018 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001019 } finally {
1020 if (logger != null) {
1021 int estimatedBinderLatencyMillis =
1022 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1023 int totalLatencyMillis =
1024 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
1025 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
1026 databaseName)
1027 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH)
1028 // TODO(b/173532925) check the existing binder call latency chart
1029 // is good enough for us:
1030 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1031 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1032 .setNumOperationsSucceeded(operationSuccessCount)
1033 .setNumOperationsFailed(operationFailureCount);
1034 cBuilder.getGeneralStatsBuilder()
1035 .setStatusCode(statusCode)
1036 .setTotalLatencyMillis(totalLatencyMillis);
1037 logger.logStats(cBuilder.build());
1038 }
Terry Wange04ceab2021-03-29 19:25:12 -07001039 }
1040 });
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -07001041 }
1042
Terry Wangdbd1dca2020-11-03 17:03:56 -08001043 @Override
Cassie Wang8f0df492021-03-24 09:23:18 -07001044 public void getStorageInfo(
1045 @NonNull String packageName,
1046 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001047 @NonNull UserHandle userHandle,
Cassie Wang8f0df492021-03-24 09:23:18 -07001048 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001049 Objects.requireNonNull(packageName);
1050 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001051 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001052 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001053
Cassie Wang8f0df492021-03-24 09:23:18 -07001054 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001055 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001056 EXECUTOR.execute(() -> {
1057 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001058 verifyUserUnlocked(callingUser);
1059 verifyCallingPackage(callingUser, callingUid, packageName);
1060 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -07001061 StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName,
1062 databaseName);
1063 Bundle storageInfoBundle = storageInfo.getBundle();
1064 invokeCallbackOnResult(
1065 callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
1066 } catch (Throwable t) {
1067 invokeCallbackOnError(callback, t);
1068 }
1069 });
Cassie Wang8f0df492021-03-24 09:23:18 -07001070 }
1071
1072 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001073 public void persistToDisk(
1074 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001075 @ElapsedRealtimeLong long binderCallStartTimeMillis) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001076 Objects.requireNonNull(userHandle);
1077
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001078 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Cassie Wangb0d60122021-03-30 12:38:46 -07001079 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001080 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001081 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001082 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
1083 PlatformLogger logger = null;
1084 int operationSuccessCount = 0;
1085 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001086 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001087 verifyUserUnlocked(callingUser);
1088 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
1089 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Alexander Dorokhinec77f4442021-04-14 09:26:06 -07001090 impl.persistToDisk(PersistType.Code.FULL);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001091 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001092 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001093 ++operationFailureCount;
1094 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001095 Log.e(TAG, "Unable to persist the data to disk", t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001096 } finally {
1097 if (logger != null) {
1098 int estimatedBinderLatencyMillis =
1099 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1100 int totalLatencyMillis =
1101 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
1102 CallStats.Builder cBuilder = new CallStats.Builder(/*packageName=*/ "",
1103 /*databaseName=*/ "")
1104 .setCallType(CallStats.CALL_TYPE_FLUSH)
1105 // TODO(b/173532925) check the existing binder call latency chart
1106 // is good enough for us:
1107 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1108 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1109 .setNumOperationsSucceeded(operationSuccessCount)
1110 .setNumOperationsFailed(operationFailureCount);
1111 cBuilder.getGeneralStatsBuilder()
1112 .setStatusCode(statusCode)
1113 .setTotalLatencyMillis(totalLatencyMillis);
1114 logger.logStats(cBuilder.build());
1115 }
Terry Wange04ceab2021-03-29 19:25:12 -07001116 }
1117 });
Terry Wang2da17852020-12-16 19:59:08 -08001118 }
1119
1120 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001121 public void initialize(
1122 @NonNull UserHandle userHandle,
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001123 @ElapsedRealtimeLong long binderCallStartTimeMillis,
1124 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001125 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001126 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001127
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001128 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -08001129 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001130 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001131 EXECUTOR.execute(() -> {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001132 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
1133 PlatformLogger logger = null;
1134 int operationSuccessCount = 0;
1135 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001136 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001137 verifyUserUnlocked(callingUser);
1138 logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
1139 mContext, callingUser);
1140 mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUser, logger);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001141 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001142 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
1143 } catch (Throwable t) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001144 ++operationFailureCount;
1145 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001146 invokeCallbackOnError(callback, t);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001147 } finally {
1148 if (logger != null) {
1149 int estimatedBinderLatencyMillis =
1150 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1151 int totalLatencyMillis =
1152 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
1153 // TODO(b/173532925) make packageName and database nullable after
1154 // removing generalStats
1155 CallStats.Builder cBuilder = new CallStats.Builder(/*packageName=*/"",
1156 /*database=*/ "")
1157 .setCallType(CallStats.CALL_TYPE_INITIALIZE)
1158 // TODO(b/173532925) check the existing binder call latency chart
1159 // is good enough for us:
1160 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1161 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1162 .setNumOperationsSucceeded(operationSuccessCount)
1163 .setNumOperationsFailed(operationFailureCount);
1164 cBuilder.getGeneralStatsBuilder()
1165 .setStatusCode(statusCode)
1166 .setTotalLatencyMillis(totalLatencyMillis);
1167 logger.logStats(cBuilder.build());
1168 }
Terry Wange04ceab2021-03-29 19:25:12 -07001169 }
1170 });
Terry Wangdbd1dca2020-11-03 17:03:56 -08001171 }
1172
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001173 private void verifyCallingPackage(
1174 @NonNull UserHandle actualCallingUser,
1175 int actualCallingUid,
1176 @NonNull String claimedCallingPackage) {
1177 Objects.requireNonNull(actualCallingUser);
1178 Objects.requireNonNull(claimedCallingPackage);
1179
1180 int claimedCallingUid;
1181 try {
1182 Context claimedCallingContext =
1183 mContext.createContextAsUser(actualCallingUser, /*flags=*/ 0);
1184 claimedCallingUid = claimedCallingContext.getPackageManager().getPackageUid(
1185 claimedCallingPackage, /*flags=*/ 0);
1186 } catch (PackageManager.NameNotFoundException e) {
1187 throw new SecurityException(
1188 "Specified calling package [" + claimedCallingPackage + "] not found");
1189 }
1190 if (claimedCallingUid != actualCallingUid) {
Cassie Wang0c62d992021-01-15 14:39:30 -08001191 throw new SecurityException(
1192 "Specified calling package ["
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001193 + claimedCallingPackage
Cassie Wang0c62d992021-01-15 14:39:30 -08001194 + "] does not match the calling uid "
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001195 + actualCallingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -07001196 }
Alexander Dorokhineebd37742020-09-22 15:02:26 -07001197 }
1198
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001199 /** Invokes the {@link IAppSearchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -08001200 private void invokeCallbackOnResult(
1201 IAppSearchResultCallback callback, AppSearchResult<?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -08001202 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001203 callback.onResult(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001204 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001205 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001206 }
Terry Wangdbd1dca2020-11-03 17:03:56 -08001207 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001208
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001209 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -08001210 private void invokeCallbackOnResult(
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001211 IAppSearchBatchResultCallback callback, AppSearchBatchResult<String, ?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -08001212 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001213 callback.onResult(new AppSearchBatchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001214 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001215 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001216 }
Terry Wangdbd1dca2020-11-03 17:03:56 -08001217 }
1218
1219 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001220 * Invokes the {@link IAppSearchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001221 *
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001222 * <p>The throwable is convert to a {@link AppSearchResult};
Terry Wangdbd1dca2020-11-03 17:03:56 -08001223 */
1224 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001225 AppSearchResult<?> result = throwableToFailedResult(throwable);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001226 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001227 callback.onResult(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001228 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001229 Log.e(TAG, "Unable to send result to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001230 }
1231 }
1232
1233 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001234 * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001235 *
Alexander Dorokhineb5d34b12021-04-15 00:32:15 -07001236 * <p>The throwable is converted to {@link AppSearchResult}.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001237 */
Cassie Wang0c62d992021-01-15 14:39:30 -08001238 private void invokeCallbackOnError(
Alexander Dorokhineb5d34b12021-04-15 00:32:15 -07001239 @NonNull IAppSearchBatchResultCallback callback, @NonNull Throwable throwable) {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001240 AppSearchResult<?> result = throwableToFailedResult(throwable);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001241 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001242 callback.onSystemError(new AppSearchResultParcel<>(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 error to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001245 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001246 }
Terry Wangfebbead2019-10-17 17:05:18 -07001247 }
Terry Wangf2093072020-11-30 04:47:19 -08001248
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001249 /**
1250 * Helper for dealing with incoming user arguments to system service calls.
1251 *
1252 * <p>Takes care of checking permissions and converting USER_CURRENT to the actual current user.
1253 *
1254 * @return the user handle that the call should run as. Will always be a concrete user.
1255 */
Cassie Wang0c62d992021-01-15 14:39:30 -08001256 // TODO(b/173553485) verifying that the caller has permission to access target user's data
1257 // TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast
1258 // TODO(b/173553485) Implement SystemService.onUserStopping()
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001259 @NonNull
1260 private static UserHandle handleIncomingUser(@NonNull UserHandle userHandle, int callingUid) {
Terry Wangf2093072020-11-30 04:47:19 -08001261 int callingPid = Binder.getCallingPid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001262 int finalUserId = ActivityManager.handleIncomingUser(
Cassie Wang0c62d992021-01-15 14:39:30 -08001263 callingPid,
1264 callingUid,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001265 userHandle.getIdentifier(),
Cassie Wang0c62d992021-01-15 14:39:30 -08001266 /*allowAll=*/ false,
1267 /*requireFull=*/ false,
1268 /*name=*/ null,
1269 /*callerPackage=*/ null);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001270 return UserHandle.of(finalUserId);
Terry Wangf2093072020-11-30 04:47:19 -08001271 }
Yang Yu0fcd51a2021-04-23 11:25:44 -07001272
1273 // TODO(b/179160886): Cache the previous storage stats.
1274 private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter {
1275 @Override
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001276 public void augmentStatsForPackageForUser(
Yang Yu0fcd51a2021-04-23 11:25:44 -07001277 @NonNull PackageStats stats,
1278 @NonNull String packageName,
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001279 @NonNull UserHandle userHandle,
1280 boolean canCallerAccessAllStats) {
Yang Yu0fcd51a2021-04-23 11:25:44 -07001281 Objects.requireNonNull(stats);
1282 Objects.requireNonNull(packageName);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001283 Objects.requireNonNull(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001284
Yang Yu0fcd51a2021-04-23 11:25:44 -07001285 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001286 verifyUserUnlocked(userHandle);
1287 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
1288 mContext, userHandle);
1289 AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
1290 mContext, userHandle, logger);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001291 stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
1292 } catch (Throwable t) {
1293 Log.e(
1294 TAG,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001295 "Unable to augment storage stats for "
1296 + userHandle
Yang Yu0fcd51a2021-04-23 11:25:44 -07001297 + " packageName "
1298 + packageName,
1299 t);
1300 }
1301 }
1302
1303 @Override
1304 public void augmentStatsForUid(
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001305 @NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats) {
Yang Yu0fcd51a2021-04-23 11:25:44 -07001306 Objects.requireNonNull(stats);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001307
1308 UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001309 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001310 verifyUserUnlocked(userHandle);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001311 String[] packagesForUid = mPackageManager.getPackagesForUid(uid);
1312 if (packagesForUid == null) {
1313 return;
1314 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001315 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
1316 mContext, userHandle);
1317 AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
1318 mContext, userHandle, logger);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001319 for (int i = 0; i < packagesForUid.length; i++) {
1320 stats.dataSize +=
1321 impl.getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
Yang Yu0fcd51a2021-04-23 11:25:44 -07001322 }
1323 } catch (Throwable t) {
1324 Log.e(TAG, "Unable to augment storage stats for uid " + uid, t);
1325 }
1326 }
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001327
1328 @Override
1329 public void augmentStatsForUser(
1330 @NonNull PackageStats stats, @NonNull UserHandle userHandle) {
1331 // TODO(b/179160886): this implementation could incur many jni calls and a lot of
1332 // in-memory processing from getStorageInfoForPackage. Instead, we can just compute the
1333 // size of the icing dir (or use the overall StorageInfo without interpolating it).
1334 Objects.requireNonNull(stats);
1335 Objects.requireNonNull(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001336
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001337 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001338 verifyUserUnlocked(userHandle);
1339 List<PackageInfo> packagesForUser = mPackageManager.getInstalledPackagesAsUser(
1340 /*flags=*/0, userHandle.getIdentifier());
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001341 if (packagesForUser == null) {
1342 return;
1343 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001344 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
1345 mContext, userHandle);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001346 AppSearchImpl impl =
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001347 mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userHandle, logger);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001348 for (int i = 0; i < packagesForUser.size(); i++) {
1349 String packageName = packagesForUser.get(i).packageName;
1350 stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
1351 }
1352 } catch (Throwable t) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001353 Log.e(TAG, "Unable to augment storage stats for " + userHandle, t);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001354 }
1355 }
Yang Yu0fcd51a2021-04-23 11:25:44 -07001356 }
Terry Wangfebbead2019-10-17 17:05:18 -07001357}