Loading services/core/java/com/android/server/rollback/Rollback.java +51 −12 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.server.rollback.RollbackManagerServiceImpl.sendFailure import android.Manifest; import android.Manifest; import android.annotation.IntDef; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentSender; import android.content.IntentSender; Loading @@ -33,7 +34,9 @@ import android.content.rollback.RollbackInfo; import android.content.rollback.RollbackManager; import android.content.rollback.RollbackManager; import android.os.Binder; import android.os.Binder; import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManager; import android.text.TextUtils; import android.util.IntArray; import android.util.IntArray; import android.util.Slog; import android.util.Slog; import android.util.SparseLongArray; import android.util.SparseLongArray; Loading Loading @@ -141,19 +144,38 @@ class Rollback { */ */ private final Object mLock = new Object(); private final Object mLock = new Object(); /** * The user that performed the install with rollback enabled. */ public final int mUserId; /** * The installer package name from the install session that enabled the rollback. May be null if * that session did not set this value. * * If this is an empty string then the installer package name will be resolved by * PackageManager. */ @Nullable public final String mInstallerPackageName; /** /** * Constructs a new, empty Rollback instance. * Constructs a new, empty Rollback instance. * * * @param rollbackId the id of the rollback. * @param rollbackId the id of the rollback. * @param backupDir the directory where the rollback data is stored. * @param backupDir the directory where the rollback data is stored. * @param stagedSessionId the session id if this is a staged rollback, -1 otherwise. * @param stagedSessionId the session id if this is a staged rollback, -1 otherwise. * @param userId the user that performed the install with rollback enabled. * @param installerPackageName the installer package name from the original install session. */ */ Rollback(int rollbackId, File backupDir, int stagedSessionId) { Rollback(int rollbackId, File backupDir, int stagedSessionId, int userId, String installerPackageName) { this.info = new RollbackInfo(rollbackId, this.info = new RollbackInfo(rollbackId, /* packages */ new ArrayList<>(), /* packages */ new ArrayList<>(), /* isStaged */ stagedSessionId != -1, /* isStaged */ stagedSessionId != -1, /* causePackages */ new ArrayList<>(), /* causePackages */ new ArrayList<>(), /* committedSessionId */ -1); /* committedSessionId */ -1); mUserId = userId; mInstallerPackageName = installerPackageName; mBackupDir = backupDir; mBackupDir = backupDir; mStagedSessionId = stagedSessionId; mStagedSessionId = stagedSessionId; mState = ROLLBACK_STATE_ENABLING; mState = ROLLBACK_STATE_ENABLING; Loading @@ -164,8 +186,11 @@ class Rollback { * Constructs a pre-populated Rollback instance. * Constructs a pre-populated Rollback instance. */ */ Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId, Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId, @RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress) { @RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress, int userId, String installerPackageName) { this.info = info; this.info = info; mUserId = userId; mInstallerPackageName = installerPackageName; mBackupDir = backupDir; mBackupDir = backupDir; mTimestamp = timestamp; mTimestamp = timestamp; mStagedSessionId = stagedSessionId; mStagedSessionId = stagedSessionId; Loading Loading @@ -215,6 +240,21 @@ class Rollback { return mStagedSessionId; return mStagedSessionId; } } /** * Returns the ID of the user that performed the install with rollback enabled. */ int getUserId() { return mUserId; } /** * Returns the installer package name from the install session that enabled the rollback. In the * case that this is called on a rollback from an older version, returns the empty string. */ @Nullable String getInstallerPackageName() { return mInstallerPackageName; } /** /** * Returns true if the rollback is in the ENABLING state. * Returns true if the rollback is in the ENABLING state. */ */ Loading Loading @@ -360,7 +400,8 @@ class Rollback { // Get a context to use to install the downgraded version of the package. // Get a context to use to install the downgraded version of the package. Context pkgContext; Context pkgContext; try { try { pkgContext = context.createPackageContext(callerPackageName, 0); pkgContext = context.createPackageContextAsUser(callerPackageName, 0, UserHandle.of(mUserId)); } catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) { sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, "Invalid callerPackageName"); "Invalid callerPackageName"); Loading @@ -385,16 +426,14 @@ class Rollback { for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( PackageInstaller.SessionParams.MODE_FULL_INSTALL); PackageInstaller.SessionParams.MODE_FULL_INSTALL); // TODO: We can't get the installerPackageName for apex String installerPackageName = mInstallerPackageName; // (b/123920130). Is it okay to ignore the installer package if (TextUtils.isEmpty(mInstallerPackageName)) { // for apex? installerPackageName = pm.getInstallerPackageName( if (!pkgRollbackInfo.isApex()) { pkgRollbackInfo.getPackageName()); String installerPackageName = } pm.getInstallerPackageName(pkgRollbackInfo.getPackageName()); if (installerPackageName != null) { if (installerPackageName != null) { params.setInstallerPackageName(installerPackageName); params.setInstallerPackageName(installerPackageName); } } } params.setRequestDowngrade(true); params.setRequestDowngrade(true); params.setRequiredInstalledVersionCode( params.setRequiredInstalledVersionCode( pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode()); pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode()); Loading services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +11 −2 Original line number Original line Diff line number Diff line Loading @@ -1248,13 +1248,22 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { @GuardedBy("mLock") @GuardedBy("mLock") private NewRollback createNewRollbackLocked(PackageInstaller.SessionInfo parentSession) { private NewRollback createNewRollbackLocked(PackageInstaller.SessionInfo parentSession) { int rollbackId = allocateRollbackIdLocked(); int rollbackId = allocateRollbackIdLocked(); final int userId; if (parentSession.getUser() == UserHandle.ALL) { userId = UserHandle.USER_SYSTEM; } else { userId = parentSession.getUser().getIdentifier(); } String installerPackageName = parentSession.getInstallerPackageName(); final Rollback rollback; final Rollback rollback; int parentSessionId = parentSession.getSessionId(); int parentSessionId = parentSession.getSessionId(); if (parentSession.isStaged()) { if (parentSession.isStaged()) { rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId); rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId, userId, installerPackageName); } else { } else { rollback = mRollbackStore.createNonStagedRollback(rollbackId); rollback = mRollbackStore.createNonStagedRollback(rollbackId, userId, installerPackageName); } } int[] packageSessionIds; int[] packageSessionIds; Loading services/core/java/com/android/server/rollback/RollbackStore.java +12 −5 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.rollback; package com.android.server.rollback; import static android.os.UserHandle.USER_SYSTEM; import static com.android.server.rollback.Rollback.rollbackStateFromString; import static com.android.server.rollback.Rollback.rollbackStateFromString; import android.annotation.NonNull; import android.annotation.NonNull; Loading Loading @@ -196,18 +198,19 @@ class RollbackStore { * Creates a new Rollback instance for a non-staged rollback with * Creates a new Rollback instance for a non-staged rollback with * backupDir assigned. * backupDir assigned. */ */ Rollback createNonStagedRollback(int rollbackId) { Rollback createNonStagedRollback(int rollbackId, int userId, String installerPackageName) { File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); return new Rollback(rollbackId, backupDir, -1); return new Rollback(rollbackId, backupDir, -1, userId, installerPackageName); } } /** /** * Creates a new Rollback instance for a staged rollback with * Creates a new Rollback instance for a staged rollback with * backupDir assigned. * backupDir assigned. */ */ Rollback createStagedRollback(int rollbackId, int stagedSessionId) { Rollback createStagedRollback(int rollbackId, int stagedSessionId, int userId, String installerPackageName) { File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); return new Rollback(rollbackId, backupDir, stagedSessionId); return new Rollback(rollbackId, backupDir, stagedSessionId, userId, installerPackageName); } } /** /** Loading Loading @@ -263,6 +266,8 @@ class RollbackStore { dataJson.put("state", rollback.getStateAsString()); dataJson.put("state", rollback.getStateAsString()); dataJson.put("apkSessionId", rollback.getApkSessionId()); dataJson.put("apkSessionId", rollback.getApkSessionId()); dataJson.put("restoreUserDataInProgress", rollback.isRestoreUserDataInProgress()); dataJson.put("restoreUserDataInProgress", rollback.isRestoreUserDataInProgress()); dataJson.put("userId", rollback.getUserId()); dataJson.putOpt("installerPackageName", rollback.getInstallerPackageName()); PrintWriter pw = new PrintWriter(new File(rollback.getBackupDir(), "rollback.json")); PrintWriter pw = new PrintWriter(new File(rollback.getBackupDir(), "rollback.json")); pw.println(dataJson.toString()); pw.println(dataJson.toString()); Loading Loading @@ -305,7 +310,9 @@ class RollbackStore { dataJson.getInt("stagedSessionId"), dataJson.getInt("stagedSessionId"), rollbackStateFromString(dataJson.getString("state")), rollbackStateFromString(dataJson.getString("state")), dataJson.getInt("apkSessionId"), dataJson.getInt("apkSessionId"), dataJson.getBoolean("restoreUserDataInProgress")); dataJson.getBoolean("restoreUserDataInProgress"), dataJson.optInt("userId", USER_SYSTEM), dataJson.optString("installerPackageName", "")); } } private static JSONObject toJson(VersionedPackage pkg) throws JSONException { private static JSONObject toJson(VersionedPackage pkg) throws JSONException { Loading services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java +9 −6 Original line number Original line Diff line number Diff line Loading @@ -106,6 +106,11 @@ public class AppDataRollbackHelperTest { return createPackageRollbackInfo(packageName, new int[] {}); return createPackageRollbackInfo(packageName, new int[] {}); } } private static Rollback createRollbackForId(int rollbackId) { return new Rollback(rollbackId, new File("/does/not/exist"), -1, 0, "com.xyz"); } @Test @Test public void testRestoreAppDataSnapshot_pendingBackupForUser() throws Exception { public void testRestoreAppDataSnapshot_pendingBackupForUser() throws Exception { Installer installer = mock(Installer.class); Installer installer = mock(Installer.class); Loading Loading @@ -232,18 +237,16 @@ public class AppDataRollbackHelperTest { wasRecentlyRestored.getPendingRestores().add( wasRecentlyRestored.getPendingRestores().add( new RestoreInfo(73 /* userId */, 239 /* appId*/, "seInfo")); new RestoreInfo(73 /* userId */, 239 /* appId*/, "seInfo")); Rollback dataWithPendingBackup = new Rollback(101, new File("/does/not/exist"), -1); Rollback dataWithPendingBackup = createRollbackForId(101); dataWithPendingBackup.info.getPackages().add(pendingBackup); dataWithPendingBackup.info.getPackages().add(pendingBackup); Rollback dataWithRecentRestore = new Rollback(17239, new File("/does/not/exist"), Rollback dataWithRecentRestore = createRollbackForId(17239); -1); dataWithRecentRestore.info.getPackages().add(wasRecentlyRestored); dataWithRecentRestore.info.getPackages().add(wasRecentlyRestored); Rollback dataForDifferentUser = new Rollback(17239, new File("/does/not/exist"), Rollback dataForDifferentUser = createRollbackForId(17239); -1); dataForDifferentUser.info.getPackages().add(ignoredInfo); dataForDifferentUser.info.getPackages().add(ignoredInfo); Rollback dataForRestore = new Rollback(17239, new File("/does/not/exist"), -1); Rollback dataForRestore = createRollbackForId(17239); dataForRestore.info.getPackages().add(pendingRestore); dataForRestore.info.getPackages().add(pendingRestore); dataForRestore.info.getPackages().add(wasRecentlyRestored); dataForRestore.info.getPackages().add(wasRecentlyRestored); Loading services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java +12 −6 Original line number Original line Diff line number Diff line Loading @@ -43,6 +43,8 @@ import java.util.Objects; public class RollbackStoreTest { public class RollbackStoreTest { private static final int ID = 123; private static final int ID = 123; private static final int USER = 0; private static final String INSTALLER = "some.installer"; private static final Correspondence<VersionedPackage, VersionedPackage> VER_PKG_CORR = private static final Correspondence<VersionedPackage, VersionedPackage> VER_PKG_CORR = new Correspondence<VersionedPackage, VersionedPackage>() { new Correspondence<VersionedPackage, VersionedPackage>() { Loading Loading @@ -97,7 +99,8 @@ public class RollbackStoreTest { + "'longVersionCode':23},{'packageName':'something','longVersionCode':999}]," + "'longVersionCode':23},{'packageName':'something','longVersionCode':999}]," + "'committedSessionId':45654465},'timestamp':'2019-10-01T12:29:08.855Z'," + "'committedSessionId':45654465},'timestamp':'2019-10-01T12:29:08.855Z'," + "'stagedSessionId':-1,'state':'enabling','apkSessionId':-1," + "'stagedSessionId':-1,'state':'enabling','apkSessionId':-1," + "'restoreUserDataInProgress':true}"; + "'restoreUserDataInProgress':true, 'userId':0," + "'installerPackageName':'some.installer'}"; @Rule @Rule public TemporaryFolder mFolder = new TemporaryFolder(); public TemporaryFolder mFolder = new TemporaryFolder(); Loading @@ -115,7 +118,7 @@ public class RollbackStoreTest { @Test @Test public void createNonStaged() { public void createNonStaged() { Rollback rollback = mRollbackStore.createNonStagedRollback(ID); Rollback rollback = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER); assertThat(rollback.getBackupDir().getAbsolutePath()) assertThat(rollback.getBackupDir().getAbsolutePath()) .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID); .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID); Loading @@ -128,7 +131,7 @@ public class RollbackStoreTest { @Test @Test public void createStaged() { public void createStaged() { Rollback rollback = mRollbackStore.createStagedRollback(ID, 897); Rollback rollback = mRollbackStore.createStagedRollback(ID, 897, USER, INSTALLER); assertThat(rollback.getBackupDir().getAbsolutePath()) assertThat(rollback.getBackupDir().getAbsolutePath()) .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID); .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID); Loading @@ -143,7 +146,7 @@ public class RollbackStoreTest { @Test @Test public void saveAndLoadRollback() { public void saveAndLoadRollback() { Rollback origRb = mRollbackStore.createNonStagedRollback(ID); Rollback origRb = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER); origRb.setRestoreUserDataInProgress(true); origRb.setRestoreUserDataInProgress(true); origRb.info.getCausePackages().add(new VersionedPackage("com.made.up", 2)); origRb.info.getCausePackages().add(new VersionedPackage("com.made.up", 2)); Loading Loading @@ -193,7 +196,7 @@ public class RollbackStoreTest { @Test @Test public void loadFromJson() throws Exception { public void loadFromJson() throws Exception { Rollback expectedRb = mRollbackStore.createNonStagedRollback(ID); Rollback expectedRb = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER); expectedRb.setTimestamp(Instant.parse("2019-10-01T12:29:08.855Z")); expectedRb.setTimestamp(Instant.parse("2019-10-01T12:29:08.855Z")); expectedRb.setRestoreUserDataInProgress(true); expectedRb.setRestoreUserDataInProgress(true); Loading Loading @@ -242,7 +245,7 @@ public class RollbackStoreTest { @Test @Test public void saveAndDelete() { public void saveAndDelete() { Rollback rollback = mRollbackStore.createNonStagedRollback(ID); Rollback rollback = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER); RollbackStore.saveRollback(rollback); RollbackStore.saveRollback(rollback); Loading Loading @@ -287,6 +290,9 @@ public class RollbackStoreTest { assertPackageRollbacksAreEquivalent( assertPackageRollbacksAreEquivalent( b.info.getPackages().get(i), a.info.getPackages().get(i)); b.info.getPackages().get(i), a.info.getPackages().get(i)); } } assertThat(a.getUserId()).isEqualTo(b.getUserId()); assertThat(a.getInstallerPackageName()).isEqualTo(b.getInstallerPackageName()); } } private void assertPackageRollbacksAreEquivalent(PackageRollbackInfo b, PackageRollbackInfo a) { private void assertPackageRollbacksAreEquivalent(PackageRollbackInfo b, PackageRollbackInfo a) { Loading Loading
services/core/java/com/android/server/rollback/Rollback.java +51 −12 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.server.rollback.RollbackManagerServiceImpl.sendFailure import android.Manifest; import android.Manifest; import android.annotation.IntDef; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentSender; import android.content.IntentSender; Loading @@ -33,7 +34,9 @@ import android.content.rollback.RollbackInfo; import android.content.rollback.RollbackManager; import android.content.rollback.RollbackManager; import android.os.Binder; import android.os.Binder; import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManager; import android.text.TextUtils; import android.util.IntArray; import android.util.IntArray; import android.util.Slog; import android.util.Slog; import android.util.SparseLongArray; import android.util.SparseLongArray; Loading Loading @@ -141,19 +144,38 @@ class Rollback { */ */ private final Object mLock = new Object(); private final Object mLock = new Object(); /** * The user that performed the install with rollback enabled. */ public final int mUserId; /** * The installer package name from the install session that enabled the rollback. May be null if * that session did not set this value. * * If this is an empty string then the installer package name will be resolved by * PackageManager. */ @Nullable public final String mInstallerPackageName; /** /** * Constructs a new, empty Rollback instance. * Constructs a new, empty Rollback instance. * * * @param rollbackId the id of the rollback. * @param rollbackId the id of the rollback. * @param backupDir the directory where the rollback data is stored. * @param backupDir the directory where the rollback data is stored. * @param stagedSessionId the session id if this is a staged rollback, -1 otherwise. * @param stagedSessionId the session id if this is a staged rollback, -1 otherwise. * @param userId the user that performed the install with rollback enabled. * @param installerPackageName the installer package name from the original install session. */ */ Rollback(int rollbackId, File backupDir, int stagedSessionId) { Rollback(int rollbackId, File backupDir, int stagedSessionId, int userId, String installerPackageName) { this.info = new RollbackInfo(rollbackId, this.info = new RollbackInfo(rollbackId, /* packages */ new ArrayList<>(), /* packages */ new ArrayList<>(), /* isStaged */ stagedSessionId != -1, /* isStaged */ stagedSessionId != -1, /* causePackages */ new ArrayList<>(), /* causePackages */ new ArrayList<>(), /* committedSessionId */ -1); /* committedSessionId */ -1); mUserId = userId; mInstallerPackageName = installerPackageName; mBackupDir = backupDir; mBackupDir = backupDir; mStagedSessionId = stagedSessionId; mStagedSessionId = stagedSessionId; mState = ROLLBACK_STATE_ENABLING; mState = ROLLBACK_STATE_ENABLING; Loading @@ -164,8 +186,11 @@ class Rollback { * Constructs a pre-populated Rollback instance. * Constructs a pre-populated Rollback instance. */ */ Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId, Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId, @RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress) { @RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress, int userId, String installerPackageName) { this.info = info; this.info = info; mUserId = userId; mInstallerPackageName = installerPackageName; mBackupDir = backupDir; mBackupDir = backupDir; mTimestamp = timestamp; mTimestamp = timestamp; mStagedSessionId = stagedSessionId; mStagedSessionId = stagedSessionId; Loading Loading @@ -215,6 +240,21 @@ class Rollback { return mStagedSessionId; return mStagedSessionId; } } /** * Returns the ID of the user that performed the install with rollback enabled. */ int getUserId() { return mUserId; } /** * Returns the installer package name from the install session that enabled the rollback. In the * case that this is called on a rollback from an older version, returns the empty string. */ @Nullable String getInstallerPackageName() { return mInstallerPackageName; } /** /** * Returns true if the rollback is in the ENABLING state. * Returns true if the rollback is in the ENABLING state. */ */ Loading Loading @@ -360,7 +400,8 @@ class Rollback { // Get a context to use to install the downgraded version of the package. // Get a context to use to install the downgraded version of the package. Context pkgContext; Context pkgContext; try { try { pkgContext = context.createPackageContext(callerPackageName, 0); pkgContext = context.createPackageContextAsUser(callerPackageName, 0, UserHandle.of(mUserId)); } catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) { sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, sendFailure(context, statusReceiver, RollbackManager.STATUS_FAILURE, "Invalid callerPackageName"); "Invalid callerPackageName"); Loading @@ -385,16 +426,14 @@ class Rollback { for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) { PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( PackageInstaller.SessionParams.MODE_FULL_INSTALL); PackageInstaller.SessionParams.MODE_FULL_INSTALL); // TODO: We can't get the installerPackageName for apex String installerPackageName = mInstallerPackageName; // (b/123920130). Is it okay to ignore the installer package if (TextUtils.isEmpty(mInstallerPackageName)) { // for apex? installerPackageName = pm.getInstallerPackageName( if (!pkgRollbackInfo.isApex()) { pkgRollbackInfo.getPackageName()); String installerPackageName = } pm.getInstallerPackageName(pkgRollbackInfo.getPackageName()); if (installerPackageName != null) { if (installerPackageName != null) { params.setInstallerPackageName(installerPackageName); params.setInstallerPackageName(installerPackageName); } } } params.setRequestDowngrade(true); params.setRequestDowngrade(true); params.setRequiredInstalledVersionCode( params.setRequiredInstalledVersionCode( pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode()); pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode()); Loading
services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +11 −2 Original line number Original line Diff line number Diff line Loading @@ -1248,13 +1248,22 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { @GuardedBy("mLock") @GuardedBy("mLock") private NewRollback createNewRollbackLocked(PackageInstaller.SessionInfo parentSession) { private NewRollback createNewRollbackLocked(PackageInstaller.SessionInfo parentSession) { int rollbackId = allocateRollbackIdLocked(); int rollbackId = allocateRollbackIdLocked(); final int userId; if (parentSession.getUser() == UserHandle.ALL) { userId = UserHandle.USER_SYSTEM; } else { userId = parentSession.getUser().getIdentifier(); } String installerPackageName = parentSession.getInstallerPackageName(); final Rollback rollback; final Rollback rollback; int parentSessionId = parentSession.getSessionId(); int parentSessionId = parentSession.getSessionId(); if (parentSession.isStaged()) { if (parentSession.isStaged()) { rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId); rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId, userId, installerPackageName); } else { } else { rollback = mRollbackStore.createNonStagedRollback(rollbackId); rollback = mRollbackStore.createNonStagedRollback(rollbackId, userId, installerPackageName); } } int[] packageSessionIds; int[] packageSessionIds; Loading
services/core/java/com/android/server/rollback/RollbackStore.java +12 −5 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.rollback; package com.android.server.rollback; import static android.os.UserHandle.USER_SYSTEM; import static com.android.server.rollback.Rollback.rollbackStateFromString; import static com.android.server.rollback.Rollback.rollbackStateFromString; import android.annotation.NonNull; import android.annotation.NonNull; Loading Loading @@ -196,18 +198,19 @@ class RollbackStore { * Creates a new Rollback instance for a non-staged rollback with * Creates a new Rollback instance for a non-staged rollback with * backupDir assigned. * backupDir assigned. */ */ Rollback createNonStagedRollback(int rollbackId) { Rollback createNonStagedRollback(int rollbackId, int userId, String installerPackageName) { File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); return new Rollback(rollbackId, backupDir, -1); return new Rollback(rollbackId, backupDir, -1, userId, installerPackageName); } } /** /** * Creates a new Rollback instance for a staged rollback with * Creates a new Rollback instance for a staged rollback with * backupDir assigned. * backupDir assigned. */ */ Rollback createStagedRollback(int rollbackId, int stagedSessionId) { Rollback createStagedRollback(int rollbackId, int stagedSessionId, int userId, String installerPackageName) { File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); return new Rollback(rollbackId, backupDir, stagedSessionId); return new Rollback(rollbackId, backupDir, stagedSessionId, userId, installerPackageName); } } /** /** Loading Loading @@ -263,6 +266,8 @@ class RollbackStore { dataJson.put("state", rollback.getStateAsString()); dataJson.put("state", rollback.getStateAsString()); dataJson.put("apkSessionId", rollback.getApkSessionId()); dataJson.put("apkSessionId", rollback.getApkSessionId()); dataJson.put("restoreUserDataInProgress", rollback.isRestoreUserDataInProgress()); dataJson.put("restoreUserDataInProgress", rollback.isRestoreUserDataInProgress()); dataJson.put("userId", rollback.getUserId()); dataJson.putOpt("installerPackageName", rollback.getInstallerPackageName()); PrintWriter pw = new PrintWriter(new File(rollback.getBackupDir(), "rollback.json")); PrintWriter pw = new PrintWriter(new File(rollback.getBackupDir(), "rollback.json")); pw.println(dataJson.toString()); pw.println(dataJson.toString()); Loading Loading @@ -305,7 +310,9 @@ class RollbackStore { dataJson.getInt("stagedSessionId"), dataJson.getInt("stagedSessionId"), rollbackStateFromString(dataJson.getString("state")), rollbackStateFromString(dataJson.getString("state")), dataJson.getInt("apkSessionId"), dataJson.getInt("apkSessionId"), dataJson.getBoolean("restoreUserDataInProgress")); dataJson.getBoolean("restoreUserDataInProgress"), dataJson.optInt("userId", USER_SYSTEM), dataJson.optString("installerPackageName", "")); } } private static JSONObject toJson(VersionedPackage pkg) throws JSONException { private static JSONObject toJson(VersionedPackage pkg) throws JSONException { Loading
services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java +9 −6 Original line number Original line Diff line number Diff line Loading @@ -106,6 +106,11 @@ public class AppDataRollbackHelperTest { return createPackageRollbackInfo(packageName, new int[] {}); return createPackageRollbackInfo(packageName, new int[] {}); } } private static Rollback createRollbackForId(int rollbackId) { return new Rollback(rollbackId, new File("/does/not/exist"), -1, 0, "com.xyz"); } @Test @Test public void testRestoreAppDataSnapshot_pendingBackupForUser() throws Exception { public void testRestoreAppDataSnapshot_pendingBackupForUser() throws Exception { Installer installer = mock(Installer.class); Installer installer = mock(Installer.class); Loading Loading @@ -232,18 +237,16 @@ public class AppDataRollbackHelperTest { wasRecentlyRestored.getPendingRestores().add( wasRecentlyRestored.getPendingRestores().add( new RestoreInfo(73 /* userId */, 239 /* appId*/, "seInfo")); new RestoreInfo(73 /* userId */, 239 /* appId*/, "seInfo")); Rollback dataWithPendingBackup = new Rollback(101, new File("/does/not/exist"), -1); Rollback dataWithPendingBackup = createRollbackForId(101); dataWithPendingBackup.info.getPackages().add(pendingBackup); dataWithPendingBackup.info.getPackages().add(pendingBackup); Rollback dataWithRecentRestore = new Rollback(17239, new File("/does/not/exist"), Rollback dataWithRecentRestore = createRollbackForId(17239); -1); dataWithRecentRestore.info.getPackages().add(wasRecentlyRestored); dataWithRecentRestore.info.getPackages().add(wasRecentlyRestored); Rollback dataForDifferentUser = new Rollback(17239, new File("/does/not/exist"), Rollback dataForDifferentUser = createRollbackForId(17239); -1); dataForDifferentUser.info.getPackages().add(ignoredInfo); dataForDifferentUser.info.getPackages().add(ignoredInfo); Rollback dataForRestore = new Rollback(17239, new File("/does/not/exist"), -1); Rollback dataForRestore = createRollbackForId(17239); dataForRestore.info.getPackages().add(pendingRestore); dataForRestore.info.getPackages().add(pendingRestore); dataForRestore.info.getPackages().add(wasRecentlyRestored); dataForRestore.info.getPackages().add(wasRecentlyRestored); Loading
services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java +12 −6 Original line number Original line Diff line number Diff line Loading @@ -43,6 +43,8 @@ import java.util.Objects; public class RollbackStoreTest { public class RollbackStoreTest { private static final int ID = 123; private static final int ID = 123; private static final int USER = 0; private static final String INSTALLER = "some.installer"; private static final Correspondence<VersionedPackage, VersionedPackage> VER_PKG_CORR = private static final Correspondence<VersionedPackage, VersionedPackage> VER_PKG_CORR = new Correspondence<VersionedPackage, VersionedPackage>() { new Correspondence<VersionedPackage, VersionedPackage>() { Loading Loading @@ -97,7 +99,8 @@ public class RollbackStoreTest { + "'longVersionCode':23},{'packageName':'something','longVersionCode':999}]," + "'longVersionCode':23},{'packageName':'something','longVersionCode':999}]," + "'committedSessionId':45654465},'timestamp':'2019-10-01T12:29:08.855Z'," + "'committedSessionId':45654465},'timestamp':'2019-10-01T12:29:08.855Z'," + "'stagedSessionId':-1,'state':'enabling','apkSessionId':-1," + "'stagedSessionId':-1,'state':'enabling','apkSessionId':-1," + "'restoreUserDataInProgress':true}"; + "'restoreUserDataInProgress':true, 'userId':0," + "'installerPackageName':'some.installer'}"; @Rule @Rule public TemporaryFolder mFolder = new TemporaryFolder(); public TemporaryFolder mFolder = new TemporaryFolder(); Loading @@ -115,7 +118,7 @@ public class RollbackStoreTest { @Test @Test public void createNonStaged() { public void createNonStaged() { Rollback rollback = mRollbackStore.createNonStagedRollback(ID); Rollback rollback = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER); assertThat(rollback.getBackupDir().getAbsolutePath()) assertThat(rollback.getBackupDir().getAbsolutePath()) .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID); .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID); Loading @@ -128,7 +131,7 @@ public class RollbackStoreTest { @Test @Test public void createStaged() { public void createStaged() { Rollback rollback = mRollbackStore.createStagedRollback(ID, 897); Rollback rollback = mRollbackStore.createStagedRollback(ID, 897, USER, INSTALLER); assertThat(rollback.getBackupDir().getAbsolutePath()) assertThat(rollback.getBackupDir().getAbsolutePath()) .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID); .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID); Loading @@ -143,7 +146,7 @@ public class RollbackStoreTest { @Test @Test public void saveAndLoadRollback() { public void saveAndLoadRollback() { Rollback origRb = mRollbackStore.createNonStagedRollback(ID); Rollback origRb = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER); origRb.setRestoreUserDataInProgress(true); origRb.setRestoreUserDataInProgress(true); origRb.info.getCausePackages().add(new VersionedPackage("com.made.up", 2)); origRb.info.getCausePackages().add(new VersionedPackage("com.made.up", 2)); Loading Loading @@ -193,7 +196,7 @@ public class RollbackStoreTest { @Test @Test public void loadFromJson() throws Exception { public void loadFromJson() throws Exception { Rollback expectedRb = mRollbackStore.createNonStagedRollback(ID); Rollback expectedRb = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER); expectedRb.setTimestamp(Instant.parse("2019-10-01T12:29:08.855Z")); expectedRb.setTimestamp(Instant.parse("2019-10-01T12:29:08.855Z")); expectedRb.setRestoreUserDataInProgress(true); expectedRb.setRestoreUserDataInProgress(true); Loading Loading @@ -242,7 +245,7 @@ public class RollbackStoreTest { @Test @Test public void saveAndDelete() { public void saveAndDelete() { Rollback rollback = mRollbackStore.createNonStagedRollback(ID); Rollback rollback = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER); RollbackStore.saveRollback(rollback); RollbackStore.saveRollback(rollback); Loading Loading @@ -287,6 +290,9 @@ public class RollbackStoreTest { assertPackageRollbacksAreEquivalent( assertPackageRollbacksAreEquivalent( b.info.getPackages().get(i), a.info.getPackages().get(i)); b.info.getPackages().get(i), a.info.getPackages().get(i)); } } assertThat(a.getUserId()).isEqualTo(b.getUserId()); assertThat(a.getInstallerPackageName()).isEqualTo(b.getInstallerPackageName()); } } private void assertPackageRollbacksAreEquivalent(PackageRollbackInfo b, PackageRollbackInfo a) { private void assertPackageRollbacksAreEquivalent(PackageRollbackInfo b, PackageRollbackInfo a) { Loading