blob: 31203c73c76ad3ff84e9d4ca60c7d371bc2b242f [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;
Terry Wanga9e6e212021-04-23 15:51:37 -070066import com.android.server.appsearch.visibilitystore.VisibilityStore;
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -070067import com.android.server.usage.StorageStatsManagerLocal;
68import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -080069
Alexander Dorokhinec77f4442021-04-14 09:26:06 -070070import com.google.android.icing.proto.PersistType;
71
Terry Wang623e3b02021-02-02 20:27:33 -080072import java.io.DataInputStream;
73import java.io.DataOutputStream;
74import java.io.EOFException;
75import java.io.FileInputStream;
76import java.io.FileOutputStream;
Alexander Dorokhine6a99f942020-12-04 02:57:22 -080077import java.util.ArrayList;
Alexander Dorokhine18465842020-01-21 01:08:57 -080078import java.util.List;
Alexander Dorokhineab789062021-01-11 21:00:00 -080079import java.util.Map;
Alexander Dorokhined18f8842021-01-20 15:26:13 -080080import java.util.Objects;
Cassie Wang9ba9ae12021-02-01 16:39:37 -080081import java.util.Set;
Terry Wange04ceab2021-03-29 19:25:12 -070082import java.util.concurrent.Executor;
Terry Wangd2186e52021-04-14 13:19:45 -070083import java.util.concurrent.LinkedBlockingQueue;
Terry Wange04ceab2021-03-29 19:25:12 -070084import java.util.concurrent.ThreadPoolExecutor;
85import java.util.concurrent.TimeUnit;
Alexander Dorokhine18465842020-01-21 01:08:57 -080086
Cassie Wang0c62d992021-01-15 14:39:30 -080087/** TODO(b/142567528): add comments when implement this class */
Terry Wangfebbead2019-10-17 17:05:18 -070088public class AppSearchManagerService extends SystemService {
Alexander Dorokhineebd37742020-09-22 15:02:26 -070089 private static final String TAG = "AppSearchManagerService";
Terry Wang12dc6c02021-03-31 19:26:16 -070090 private final Context mContext;
Yang Yu0fcd51a2021-04-23 11:25:44 -070091 private PackageManager mPackageManager;
Cassie Wang21c2d6a2021-01-20 23:59:55 -080092 private ImplInstanceManager mImplInstanceManager;
Pinyao Tingd5c2ed92021-03-18 14:51:54 -070093 private UserManager mUserManager;
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -080094 private LoggerInstanceManager mLoggerInstanceManager;
Terry Wangfebbead2019-10-17 17:05:18 -070095
Terry Wange04ceab2021-03-29 19:25:12 -070096 // Never call shutdownNow(). It will cancel the futures it's returned. And since
97 // Executor#execute won't return anything, we will hang forever waiting for the execution.
98 // AppSearch multi-thread execution is guarded by Read & Write Lock in AppSearchImpl, all
99 // mutate requests will need to gain write lock and query requests need to gain read lock.
100 private static final Executor EXECUTOR = new ThreadPoolExecutor(/*corePoolSize=*/1,
101 Runtime.getRuntime().availableProcessors(), /*keepAliveTime*/ 60L, TimeUnit.SECONDS,
Terry Wangd2186e52021-04-14 13:19:45 -0700102 new LinkedBlockingQueue<>());
Terry Wange04ceab2021-03-29 19:25:12 -0700103
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700104 // Cache of unlocked users so we don't have to query UserManager service each time. The "locked"
105 // suffix refers to the fact that access to the field should be locked; unrelated to the
106 // unlocked status of users.
107 @GuardedBy("mUnlockedUsersLocked")
108 private final Set<UserHandle> mUnlockedUsersLocked = new ArraySet<>();
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800109
Terry Wangfebbead2019-10-17 17:05:18 -0700110 public AppSearchManagerService(Context context) {
111 super(context);
Terry Wang12dc6c02021-03-31 19:26:16 -0700112 mContext = context;
Terry Wangfebbead2019-10-17 17:05:18 -0700113 }
114
115 @Override
116 public void onStart() {
117 publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
Yang Yu0fcd51a2021-04-23 11:25:44 -0700118 mPackageManager = getContext().getPackageManager();
Terry Wang12dc6c02021-03-31 19:26:16 -0700119 mImplInstanceManager = ImplInstanceManager.getInstance(mContext);
120 mUserManager = mContext.getSystemService(UserManager.class);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800121 mLoggerInstanceManager = LoggerInstanceManager.getInstance();
Terry Wang12dc6c02021-03-31 19:26:16 -0700122 registerReceivers();
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -0700123 LocalManagerRegistry.getManager(StorageStatsManagerLocal.class)
Yang Yu0fcd51a2021-04-23 11:25:44 -0700124 .registerStorageStatsAugmenter(new AppSearchStorageStatsAugmenter(), TAG);
Terry Wang12dc6c02021-03-31 19:26:16 -0700125 }
126
127 private void registerReceivers() {
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700128 mContext.registerReceiverForAllUsers(
129 new UserActionReceiver(),
130 new IntentFilter(Intent.ACTION_USER_REMOVED),
131 /*broadcastPermission=*/ null,
Terry Wang12dc6c02021-03-31 19:26:16 -0700132 /*scheduler=*/ null);
Terry Wange201dc02021-04-16 01:03:20 -0700133
134 //TODO(b/145759910) Add a direct callback when user clears the data instead of relying on
135 // broadcasts
136 IntentFilter packageChangedFilter = new IntentFilter();
137 packageChangedFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
138 packageChangedFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
139 packageChangedFilter.addDataScheme("package");
140 packageChangedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700141 mContext.registerReceiverForAllUsers(
142 new PackageChangedReceiver(),
143 packageChangedFilter,
144 /*broadcastPermission=*/ null,
Terry Wange201dc02021-04-16 01:03:20 -0700145 /*scheduler=*/ null);
Terry Wang12dc6c02021-03-31 19:26:16 -0700146 }
147
148 private class UserActionReceiver extends BroadcastReceiver {
149 @Override
150 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700151 Objects.requireNonNull(context);
152 Objects.requireNonNull(intent);
153
Terry Wang12dc6c02021-03-31 19:26:16 -0700154 switch (intent.getAction()) {
155 case Intent.ACTION_USER_REMOVED:
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700156 UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
157 if (userHandle == null) {
158 Log.e(TAG, "Extra "
159 + Intent.EXTRA_USER + " is missing in the intent: " + intent);
Terry Wang12dc6c02021-03-31 19:26:16 -0700160 return;
161 }
Alexander Dorokhine5c416772021-06-04 09:05:00 -0700162 handleUserRemoved(userHandle);
Terry Wang12dc6c02021-03-31 19:26:16 -0700163 break;
164 default:
Terry Wange201dc02021-04-16 01:03:20 -0700165 Log.e(TAG, "Received unknown intent: " + intent);
Terry Wang12dc6c02021-03-31 19:26:16 -0700166 }
167 }
168 }
169
170 /**
171 * Handles user removed action.
172 *
173 * <p>Only need to clear the AppSearchImpl instance. The data of AppSearch is saved in the
174 * "credential encrypted" system directory of each user. That directory will be auto-deleted
175 * when a user is removed.
176 *
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700177 * @param userHandle The multi-user handle of the user that need to be removed.
Terry Wang12dc6c02021-03-31 19:26:16 -0700178 *
179 * @see android.os.Environment#getDataSystemCeDirectory
180 */
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700181 private void handleUserRemoved(@NonNull UserHandle userHandle) {
Terry Wang12dc6c02021-03-31 19:26:16 -0700182 try {
Terry Wangec2f3152021-06-09 18:50:53 -0700183 mImplInstanceManager.closeAndRemoveAppSearchImplForUser(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700184 mLoggerInstanceManager.removePlatformLoggerForUser(userHandle);
185 Log.i(TAG, "Removed AppSearchImpl instance for: " + userHandle);
Terry Wang12dc6c02021-03-31 19:26:16 -0700186 } catch (Throwable t) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700187 Log.e(TAG, "Unable to remove data for: " + userHandle, t);
Terry Wange201dc02021-04-16 01:03:20 -0700188 }
189 }
190
191 private class PackageChangedReceiver extends BroadcastReceiver {
192 @Override
193 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700194 Objects.requireNonNull(context);
195 Objects.requireNonNull(intent);
196
Terry Wange201dc02021-04-16 01:03:20 -0700197 switch (intent.getAction()) {
198 case Intent.ACTION_PACKAGE_FULLY_REMOVED:
199 case Intent.ACTION_PACKAGE_DATA_CLEARED:
200 String packageName = intent.getData().getSchemeSpecificPart();
201 if (packageName == null) {
202 Log.e(TAG, "Package name is missing in the intent: " + intent);
203 return;
204 }
205 int uid = intent.getIntExtra(Intent.EXTRA_UID, INVALID_UID);
206 if (uid == INVALID_UID) {
207 Log.e(TAG, "uid is missing in the intent: " + intent);
208 return;
209 }
210 handlePackageRemoved(packageName, uid);
211 break;
212 default:
213 Log.e(TAG, "Received unknown intent: " + intent);
214 }
215 }
216 }
217
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700218 private void handlePackageRemoved(@NonNull String packageName, int uid) {
219 UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
Terry Wange201dc02021-04-16 01:03:20 -0700220 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700221 if (isUserLocked(userHandle)) {
Terry Wanga9e6e212021-04-23 15:51:37 -0700222 // We cannot access a locked user's directry and remove package data from it.
223 // We should remove those uninstalled package data when the user is unlocking.
Terry Wange201dc02021-04-16 01:03:20 -0700224 return;
225 }
Terry Wanga9e6e212021-04-23 15:51:37 -0700226 // Only clear the package's data if AppSearch exists for this user.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700227 if (ImplInstanceManager.getAppSearchDir(userHandle).exists()) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700228 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(mContext,
Xiaoyu Jin433892c2021-05-24 16:19:02 -0700229 userHandle, AppSearchConfig.getInstance(EXECUTOR));
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700230 AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700231 userHandle, logger);
Terry Wange201dc02021-04-16 01:03:20 -0700232 //TODO(b/145759910) clear visibility setting for package.
233 impl.clearPackageData(packageName);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700234 logger.removeCachedUidForPackage(packageName);
Terry Wange201dc02021-04-16 01:03:20 -0700235 }
236 } catch (Throwable t) {
237 Log.e(TAG, "Unable to remove data for package: " + packageName, t);
Terry Wang12dc6c02021-03-31 19:26:16 -0700238 }
Terry Wangfebbead2019-10-17 17:05:18 -0700239 }
240
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800241 @Override
Pinyao Tingd5c2ed92021-03-18 14:51:54 -0700242 public void onUserUnlocking(@NonNull TargetUser user) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700243 Objects.requireNonNull(user);
Terry Wanga9e6e212021-04-23 15:51:37 -0700244 UserHandle userHandle = user.getUserHandle();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700245 synchronized (mUnlockedUsersLocked) {
Terry Wanga9e6e212021-04-23 15:51:37 -0700246 mUnlockedUsersLocked.add(userHandle);
Cassie Wang15c86972021-02-09 13:43:25 -0800247 }
Terry Wanga9e6e212021-04-23 15:51:37 -0700248 EXECUTOR.execute(() -> {
249 try {
250 // Only clear the package's data if AppSearch exists for this user.
251 if (ImplInstanceManager.getAppSearchDir(userHandle).exists()) {
252 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
253 mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR));
254 AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
255 userHandle, logger);
256 List<PackageInfo> installedPackageInfos = mContext
257 .createContextAsUser(userHandle, /*flags=*/0)
258 .getPackageManager()
259 .getInstalledPackages(/*flags=*/0);
260 Set<String> packagesToKeep = new ArraySet<>(installedPackageInfos.size());
261 for (int i = 0; i < installedPackageInfos.size(); i++) {
262 packagesToKeep.add(installedPackageInfos.get(i).packageName);
263 }
264 packagesToKeep.add(VisibilityStore.PACKAGE_NAME);
265 //TODO(b/145759910) clear visibility setting for package.
266 impl.prunePackageData(packagesToKeep);
267 }
268 } catch (Throwable t) {
269 Log.e(TAG, "Unable to prune packages for " + user, t);
270 }
271 });
Cassie Wang9ba9ae12021-02-01 16:39:37 -0800272 }
273
Terry Wangde9f3382021-04-28 19:45:07 -0700274 @Override
275 public void onUserStopping(@NonNull TargetUser user) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700276 Objects.requireNonNull(user);
277
278 synchronized (mUnlockedUsersLocked) {
279 UserHandle userHandle = user.getUserHandle();
280 mUnlockedUsersLocked.remove(userHandle);
Terry Wangde9f3382021-04-28 19:45:07 -0700281 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700282 mImplInstanceManager.closeAndRemoveAppSearchImplForUser(userHandle);
Terry Wangde9f3382021-04-28 19:45:07 -0700283 } catch (Throwable t) {
284 Log.e(TAG, "Error handling user stopping.", t);
285 }
286 }
287 }
288
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700289 private void verifyUserUnlocked(@NonNull UserHandle callingUser) {
290 if (isUserLocked(callingUser)) {
291 throw new IllegalStateException(callingUser + " is locked or not running.");
Terry Wange201dc02021-04-16 01:03:20 -0700292 }
293 }
294
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700295 private boolean isUserLocked(@NonNull UserHandle callingUser) {
296 synchronized (mUnlockedUsersLocked) {
Yang Yu0fcd51a2021-04-23 11:25:44 -0700297 // First, check the local copy.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700298 if (mUnlockedUsersLocked.contains(callingUser)) {
Terry Wange201dc02021-04-16 01:03:20 -0700299 return false;
Yang Yu0fcd51a2021-04-23 11:25:44 -0700300 }
301 // If the local copy says the user is locked, check with UM for the actual state,
302 // since the user might just have been unlocked.
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700303 return !mUserManager.isUserUnlockingOrUnlocked(callingUser);
Yang Yu0fcd51a2021-04-23 11:25:44 -0700304 }
305 }
306
Terry Wangfebbead2019-10-17 17:05:18 -0700307 private class Stub extends IAppSearchManager.Stub {
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800308 @Override
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800309 public void setSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800310 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700311 @NonNull String databaseName,
Alexander Dorokhine92ce3532020-10-06 01:39:36 -0700312 @NonNull List<Bundle> schemaBundles,
Alexander Dorokhine315cca62021-03-04 12:34:41 -0800313 @NonNull List<String> schemasNotDisplayedBySystem,
Alexander Dorokhineab789062021-01-11 21:00:00 -0800314 @NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800315 boolean forceOverride,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700316 int schemaVersion,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700317 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700318 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800319 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700320 Objects.requireNonNull(packageName);
321 Objects.requireNonNull(databaseName);
322 Objects.requireNonNull(schemaBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700323 Objects.requireNonNull(schemasNotDisplayedBySystem);
324 Objects.requireNonNull(schemasPackageAccessibleBundles);
325 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700326 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700327
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700328 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800329 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700330 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700331 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700332 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
333 PlatformLogger logger = null;
334 int operationSuccessCount = 0;
335 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700336 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700337 verifyUserUnlocked(callingUser);
338 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700339 List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
340 for (int i = 0; i < schemaBundles.size(); i++) {
341 schemas.add(new AppSearchSchema(schemaBundles.get(i)));
Alexander Dorokhineab789062021-01-11 21:00:00 -0800342 }
Terry Wange04ceab2021-03-29 19:25:12 -0700343 Map<String, List<PackageIdentifier>> schemasPackageAccessible =
344 new ArrayMap<>(schemasPackageAccessibleBundles.size());
345 for (Map.Entry<String, List<Bundle>> entry :
346 schemasPackageAccessibleBundles.entrySet()) {
347 List<PackageIdentifier> packageIdentifiers =
348 new ArrayList<>(entry.getValue().size());
349 for (int i = 0; i < entry.getValue().size(); i++) {
350 packageIdentifiers.add(
351 new PackageIdentifier(entry.getValue().get(i)));
352 }
353 schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
354 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700355 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
356 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700357 SetSchemaResponse setSchemaResponse = impl.setSchema(
358 packageName,
359 databaseName,
360 schemas,
361 schemasNotDisplayedBySystem,
362 schemasPackageAccessible,
363 forceOverride,
364 schemaVersion);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700365 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700366 invokeCallbackOnResult(callback,
367 AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
368 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700369 ++operationFailureCount;
370 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700371 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700372 } finally {
373 if (logger != null) {
374 int estimatedBinderLatencyMillis =
375 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
376 int totalLatencyMillis =
377 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700378 logger.logStats(new CallStats.Builder()
379 .setPackageName(packageName)
380 .setDatabase(databaseName)
381 .setStatusCode(statusCode)
382 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700383 .setCallType(CallStats.CALL_TYPE_SET_SCHEMA)
384 // TODO(b/173532925) check the existing binder call latency chart
385 // is good enough for us:
386 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
387 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
388 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700389 .setNumOperationsFailed(operationFailureCount)
390 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700391 }
Alexander Dorokhineab789062021-01-11 21:00:00 -0800392 }
Terry Wange04ceab2021-03-29 19:25:12 -0700393 });
Alexander Dorokhine179c8b82020-01-11 00:17:48 -0800394 }
395
396 @Override
Terry Wang83a24932020-12-09 21:00:18 -0800397 public void getSchema(
Cassie Wang0c62d992021-01-15 14:39:30 -0800398 @NonNull String packageName,
Terry Wang83a24932020-12-09 21:00:18 -0800399 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700400 @NonNull UserHandle userHandle,
Terry Wang83a24932020-12-09 21:00:18 -0800401 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700402 Objects.requireNonNull(packageName);
403 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700404 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700405 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700406
Cassie Wangb0d60122021-03-30 12:38:46 -0700407 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700408 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700409 EXECUTOR.execute(() -> {
410 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700411 verifyUserUnlocked(callingUser);
412 verifyCallingPackage(callingUser, callingUid, packageName);
413 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700414 GetSchemaResponse response = impl.getSchema(packageName, databaseName);
415 invokeCallbackOnResult(
416 callback,
417 AppSearchResult.newSuccessfulResult(response.getBundle()));
418 } catch (Throwable t) {
419 invokeCallbackOnError(callback, t);
420 }
421 });
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700422 }
423
424 @Override
425 public void getNamespaces(
426 @NonNull String packageName,
427 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700428 @NonNull UserHandle userHandle,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700429 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700430 Objects.requireNonNull(packageName);
431 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700432 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700433 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700434
Cassie Wangb0d60122021-03-30 12:38:46 -0700435 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700436 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700437 EXECUTOR.execute(() -> {
438 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700439 verifyUserUnlocked(callingUser);
440 verifyCallingPackage(callingUser, callingUid, packageName);
441 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700442 List<String> namespaces = impl.getNamespaces(packageName, databaseName);
443 invokeCallbackOnResult(callback,
444 AppSearchResult.newSuccessfulResult(namespaces));
445 } catch (Throwable t) {
446 invokeCallbackOnError(callback, t);
447 }
448 });
Terry Wang83a24932020-12-09 21:00:18 -0800449 }
450
451 @Override
Alexander Dorokhine18465842020-01-21 01:08:57 -0800452 public void putDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800453 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700454 @NonNull String databaseName,
Alexander Dorokhinec66d67c2020-10-08 13:44:04 -0700455 @NonNull List<Bundle> documentBundles,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700456 @NonNull UserHandle userHandle,
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800457 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800458 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700459 Objects.requireNonNull(packageName);
460 Objects.requireNonNull(databaseName);
461 Objects.requireNonNull(documentBundles);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700462 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700463 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700464
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700465 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800466 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700467 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700468 EXECUTOR.execute(() -> {
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800469 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
470 PlatformLogger logger = null;
471 int operationSuccessCount = 0;
472 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700473 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700474 verifyUserUnlocked(callingUser);
475 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700476 AppSearchBatchResult.Builder<String, Void> resultBuilder =
477 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700478 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
479 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700480 for (int i = 0; i < documentBundles.size(); i++) {
481 GenericDocument document = new GenericDocument(documentBundles.get(i));
482 try {
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800483 impl.putDocument(packageName, databaseName, document, logger);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700484 resultBuilder.setSuccess(document.getId(), /*result=*/ null);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800485 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700486 } catch (Throwable t) {
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700487 resultBuilder.setResult(document.getId(),
Terry Wange04ceab2021-03-29 19:25:12 -0700488 throwableToFailedResult(t));
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800489 AppSearchResult<Void> result = throwableToFailedResult(t);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700490 resultBuilder.setResult(document.getId(), result);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700491 // Since we can only include one status code in the atom,
492 // for failures, we would just save the one for the last failure
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800493 statusCode = result.getResultCode();
494 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700495 }
Alexander Dorokhine18465842020-01-21 01:08:57 -0800496 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700497 // Now that the batch has been written. Persist the newly written data.
498 impl.persistToDisk(PersistType.Code.LITE);
Terry Wange04ceab2021-03-29 19:25:12 -0700499 invokeCallbackOnResult(callback, resultBuilder.build());
500 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700501 ++operationFailureCount;
502 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700503 invokeCallbackOnError(callback, t);
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800504 } finally {
505 if (logger != null) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700506 int estimatedBinderLatencyMillis =
507 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
508 int totalLatencyMillis =
509 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700510 logger.logStats(new CallStats.Builder()
511 .setPackageName(packageName)
512 .setDatabase(databaseName)
513 .setStatusCode(statusCode)
514 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800515 .setCallType(CallStats.CALL_TYPE_PUT_DOCUMENTS)
516 // TODO(b/173532925) check the existing binder call latency chart
517 // is good enough for us:
518 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -0700519 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800520 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700521 .setNumOperationsFailed(operationFailureCount)
522 .build());
Xiaoyu Jinf8cc2012021-03-12 11:00:54 -0800523 }
Alexander Dorokhine18465842020-01-21 01:08:57 -0800524 }
Terry Wange04ceab2021-03-29 19:25:12 -0700525 });
Alexander Dorokhinefd07eba2020-01-13 20:22:20 -0800526 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800527
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800528 @Override
Terry Wangf2093072020-11-30 04:47:19 -0800529 public void getDocuments(
Cassie Wang0c62d992021-01-15 14:39:30 -0800530 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800531 @NonNull String databaseName,
532 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700533 @NonNull List<String> ids,
Alexander Dorokhine87cdd152021-01-20 15:41:25 -0800534 @NonNull Map<String, List<String>> typePropertyPaths,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700535 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700536 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800537 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700538 Objects.requireNonNull(packageName);
539 Objects.requireNonNull(databaseName);
540 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700541 Objects.requireNonNull(ids);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700542 Objects.requireNonNull(typePropertyPaths);
543 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700544 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700545
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700546 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800547 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700548 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700549 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700550 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
551 PlatformLogger logger = null;
552 int operationSuccessCount = 0;
553 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700554 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700555 verifyUserUnlocked(callingUser);
556 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700557 AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
558 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700559 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
560 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700561 for (int i = 0; i < ids.size(); i++) {
562 String id = ids.get(i);
Terry Wange04ceab2021-03-29 19:25:12 -0700563 try {
564 GenericDocument document =
565 impl.getDocument(
566 packageName,
567 databaseName,
568 namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700569 id,
Terry Wange04ceab2021-03-29 19:25:12 -0700570 typePropertyPaths);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700571 ++operationSuccessCount;
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700572 resultBuilder.setSuccess(id, document.getBundle());
Terry Wange04ceab2021-03-29 19:25:12 -0700573 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700574 // Since we can only include one status code in the atom,
575 // for failures, we would just save the one for the last failure
576 AppSearchResult<Bundle> result = throwableToFailedResult(t);
577 resultBuilder.setResult(id, result);
578 statusCode = result.getResultCode();
579 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700580 }
Alexander Dorokhinea95f44f2020-03-06 13:53:14 -0800581 }
Terry Wange04ceab2021-03-29 19:25:12 -0700582 invokeCallbackOnResult(callback, resultBuilder.build());
583 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700584 ++operationFailureCount;
585 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700586 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700587 } finally {
588 if (logger != null) {
589 int estimatedBinderLatencyMillis =
590 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
591 int totalLatencyMillis =
592 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700593 logger.logStats(new CallStats.Builder()
594 .setPackageName(packageName)
595 .setDatabase(databaseName)
596 .setStatusCode(statusCode)
597 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700598 .setCallType(CallStats.CALL_TYPE_GET_DOCUMENTS)
599 // TODO(b/173532925) check the existing binder call latency chart
600 // is good enough for us:
601 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
602 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
603 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700604 .setNumOperationsFailed(operationFailureCount)
605 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700606 }
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800607 }
Terry Wange04ceab2021-03-29 19:25:12 -0700608 });
Alexander Dorokhine69a8d9f2020-03-06 10:43:16 -0800609 }
610
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800611 @Override
Alexander Dorokhinee708e182020-03-06 15:30:34 -0800612 public void query(
Cassie Wang0c62d992021-01-15 14:39:30 -0800613 @NonNull String packageName,
Terry Wang6413aee2020-10-07 03:04:58 -0700614 @NonNull String databaseName,
Alexander Dorokhinec9fc9602020-10-06 01:39:50 -0700615 @NonNull String queryExpression,
616 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700617 @NonNull UserHandle userHandle,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700618 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700619 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700620 Objects.requireNonNull(packageName);
621 Objects.requireNonNull(databaseName);
622 Objects.requireNonNull(queryExpression);
623 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700624 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700625 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700626
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700627 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800628 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700629 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700630 EXECUTOR.execute(() -> {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700631 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
632 PlatformLogger logger = null;
633 int operationSuccessCount = 0;
634 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700635 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700636 verifyUserUnlocked(callingUser);
637 verifyCallingPackage(callingUser, callingUid, packageName);
638 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
639 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700640 SearchResultPage searchResultPage =
641 impl.query(
642 packageName,
643 databaseName,
644 queryExpression,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700645 new SearchSpec(searchSpecBundle),
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700646 logger);
647 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700648 invokeCallbackOnResult(
649 callback,
650 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
651 } catch (Throwable t) {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700652 ++operationFailureCount;
653 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700654 invokeCallbackOnError(callback, t);
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700655 } finally {
656 if (logger != null) {
657 int estimatedBinderLatencyMillis =
658 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
659 int totalLatencyMillis =
660 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700661 logger.logStats(new CallStats.Builder()
662 .setPackageName(packageName)
663 .setDatabase(databaseName)
664 .setStatusCode(statusCode)
665 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700666 .setCallType(CallStats.CALL_TYPE_SEARCH)
667 // TODO(b/173532925) check the existing binder call latency chart
668 // is good enough for us:
669 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
670 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
671 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700672 .setNumOperationsFailed(operationFailureCount)
673 .build());
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700674 }
Terry Wange04ceab2021-03-29 19:25:12 -0700675 }
676 });
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700677 }
678
Terry Wangf2093072020-11-30 04:47:19 -0800679 @Override
Terry Wangbfbfcac2020-11-06 15:46:44 -0800680 public void globalQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -0800681 @NonNull String packageName,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800682 @NonNull String queryExpression,
683 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700684 @NonNull UserHandle userHandle,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700685 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangbfbfcac2020-11-06 15:46:44 -0800686 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700687 Objects.requireNonNull(packageName);
688 Objects.requireNonNull(queryExpression);
689 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700690 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700691 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700692
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700693 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800694 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700695 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700696 EXECUTOR.execute(() -> {
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700697 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
698 PlatformLogger logger = null;
699 int operationSuccessCount = 0;
700 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700701 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700702 verifyUserUnlocked(callingUser);
703 verifyCallingPackage(callingUser, callingUid, packageName);
704 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
705 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700706 SearchResultPage searchResultPage =
707 impl.globalQuery(
708 queryExpression,
709 new SearchSpec(searchSpecBundle),
710 packageName,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700711 callingUid,
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700712 logger);
713 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700714 invokeCallbackOnResult(
715 callback,
716 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700717 } catch (Throwable t) {
718 ++operationFailureCount;
719 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700720 invokeCallbackOnError(callback, t);
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700721 } finally {
722 if (logger != null) {
723 int estimatedBinderLatencyMillis =
724 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
725 int totalLatencyMillis =
726 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700727 logger.logStats(new CallStats.Builder()
728 .setPackageName(packageName)
729 .setStatusCode(statusCode)
730 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700731 .setCallType(CallStats.CALL_TYPE_GLOBAL_SEARCH)
732 // TODO(b/173532925) check the existing binder call latency chart
733 // is good enough for us:
734 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
735 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
736 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700737 .setNumOperationsFailed(operationFailureCount)
738 .build());
Xiaoyu Jinef66a422021-05-09 17:38:59 -0700739 }
Terry Wange04ceab2021-03-29 19:25:12 -0700740 }
741 });
Terry Wangbfbfcac2020-11-06 15:46:44 -0800742 }
743
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700744 @Override
Cassie Wang0c62d992021-01-15 14:39:30 -0800745 public void getNextPage(
746 long nextPageToken,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700747 @NonNull UserHandle userHandle,
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700748 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700749 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700750 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700751
Terry Wangf2093072020-11-30 04:47:19 -0800752 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700753 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700754 // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
755 // opened it
Terry Wange04ceab2021-03-29 19:25:12 -0700756 EXECUTOR.execute(() -> {
757 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700758 verifyUserUnlocked(callingUser);
759 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700760 SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
761 invokeCallbackOnResult(
762 callback,
763 AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
764 } catch (Throwable t) {
765 invokeCallbackOnError(callback, t);
766 }
767 });
Alexander Dorokhined48f2362020-10-20 17:40:49 -0700768 }
769
770 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700771 public void invalidateNextPageToken(long nextPageToken, @NonNull UserHandle userHandle) {
772 Objects.requireNonNull(userHandle);
773
Terry Wangf2093072020-11-30 04:47:19 -0800774 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700775 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700776 EXECUTOR.execute(() -> {
777 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700778 verifyUserUnlocked(callingUser);
779 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700780 impl.invalidateNextPageToken(nextPageToken);
781 } catch (Throwable t) {
782 Log.e(TAG, "Unable to invalidate the query page token", t);
783 }
784 });
sidchhabraa7c8f8a2020-01-16 18:38:17 -0800785 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -0800786
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -0700787 @Override
Terry Wang623e3b02021-02-02 20:27:33 -0800788 public void writeQueryResultsToFile(
789 @NonNull String packageName,
790 @NonNull String databaseName,
791 @NonNull ParcelFileDescriptor fileDescriptor,
792 @NonNull String queryExpression,
793 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700794 @NonNull UserHandle userHandle,
Terry Wang623e3b02021-02-02 20:27:33 -0800795 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700796 Objects.requireNonNull(packageName);
797 Objects.requireNonNull(databaseName);
798 Objects.requireNonNull(fileDescriptor);
799 Objects.requireNonNull(queryExpression);
800 Objects.requireNonNull(searchSpecBundle);
801 Objects.requireNonNull(userHandle);
802 Objects.requireNonNull(callback);
803
Terry Wang623e3b02021-02-02 20:27:33 -0800804 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700805 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700806 EXECUTOR.execute(() -> {
807 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700808 verifyCallingPackage(callingUser, callingUid, packageName);
809 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700810 // we don't need to append the file. The file is always brand new.
811 try (DataOutputStream outputStream = new DataOutputStream(
812 new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
813 SearchResultPage searchResultPage = impl.query(
814 packageName,
815 databaseName,
816 queryExpression,
Alexander Dorokhine7cbc4712021-04-27 14:47:39 -0700817 new SearchSpec(searchSpecBundle),
818 /*logger=*/ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700819 while (!searchResultPage.getResults().isEmpty()) {
820 for (int i = 0; i < searchResultPage.getResults().size(); i++) {
821 AppSearchMigrationHelper.writeBundleToOutputStream(
822 outputStream, searchResultPage.getResults().get(i)
823 .getGenericDocument().getBundle());
824 }
825 searchResultPage = impl.getNextPage(
826 searchResultPage.getNextPageToken());
Terry Wang623e3b02021-02-02 20:27:33 -0800827 }
Terry Wang623e3b02021-02-02 20:27:33 -0800828 }
Terry Wange04ceab2021-03-29 19:25:12 -0700829 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
830 } catch (Throwable t) {
831 invokeCallbackOnError(callback, t);
Terry Wang623e3b02021-02-02 20:27:33 -0800832 }
Terry Wange04ceab2021-03-29 19:25:12 -0700833 });
Terry Wang623e3b02021-02-02 20:27:33 -0800834 }
835
836 @Override
837 public void putDocumentsFromFile(
838 @NonNull String packageName,
839 @NonNull String databaseName,
840 @NonNull ParcelFileDescriptor fileDescriptor,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700841 @NonNull UserHandle userHandle,
Terry Wang623e3b02021-02-02 20:27:33 -0800842 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700843 Objects.requireNonNull(packageName);
844 Objects.requireNonNull(databaseName);
845 Objects.requireNonNull(fileDescriptor);
846 Objects.requireNonNull(userHandle);
847 Objects.requireNonNull(callback);
848
Terry Wang623e3b02021-02-02 20:27:33 -0800849 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700850 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700851 EXECUTOR.execute(() -> {
852 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700853 verifyCallingPackage(callingUser, callingUid, packageName);
854 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wang623e3b02021-02-02 20:27:33 -0800855
Terry Wange04ceab2021-03-29 19:25:12 -0700856 GenericDocument document;
857 ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
858 try (DataInputStream inputStream = new DataInputStream(
859 new FileInputStream(fileDescriptor.getFileDescriptor()))) {
860 while (true) {
861 try {
862 document = AppSearchMigrationHelper
863 .readDocumentFromInputStream(inputStream);
864 } catch (EOFException e) {
865 // nothing wrong, we just finish the reading.
866 break;
867 }
868 try {
869 impl.putDocument(packageName, databaseName, document,
870 /*logger=*/ null);
871 } catch (Throwable t) {
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700872 migrationFailureBundles.add(new SetSchemaResponse.MigrationFailure(
873 document.getNamespace(),
874 document.getId(),
875 document.getSchemaType(),
876 AppSearchResult.throwableToFailedResult(t))
877 .getBundle());
Terry Wange04ceab2021-03-29 19:25:12 -0700878 }
Terry Wang623e3b02021-02-02 20:27:33 -0800879 }
880 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700881 impl.persistToDisk(PersistType.Code.FULL);
Terry Wange04ceab2021-03-29 19:25:12 -0700882 invokeCallbackOnResult(callback,
883 AppSearchResult.newSuccessfulResult(migrationFailureBundles));
884 } catch (Throwable t) {
885 invokeCallbackOnError(callback, t);
Terry Wang623e3b02021-02-02 20:27:33 -0800886 }
Terry Wange04ceab2021-03-29 19:25:12 -0700887 });
Terry Wang623e3b02021-02-02 20:27:33 -0800888 }
889
890 @Override
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800891 public void reportUsage(
892 @NonNull String packageName,
893 @NonNull String databaseName,
894 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700895 @NonNull String documentId,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800896 long usageTimeMillis,
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700897 boolean systemUsage,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700898 @NonNull UserHandle userHandle,
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800899 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700900 Objects.requireNonNull(packageName);
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800901 Objects.requireNonNull(databaseName);
902 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700903 Objects.requireNonNull(documentId);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700904 Objects.requireNonNull(userHandle);
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800905 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700906
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800907 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700908 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700909 EXECUTOR.execute(() -> {
910 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700911 verifyUserUnlocked(callingUser);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700912
Terry Wange04ceab2021-03-29 19:25:12 -0700913 if (systemUsage) {
914 // TODO(b/183031844): Validate that the call comes from the system
915 }
916
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700917 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -0700918 impl.reportUsage(
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700919 packageName, databaseName, namespace, documentId,
Terry Wange04ceab2021-03-29 19:25:12 -0700920 usageTimeMillis, systemUsage);
921 invokeCallbackOnResult(
922 callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
923 } catch (Throwable t) {
924 invokeCallbackOnError(callback, t);
Alexander Dorokhine9795b512021-03-23 22:06:59 -0700925 }
Terry Wange04ceab2021-03-29 19:25:12 -0700926 });
Alexander Dorokhined18f8842021-01-20 15:26:13 -0800927 }
928
929 @Override
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700930 public void removeByDocumentId(
Cassie Wang0c62d992021-01-15 14:39:30 -0800931 @NonNull String packageName,
Terry Wangf2093072020-11-30 04:47:19 -0800932 @NonNull String databaseName,
933 @NonNull String namespace,
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700934 @NonNull List<String> ids,
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700935 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700936 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Terry Wangdbd1dca2020-11-03 17:03:56 -0800937 @NonNull IAppSearchBatchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700938 Objects.requireNonNull(packageName);
939 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700940 Objects.requireNonNull(namespace);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700941 Objects.requireNonNull(ids);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700942 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -0700943 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700944
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700945 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -0800946 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700947 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -0700948 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700949 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
950 PlatformLogger logger = null;
951 int operationSuccessCount = 0;
952 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -0700953 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700954 verifyUserUnlocked(callingUser);
955 verifyCallingPackage(callingUser, callingUid, packageName);
Terry Wange04ceab2021-03-29 19:25:12 -0700956 AppSearchBatchResult.Builder<String, Void> resultBuilder =
957 new AppSearchBatchResult.Builder<>();
Alexander Dorokhinebea55602021-05-19 13:59:45 -0700958 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
959 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700960 for (int i = 0; i < ids.size(); i++) {
961 String id = ids.get(i);
Terry Wange04ceab2021-03-29 19:25:12 -0700962 try {
Alexander Dorokhinea4b5bab2021-05-20 14:24:50 -0700963 impl.remove(
964 packageName,
965 databaseName,
966 namespace,
967 id,
968 /*removeStatsBuilder=*/ null);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700969 ++operationSuccessCount;
Alexander Dorokhine17f79372021-04-21 11:23:09 -0700970 resultBuilder.setSuccess(id, /*result= */ null);
Terry Wange04ceab2021-03-29 19:25:12 -0700971 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700972 AppSearchResult<Void> result = throwableToFailedResult(t);
973 resultBuilder.setResult(id, result);
974 // Since we can only include one status code in the atom,
975 // for failures, we would just save the one for the last failure
976 statusCode = result.getResultCode();
977 ++operationFailureCount;
Terry Wange04ceab2021-03-29 19:25:12 -0700978 }
Alexander Dorokhineff82fba2020-03-09 16:35:24 -0700979 }
Alexander Dorokhinec77f4442021-04-14 09:26:06 -0700980 // Now that the batch has been written. Persist the newly written data.
981 impl.persistToDisk(PersistType.Code.LITE);
Terry Wange04ceab2021-03-29 19:25:12 -0700982 invokeCallbackOnResult(callback, resultBuilder.build());
983 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700984 ++operationFailureCount;
985 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -0700986 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700987 } finally {
988 if (logger != null) {
989 int estimatedBinderLatencyMillis =
990 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
991 int totalLatencyMillis =
992 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine82a38722021-06-09 16:35:22 -0700993 logger.logStats(new CallStats.Builder()
994 .setPackageName(packageName)
995 .setDatabase(databaseName)
996 .setStatusCode(statusCode)
997 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -0700998 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_ID)
999 // TODO(b/173532925) check the existing binder call latency chart
1000 // is good enough for us:
1001 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1002 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1003 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001004 .setNumOperationsFailed(operationFailureCount)
1005 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001006 }
Alexander Dorokhineff82fba2020-03-09 16:35:24 -07001007 }
Terry Wange04ceab2021-03-29 19:25:12 -07001008 });
Alexander Dorokhineff82fba2020-03-09 16:35:24 -07001009 }
1010
1011 @Override
Terry Wang26b9e5c2020-10-23 02:05:01 -07001012 public void removeByQuery(
Cassie Wang0c62d992021-01-15 14:39:30 -08001013 @NonNull String packageName,
Terry Wang26b9e5c2020-10-23 02:05:01 -07001014 @NonNull String databaseName,
1015 @NonNull String queryExpression,
1016 @NonNull Bundle searchSpecBundle,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001017 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001018 @ElapsedRealtimeLong long binderCallStartTimeMillis,
Alexander Dorokhine178366b2020-10-20 17:40:49 -07001019 @NonNull IAppSearchResultCallback callback) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001020 // TODO(b/173532925) log CallStats once we have CALL_TYPE_REMOVE_BY_QUERY added
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001021 Objects.requireNonNull(packageName);
1022 Objects.requireNonNull(databaseName);
1023 Objects.requireNonNull(queryExpression);
1024 Objects.requireNonNull(searchSpecBundle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001025 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001026 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001027
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001028 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -08001029 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001030 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001031 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001032 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
1033 PlatformLogger logger = null;
1034 int operationSuccessCount = 0;
1035 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001036 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001037 verifyUserUnlocked(callingUser);
1038 verifyCallingPackage(callingUser, callingUid, packageName);
1039 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
1040 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -07001041 impl.removeByQuery(
1042 packageName,
1043 databaseName,
1044 queryExpression,
Alexander Dorokhinea4b5bab2021-05-20 14:24:50 -07001045 new SearchSpec(searchSpecBundle),
1046 /*removeStatsBuilder=*/ null);
Alexander Dorokhinec77f4442021-04-14 09:26:06 -07001047 // Now that the batch has been written. Persist the newly written data.
1048 impl.persistToDisk(PersistType.Code.LITE);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001049 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001050 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
1051 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001052 ++operationFailureCount;
1053 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001054 invokeCallbackOnError(callback, t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001055 } finally {
1056 if (logger != null) {
1057 int estimatedBinderLatencyMillis =
1058 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1059 int totalLatencyMillis =
1060 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001061 logger.logStats(new CallStats.Builder()
1062 .setPackageName(packageName)
1063 .setDatabase(databaseName)
1064 .setStatusCode(statusCode)
1065 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001066 .setCallType(CallStats.CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH)
1067 // TODO(b/173532925) check the existing binder call latency chart
1068 // is good enough for us:
1069 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1070 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1071 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001072 .setNumOperationsFailed(operationFailureCount)
1073 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001074 }
Terry Wange04ceab2021-03-29 19:25:12 -07001075 }
1076 });
Alexander Dorokhinef6c66ae2020-03-09 14:47:25 -07001077 }
1078
Terry Wangdbd1dca2020-11-03 17:03:56 -08001079 @Override
Cassie Wang8f0df492021-03-24 09:23:18 -07001080 public void getStorageInfo(
1081 @NonNull String packageName,
1082 @NonNull String databaseName,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001083 @NonNull UserHandle userHandle,
Cassie Wang8f0df492021-03-24 09:23:18 -07001084 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001085 Objects.requireNonNull(packageName);
1086 Objects.requireNonNull(databaseName);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001087 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001088 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001089
Cassie Wang8f0df492021-03-24 09:23:18 -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(() -> {
1093 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001094 verifyUserUnlocked(callingUser);
1095 verifyCallingPackage(callingUser, callingUid, packageName);
1096 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
Terry Wange04ceab2021-03-29 19:25:12 -07001097 StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName,
1098 databaseName);
1099 Bundle storageInfoBundle = storageInfo.getBundle();
1100 invokeCallbackOnResult(
1101 callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
1102 } catch (Throwable t) {
1103 invokeCallbackOnError(callback, t);
1104 }
1105 });
Cassie Wang8f0df492021-03-24 09:23:18 -07001106 }
1107
1108 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001109 public void persistToDisk(
1110 @NonNull UserHandle userHandle,
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001111 @ElapsedRealtimeLong long binderCallStartTimeMillis) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001112 Objects.requireNonNull(userHandle);
1113
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001114 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Cassie Wangb0d60122021-03-30 12:38:46 -07001115 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001116 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001117 EXECUTOR.execute(() -> {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001118 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
1119 PlatformLogger logger = null;
1120 int operationSuccessCount = 0;
1121 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001122 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001123 verifyUserUnlocked(callingUser);
1124 AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUser);
1125 logger = mLoggerInstanceManager.getPlatformLogger(callingUser);
Alexander Dorokhinec77f4442021-04-14 09:26:06 -07001126 impl.persistToDisk(PersistType.Code.FULL);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001127 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001128 } catch (Throwable t) {
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001129 ++operationFailureCount;
1130 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001131 Log.e(TAG, "Unable to persist the data to disk", t);
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001132 } finally {
1133 if (logger != null) {
1134 int estimatedBinderLatencyMillis =
1135 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1136 int totalLatencyMillis =
1137 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001138 logger.logStats(new CallStats.Builder()
1139 .setStatusCode(statusCode)
1140 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001141 .setCallType(CallStats.CALL_TYPE_FLUSH)
1142 // TODO(b/173532925) check the existing binder call latency chart
1143 // is good enough for us:
1144 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1145 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1146 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001147 .setNumOperationsFailed(operationFailureCount)
1148 .build());
Xiaoyu Jinc5a75772021-05-09 20:12:44 -07001149 }
Terry Wange04ceab2021-03-29 19:25:12 -07001150 }
1151 });
Terry Wang2da17852020-12-16 19:59:08 -08001152 }
1153
1154 @Override
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001155 public void initialize(
1156 @NonNull UserHandle userHandle,
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001157 @ElapsedRealtimeLong long binderCallStartTimeMillis,
1158 @NonNull IAppSearchResultCallback callback) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001159 Objects.requireNonNull(userHandle);
Alexander Dorokhine5258ad22021-04-15 10:59:55 -07001160 Objects.requireNonNull(callback);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001161
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001162 long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
Terry Wangf2093072020-11-30 04:47:19 -08001163 int callingUid = Binder.getCallingUid();
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001164 UserHandle callingUser = handleIncomingUser(userHandle, callingUid);
Terry Wange04ceab2021-03-29 19:25:12 -07001165 EXECUTOR.execute(() -> {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001166 @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
1167 PlatformLogger logger = null;
1168 int operationSuccessCount = 0;
1169 int operationFailureCount = 0;
Terry Wange04ceab2021-03-29 19:25:12 -07001170 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001171 verifyUserUnlocked(callingUser);
1172 logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
Xiaoyu Jin433892c2021-05-24 16:19:02 -07001173 mContext, callingUser,
1174 AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001175 mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUser, logger);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001176 ++operationSuccessCount;
Terry Wange04ceab2021-03-29 19:25:12 -07001177 invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
1178 } catch (Throwable t) {
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001179 ++operationFailureCount;
1180 statusCode = throwableToFailedResult(t).getResultCode();
Terry Wange04ceab2021-03-29 19:25:12 -07001181 invokeCallbackOnError(callback, t);
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001182 } finally {
1183 if (logger != null) {
1184 int estimatedBinderLatencyMillis =
1185 2 * (int) (totalLatencyStartTimeMillis - binderCallStartTimeMillis);
1186 int totalLatencyMillis =
1187 (int) (SystemClock.elapsedRealtime() - totalLatencyStartTimeMillis);
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001188 logger.logStats(new CallStats.Builder()
1189 .setStatusCode(statusCode)
1190 .setTotalLatencyMillis(totalLatencyMillis)
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001191 .setCallType(CallStats.CALL_TYPE_INITIALIZE)
1192 // TODO(b/173532925) check the existing binder call latency chart
1193 // is good enough for us:
1194 // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
1195 .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
1196 .setNumOperationsSucceeded(operationSuccessCount)
Alexander Dorokhine82a38722021-06-09 16:35:22 -07001197 .setNumOperationsFailed(operationFailureCount)
1198 .build());
Xiaoyu Jinc410c4f2021-05-09 14:15:50 -07001199 }
Terry Wange04ceab2021-03-29 19:25:12 -07001200 }
1201 });
Terry Wangdbd1dca2020-11-03 17:03:56 -08001202 }
1203
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001204 private void verifyCallingPackage(
1205 @NonNull UserHandle actualCallingUser,
1206 int actualCallingUid,
1207 @NonNull String claimedCallingPackage) {
1208 Objects.requireNonNull(actualCallingUser);
1209 Objects.requireNonNull(claimedCallingPackage);
1210
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001211 int claimedCallingUid = PackageUtil.getPackageUidAsUser(
1212 mContext, claimedCallingPackage, actualCallingUser);
1213 if (claimedCallingUid == INVALID_UID) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001214 throw new SecurityException(
1215 "Specified calling package [" + claimedCallingPackage + "] not found");
1216 }
1217 if (claimedCallingUid != actualCallingUid) {
Cassie Wang0c62d992021-01-15 14:39:30 -08001218 throw new SecurityException(
1219 "Specified calling package ["
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001220 + claimedCallingPackage
Cassie Wang0c62d992021-01-15 14:39:30 -08001221 + "] does not match the calling uid "
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001222 + actualCallingUid);
Alexander Dorokhineebd37742020-09-22 15:02:26 -07001223 }
Alexander Dorokhineebd37742020-09-22 15:02:26 -07001224 }
1225
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001226 /** Invokes the {@link IAppSearchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -08001227 private void invokeCallbackOnResult(
1228 IAppSearchResultCallback callback, AppSearchResult<?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -08001229 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001230 callback.onResult(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001231 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001232 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001233 }
Terry Wangdbd1dca2020-11-03 17:03:56 -08001234 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001235
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001236 /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */
Cassie Wang0c62d992021-01-15 14:39:30 -08001237 private void invokeCallbackOnResult(
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001238 IAppSearchBatchResultCallback callback, AppSearchBatchResult<String, ?> result) {
Terry Wangdbd1dca2020-11-03 17:03:56 -08001239 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001240 callback.onResult(new AppSearchBatchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001241 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001242 Log.e(TAG, "Unable to send result to the callback", e);
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001243 }
Terry Wangdbd1dca2020-11-03 17:03:56 -08001244 }
1245
1246 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001247 * Invokes the {@link IAppSearchResultCallback} with an throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001248 *
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001249 * <p>The throwable is convert to a {@link AppSearchResult};
Terry Wangdbd1dca2020-11-03 17:03:56 -08001250 */
1251 private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001252 AppSearchResult<?> result = throwableToFailedResult(throwable);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001253 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001254 callback.onResult(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001255 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001256 Log.e(TAG, "Unable to send result to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001257 }
1258 }
1259
1260 /**
Alexander Dorokhine8c5ba912020-12-14 22:58:12 -08001261 * Invokes the {@link IAppSearchBatchResultCallback} with an unexpected internal throwable.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001262 *
Alexander Dorokhineb5d34b12021-04-15 00:32:15 -07001263 * <p>The throwable is converted to {@link AppSearchResult}.
Terry Wangdbd1dca2020-11-03 17:03:56 -08001264 */
Cassie Wang0c62d992021-01-15 14:39:30 -08001265 private void invokeCallbackOnError(
Alexander Dorokhineb5d34b12021-04-15 00:32:15 -07001266 @NonNull IAppSearchBatchResultCallback callback, @NonNull Throwable throwable) {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001267 AppSearchResult<?> result = throwableToFailedResult(throwable);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001268 try {
Alexander Dorokhined5e8eda2021-05-04 13:24:47 -07001269 callback.onSystemError(new AppSearchResultParcel<>(result));
Terry Wangdbd1dca2020-11-03 17:03:56 -08001270 } catch (RemoteException e) {
Terry Wang2da17852020-12-16 19:59:08 -08001271 Log.e(TAG, "Unable to send error to the callback", e);
Terry Wangdbd1dca2020-11-03 17:03:56 -08001272 }
Alexander Dorokhine969f4462020-03-05 15:54:19 -08001273 }
Terry Wangfebbead2019-10-17 17:05:18 -07001274 }
Terry Wangf2093072020-11-30 04:47:19 -08001275
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001276 /**
1277 * Helper for dealing with incoming user arguments to system service calls.
1278 *
1279 * <p>Takes care of checking permissions and converting USER_CURRENT to the actual current user.
1280 *
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001281 * @param requestedUser The user which the caller is requesting to execute as.
1282 * @param callingUid The actual uid of the caller as determined by Binder.
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001283 * @return the user handle that the call should run as. Will always be a concrete user.
1284 */
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001285 @NonNull
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001286 private UserHandle handleIncomingUser(@NonNull UserHandle requestedUser, int callingUid) {
Terry Wangf2093072020-11-30 04:47:19 -08001287 int callingPid = Binder.getCallingPid();
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001288 UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid);
1289 if (callingUser.equals(requestedUser)) {
1290 return requestedUser;
1291 }
1292 // Duplicates UserController#ensureNotSpecialUser
1293 if (requestedUser.getIdentifier() < 0) {
1294 throw new IllegalArgumentException(
1295 "Call does not support special user " + requestedUser);
1296 }
1297 boolean canInteractAcrossUsers = mContext.checkPermission(
1298 Manifest.permission.INTERACT_ACROSS_USERS,
Cassie Wang0c62d992021-01-15 14:39:30 -08001299 callingPid,
Alexander Dorokhine5c416772021-06-04 09:05:00 -07001300 callingUid) == PackageManager.PERMISSION_GRANTED;
1301 if (!canInteractAcrossUsers) {
1302 canInteractAcrossUsers = mContext.checkPermission(
1303 Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1304 callingPid,
1305 callingUid) == PackageManager.PERMISSION_GRANTED;
1306 }
1307 if (canInteractAcrossUsers) {
1308 return requestedUser;
1309 }
1310 throw new SecurityException(
1311 "Permission denied while calling from uid " + callingUid
1312 + " with " + requestedUser + "; Need to run as either the calling user ("
1313 + callingUser + "), or with one of the following permissions: "
1314 + Manifest.permission.INTERACT_ACROSS_USERS + " or "
1315 + Manifest.permission.INTERACT_ACROSS_USERS_FULL);
Terry Wangf2093072020-11-30 04:47:19 -08001316 }
Yang Yu0fcd51a2021-04-23 11:25:44 -07001317
1318 // TODO(b/179160886): Cache the previous storage stats.
1319 private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter {
1320 @Override
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001321 public void augmentStatsForPackageForUser(
Yang Yu0fcd51a2021-04-23 11:25:44 -07001322 @NonNull PackageStats stats,
1323 @NonNull String packageName,
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001324 @NonNull UserHandle userHandle,
1325 boolean canCallerAccessAllStats) {
Yang Yu0fcd51a2021-04-23 11:25:44 -07001326 Objects.requireNonNull(stats);
1327 Objects.requireNonNull(packageName);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001328 Objects.requireNonNull(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001329
Yang Yu0fcd51a2021-04-23 11:25:44 -07001330 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001331 verifyUserUnlocked(userHandle);
1332 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
Xiaoyu Jin433892c2021-05-24 16:19:02 -07001333 mContext, userHandle,
1334 AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001335 AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
1336 mContext, userHandle, logger);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001337 stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
1338 } catch (Throwable t) {
1339 Log.e(
1340 TAG,
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001341 "Unable to augment storage stats for "
1342 + userHandle
Yang Yu0fcd51a2021-04-23 11:25:44 -07001343 + " packageName "
1344 + packageName,
1345 t);
1346 }
1347 }
1348
1349 @Override
1350 public void augmentStatsForUid(
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001351 @NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats) {
Yang Yu0fcd51a2021-04-23 11:25:44 -07001352 Objects.requireNonNull(stats);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001353
1354 UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001355 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001356 verifyUserUnlocked(userHandle);
Yang Yu0fcd51a2021-04-23 11:25:44 -07001357 String[] packagesForUid = mPackageManager.getPackagesForUid(uid);
1358 if (packagesForUid == null) {
1359 return;
1360 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001361 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
Xiaoyu Jin433892c2021-05-24 16:19:02 -07001362 mContext, userHandle,
1363 AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001364 AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(
1365 mContext, userHandle, logger);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001366 for (int i = 0; i < packagesForUid.length; i++) {
1367 stats.dataSize +=
1368 impl.getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
Yang Yu0fcd51a2021-04-23 11:25:44 -07001369 }
1370 } catch (Throwable t) {
1371 Log.e(TAG, "Unable to augment storage stats for uid " + uid, t);
1372 }
1373 }
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001374
1375 @Override
1376 public void augmentStatsForUser(
1377 @NonNull PackageStats stats, @NonNull UserHandle userHandle) {
1378 // TODO(b/179160886): this implementation could incur many jni calls and a lot of
1379 // in-memory processing from getStorageInfoForPackage. Instead, we can just compute the
1380 // size of the icing dir (or use the overall StorageInfo without interpolating it).
1381 Objects.requireNonNull(stats);
1382 Objects.requireNonNull(userHandle);
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001383
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001384 try {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001385 verifyUserUnlocked(userHandle);
1386 List<PackageInfo> packagesForUser = mPackageManager.getInstalledPackagesAsUser(
1387 /*flags=*/0, userHandle.getIdentifier());
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001388 if (packagesForUser == null) {
1389 return;
1390 }
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001391 PlatformLogger logger = mLoggerInstanceManager.getOrCreatePlatformLogger(
Xiaoyu Jin433892c2021-05-24 16:19:02 -07001392 mContext, userHandle,
1393 AppSearchConfig.getInstance(EXECUTOR));
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001394 AppSearchImpl impl =
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001395 mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userHandle, logger);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001396 for (int i = 0; i < packagesForUser.size(); i++) {
1397 String packageName = packagesForUser.get(i).packageName;
1398 stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
1399 }
1400 } catch (Throwable t) {
Alexander Dorokhinebea55602021-05-19 13:59:45 -07001401 Log.e(TAG, "Unable to augment storage stats for " + userHandle, t);
Alexander Dorokhinea5d0d322021-05-10 15:59:31 -07001402 }
1403 }
Yang Yu0fcd51a2021-04-23 11:25:44 -07001404 }
Terry Wangfebbead2019-10-17 17:05:18 -07001405}