diff options
| -rw-r--r-- | apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java | 79 | ||||
| -rw-r--r-- | apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java | 16 |
2 files changed, 78 insertions, 17 deletions
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java index 7ca77d41cc89..3f6e8a5a7906 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java @@ -16,6 +16,7 @@ package com.android.server.appsearch; import static android.app.appsearch.AppSearchResult.throwableToFailedResult; +import static android.os.Process.INVALID_UID; import static android.os.UserHandle.USER_NULL; import android.annotation.ElapsedRealtimeLong; @@ -53,7 +54,6 @@ import android.os.UserManager; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; -import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.server.LocalServices; @@ -128,6 +128,17 @@ public class AppSearchManagerService extends SystemService { mContext.registerReceiverAsUser(new UserActionReceiver(), UserHandle.ALL, new IntentFilter(Intent.ACTION_USER_REMOVED), /*broadcastPermission=*/ null, /*scheduler=*/ null); + + //TODO(b/145759910) Add a direct callback when user clears the data instead of relying on + // broadcasts + IntentFilter packageChangedFilter = new IntentFilter(); + packageChangedFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED); + packageChangedFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED); + packageChangedFilter.addDataScheme("package"); + packageChangedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + mContext.registerReceiverAsUser(new PackageChangedReceiver(), UserHandle.ALL, + packageChangedFilter, /*broadcastPermission=*/ null, + /*scheduler=*/ null); } private class UserActionReceiver extends BroadcastReceiver { @@ -135,15 +146,15 @@ public class AppSearchManagerService extends SystemService { public void onReceive(@NonNull Context context, @NonNull Intent intent) { switch (intent.getAction()) { case Intent.ACTION_USER_REMOVED: - final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL); + int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL); if (userId == USER_NULL) { - Slog.e(TAG, "userId is missing in the intent: " + intent); + Log.e(TAG, "userId is missing in the intent: " + intent); return; } handleUserRemoved(userId); break; default: - Slog.e(TAG, "Received unknown intent: " + intent); + Log.e(TAG, "Received unknown intent: " + intent); } } } @@ -163,9 +174,52 @@ public class AppSearchManagerService extends SystemService { try { mImplInstanceManager.removeAppSearchImplForUser(userId); mLoggerInstanceManager.removePlatformLoggerForUser(userId); - Slog.i(TAG, "Removed AppSearchImpl instance for user: " + userId); + Log.i(TAG, "Removed AppSearchImpl instance for user: " + userId); + } catch (Throwable t) { + Log.e(TAG, "Unable to remove data for user: " + userId, t); + } + } + + private class PackageChangedReceiver extends BroadcastReceiver { + @Override + public void onReceive(@NonNull Context context, @NonNull Intent intent) { + switch (intent.getAction()) { + case Intent.ACTION_PACKAGE_FULLY_REMOVED: + case Intent.ACTION_PACKAGE_DATA_CLEARED: + String packageName = intent.getData().getSchemeSpecificPart(); + if (packageName == null) { + Log.e(TAG, "Package name is missing in the intent: " + intent); + return; + } + int uid = intent.getIntExtra(Intent.EXTRA_UID, INVALID_UID); + if (uid == INVALID_UID) { + Log.e(TAG, "uid is missing in the intent: " + intent); + return; + } + handlePackageRemoved(packageName, uid); + break; + default: + Log.e(TAG, "Received unknown intent: " + intent); + } + } + } + + private void handlePackageRemoved(String packageName, int uid) { + int userId = UserHandle.getUserId(uid); + try { + if (isUserLocked(userId)) { + //TODO(b/186151459) clear the uninstalled package data when user is unlocked. + return; + } + if (ImplInstanceManager.getAppSearchDir(userId).exists()) { + // Only clear the package's data if AppSearch exists for this user. + AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext, + userId); + //TODO(b/145759910) clear visibility setting for package. + impl.clearPackageData(packageName); + } } catch (Throwable t) { - Slog.e(TAG, "Unable to remove data for user: " + userId, t); + Log.e(TAG, "Unable to remove data for package: " + packageName, t); } } @@ -177,17 +231,20 @@ public class AppSearchManagerService extends SystemService { } private void verifyUserUnlocked(int callingUserId) { + if (isUserLocked(callingUserId)) { + throw new IllegalStateException("User " + callingUserId + " is locked or not running."); + } + } + + private boolean isUserLocked(int callingUserId) { synchronized (mUnlockedUserIdsLocked) { // First, check the local copy. if (mUnlockedUserIdsLocked.contains(callingUserId)) { - return; + return false; } // If the local copy says the user is locked, check with UM for the actual state, // since the user might just have been unlocked. - if (!mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(callingUserId))) { - throw new IllegalStateException( - "User " + callingUserId + " is locked or not running."); - } + return !mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(callingUserId)); } } diff --git a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java index af39b790168c..45023f966ad2 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java @@ -73,6 +73,15 @@ public final class ImplInstanceManager { } /** + * Returns AppSearch directory in the credential encrypted system directory for the given user. + * + * <p>This folder should only be accessed after unlock. + */ + public static File getAppSearchDir(@UserIdInt int userId) { + return new File(Environment.getDataSystemCeDirectory(userId), APP_SEARCH_DIR); + } + + /** * Gets an instance of AppSearchImpl for the given user, or creates one if none exists. * * <p>If no AppSearchImpl instance exists for the unlocked user, Icing will be initialized and @@ -139,15 +148,10 @@ public final class ImplInstanceManager { private AppSearchImpl createImpl(@NonNull Context context, @UserIdInt int userId) throws AppSearchException { - File appSearchDir = getAppSearchDir(context, userId); + File appSearchDir = getAppSearchDir(userId); return AppSearchImpl.create(appSearchDir, context, userId, mGlobalQuerierPackage); } - private static File getAppSearchDir(@NonNull Context context, @UserIdInt int userId) { - // See com.android.internal.app.ChooserActivity::getPinnedSharedPrefs - return new File(Environment.getDataSystemCeDirectory(userId), APP_SEARCH_DIR); - } - /** * Returns the global querier package if it's a system package. Otherwise, empty string. * |