Loading services/core/java/com/android/server/rollback/Rollback.java +39 −1 Original line number Diff line number Diff line Loading @@ -178,6 +178,13 @@ class Rollback { @GuardedBy("mLock") private final IntArray mTokens = new IntArray(); /** * Session ids for all packages in the install. For multi-package sessions, this is the list * of child session ids. For normal sessions, this list is a single element with the normal * session id. */ private final int[] mPackageSessionIds; /** * Constructs a new, empty Rollback instance. * Loading @@ -186,9 +193,10 @@ class Rollback { * @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. * @param packageSessionIds the session ids for all packages in the install. */ Rollback(int rollbackId, File backupDir, int stagedSessionId, int userId, String installerPackageName) { String installerPackageName, int[] packageSessionIds) { this.info = new RollbackInfo(rollbackId, /* packages */ new ArrayList<>(), /* isStaged */ stagedSessionId != -1, Loading @@ -200,6 +208,12 @@ class Rollback { mStagedSessionId = stagedSessionId; mState = ROLLBACK_STATE_ENABLING; mTimestamp = Instant.now(); mPackageSessionIds = packageSessionIds != null ? packageSessionIds : new int[0]; } Rollback(int rollbackId, File backupDir, int stagedSessionId, int userId, String installerPackageName) { this(rollbackId, backupDir, stagedSessionId, userId, installerPackageName, null); } /** Loading @@ -217,6 +231,11 @@ class Rollback { mState = state; mApkSessionId = apkSessionId; mRestoreUserDataInProgress = restoreUserDataInProgress; // TODO(b/120200473): Include this field during persistence. This field will be used to // decide which rollback to expire when ACTION_PACKAGE_REPLACED is received. Note persisting // this field is not backward compatible. We won't fix b/120200473 until S to minimize the // impact. mPackageSessionIds = new int[0]; } /** Loading Loading @@ -793,6 +812,25 @@ class Rollback { } } /** * Returns true if this rollback contains the provided {@code packageSessionId}. */ boolean containsSessionId(int packageSessionId) { for (int id : mPackageSessionIds) { if (id == packageSessionId) { return true; } } return false; } /** * Returns the number of package session ids in this rollback. */ int getPackageSessionIdCount() { return mPackageSessionIds.length; } static String rollbackStateToString(@RollbackState int state) { switch (state) { case Rollback.ROLLBACK_STATE_ENABLING: return "enabling"; Loading services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +14 −40 Original line number Diff line number Diff line Loading @@ -1238,7 +1238,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { // equal to the number of sessions we are installing, to ensure we didn't skip enabling // of any sessions. If we successfully enable an apex, then we can assume we enabled // rollback for the embedded apk-in-apex, if any. if (rollback.getPackageCount(0 /*flags*/) != newRollback.getPackageSessionIdCount()) { // TODO: add a helper instead of exposing 2 methods from Rollback if (rollback.getPackageCount(0 /*flags*/) != rollback.getPackageSessionIdCount()) { Slog.e(TAG, "Failed to enable rollback for all packages in session."); rollback.delete(mAppDataRollbackHelper); return null; Loading Loading @@ -1342,13 +1343,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { private static class NewRollback { public final Rollback rollback; /** * Session ids for all packages in the install. For multi-package sessions, this is the list * of child session ids. For normal sessions, this list is a single element with the normal * session id. */ private final int[] mPackageSessionIds; /** * The number of sessions in the install which are notified with success by * {@link PackageInstaller.SessionCallback#onFinished(int, boolean)}. Loading @@ -1359,28 +1353,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { private final Object mNewRollbackLock = new Object(); NewRollback(Rollback rollback, int[] packageSessionIds) { NewRollback(Rollback rollback) { this.rollback = rollback; this.mPackageSessionIds = packageSessionIds; } /** * Returns true if this NewRollback contains the provided {@code packageSessionId}. */ boolean containsSessionId(int packageSessionId) { for (int id : mPackageSessionIds) { if (id == packageSessionId) { return true; } } return false; } /** * Returns the number of package session ids in this NewRollback. */ int getPackageSessionIdCount() { return mPackageSessionIds.length; } /** Loading @@ -1390,7 +1364,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { */ boolean notifySessionWithSuccess() { synchronized (mNewRollbackLock) { return ++mNumPackageSessionsWithSuccess == mPackageSessionIds.length; return ++mNumPackageSessionsWithSuccess == rollback.getPackageSessionIdCount(); } } } Loading @@ -1414,14 +1388,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { + " user=" + userId + " installer=" + installerPackageName); } if (parentSession.isStaged()) { rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId, userId, installerPackageName); } else { rollback = mRollbackStore.createNonStagedRollback(rollbackId, userId, installerPackageName); } int[] packageSessionIds; if (parentSession.isMultiPackage()) { packageSessionIds = parentSession.getChildSessionIds(); Loading @@ -1429,7 +1395,15 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { packageSessionIds = new int[]{parentSessionId}; } return new NewRollback(rollback, packageSessionIds); if (parentSession.isStaged()) { rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId, userId, installerPackageName, packageSessionIds); } else { rollback = mRollbackStore.createNonStagedRollback(rollbackId, userId, installerPackageName, packageSessionIds); } return new NewRollback(rollback); } /** Loading @@ -1443,7 +1417,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { // We expect mNewRollbacks to be a very small list; linear search // should be plenty fast. for (NewRollback newRollback: mNewRollbacks) { if (newRollback.containsSessionId(packageSessionId)) { if (newRollback.rollback.containsSessionId(packageSessionId)) { return newRollback; } } Loading services/core/java/com/android/server/rollback/RollbackStore.java +18 −0 Original line number Diff line number Diff line Loading @@ -204,6 +204,13 @@ class RollbackStore { return new Rollback(rollbackId, backupDir, -1, userId, installerPackageName); } Rollback createNonStagedRollback(int rollbackId, int userId, String installerPackageName, int[] packageSessionIds) { File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); return new Rollback(rollbackId, backupDir, -1, userId, installerPackageName, packageSessionIds); } /** * Creates a new Rollback instance for a staged rollback with * backupDir assigned. Loading @@ -214,6 +221,17 @@ class RollbackStore { return new Rollback(rollbackId, backupDir, stagedSessionId, userId, installerPackageName); } /** * TODO: Now we have 4 factory methods for creating Rollback objects which is verbose and * cumbersome. Need to merge them for simplicity. */ Rollback createStagedRollback(int rollbackId, int stagedSessionId, int userId, String installerPackageName, int[] packageSessionIds) { File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); return new Rollback(rollbackId, backupDir, stagedSessionId, userId, installerPackageName, packageSessionIds); } /** * Creates a backup copy of an apk or apex for a package. * For packages containing splits, this method should be called for each Loading Loading
services/core/java/com/android/server/rollback/Rollback.java +39 −1 Original line number Diff line number Diff line Loading @@ -178,6 +178,13 @@ class Rollback { @GuardedBy("mLock") private final IntArray mTokens = new IntArray(); /** * Session ids for all packages in the install. For multi-package sessions, this is the list * of child session ids. For normal sessions, this list is a single element with the normal * session id. */ private final int[] mPackageSessionIds; /** * Constructs a new, empty Rollback instance. * Loading @@ -186,9 +193,10 @@ class Rollback { * @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. * @param packageSessionIds the session ids for all packages in the install. */ Rollback(int rollbackId, File backupDir, int stagedSessionId, int userId, String installerPackageName) { String installerPackageName, int[] packageSessionIds) { this.info = new RollbackInfo(rollbackId, /* packages */ new ArrayList<>(), /* isStaged */ stagedSessionId != -1, Loading @@ -200,6 +208,12 @@ class Rollback { mStagedSessionId = stagedSessionId; mState = ROLLBACK_STATE_ENABLING; mTimestamp = Instant.now(); mPackageSessionIds = packageSessionIds != null ? packageSessionIds : new int[0]; } Rollback(int rollbackId, File backupDir, int stagedSessionId, int userId, String installerPackageName) { this(rollbackId, backupDir, stagedSessionId, userId, installerPackageName, null); } /** Loading @@ -217,6 +231,11 @@ class Rollback { mState = state; mApkSessionId = apkSessionId; mRestoreUserDataInProgress = restoreUserDataInProgress; // TODO(b/120200473): Include this field during persistence. This field will be used to // decide which rollback to expire when ACTION_PACKAGE_REPLACED is received. Note persisting // this field is not backward compatible. We won't fix b/120200473 until S to minimize the // impact. mPackageSessionIds = new int[0]; } /** Loading Loading @@ -793,6 +812,25 @@ class Rollback { } } /** * Returns true if this rollback contains the provided {@code packageSessionId}. */ boolean containsSessionId(int packageSessionId) { for (int id : mPackageSessionIds) { if (id == packageSessionId) { return true; } } return false; } /** * Returns the number of package session ids in this rollback. */ int getPackageSessionIdCount() { return mPackageSessionIds.length; } static String rollbackStateToString(@RollbackState int state) { switch (state) { case Rollback.ROLLBACK_STATE_ENABLING: return "enabling"; Loading
services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +14 −40 Original line number Diff line number Diff line Loading @@ -1238,7 +1238,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { // equal to the number of sessions we are installing, to ensure we didn't skip enabling // of any sessions. If we successfully enable an apex, then we can assume we enabled // rollback for the embedded apk-in-apex, if any. if (rollback.getPackageCount(0 /*flags*/) != newRollback.getPackageSessionIdCount()) { // TODO: add a helper instead of exposing 2 methods from Rollback if (rollback.getPackageCount(0 /*flags*/) != rollback.getPackageSessionIdCount()) { Slog.e(TAG, "Failed to enable rollback for all packages in session."); rollback.delete(mAppDataRollbackHelper); return null; Loading Loading @@ -1342,13 +1343,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { private static class NewRollback { public final Rollback rollback; /** * Session ids for all packages in the install. For multi-package sessions, this is the list * of child session ids. For normal sessions, this list is a single element with the normal * session id. */ private final int[] mPackageSessionIds; /** * The number of sessions in the install which are notified with success by * {@link PackageInstaller.SessionCallback#onFinished(int, boolean)}. Loading @@ -1359,28 +1353,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { private final Object mNewRollbackLock = new Object(); NewRollback(Rollback rollback, int[] packageSessionIds) { NewRollback(Rollback rollback) { this.rollback = rollback; this.mPackageSessionIds = packageSessionIds; } /** * Returns true if this NewRollback contains the provided {@code packageSessionId}. */ boolean containsSessionId(int packageSessionId) { for (int id : mPackageSessionIds) { if (id == packageSessionId) { return true; } } return false; } /** * Returns the number of package session ids in this NewRollback. */ int getPackageSessionIdCount() { return mPackageSessionIds.length; } /** Loading @@ -1390,7 +1364,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { */ boolean notifySessionWithSuccess() { synchronized (mNewRollbackLock) { return ++mNumPackageSessionsWithSuccess == mPackageSessionIds.length; return ++mNumPackageSessionsWithSuccess == rollback.getPackageSessionIdCount(); } } } Loading @@ -1414,14 +1388,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { + " user=" + userId + " installer=" + installerPackageName); } if (parentSession.isStaged()) { rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId, userId, installerPackageName); } else { rollback = mRollbackStore.createNonStagedRollback(rollbackId, userId, installerPackageName); } int[] packageSessionIds; if (parentSession.isMultiPackage()) { packageSessionIds = parentSession.getChildSessionIds(); Loading @@ -1429,7 +1395,15 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { packageSessionIds = new int[]{parentSessionId}; } return new NewRollback(rollback, packageSessionIds); if (parentSession.isStaged()) { rollback = mRollbackStore.createStagedRollback(rollbackId, parentSessionId, userId, installerPackageName, packageSessionIds); } else { rollback = mRollbackStore.createNonStagedRollback(rollbackId, userId, installerPackageName, packageSessionIds); } return new NewRollback(rollback); } /** Loading @@ -1443,7 +1417,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { // We expect mNewRollbacks to be a very small list; linear search // should be plenty fast. for (NewRollback newRollback: mNewRollbacks) { if (newRollback.containsSessionId(packageSessionId)) { if (newRollback.rollback.containsSessionId(packageSessionId)) { return newRollback; } } Loading
services/core/java/com/android/server/rollback/RollbackStore.java +18 −0 Original line number Diff line number Diff line Loading @@ -204,6 +204,13 @@ class RollbackStore { return new Rollback(rollbackId, backupDir, -1, userId, installerPackageName); } Rollback createNonStagedRollback(int rollbackId, int userId, String installerPackageName, int[] packageSessionIds) { File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); return new Rollback(rollbackId, backupDir, -1, userId, installerPackageName, packageSessionIds); } /** * Creates a new Rollback instance for a staged rollback with * backupDir assigned. Loading @@ -214,6 +221,17 @@ class RollbackStore { return new Rollback(rollbackId, backupDir, stagedSessionId, userId, installerPackageName); } /** * TODO: Now we have 4 factory methods for creating Rollback objects which is verbose and * cumbersome. Need to merge them for simplicity. */ Rollback createStagedRollback(int rollbackId, int stagedSessionId, int userId, String installerPackageName, int[] packageSessionIds) { File backupDir = new File(mRollbackDataDir, Integer.toString(rollbackId)); return new Rollback(rollbackId, backupDir, stagedSessionId, userId, installerPackageName, packageSessionIds); } /** * Creates a backup copy of an apk or apex for a package. * For packages containing splits, this method should be called for each Loading