Loading services/core/java/com/android/server/pm/PackageManagerService.java +45 −32 Original line number Diff line number Diff line Loading @@ -21486,7 +21486,7 @@ public class PackageManagerService extends IPackageManager.Stub // user handle installed state int[] allUsers; final int freezeUser; final SparseArray<Pair<Integer, String>> enabledStateAndCallerPerUser; final SparseArray<TempUserState> priorUserStates; /** enabled state of the uninstalled application */ synchronized (mLock) { uninstalledPs = mSettings.getPackageLPr(packageName); Loading Loading @@ -21537,16 +21537,16 @@ public class PackageManagerService extends IPackageManager.Stub // We're downgrading a system app, which will apply to all users, so // freeze them all during the downgrade freezeUser = UserHandle.USER_ALL; enabledStateAndCallerPerUser = new SparseArray<>(); priorUserStates = new SparseArray<>(); for (int i = 0; i < allUsers.length; i++) { PackageUserState userState = uninstalledPs.readUserState(allUsers[i]); Pair<Integer, String> enabledStateAndCaller = new Pair<>(userState.enabled, userState.lastDisableAppCaller); enabledStateAndCallerPerUser.put(allUsers[i], enabledStateAndCaller); priorUserStates.put(allUsers[i], new TempUserState(userState.enabled, userState.lastDisableAppCaller, userState.installed)); } } else { freezeUser = removeUser; enabledStateAndCallerPerUser = null; priorUserStates = null; } } Loading Loading @@ -21583,6 +21583,30 @@ public class PackageManagerService extends IPackageManager.Stub if (info.args != null) { info.args.doPostDeleteLI(true); } boolean reEnableStub = false; if (priorUserStates != null) { synchronized (mLock) { for (int i = 0; i < allUsers.length; i++) { TempUserState priorUserState = priorUserStates.get(allUsers[i]); int enabledState = priorUserState.enabledState; PackageSetting pkgSetting = getPackageSetting(packageName); pkgSetting.setEnabled(enabledState, allUsers[i], priorUserState.lastDisableAppCaller); AndroidPackage aPkg = pkgSetting.getPkg(); boolean pkgEnabled = aPkg != null && aPkg.isEnabled(); if (!reEnableStub && priorUserState.installed && ((enabledState == COMPONENT_ENABLED_STATE_DEFAULT && pkgEnabled) || enabledState == COMPONENT_ENABLED_STATE_ENABLED)) { reEnableStub = true; } } mSettings.writeAllUsersPackageRestrictionsLPr(); } } final AndroidPackage stubPkg = (disabledSystemPs == null) ? null : disabledSystemPs.pkg; if (stubPkg != null && stubPkg.isStub()) { Loading @@ -21592,19 +21616,7 @@ public class PackageManagerService extends IPackageManager.Stub } if (stubPs != null) { boolean enable = false; for (int aUserId : allUsers) { if (stubPs.getInstalled(aUserId)) { int enabled = stubPs.getEnabled(aUserId); if (enabled == COMPONENT_ENABLED_STATE_DEFAULT || enabled == COMPONENT_ENABLED_STATE_ENABLED) { enable = true; break; } } } if (enable) { if (reEnableStub) { if (DEBUG_COMPRESSION) { Slog.i(TAG, "Enabling system stub after removal; pkg: " + stubPkg.getPackageName()); Loading @@ -21616,19 +21628,6 @@ public class PackageManagerService extends IPackageManager.Stub } } } if (enabledStateAndCallerPerUser != null) { synchronized (mLock) { for (int i = 0; i < allUsers.length; i++) { Pair<Integer, String> enabledStateAndCaller = enabledStateAndCallerPerUser.get(allUsers[i]); getPackageSetting(packageName) .setEnabled(enabledStateAndCaller.first, allUsers[i], enabledStateAndCaller.second); } mSettings.writeAllUsersPackageRestrictionsLPr(); } } } return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; Loading Loading @@ -28933,6 +28932,20 @@ public class PackageManagerService extends IPackageManager.Stub } } } private static class TempUserState { public final int enabledState; @Nullable public final String lastDisableAppCaller; public final boolean installed; private TempUserState(int enabledState, @Nullable String lastDisableAppCaller, boolean installed) { this.enabledState = enabledState; this.lastDisableAppCaller = lastDisableAppCaller; this.installed = installed; } } } interface PackageSender { services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemStubMultiUserDisableUninstallTest.kt +33 −30 Original line number Diff line number Diff line Loading @@ -281,7 +281,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) uninstall(User.SECONDARY) Loading @@ -289,7 +289,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) installExisting(User.PRIMARY) Loading @@ -311,20 +311,20 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { @Test fun uninstallSecondaryFirstByUserAndInstallExistingSecondaryFirst() { uninstall(User.PRIMARY) uninstall(User.SECONDARY) assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) primaryInstalled = true, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) uninstall(User.SECONDARY) uninstall(User.PRIMARY) assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) installExisting(User.SECONDARY) Loading @@ -348,15 +348,14 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { fun uninstallUpdatesAndEnablePrimaryFirst() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") // Uninstall-system-updates always disables system user 0 // TODO: Is this intentional? There is no user argument for this command. assertState( primaryInstalled = true, primaryEnabled = false, primaryInstalled = true, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, // If any user is enabled when uninstalling updates, /data is re-uncompressed codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) ) toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.PRIMARY) assertState( Loading @@ -379,14 +378,15 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { fun uninstallUpdatesAndEnableSecondaryFirst() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") // Uninstall-system-updates always disables system user 0 assertState( primaryInstalled = true, primaryEnabled = false, primaryInstalled = true, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, // If any user is enabled when uninstalling updates, /data is re-uncompressed codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) ) toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.SECONDARY) assertState( Loading Loading @@ -417,6 +417,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { codePaths = listOf(CodePath.SYSTEM) ) toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.PRIMARY) assertState( Loading Loading @@ -447,6 +448,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { codePaths = listOf(CodePath.SYSTEM) ) toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.SECONDARY) assertState( Loading @@ -471,13 +473,13 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") // Uninstall-system-updates always disables system user 0 assertState( primaryInstalled = false, primaryEnabled = false, primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.SYSTEM) ) toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.PRIMARY) assertState( Loading @@ -502,9 +504,8 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") // Uninstall-system-updates always disables system user 0 assertState( primaryInstalled = false, primaryEnabled = false, primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.SYSTEM) ) Loading @@ -512,7 +513,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { toggleEnabled(true, User.SECONDARY) assertState( primaryInstalled = false, primaryEnabled = false, primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) ) Loading Loading @@ -582,6 +583,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { codePaths: List<CodePath> ) { HostUtils.getUserIdToPkgInstalledState(device, TEST_PKG_NAME) .also { assertThat(it.size).isAtLeast(USER_COUNT) } .forEach { (userId, installed) -> if (userId == 0) { assertThat(installed).isEqualTo(primaryInstalled) Loading @@ -591,6 +593,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { } HostUtils.getUserIdToPkgEnabledState(device, TEST_PKG_NAME) .also { assertThat(it.size).isAtLeast(USER_COUNT) } .forEach { (userId, enabled) -> if (userId == 0) { assertThat(enabled).isEqualTo(primaryEnabled) Loading Loading
services/core/java/com/android/server/pm/PackageManagerService.java +45 −32 Original line number Diff line number Diff line Loading @@ -21486,7 +21486,7 @@ public class PackageManagerService extends IPackageManager.Stub // user handle installed state int[] allUsers; final int freezeUser; final SparseArray<Pair<Integer, String>> enabledStateAndCallerPerUser; final SparseArray<TempUserState> priorUserStates; /** enabled state of the uninstalled application */ synchronized (mLock) { uninstalledPs = mSettings.getPackageLPr(packageName); Loading Loading @@ -21537,16 +21537,16 @@ public class PackageManagerService extends IPackageManager.Stub // We're downgrading a system app, which will apply to all users, so // freeze them all during the downgrade freezeUser = UserHandle.USER_ALL; enabledStateAndCallerPerUser = new SparseArray<>(); priorUserStates = new SparseArray<>(); for (int i = 0; i < allUsers.length; i++) { PackageUserState userState = uninstalledPs.readUserState(allUsers[i]); Pair<Integer, String> enabledStateAndCaller = new Pair<>(userState.enabled, userState.lastDisableAppCaller); enabledStateAndCallerPerUser.put(allUsers[i], enabledStateAndCaller); priorUserStates.put(allUsers[i], new TempUserState(userState.enabled, userState.lastDisableAppCaller, userState.installed)); } } else { freezeUser = removeUser; enabledStateAndCallerPerUser = null; priorUserStates = null; } } Loading Loading @@ -21583,6 +21583,30 @@ public class PackageManagerService extends IPackageManager.Stub if (info.args != null) { info.args.doPostDeleteLI(true); } boolean reEnableStub = false; if (priorUserStates != null) { synchronized (mLock) { for (int i = 0; i < allUsers.length; i++) { TempUserState priorUserState = priorUserStates.get(allUsers[i]); int enabledState = priorUserState.enabledState; PackageSetting pkgSetting = getPackageSetting(packageName); pkgSetting.setEnabled(enabledState, allUsers[i], priorUserState.lastDisableAppCaller); AndroidPackage aPkg = pkgSetting.getPkg(); boolean pkgEnabled = aPkg != null && aPkg.isEnabled(); if (!reEnableStub && priorUserState.installed && ((enabledState == COMPONENT_ENABLED_STATE_DEFAULT && pkgEnabled) || enabledState == COMPONENT_ENABLED_STATE_ENABLED)) { reEnableStub = true; } } mSettings.writeAllUsersPackageRestrictionsLPr(); } } final AndroidPackage stubPkg = (disabledSystemPs == null) ? null : disabledSystemPs.pkg; if (stubPkg != null && stubPkg.isStub()) { Loading @@ -21592,19 +21616,7 @@ public class PackageManagerService extends IPackageManager.Stub } if (stubPs != null) { boolean enable = false; for (int aUserId : allUsers) { if (stubPs.getInstalled(aUserId)) { int enabled = stubPs.getEnabled(aUserId); if (enabled == COMPONENT_ENABLED_STATE_DEFAULT || enabled == COMPONENT_ENABLED_STATE_ENABLED) { enable = true; break; } } } if (enable) { if (reEnableStub) { if (DEBUG_COMPRESSION) { Slog.i(TAG, "Enabling system stub after removal; pkg: " + stubPkg.getPackageName()); Loading @@ -21616,19 +21628,6 @@ public class PackageManagerService extends IPackageManager.Stub } } } if (enabledStateAndCallerPerUser != null) { synchronized (mLock) { for (int i = 0; i < allUsers.length; i++) { Pair<Integer, String> enabledStateAndCaller = enabledStateAndCallerPerUser.get(allUsers[i]); getPackageSetting(packageName) .setEnabled(enabledStateAndCaller.first, allUsers[i], enabledStateAndCaller.second); } mSettings.writeAllUsersPackageRestrictionsLPr(); } } } return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; Loading Loading @@ -28933,6 +28932,20 @@ public class PackageManagerService extends IPackageManager.Stub } } } private static class TempUserState { public final int enabledState; @Nullable public final String lastDisableAppCaller; public final boolean installed; private TempUserState(int enabledState, @Nullable String lastDisableAppCaller, boolean installed) { this.enabledState = enabledState; this.lastDisableAppCaller = lastDisableAppCaller; this.installed = installed; } } } interface PackageSender {
services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemStubMultiUserDisableUninstallTest.kt +33 −30 Original line number Diff line number Diff line Loading @@ -281,7 +281,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) uninstall(User.SECONDARY) Loading @@ -289,7 +289,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) installExisting(User.PRIMARY) Loading @@ -311,20 +311,20 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { @Test fun uninstallSecondaryFirstByUserAndInstallExistingSecondaryFirst() { uninstall(User.PRIMARY) uninstall(User.SECONDARY) assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) primaryInstalled = true, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) uninstall(User.SECONDARY) uninstall(User.PRIMARY) assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) installExisting(User.SECONDARY) Loading @@ -348,15 +348,14 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { fun uninstallUpdatesAndEnablePrimaryFirst() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") // Uninstall-system-updates always disables system user 0 // TODO: Is this intentional? There is no user argument for this command. assertState( primaryInstalled = true, primaryEnabled = false, primaryInstalled = true, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, // If any user is enabled when uninstalling updates, /data is re-uncompressed codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) ) toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.PRIMARY) assertState( Loading @@ -379,14 +378,15 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { fun uninstallUpdatesAndEnableSecondaryFirst() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") // Uninstall-system-updates always disables system user 0 assertState( primaryInstalled = true, primaryEnabled = false, primaryInstalled = true, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, // If any user is enabled when uninstalling updates, /data is re-uncompressed codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) ) toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.SECONDARY) assertState( Loading Loading @@ -417,6 +417,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { codePaths = listOf(CodePath.SYSTEM) ) toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.PRIMARY) assertState( Loading Loading @@ -447,6 +448,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { codePaths = listOf(CodePath.SYSTEM) ) toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.SECONDARY) assertState( Loading @@ -471,13 +473,13 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") // Uninstall-system-updates always disables system user 0 assertState( primaryInstalled = false, primaryEnabled = false, primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.SYSTEM) ) toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.PRIMARY) assertState( Loading @@ -502,9 +504,8 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") // Uninstall-system-updates always disables system user 0 assertState( primaryInstalled = false, primaryEnabled = false, primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.SYSTEM) ) Loading @@ -512,7 +513,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { toggleEnabled(true, User.SECONDARY) assertState( primaryInstalled = false, primaryEnabled = false, primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) ) Loading Loading @@ -582,6 +583,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { codePaths: List<CodePath> ) { HostUtils.getUserIdToPkgInstalledState(device, TEST_PKG_NAME) .also { assertThat(it.size).isAtLeast(USER_COUNT) } .forEach { (userId, installed) -> if (userId == 0) { assertThat(installed).isEqualTo(primaryInstalled) Loading @@ -591,6 +593,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { } HostUtils.getUserIdToPkgEnabledState(device, TEST_PKG_NAME) .also { assertThat(it.size).isAtLeast(USER_COUNT) } .forEach { (userId, enabled) -> if (userId == 0) { assertThat(enabled).isEqualTo(primaryEnabled) Loading