diff options
2 files changed, 45 insertions, 7 deletions
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java index 366718c65d84..18e21226503d 100644 --- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java +++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java @@ -230,8 +230,10 @@ public final class AppHibernationService extends SystemService { } final Map<String, UserLevelState> packageStates = mUserStates.get(userId); final UserLevelState pkgState = packageStates.get(packageName); - if (pkgState == null) { - Slog.e(TAG, String.format("Package %s is not installed for user %s", + if (pkgState == null + || !mPackageManagerInternal.canQueryPackage( + Binder.getCallingUid(), packageName)) { + Slog.e(TAG, TextUtils.formatSimple("Package %s is not installed for user %s", packageName, userId)); return false; } @@ -254,7 +256,9 @@ public final class AppHibernationService extends SystemService { "Caller does not have MANAGE_APP_HIBERNATION permission."); synchronized (mLock) { GlobalLevelState state = mGlobalHibernationStates.get(packageName); - if (state == null) { + if (state == null + || !mPackageManagerInternal.canQueryPackage( + Binder.getCallingUid(), packageName)) { // This API can be legitimately called before installation finishes as part of // dex optimization, so we just return false here. return false; @@ -285,8 +289,10 @@ public final class AppHibernationService extends SystemService { } final Map<String, UserLevelState> packageStates = mUserStates.get(realUserId); final UserLevelState pkgState = packageStates.get(packageName); - if (pkgState == null) { - Slog.e(TAG, String.format("Package %s is not installed for user %s", + if (pkgState == null + || !mPackageManagerInternal.canQueryPackage( + Binder.getCallingUid(), packageName)) { + Slog.e(TAG, TextUtils.formatSimple("Package %s is not installed for user %s", packageName, realUserId)); return; } @@ -334,8 +340,11 @@ public final class AppHibernationService extends SystemService { "Caller does not have MANAGE_APP_HIBERNATION permission."); synchronized (mLock) { GlobalLevelState state = mGlobalHibernationStates.get(packageName); - if (state == null) { - Slog.e(TAG, String.format("Package %s is not installed for any user", packageName)); + if (state == null + || !mPackageManagerInternal.canQueryPackage( + Binder.getCallingUid(), packageName)) { + Slog.e(TAG, TextUtils.formatSimple( + "Package %s is not installed for any user", packageName)); return; } if (state.hibernated != isHibernating) { @@ -372,6 +381,12 @@ public final class AppHibernationService extends SystemService { } Map<String, UserLevelState> userStates = mUserStates.get(userId); for (UserLevelState state : userStates.values()) { + String packageName = state.packageName; + if (!mPackageManagerInternal.canQueryPackage( + Binder.getCallingUid(), packageName)) { + // Package is not visible to caller + continue; + } if (state.hibernated) { hibernatingPackages.add(state.packageName); } diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java index e1aa08d9176a..bec094006c8d 100644 --- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java @@ -235,6 +235,29 @@ public final class AppHibernationServiceTest { } @Test + public void testGetHibernatingPackagesForUser_doesNotReturnPackagesThatArentVisible() + throws RemoteException { + // GIVEN an unlocked user with all packages installed but only some are visible to the + // caller + UserInfo userInfo = + addUser(USER_ID_2, new String[]{PACKAGE_NAME_1, PACKAGE_NAME_2, PACKAGE_NAME_3}); + doReturn(false).when(mPackageManagerInternal).canQueryPackage(anyInt(), eq(PACKAGE_NAME_2)); + doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_2); + mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(userInfo)); + + // WHEN packages are hibernated for the user + mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_2, true); + mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_2, USER_ID_2, true); + + // THEN the hibernating packages returned does not contain the package that was not visible + List<String> hibernatingPackages = + mAppHibernationService.getHibernatingPackagesForUser(USER_ID_2); + assertEquals(1, hibernatingPackages.size()); + assertTrue(hibernatingPackages.contains(PACKAGE_NAME_1)); + assertFalse(hibernatingPackages.contains(PACKAGE_NAME_2)); + } + + @Test public void testUserLevelStatesInitializedFromDisk() throws RemoteException { // GIVEN states stored on disk that match with package manager's force-stop states List<UserLevelState> diskStates = new ArrayList<>(); |