Merge "Fix uninstall system updates disabling stub for single user" into sc-dev

This commit is contained in:
Patrick Baumann
2021-06-29 17:49:25 +00:00
committed by Android (Google) Code Review
2 changed files with 81 additions and 65 deletions

View File

@@ -21486,7 +21486,7 @@ public class PackageManagerService extends IPackageManager.Stub
// user handle installed state // user handle installed state
int[] allUsers; int[] allUsers;
final int freezeUser; final int freezeUser;
final SparseArray<Pair<Integer, String>> enabledStateAndCallerPerUser; final SparseArray<TempUserState> priorUserStates;
/** enabled state of the uninstalled application */ /** enabled state of the uninstalled application */
synchronized (mLock) { synchronized (mLock) {
uninstalledPs = mSettings.getPackageLPr(packageName); uninstalledPs = mSettings.getPackageLPr(packageName);
@@ -21537,16 +21537,16 @@ public class PackageManagerService extends IPackageManager.Stub
// We're downgrading a system app, which will apply to all users, so // We're downgrading a system app, which will apply to all users, so
// freeze them all during the downgrade // freeze them all during the downgrade
freezeUser = UserHandle.USER_ALL; freezeUser = UserHandle.USER_ALL;
enabledStateAndCallerPerUser = new SparseArray<>(); priorUserStates = new SparseArray<>();
for (int i = 0; i < allUsers.length; i++) { for (int i = 0; i < allUsers.length; i++) {
PackageUserState userState = uninstalledPs.readUserState(allUsers[i]); PackageUserState userState = uninstalledPs.readUserState(allUsers[i]);
Pair<Integer, String> enabledStateAndCaller = priorUserStates.put(allUsers[i],
new Pair<>(userState.enabled, userState.lastDisableAppCaller); new TempUserState(userState.enabled, userState.lastDisableAppCaller,
enabledStateAndCallerPerUser.put(allUsers[i], enabledStateAndCaller); userState.installed));
} }
} else { } else {
freezeUser = removeUser; freezeUser = removeUser;
enabledStateAndCallerPerUser = null; priorUserStates = null;
} }
} }
@@ -21583,6 +21583,30 @@ public class PackageManagerService extends IPackageManager.Stub
if (info.args != null) { if (info.args != null) {
info.args.doPostDeleteLI(true); 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 = final AndroidPackage stubPkg =
(disabledSystemPs == null) ? null : disabledSystemPs.pkg; (disabledSystemPs == null) ? null : disabledSystemPs.pkg;
if (stubPkg != null && stubPkg.isStub()) { if (stubPkg != null && stubPkg.isStub()) {
@@ -21592,19 +21616,7 @@ public class PackageManagerService extends IPackageManager.Stub
} }
if (stubPs != null) { if (stubPs != null) {
boolean enable = false; if (reEnableStub) {
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 (DEBUG_COMPRESSION) { if (DEBUG_COMPRESSION) {
Slog.i(TAG, "Enabling system stub after removal; pkg: " Slog.i(TAG, "Enabling system stub after removal; pkg: "
+ stubPkg.getPackageName()); + stubPkg.getPackageName());
@@ -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; return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
@@ -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 { interface PackageSender {

View File

@@ -281,7 +281,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
assertState( assertState(
primaryInstalled = false, primaryEnabled = true, primaryInstalled = false, primaryEnabled = true,
secondaryInstalled = true, secondaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true,
codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.SAME, CodePath.SYSTEM)
) )
uninstall(User.SECONDARY) uninstall(User.SECONDARY)
@@ -289,7 +289,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
assertState( assertState(
primaryInstalled = false, primaryEnabled = true, primaryInstalled = false, primaryEnabled = true,
secondaryInstalled = false, secondaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true,
codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.SAME, CodePath.SYSTEM)
) )
installExisting(User.PRIMARY) installExisting(User.PRIMARY)
@@ -311,20 +311,20 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
@Test @Test
fun uninstallSecondaryFirstByUserAndInstallExistingSecondaryFirst() { fun uninstallSecondaryFirstByUserAndInstallExistingSecondaryFirst() {
uninstall(User.SECONDARY)
assertState(
primaryInstalled = true, primaryEnabled = true,
secondaryInstalled = false, secondaryEnabled = true,
codePaths = listOf(CodePath.SAME, CodePath.SYSTEM)
)
uninstall(User.PRIMARY) uninstall(User.PRIMARY)
assertState(
primaryInstalled = false, primaryEnabled = true,
secondaryInstalled = true, secondaryEnabled = true,
codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM)
)
uninstall(User.SECONDARY)
assertState( assertState(
primaryInstalled = false, primaryEnabled = true, primaryInstalled = false, primaryEnabled = true,
secondaryInstalled = false, secondaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true,
codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.SAME, CodePath.SYSTEM)
) )
installExisting(User.SECONDARY) installExisting(User.SECONDARY)
@@ -348,15 +348,14 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
fun uninstallUpdatesAndEnablePrimaryFirst() { fun uninstallUpdatesAndEnablePrimaryFirst() {
device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") 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( assertState(
primaryInstalled = true, primaryEnabled = false, primaryInstalled = true, primaryEnabled = true,
secondaryInstalled = true, secondaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true,
// If any user is enabled when uninstalling updates, /data is re-uncompressed // If any user is enabled when uninstalling updates, /data is re-uncompressed
codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM)
) )
toggleEnabled(false, User.PRIMARY)
toggleEnabled(true, User.PRIMARY) toggleEnabled(true, User.PRIMARY)
assertState( assertState(
@@ -379,14 +378,15 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
fun uninstallUpdatesAndEnableSecondaryFirst() { fun uninstallUpdatesAndEnableSecondaryFirst() {
device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME")
// Uninstall-system-updates always disables system user 0
assertState( assertState(
primaryInstalled = true, primaryEnabled = false, primaryInstalled = true, primaryEnabled = true,
secondaryInstalled = true, secondaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true,
// If any user is enabled when uninstalling updates, /data is re-uncompressed // If any user is enabled when uninstalling updates, /data is re-uncompressed
codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM)
) )
toggleEnabled(false, User.PRIMARY)
toggleEnabled(true, User.SECONDARY) toggleEnabled(true, User.SECONDARY)
assertState( assertState(
@@ -417,6 +417,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
codePaths = listOf(CodePath.SYSTEM) codePaths = listOf(CodePath.SYSTEM)
) )
toggleEnabled(false, User.PRIMARY)
toggleEnabled(true, User.PRIMARY) toggleEnabled(true, User.PRIMARY)
assertState( assertState(
@@ -447,6 +448,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
codePaths = listOf(CodePath.SYSTEM) codePaths = listOf(CodePath.SYSTEM)
) )
toggleEnabled(false, User.PRIMARY)
toggleEnabled(true, User.SECONDARY) toggleEnabled(true, User.SECONDARY)
assertState( assertState(
@@ -471,13 +473,13 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME")
// Uninstall-system-updates always disables system user 0
assertState( assertState(
primaryInstalled = false, primaryEnabled = false, primaryInstalled = false, primaryEnabled = true,
secondaryInstalled = false, secondaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true,
codePaths = listOf(CodePath.SYSTEM) codePaths = listOf(CodePath.SYSTEM)
) )
toggleEnabled(false, User.PRIMARY)
toggleEnabled(true, User.PRIMARY) toggleEnabled(true, User.PRIMARY)
assertState( assertState(
@@ -502,9 +504,8 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME")
// Uninstall-system-updates always disables system user 0
assertState( assertState(
primaryInstalled = false, primaryEnabled = false, primaryInstalled = false, primaryEnabled = true,
secondaryInstalled = false, secondaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true,
codePaths = listOf(CodePath.SYSTEM) codePaths = listOf(CodePath.SYSTEM)
) )
@@ -512,7 +513,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
toggleEnabled(true, User.SECONDARY) toggleEnabled(true, User.SECONDARY)
assertState( assertState(
primaryInstalled = false, primaryEnabled = false, primaryInstalled = false, primaryEnabled = true,
secondaryInstalled = false, secondaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true,
codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM)
) )
@@ -582,6 +583,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
codePaths: List<CodePath> codePaths: List<CodePath>
) { ) {
HostUtils.getUserIdToPkgInstalledState(device, TEST_PKG_NAME) HostUtils.getUserIdToPkgInstalledState(device, TEST_PKG_NAME)
.also { assertThat(it.size).isAtLeast(USER_COUNT) }
.forEach { (userId, installed) -> .forEach { (userId, installed) ->
if (userId == 0) { if (userId == 0) {
assertThat(installed).isEqualTo(primaryInstalled) assertThat(installed).isEqualTo(primaryInstalled)
@@ -591,6 +593,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() {
} }
HostUtils.getUserIdToPkgEnabledState(device, TEST_PKG_NAME) HostUtils.getUserIdToPkgEnabledState(device, TEST_PKG_NAME)
.also { assertThat(it.size).isAtLeast(USER_COUNT) }
.forEach { (userId, enabled) -> .forEach { (userId, enabled) ->
if (userId == 0) { if (userId == 0) {
assertThat(enabled).isEqualTo(primaryEnabled) assertThat(enabled).isEqualTo(primaryEnabled)