Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42cef990 authored by Kevin Han's avatar Kevin Han Committed by Android (Google) Code Review
Browse files

Merge "Add pkg visibility checks to all hibernation APIs"

parents b9764480 392c84af
Loading
Loading
Loading
Loading
+22 −7
Original line number Diff line number Diff line
@@ -235,8 +235,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;
            }
@@ -259,7 +261,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;
@@ -290,8 +294,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;
            }
@@ -340,8 +346,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) {
@@ -378,6 +387,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);
                }
+23 −0
Original line number Diff line number Diff line
@@ -248,6 +248,29 @@ public final class AppHibernationServiceTest {
        assertTrue(hibernatingPackages.contains(PACKAGE_NAME_2));
    }

    @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