blob: a3b89b0f27fb70d91730e3b9f1dbc88c54b176ff [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;
Terry Wang12dc6c02021-03-31 19:26:16 -070040import android.content.BroadcastReceiver;
Terry Wangfebbead2019-10-17 17:05:18 -070041import android.content.Context;
Terry Wang12dc6c02021-03-31 19:26:16 -070042import android.content.Intent;
43import android.content.IntentFilter;
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -070044import android.content.pm.PackageInfo;
Yang Yu0fcd51a2021-04-23 11:25:44 -070045import android.content.pm.PackageManager;
Yang Yu0fcd51a2021-04-23 11:25:44 -070046import android.content.pm.PackageStats;
Alexander Dorokhine270d4f12020-01-15 17:24:35 -080047import android.os.Binder;
Alexander Dorokhine92ce3532020-10-06 01:39:36 -070048import android.os.Bundle;
Terry Wang623e3b02021-02-02 20:27:33 -080049import android.os.ParcelFileDescriptor;
Terry Wangdbd1dca2020-11-03 17:03:56 -080050import android.os.RemoteException;
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -080051import android.os.SystemClock;
Cassie Wang0c62d992021-01-15 14:39:30 -080052import android.os.UserHandle;
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070053import android.os.UserManager;
Alexander Dorokhineab789062021-01-11 21:00:00 -080054import android.util.ArrayMap;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080055import android.util.ArraySet;
Terry Wangdbd1dca2020-11-03 17:03:56 -080056import android.util.Log;
Terry Wangfebbead2019-10-17 17:05:18 -070057
Cassie Wang15c86972021-02-09 13:43:25 -080058import com.android.internal.annotations.GuardedBy;
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -070059import com.android.server.LocalManagerRegistry;
Terry Wangfebbead2019-10-17 17:05:18 -070060import com.android.server.SystemService;
Alexander Dorokhinef660d8f2020-10-29 22:37:00 -070061import com.android.server.appsearch.external.localstorage.AppSearchImpl;
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -080062import com.android.server.appsearch.external.localstorage.stats.CallStats;
63import com.android.server.appsearch.stats.LoggerInstanceManager;
64import com.android.server.appsearch.stats.PlatformLogger;
Alexander Dorokhine5c416772021-06-04 09:05:00 -070065import com.android.server.appsearch.util.PackageUtil;
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() {
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700127 mContext.registerReceiverForAllUsers(
128 new UserActionReceiver(),
129 new IntentFilter(Intent.ACTION_USER_REMOVED),
130 /*broadcastPermission=*/ null,
Terry Wang12dc6c02021-03-31 19:26:16 -0700131 /*scheduler=*/ null);
Terry Wange201dc02021-04-16 01:03:20 -0700132
133 //TODO(b/145759910) Add a direct callback when user clears the data instead of relying on
134 // broadcasts
135 IntentFilter packageChangedFilter = new IntentFilter();
136 packageChangedFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
137 packageChangedFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
138 packageChangedFilter.addDataScheme("package");
139 packageChangedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700140 mContext.registerReceiverForAllUsers(
141 new PackageChangedReceiver(),
142 packageChangedFilter,
143 /*broadcastPermission=*/ null,
Terry Wange201dc02021-04-16 01:03:20 -0700144 /*scheduler=*/ null);
Terry Wang12dc6c02021-03-31 19:26:16 -0700145 }
146
147 private class UserActionReceiver extends BroadcastReceiver {
148 @Override
149 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700150 Objects.requireNonNull(context);
151 Objects.requireNonNull(intent);
152
Terry Wang12dc6c02021-03-31 19:26:16 -0700153 switch (intent.getAction()) {
154 case Intent.ACTION_USER_REMOVED:
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700155 UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
156 if (userHandle == null) {
157 Log.e(TAG, "Extra "
158 + Intent.EXTRA_USER + " is missing in the intent: " + intent);
Terry Wang12dc6c02021-03-31 19:26:16 -0700159 return;
160 }
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700161 handleUserRemoved(userHandle);
Terry Wang12dc6c02021-03-31 19:26:16 -0700162 break;
163 default:
Terry Wange201dc02021-04-16 01:03:20 -0700164 Log.e(TAG, "Received unknown intent: " + intent);
Terry Wang12dc6c02021-03-31 19:26:16 -0700165 }
166 }
167 }
168
169 /**
170 * Handles user removed action.
171 *
172 * <p>Only need to clear the AppSearchImpl instance. The data of AppSearch is saved in the
173 * "credential encrypted" system directory of each user. That directory will be auto-deleted
174 * when a user is removed.
175 *
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700176 * @param userHandle The multi-user handle of the user that need to be removed.
Terry Wang12dc6c02021-03-31 19:26:16 -0700177 *
178 * @see android.os.Environment#getDataSystemCeDirectory
179 */
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700180 private void handleUserRemoved(@NonNull UserHandle userHandle) {
Terry Wang12dc6c02021-03-31 19:26:16 -0700181 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700182 mImplInstanceManager.removeAppSearchImplForUser(userHandle);
183 mLoggerInstanceManager.removePlatformLoggerForUser(userHandle);
184 Log.i(TAG, "Removed AppSearchImpl instance for: " + userHandle);
Terry Wang12dc6c02021-03-31 19:26:16 -0700185 } catch (Throwable t) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700186 Log.e(TAG, "Unable to remove data for: " + userHandle, t);
Terry Wange201dc02021-04-16 01:03:20 -0700187 }
188 }
189
190 private class PackageChangedReceiver extends BroadcastReceiver {
191 @Override
192 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700193 Objects.requireNonNull(context);
194 Objects.requireNonNull(intent);
195
Terry Wange201dc02021-04-16 01:03:20 -0700196 switch (intent.getAction()) {
197 case Intent.ACTION_PACKAGE_FULLY_REMOVED:
198 case Intent.ACTION_PACKAGE_DATA_CLEARED:
199 String packageName = intent.getData().getSchemeSpecificPart();
200 if (packageName == null) {
201 Log.e(TAG, "Package name is missing in the intent: " + intent);
202 return;
203 }
204 int uid = intent.getIntExtra(Intent.EXTRA_UID, INVALID_UID);
205 if (uid == INVALID_UID) {
206 Log.e(TAG, "uid is missing in the intent: " + intent);
207 return;
208 }
209 handlePackageRemoved(packageName, uid);
210 break;
211 default:
212 Log.e(TAG, "Received unknown intent: " + intent);
213 }
214 }
215 }
216
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700217 private void handlePackageRemoved(@NonNull String packageName, int uid) {
218 UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
Terry Wange201dc02021-04-16 01:03:20 -0700219 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700220 if (isUserLocked(userHandle)) {
Terry Wange201dc02021-04-16 01:03:20 -0700221 //TODO(b/186151459) clear the uninstalled package data when user is unlocked.
222 return;
223 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700224 if (ImplInstanceManager.getAppSearchDir(userHandle).exists()) {
Terry Wange201dc02021-04-16 01:03:20 -0700225 // Only clear the package's data if AppSearch exists for this user.
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700226 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext,
Xiaoyu Jin433892c2021-05-24 16:19:02 -0700227 userHandle, AppSearchConfig.getInstance(EXECUTOR));
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700228 AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700229 userHandle, logger);
Terry Wange201dc02021-04-16 01:03:20 -0700230 //TODO(b/145759910) clear visibility setting for package.
231 impl.clearPackageData(packageName);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700232 logger.removeCachedUidForPackage(packageName);
Terry Wange201dc02021-04-16 01:03:20 -0700233 }
234 } catch (Throwable t) {
235 Log.e(TAG, "Unable to remove data for package: " + packageName, t);
Terry Wang12dc6c02021-03-31 19:26:16 -0700236 }
Terry Wangfebbead2019-10-17 17:05:18 -0700237 }
238
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800239 @Override
Pinyao Tingd5c2ed92021-03-18 14:51:54 -0700240 public void onUserUnlocking(@NonNull TargetUser user) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700241 Objects.requireNonNull(user);
242 synchronized (mUnlockedUsersLocked) {
243 mUnlockedUsersLocked.add(user.getUserHandle());
Cassie Wang15c86972021-02-09 13:43:25 -0800244 }
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800245 }
246
Terry Wangde9f3382021-04-28 19:45:07 -0700247 @Override
248 public void onUserStopping(@NonNull TargetUser user) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700249 Objects.requireNonNull(user);
250
251 synchronized (mUnlockedUsersLocked) {
252 UserHandle userHandle = user.getUserHandle();
253 mUnlockedUsersLocked.remove(userHandle);
Terry Wangde9f3382021-04-28 19:45:07 -0700254 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700255 mImplInstanceManager.closeAndRemoveAppSearchImplForUser(userHandle);
Terry Wangde9f3382021-04-28 19:45:07 -0700256 } catch (Throwable t) {
257 Log.e(TAG, "Error handling user stopping.", t);
258 }
259 }
260 }
261
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700262 private void verifyUserUnlocked(@NonNull UserHandle callingUser) {
263 if (isUserLocked(callingUser)) {
264 throw new IllegalStateException(callingUser + " is locked or not running.");
Terry Wange201dc02021-04-16 01:03:20 -0700265 }
266 }
267
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700268 private boolean isUserLocked(@NonNull UserHandle callingUser) {
269 synchronized (mUnlockedUsersLocked) {
Yang Yu0fcd51a2021-04-23 11:25:44 -0700270 // First, check the local copy.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700271 if (mUnlockedUsersLocked.contains(callingUser)) {
Terry Wange201dc02021-04-16 01:03:20 -0700272 return false;
Yang Yu0fcd51a2021-04-23 11:25:44 -0700273 }
274 // If the local copy says the user is locked, check with UM for the actual state,
275 // since the user might just have been unlocked.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700276 return !mUserManager.isUserUnlockingOrUnlocked(callingUser);
Yang Yu0fcd51a2021-04-23 11:25:44 -0700277 }
278 }
279
Terry Wangfebbead2019-10-17 17:05:18 -0700280 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800281 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800282 public void setSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800283 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700284 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700285 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine315cca62021-03-04 12:34:41 -0800286 @NonNull List<String> schemasNotDisplayedBySystem,
Alexander Dorokhineab789062021-01-11 21:00:00 -0800287 @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800288 boolean forceOverride,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700289 int schemaVersion,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700290 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700291 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800292 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700293 Objects.requireNonNull(packageName);
294 Objects.requireNonNull(databaseName);
295 Objects.requireNonNull(schemaBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700296 Objects.requireNonNull(schemasNotDisplayedBySystem);
297 Objects.requireNonNull(schemasPackageAccessibleBundles);
298 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700299 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700300
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700301 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800302 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700303 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700304 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700305 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
306 PlatformLogger logger = null;
307 int operationSuccessCount = 0;
308 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700309 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700310 verifyUserUnlocked(callingUser);
311 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700312 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
313 for (int i = 0; i < schemaBundles.size(); i++) {
314 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhineab789062021-01-11 21:00:00 -0800315 }
Terry Wange04ceab2021-03-29 19:25:12 -0700316 Map<String, List<PackageIdentifier>> schemasPackageAccessible =
317 new ArrayMap<>(schemasPackageAccessibleBundles.size());
318 for (Map.Entry<String, List<Bundle>> entry :
319 schemasPackageAccessibleBundles.entrySet()) {
320 List<PackageIdentifier> packageIdentifiers =
321 new ArrayList<>(entry.getValue().size());
322 for (int i = 0; i < entry.getValue().size(); i++) {
323 packageIdentifiers.add(
324 new PackageIdentifier(entry.getValue().get(i)));
325 }
326 schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
327 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700328 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
329 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700330 SetSchemaResponse setSchemaResponse = impl.setSchema(
331 packageName,
332 databaseName,
333 schemas,
334 schemasNotDisplayedBySystem,
335 schemasPackageAccessible,
336 forceOverride,
337 schemaVersion);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700338 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700339 invokeCallbackOnResult(callback,
340 AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
341 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700342 ++operationFailureCount;
343 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700344 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700345 } finally {
346 if (logger != null) {
347 int estimatedBinderLatencyMillis =
348 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
349 int totalLatencyMillis =
350 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
351 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
352 databaseName)
353 .setCallType(CallStats.CALL_TYPE_SET_SCHEMA)
354 // TODO(b/173532925) check the existing binder call latency chart
355 // is good enough for us:
356 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
357 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
358 .setNumOperationsSucceeded(operationSuccessCount)
359 .setNumOperationsFailed(operationFailureCount);
360 cBuilder.getGeneralStatsBuilder()
361 .setStatusCode(statusCode)
362 .setTotalLatencyMillis(totalLatencyMillis);
363 logger.logStats(cBuilder.build());
364 }
Alexander Dorokhineab789062021-01-11 21:00:00 -0800365 }
Terry Wange04ceab2021-03-29 19:25:12 -0700366 });
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800367 }
368
369 @Override
Terry Wang83a24932020-12-09 21:00:18 -0800370 public void getSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800371 @NonNull String packageName,
Terry Wang83a24932020-12-09 21:00:18 -0800372 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700373 @NonNull UserHandle userHandle,
Terry Wang83a24932020-12-09 21:00:18 -0800374 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700375 Objects.requireNonNull(packageName);
376 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700377 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700378 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700379
Cassie Wangb0d60122021-03-30 12:38:46 -0700380 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700381 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700382 EXECUTOR.execute(() -> {
383 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700384 verifyUserUnlocked(callingUser);
385 verifyCallingPackage(callingUser, callingUid, packageName);
386 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700387 GetSchemaResponse response = impl.getSchema(packageName, databaseName);
388 invokeCallbackOnResult(
389 callback,
390 AppSearchResult.newSuccessfulResult(response.getBundle()));
391 } catch (Throwable t) {
392 invokeCallbackOnError(callback, t);
393 }
394 });
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700395 }
396
397 @Override
398 public void getNamespaces(
399 @NonNull String packageName,
400 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700401 @NonNull UserHandle userHandle,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700402 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700403 Objects.requireNonNull(packageName);
404 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700405 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700406 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700407
Cassie Wangb0d60122021-03-30 12:38:46 -0700408 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700409 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700410 EXECUTOR.execute(() -> {
411 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700412 verifyUserUnlocked(callingUser);
413 verifyCallingPackage(callingUser, callingUid, packageName);
414 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700415 List<String> namespaces = impl.getNamespaces(packageName, databaseName);
416 invokeCallbackOnResult(callback,
417 AppSearchResult.newSuccessfulResult(namespaces));
418 } catch (Throwable t) {
419 invokeCallbackOnError(callback, t);
420 }
421 });
Terry Wang83a24932020-12-09 21:00:18 -0800422 }
423
424 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -0800425 public void putDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800426 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700427 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700428 @NonNull List<Bundle> documentBundles,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700429 @NonNull UserHandle userHandle,
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800430 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800431 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700432 Objects.requireNonNull(packageName);
433 Objects.requireNonNull(databaseName);
434 Objects.requireNonNull(documentBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700435 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700436 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700437
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700438 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800439 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700440 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700441 EXECUTOR.execute(() -> {
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800442 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
443 PlatformLogger logger = null;
444 int operationSuccessCount = 0;
445 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700446 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700447 verifyUserUnlocked(callingUser);
448 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700449 AppSearchBatchResult.Builder<String, Void> resultBuilder =
450 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700451 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
452 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700453 for (int i = 0; i < documentBundles.size(); i++) {
454 GenericDocument document = new GenericDocument(documentBundles.get(i));
455 try {
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800456 impl.putDocument(packageName, databaseName, document, logger);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700457 resultBuilder.setSuccess(document.getId(), /*result=*/ null);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800458 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700459 } catch (Throwable t) {
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700460 resultBuilder.setResult(document.getId(),
Terry Wange04ceab2021-03-29 19:25:12 -0700461 throwableToFailedResult(t));
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800462 AppSearchResult<Void> result = throwableToFailedResult(t);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700463 resultBuilder.setResult(document.getId(), result);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700464 // Since we can only include one status code in the atom,
465 // for failures, we would just save the one for the last failure
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800466 statusCode = result.getResultCode();
467 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700468 }
Alexander Dorokhine18465842020-01-21 01:08:57 -0800469 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700470 // Now that the batch has been written. Persist the newly written data.
471 impl.persistToDisk(PersistType.Code.LITE);
Terry Wange04ceab2021-03-29 19:25:12 -0700472 invokeCallbackOnResult(callback, resultBuilder.build());
473 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700474 ++operationFailureCount;
475 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700476 invokeCallbackOnError(callback, t);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800477 } finally {
478 if (logger != null) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700479 int estimatedBinderLatencyMillis =
480 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
481 int totalLatencyMillis =
482 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800483 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
484 databaseName)
485 .setCallType(CallStats.CALL_TYPE_PUT_DOCUMENTS)
486 // TODO(b/173532925) check the existing binder call latency chart
487 // is good enough for us:
488 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700489 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800490 .setNumOperationsSucceeded(operationSuccessCount)
491 .setNumOperationsFailed(operationFailureCount);
492 cBuilder.getGeneralStatsBuilder()
493 .setStatusCode(statusCode)
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700494 .setTotalLatencyMillis(totalLatencyMillis);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800495 logger.logStats(cBuilder.build());
496 }
Alexander Dorokhine18465842020-01-21 01:08:57 -0800497 }
Terry Wange04ceab2021-03-29 19:25:12 -0700498 });
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800499 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800500
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800501 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800502 public void getDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800503 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800504 @NonNull String databaseName,
505 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700506 @NonNull List<String> ids,
Alexander Dorokhine87cdd152021-01-20 15:41:25 -0800507 @NonNull Map<String, List<String>> typePropertyPaths,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700508 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700509 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800510 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700511 Objects.requireNonNull(packageName);
512 Objects.requireNonNull(databaseName);
513 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700514 Objects.requireNonNull(ids);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700515 Objects.requireNonNull(typePropertyPaths);
516 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700517 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700518
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700519 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800520 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700521 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700522 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700523 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
524 PlatformLogger logger = null;
525 int operationSuccessCount = 0;
526 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700527 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700528 verifyUserUnlocked(callingUser);
529 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700530 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
531 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700532 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
533 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700534 for (int i = 0; i < ids.size(); i++) {
535 String id = ids.get(i);
Terry Wange04ceab2021-03-29 19:25:12 -0700536 try {
537 GenericDocument document =
538 impl.getDocument(
539 packageName,
540 databaseName,
541 namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700542 id,
Terry Wange04ceab2021-03-29 19:25:12 -0700543 typePropertyPaths);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700544 ++operationSuccessCount;
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700545 resultBuilder.setSuccess(id, document.getBundle());
Terry Wange04ceab2021-03-29 19:25:12 -0700546 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700547 // Since we can only include one status code in the atom,
548 // for failures, we would just save the one for the last failure
549 AppSearchResult<Bundle> result = throwableToFailedResult(t);
550 resultBuilder.setResult(id, result);
551 statusCode = result.getResultCode();
552 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700553 }
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800554 }
Terry Wange04ceab2021-03-29 19:25:12 -0700555 invokeCallbackOnResult(callback, resultBuilder.build());
556 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700557 ++operationFailureCount;
558 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700559 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700560 } finally {
561 if (logger != null) {
562 int estimatedBinderLatencyMillis =
563 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
564 int totalLatencyMillis =
565 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
566 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
567 databaseName)
568 .setCallType(CallStats.CALL_TYPE_GET_DOCUMENTS)
569 // TODO(b/173532925) check the existing binder call latency chart
570 // is good enough for us:
571 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
572 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
573 .setNumOperationsSucceeded(operationSuccessCount)
574 .setNumOperationsFailed(operationFailureCount);
575 cBuilder.getGeneralStatsBuilder()
576 .setStatusCode(statusCode)
577 .setTotalLatencyMillis(totalLatencyMillis);
578 logger.logStats(cBuilder.build());
579 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800580 }
Terry Wange04ceab2021-03-29 19:25:12 -0700581 });
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800582 }
583
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800584 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800585 public void query(
Cassie Wang0c62d992021-01-15 14:39:30 -0800586 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700587 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700588 @NonNull String queryExpression,
589 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700590 @NonNull UserHandle userHandle,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700591 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700592 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700593 Objects.requireNonNull(packageName);
594 Objects.requireNonNull(databaseName);
595 Objects.requireNonNull(queryExpression);
596 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700597 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700598 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700599
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700600 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800601 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700602 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700603 EXECUTOR.execute(() -> {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700604 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
605 PlatformLogger logger = null;
606 int operationSuccessCount = 0;
607 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700608 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700609 verifyUserUnlocked(callingUser);
610 verifyCallingPackage(callingUser, callingUid, packageName);
611 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
612 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700613 SearchResultPage searchResultPage =
614 impl.query(
615 packageName,
616 databaseName,
617 queryExpression,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700618 new SearchSpec(searchSpecBundle),
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700619 logger);
620 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700621 invokeCallbackOnResult(
622 callback,
623 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
624 } catch (Throwable t) {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700625 ++operationFailureCount;
626 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700627 invokeCallbackOnError(callback, t);
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700628 } finally {
629 if (logger != null) {
630 int estimatedBinderLatencyMillis =
631 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
632 int totalLatencyMillis =
633 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
634 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
635 databaseName)
636 .setCallType(CallStats.CALL_TYPE_SEARCH)
637 // TODO(b/173532925) check the existing binder call latency chart
638 // is good enough for us:
639 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
640 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
641 .setNumOperationsSucceeded(operationSuccessCount)
642 .setNumOperationsFailed(operationFailureCount);
643 cBuilder.getGeneralStatsBuilder()
644 .setStatusCode(statusCode)
645 .setTotalLatencyMillis(totalLatencyMillis);
646 logger.logStats(cBuilder.build());
647 }
Terry Wange04ceab2021-03-29 19:25:12 -0700648 }
649 });
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700650 }
651
Terry Wangf2093072020-11-30 04:47:19 -0800652 @Override
Terry Wangbfbfcac2020-11-06 15:46:44 -0800653 public void globalQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800654 @NonNull String packageName,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800655 @NonNull String queryExpression,
656 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700657 @NonNull UserHandle userHandle,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700658 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800659 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700660 Objects.requireNonNull(packageName);
661 Objects.requireNonNull(queryExpression);
662 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700663 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700664 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700665
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700666 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800667 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700668 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700669 EXECUTOR.execute(() -> {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700670 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
671 PlatformLogger logger = null;
672 int operationSuccessCount = 0;
673 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700674 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700675 verifyUserUnlocked(callingUser);
676 verifyCallingPackage(callingUser, callingUid, packageName);
677 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
678 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700679 SearchResultPage searchResultPage =
680 impl.globalQuery(
681 queryExpression,
682 new SearchSpec(searchSpecBundle),
683 packageName,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700684 callingUid,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700685 logger);
686 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700687 invokeCallbackOnResult(
688 callback,
689 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700690 } catch (Throwable t) {
691 ++operationFailureCount;
692 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700693 invokeCallbackOnError(callback, t);
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700694 } finally {
695 if (logger != null) {
696 int estimatedBinderLatencyMillis =
697 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
698 int totalLatencyMillis =
699 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
700 // TODO(b/173532925) database would be nulluable once we remove generalStats
701 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
702 /*database=*/ "")
703 .setCallType(CallStats.CALL_TYPE_GLOBAL_SEARCH)
704 // TODO(b/173532925) check the existing binder call latency chart
705 // is good enough for us:
706 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
707 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
708 .setNumOperationsSucceeded(operationSuccessCount)
709 .setNumOperationsFailed(operationFailureCount);
710 cBuilder.getGeneralStatsBuilder()
711 .setStatusCode(statusCode)
712 .setTotalLatencyMillis(totalLatencyMillis);
713 logger.logStats(cBuilder.build());
714 }
Terry Wange04ceab2021-03-29 19:25:12 -0700715 }
716 });
Terry Wangbfbfcac2020-11-06 15:46:44 -0800717 }
718
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700719 @Override
Cassie Wang0c62d992021-01-15 14:39:30 -0800720 public void getNextPage(
721 long nextPageToken,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700722 @NonNull UserHandle userHandle,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700723 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700724 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700725 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700726
Terry Wangf2093072020-11-30 04:47:19 -0800727 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700728 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700729 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
730 // opened it
Terry Wange04ceab2021-03-29 19:25:12 -0700731 EXECUTOR.execute(() -> {
732 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700733 verifyUserUnlocked(callingUser);
734 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700735 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
736 invokeCallbackOnResult(
737 callback,
738 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
739 } catch (Throwable t) {
740 invokeCallbackOnError(callback, t);
741 }
742 });
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700743 }
744
745 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700746 public void invalidateNextPageToken(long nextPageToken, @NonNull UserHandle userHandle) {
747 Objects.requireNonNull(userHandle);
748
Terry Wangf2093072020-11-30 04:47:19 -0800749 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700750 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700751 EXECUTOR.execute(() -> {
752 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700753 verifyUserUnlocked(callingUser);
754 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700755 impl.invalidateNextPageToken(nextPageToken);
756 } catch (Throwable t) {
757 Log.e(TAG, "Unable to invalidate the query page token", t);
758 }
759 });
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800760 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800761
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700762 @Override
Terry Wang623e3b02021-02-02 20:27:33 -0800763 public void writeQueryResultsToFile(
764 @NonNull String packageName,
765 @NonNull String databaseName,
766 @NonNull ParcelFileDescriptor fileDescriptor,
767 @NonNull String queryExpression,
768 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700769 @NonNull UserHandle userHandle,
Terry Wang623e3b02021-02-02 20:27:33 -0800770 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700771 Objects.requireNonNull(packageName);
772 Objects.requireNonNull(databaseName);
773 Objects.requireNonNull(fileDescriptor);
774 Objects.requireNonNull(queryExpression);
775 Objects.requireNonNull(searchSpecBundle);
776 Objects.requireNonNull(userHandle);
777 Objects.requireNonNull(callback);
778
Terry Wang623e3b02021-02-02 20:27:33 -0800779 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700780 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700781 EXECUTOR.execute(() -> {
782 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700783 verifyCallingPackage(callingUser, callingUid, packageName);
784 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700785 // we don't need to append the file. The file is always brand new.
786 try (DataOutputStream outputStream = new DataOutputStream(
787 new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
788 SearchResultPage searchResultPage = impl.query(
789 packageName,
790 databaseName,
791 queryExpression,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700792 new SearchSpec(searchSpecBundle),
793 /*logger=*/ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700794 while (!searchResultPage.getResults().isEmpty()) {
795 for (int i = 0; i < searchResultPage.getResults().size(); i++) {
796 AppSearchMigrationHelper.writeBundleToOutputStream(
797 outputStream, searchResultPage.getResults().get(i)
798 .getGenericDocument().getBundle());
799 }
800 searchResultPage = impl.getNextPage(
801 searchResultPage.getNextPageToken());
Terry Wang623e3b02021-02-02 20:27:33 -0800802 }
Terry Wang623e3b02021-02-02 20:27:33 -0800803 }
Terry Wange04ceab2021-03-29 19:25:12 -0700804 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
805 } catch (Throwable t) {
806 invokeCallbackOnError(callback, t);
Terry Wang623e3b02021-02-02 20:27:33 -0800807 }
Terry Wange04ceab2021-03-29 19:25:12 -0700808 });
Terry Wang623e3b02021-02-02 20:27:33 -0800809 }
810
811 @Override
812 public void putDocumentsFromFile(
813 @NonNull String packageName,
814 @NonNull String databaseName,
815 @NonNull ParcelFileDescriptor fileDescriptor,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700816 @NonNull UserHandle userHandle,
Terry Wang623e3b02021-02-02 20:27:33 -0800817 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700818 Objects.requireNonNull(packageName);
819 Objects.requireNonNull(databaseName);
820 Objects.requireNonNull(fileDescriptor);
821 Objects.requireNonNull(userHandle);
822 Objects.requireNonNull(callback);
823
Terry Wang623e3b02021-02-02 20:27:33 -0800824 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700825 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700826 EXECUTOR.execute(() -> {
827 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700828 verifyCallingPackage(callingUser, callingUid, packageName);
829 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wang623e3b02021-02-02 20:27:33 -0800830
Terry Wange04ceab2021-03-29 19:25:12 -0700831 GenericDocument document;
832 ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
833 try (DataInputStream inputStream = new DataInputStream(
834 new FileInputStream(fileDescriptor.getFileDescriptor()))) {
835 while (true) {
836 try {
837 document = AppSearchMigrationHelper
838 .readDocumentFromInputStream(inputStream);
839 } catch (EOFException e) {
840 // nothing wrong, we just finish the reading.
841 break;
842 }
843 try {
844 impl.putDocument(packageName, databaseName, document,
845 /*logger=*/ null);
846 } catch (Throwable t) {
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700847 migrationFailureBundles.add(new SetSchemaResponse.MigrationFailure(
848 document.getNamespace(),
849 document.getId(),
850 document.getSchemaType(),
851 AppSearchResult.throwableToFailedResult(t))
852 .getBundle());
Terry Wange04ceab2021-03-29 19:25:12 -0700853 }
Terry Wang623e3b02021-02-02 20:27:33 -0800854 }
855 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700856 impl.persistToDisk(PersistType.Code.FULL);
Terry Wange04ceab2021-03-29 19:25:12 -0700857 invokeCallbackOnResult(callback,
858 AppSearchResult.newSuccessfulResult(migrationFailureBundles));
859 } catch (Throwable t) {
860 invokeCallbackOnError(callback, t);
Terry Wang623e3b02021-02-02 20:27:33 -0800861 }
Terry Wange04ceab2021-03-29 19:25:12 -0700862 });
Terry Wang623e3b02021-02-02 20:27:33 -0800863 }
864
865 @Override
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800866 public void reportUsage(
867 @NonNull String packageName,
868 @NonNull String databaseName,
869 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700870 @NonNull String documentId,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800871 long usageTimeMillis,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700872 boolean systemUsage,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700873 @NonNull UserHandle userHandle,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800874 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700875 Objects.requireNonNull(packageName);
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800876 Objects.requireNonNull(databaseName);
877 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700878 Objects.requireNonNull(documentId);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700879 Objects.requireNonNull(userHandle);
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800880 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700881
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800882 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700883 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700884 EXECUTOR.execute(() -> {
885 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700886 verifyUserUnlocked(callingUser);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700887
Terry Wange04ceab2021-03-29 19:25:12 -0700888 if (systemUsage) {
889 // TODO(b/183031844): Validate that the call comes from the system
890 }
891
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700892 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700893 impl.reportUsage(
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700894 packageName, databaseName, namespace, documentId,
Terry Wange04ceab2021-03-29 19:25:12 -0700895 usageTimeMillis, systemUsage);
896 invokeCallbackOnResult(
897 callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
898 } catch (Throwable t) {
899 invokeCallbackOnError(callback, t);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700900 }
Terry Wange04ceab2021-03-29 19:25:12 -0700901 });
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800902 }
903
904 @Override
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700905 public void removeByDocumentId(
Cassie Wang0c62d992021-01-15 14:39:30 -0800906 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800907 @NonNull String databaseName,
908 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700909 @NonNull List<String> ids,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700910 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700911 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800912 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700913 Objects.requireNonNull(packageName);
914 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700915 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700916 Objects.requireNonNull(ids);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700917 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700918 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700919
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700920 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800921 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700922 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700923 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700924 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
925 PlatformLogger logger = null;
926 int operationSuccessCount = 0;
927 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700928 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700929 verifyUserUnlocked(callingUser);
930 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700931 AppSearchBatchResult.Builder<String, Void> resultBuilder =
932 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700933 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
934 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700935 for (int i = 0; i < ids.size(); i++) {
936 String id = ids.get(i);
Terry Wange04ceab2021-03-29 19:25:12 -0700937 try {
Alexander Dorokhinea4b5bab2021-05-20 14:24:50 -0700938 impl.remove(
939 packageName,
940 databaseName,
941 namespace,
942 id,
943 /*removeStatsBuilder=*/ null);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700944 ++operationSuccessCount;
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700945 resultBuilder.setSuccess(id, /*result= */ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700946 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700947 AppSearchResult<Void> result = throwableToFailedResult(t);
948 resultBuilder.setResult(id, result);
949 // Since we can only include one status code in the atom,
950 // for failures, we would just save the one for the last failure
951 statusCode = result.getResultCode();
952 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700953 }
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700954 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700955 // Now that the batch has been written. Persist the newly written data.
956 impl.persistToDisk(PersistType.Code.LITE);
Terry Wange04ceab2021-03-29 19:25:12 -0700957 invokeCallbackOnResult(callback, resultBuilder.build());
958 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700959 ++operationFailureCount;
960 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700961 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700962 } finally {
963 if (logger != null) {
964 int estimatedBinderLatencyMillis =
965 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
966 int totalLatencyMillis =
967 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
968 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
969 databaseName)
970 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID)
971 // TODO(b/173532925) check the existing binder call latency chart
972 // is good enough for us:
973 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
974 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
975 .setNumOperationsSucceeded(operationSuccessCount)
976 .setNumOperationsFailed(operationFailureCount);
977 cBuilder.getGeneralStatsBuilder()
978 .setStatusCode(statusCode)
979 .setTotalLatencyMillis(totalLatencyMillis);
980 logger.logStats(cBuilder.build());
981 }
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700982 }
Terry Wange04ceab2021-03-29 19:25:12 -0700983 });
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700984 }
985
986 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -0700987 public void removeByQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800988 @NonNull String packageName,
Terry Wang26b9e5c2020-10-23 02:05:01 -0700989 @NonNull String databaseName,
990 @NonNull String queryExpression,
991 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700992 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700993 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Alexander Dorokhine178366b2020-10-20 17:40:49 -0700994 @NonNull IAppSearchResultCallback callback) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700995 // TODO(b/173532925) log CallStats once we have CALL_TYPE_REMOVE_BY_QUERY added
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700996 Objects.requireNonNull(packageName);
997 Objects.requireNonNull(databaseName);
998 Objects.requireNonNull(queryExpression);
999 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001000 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001001 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001002
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001003 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -08001004 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001005 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001006 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001007 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
1008 PlatformLogger logger = null;
1009 int operationSuccessCount = 0;
1010 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001011 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001012 verifyUserUnlocked(callingUser);
1013 verifyCallingPackage(callingUser, callingUid, packageName);
1014 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
1015 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -07001016 impl.removeByQuery(
1017 packageName,
1018 databaseName,
1019 queryExpression,
Alexander Dorokhinea4b5bab2021-05-20 14:24:50 -07001020 new SearchSpec(searchSpecBundle),
1021 /*removeStatsBuilder=*/ null);
Alexander Dorokhinec77f4442021-04-14 09:26:06 -07001022 // Now that the batch has been written. Persist the newly written data.
1023 impl.persistToDisk(PersistType.Code.LITE);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001024 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001025 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
1026 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001027 ++operationFailureCount;
1028 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001029 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001030 } finally {
1031 if (logger != null) {
1032 int estimatedBinderLatencyMillis =
1033 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1034 int totalLatencyMillis =
1035 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
1036 CallStats.Builder cBuilder = new CallStats.Builder(packageName,
1037 databaseName)
1038 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH)
1039 // TODO(b/173532925) check the existing binder call latency chart
1040 // is good enough for us:
1041 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1042 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1043 .setNumOperationsSucceeded(operationSuccessCount)
1044 .setNumOperationsFailed(operationFailureCount);
1045 cBuilder.getGeneralStatsBuilder()
1046 .setStatusCode(statusCode)
1047 .setTotalLatencyMillis(totalLatencyMillis);
1048 logger.logStats(cBuilder.build());
1049 }
Terry Wange04ceab2021-03-29 19:25:12 -07001050 }
1051 });
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -07001052 }
1053
Terry Wangdbd1dca2020-11-03 17:03:56 -08001054 @Override
Cassie Wang8f0df492021-03-24 09:23:18 -07001055 public void getStorageInfo(
1056 @NonNull String packageName,
1057 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001058 @NonNull UserHandle userHandle,
Cassie Wang8f0df492021-03-24 09:23:18 -07001059 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001060 Objects.requireNonNull(packageName);
1061 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001062 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001063 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001064
Cassie Wang8f0df492021-03-24 09:23:18 -07001065 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001066 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001067 EXECUTOR.execute(() -> {
1068 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001069 verifyUserUnlocked(callingUser);
1070 verifyCallingPackage(callingUser, callingUid, packageName);
1071 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -07001072 StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName,
1073 databaseName);
1074 Bundle storageInfoBundle = storageInfo.getBundle();
1075 invokeCallbackOnResult(
1076 callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
1077 } catch (Throwable t) {
1078 invokeCallbackOnError(callback, t);
1079 }
1080 });
Cassie Wang8f0df492021-03-24 09:23:18 -07001081 }
1082
1083 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001084 public void persistToDisk(
1085 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001086 @ElapsedRealtimeLong long binderCallStartTimeMillis) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001087 Objects.requireNonNull(userHandle);
1088
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001089 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Cassie Wangb0d60122021-03-30 12:38:46 -07001090 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001091 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001092 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001093 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
1094 PlatformLogger logger = null;
1095 int operationSuccessCount = 0;
1096 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001097 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001098 verifyUserUnlocked(callingUser);
1099 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
1100 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Alexander Dorokhinec77f4442021-04-14 09:26:06 -07001101 impl.persistToDisk(PersistType.Code.FULL);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001102 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001103 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001104 ++operationFailureCount;
1105 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001106 Log.e(TAG, "Unable to persist the data to disk", t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001107 } finally {
1108 if (logger != null) {
1109 int estimatedBinderLatencyMillis =
1110 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1111 int totalLatencyMillis =
1112 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
1113 CallStats.Builder cBuilder = new CallStats.Builder(/*packageName=*/ "",
1114 /*databaseName=*/ "")
1115 .setCallType(CallStats.CALL_TYPE_FLUSH)
1116 // TODO(b/173532925) check the existing binder call latency chart
1117 // is good enough for us:
1118 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1119 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1120 .setNumOperationsSucceeded(operationSuccessCount)
1121 .setNumOperationsFailed(operationFailureCount);
1122 cBuilder.getGeneralStatsBuilder()
1123 .setStatusCode(statusCode)
1124 .setTotalLatencyMillis(totalLatencyMillis);
1125 logger.logStats(cBuilder.build());
1126 }
Terry Wange04ceab2021-03-29 19:25:12 -07001127 }
1128 });
Terry Wang2da17852020-12-16 19:59:08 -08001129 }
1130
1131 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001132 public void initialize(
1133 @NonNull UserHandle userHandle,
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001134 @ElapsedRealtimeLong long binderCallStartTimeMillis,
1135 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001136 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001137 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001138
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001139 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -08001140 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001141 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001142 EXECUTOR.execute(() -> {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001143 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
1144 PlatformLogger logger = null;
1145 int operationSuccessCount = 0;
1146 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001147 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001148 verifyUserUnlocked(callingUser);
1149 logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
Xiaoyu Jin433892c2021-05-24 16:19:02 -07001150 mContext, callingUser,
1151 AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001152 mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUser, logger);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001153 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001154 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
1155 } catch (Throwable t) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001156 ++operationFailureCount;
1157 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001158 invokeCallbackOnError(callback, t);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001159 } finally {
1160 if (logger != null) {
1161 int estimatedBinderLatencyMillis =
1162 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1163 int totalLatencyMillis =
1164 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
1165 // TODO(b/173532925) make packageName and database nullable after
1166 // removing generalStats
1167 CallStats.Builder cBuilder = new CallStats.Builder(/*packageName=*/"",
1168 /*database=*/ "")
1169 .setCallType(CallStats.CALL_TYPE_INITIALIZE)
1170 // TODO(b/173532925) check the existing binder call latency chart
1171 // is good enough for us:
1172 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1173 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1174 .setNumOperationsSucceeded(operationSuccessCount)
1175 .setNumOperationsFailed(operationFailureCount);
1176 cBuilder.getGeneralStatsBuilder()
1177 .setStatusCode(statusCode)
1178 .setTotalLatencyMillis(totalLatencyMillis);
1179 logger.logStats(cBuilder.build());
1180 }
Terry Wange04ceab2021-03-29 19:25:12 -07001181 }
1182 });
Terry Wangdbd1dca2020-11-03 17:03:56 -08001183 }
1184
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001185 private void verifyCallingPackage(
1186 @NonNull UserHandle actualCallingUser,
1187 int actualCallingUid,
1188 @NonNull String claimedCallingPackage) {
1189 Objects.requireNonNull(actualCallingUser);
1190 Objects.requireNonNull(claimedCallingPackage);
1191
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001192 int claimedCallingUid = PackageUtil.getPackageUidAsUser(
1193 mContext, claimedCallingPackage, actualCallingUser);
1194 if (claimedCallingUid == INVALID_UID) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001195 throw new SecurityException(
1196 "Specified calling package [" + claimedCallingPackage + "] not found");
1197 }
1198 if (claimedCallingUid != actualCallingUid) {
Cassie Wang0c62d992021-01-15 14:39:30 -08001199 throw new SecurityException(
1200 "Specified calling package ["
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001201 + claimedCallingPackage
Cassie Wang0c62d992021-01-15 14:39:30 -08001202 + "] does not match the calling uid "
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001203 + actualCallingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -07001204 }
Alexander Dorokhineebd37742020-09-22 15:02:26 -07001205 }
1206
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001207 /** Invokes the {@link IAppSearchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -08001208 private void invokeCallbackOnResult(
1209 IAppSearchResultCallback callback, AppSearchResult<?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -08001210 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001211 callback.onResult(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001212 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001213 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001214 }
Terry Wangdbd1dca2020-11-03 17:03:56 -08001215 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001216
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001217 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -08001218 private void invokeCallbackOnResult(
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001219 IAppSearchBatchResultCallback callback, AppSearchBatchResult<String, ?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -08001220 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001221 callback.onResult(new AppSearchBatchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001222 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001223 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001224 }
Terry Wangdbd1dca2020-11-03 17:03:56 -08001225 }
1226
1227 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001228 * Invokes the {@link IAppSearchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001229 *
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001230 * <p>The throwable is convert to a {@link AppSearchResult};
Terry Wangdbd1dca2020-11-03 17:03:56 -08001231 */
1232 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001233 AppSearchResult<?> result = throwableToFailedResult(throwable);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001234 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001235 callback.onResult(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001236 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001237 Log.e(TAG, "Unable to send result to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001238 }
1239 }
1240
1241 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001242 * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001243 *
Alexander Dorokhineb5d34b12021-04-15 00:32:15 -07001244 * <p>The throwable is converted to {@link AppSearchResult}.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001245 */
Cassie Wang0c62d992021-01-15 14:39:30 -08001246 private void invokeCallbackOnError(
Alexander Dorokhineb5d34b12021-04-15 00:32:15 -07001247 @NonNull IAppSearchBatchResultCallback callback, @NonNull Throwable throwable) {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001248 AppSearchResult<?> result = throwableToFailedResult(throwable);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001249 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001250 callback.onSystemError(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001251 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001252 Log.e(TAG, "Unable to send error to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001253 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001254 }
Terry Wangfebbead2019-10-17 17:05:18 -07001255 }
Terry Wangf2093072020-11-30 04:47:19 -08001256
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001257 /**
1258 * Helper for dealing with incoming user arguments to system service calls.
1259 *
1260 * <p>Takes care of checking permissions and converting USER_CURRENT to the actual current user.
1261 *
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001262 * @param requestedUser The user which the caller is requesting to execute as.
1263 * @param callingUid The actual uid of the caller as determined by Binder.
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001264 * @return the user handle that the call should run as. Will always be a concrete user.
1265 */
Cassie Wang0c62d992021-01-15 14:39:30 -08001266 // TODO(b/173553485) verifying that the caller has permission to access target user's data
1267 // TODO(b/173553485) Handle ACTION_USER_REMOVED broadcast
1268 // TODO(b/173553485) Implement SystemService.onUserStopping()
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001269 @NonNull
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001270 private UserHandle handleIncomingUser(@NonNull UserHandle requestedUser, int callingUid) {
Terry Wangf2093072020-11-30 04:47:19 -08001271 int callingPid = Binder.getCallingPid();
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001272 UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid);
1273 if (callingUser.equals(requestedUser)) {
1274 return requestedUser;
1275 }
1276 // Duplicates UserController#ensureNotSpecialUser
1277 if (requestedUser.getIdentifier() < 0) {
1278 throw new IllegalArgumentException(
1279 "Call does not support special user " + requestedUser);
1280 }
1281 boolean canInteractAcrossUsers = mContext.checkPermission(
1282 Manifest.permission.INTERACT_ACROSS_USERS,
Cassie Wang0c62d992021-01-15 14:39:30 -08001283 callingPid,
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001284 callingUid) == PackageManager.PERMISSION_GRANTED;
1285 if (!canInteractAcrossUsers) {
1286 canInteractAcrossUsers = mContext.checkPermission(
1287 Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1288 callingPid,
1289 callingUid) == PackageManager.PERMISSION_GRANTED;
1290 }
1291 if (canInteractAcrossUsers) {
1292 return requestedUser;
1293 }
1294 throw new SecurityException(
1295 "Permission denied while calling from uid " + callingUid
1296 + " with " + requestedUser + "; Need to run as either the calling user ("
1297 + callingUser + "), or with one of the following permissions: "
1298 + Manifest.permission.INTERACT_ACROSS_USERS + " or "
1299 + Manifest.permission.INTERACT_ACROSS_USERS_FULL);
Terry Wangf2093072020-11-30 04:47:19 -08001300 }
Yang Yu0fcd51a2021-04-23 11:25:44 -07001301
1302 // TODO(b/179160886): Cache the previous storage stats.
1303 private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter {
1304 @Override
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001305 public void augmentStatsForPackageForUser(
Yang Yu0fcd51a2021-04-23 11:25:44 -07001306 @NonNull PackageStats stats,
1307 @NonNull String packageName,
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001308 @NonNull UserHandle userHandle,
1309 boolean canCallerAccessAllStats) {
Yang Yu0fcd51a2021-04-23 11:25:44 -07001310 Objects.requireNonNull(stats);
1311 Objects.requireNonNull(packageName);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001312 Objects.requireNonNull(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001313
Yang Yu0fcd51a2021-04-23 11:25:44 -07001314 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001315 verifyUserUnlocked(userHandle);
1316 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
Xiaoyu Jin433892c2021-05-24 16:19:02 -07001317 mContext, userHandle,
1318 AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001319 AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
1320 mContext, userHandle, logger);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001321 stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
1322 } catch (Throwable t) {
1323 Log.e(
1324 TAG,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001325 "Unable to augment storage stats for "
1326 + userHandle
Yang Yu0fcd51a2021-04-23 11:25:44 -07001327 + " packageName "
1328 + packageName,
1329 t);
1330 }
1331 }
1332
1333 @Override
1334 public void augmentStatsForUid(
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001335 @NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats) {
Yang Yu0fcd51a2021-04-23 11:25:44 -07001336 Objects.requireNonNull(stats);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001337
1338 UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001339 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001340 verifyUserUnlocked(userHandle);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001341 String[] packagesForUid = mPackageManager.getPackagesForUid(uid);
1342 if (packagesForUid == null) {
1343 return;
1344 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001345 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
Xiaoyu Jin433892c2021-05-24 16:19:02 -07001346 mContext, userHandle,
1347 AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001348 AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
1349 mContext, userHandle, logger);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001350 for (int i = 0; i < packagesForUid.length; i++) {
1351 stats.dataSize +=
1352 impl.getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
Yang Yu0fcd51a2021-04-23 11:25:44 -07001353 }
1354 } catch (Throwable t) {
1355 Log.e(TAG, "Unable to augment storage stats for uid " + uid, t);
1356 }
1357 }
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001358
1359 @Override
1360 public void augmentStatsForUser(
1361 @NonNull PackageStats stats, @NonNull UserHandle userHandle) {
1362 // TODO(b/179160886): this implementation could incur many jni calls and a lot of
1363 // in-memory processing from getStorageInfoForPackage. Instead, we can just compute the
1364 // size of the icing dir (or use the overall StorageInfo without interpolating it).
1365 Objects.requireNonNull(stats);
1366 Objects.requireNonNull(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001367
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001368 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001369 verifyUserUnlocked(userHandle);
1370 List<PackageInfo> packagesForUser = mPackageManager.getInstalledPackagesAsUser(
1371 /*flags=*/0, userHandle.getIdentifier());
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001372 if (packagesForUser == null) {
1373 return;
1374 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001375 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
Xiaoyu Jin433892c2021-05-24 16:19:02 -07001376 mContext, userHandle,
1377 AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001378 AppSearchImpl impl =
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001379 mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userHandle, logger);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001380 for (int i = 0; i < packagesForUser.size(); i++) {
1381 String packageName = packagesForUser.get(i).packageName;
1382 stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
1383 }
1384 } catch (Throwable t) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001385 Log.e(TAG, "Unable to augment storage stats for " + userHandle, t);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001386 }
1387 }
Yang Yu0fcd51a2021-04-23 11:25:44 -07001388 }
Terry Wangfebbead2019-10-17 17:05:18 -07001389}