Loading core/java/android/content/rollback/IRollbackManager.aidl +2 −2 Original line number Original line Diff line number Diff line Loading @@ -30,9 +30,9 @@ interface IRollbackManager { String callerPackageName, in IntentSender statusReceiver); String callerPackageName, in IntentSender statusReceiver); // Exposed for use from the system server only. Callback from the package // Exposed for use from the system server only. Callback from the package // manager during the install flow when user data can be restored for a given // manager during the install flow when user data can be backed up and restored for a given // package. // package. void restoreUserData(String packageName, in int[] userIds, int appId, long ceDataInode, void snapshotAndRestoreUserData(String packageName, in int[] userIds, int appId, long ceDataInode, String seInfo, int token); String seInfo, int token); // Exposed for test purposes only. // Exposed for test purposes only. Loading services/core/java/com/android/server/pm/PackageManagerService.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -14758,7 +14758,7 @@ public class PackageManagerService extends IPackageManager.Stub if (ps != null) { if (ps != null) { try { try { rm.restoreUserData(packageName, installedUsers, appId, ceDataInode, rm.snapshotAndRestoreUserData(packageName, installedUsers, appId, ceDataInode, seInfo, token); seInfo, token); } catch (RemoteException re) { } catch (RemoteException re) { // Cannot happen, the RollbackManager is hosted in the same process. // Cannot happen, the RollbackManager is hosted in the same process. services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +43 −17 Original line number Original line Diff line number Diff line Loading @@ -923,8 +923,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } } if (rd != null) { if (rd != null) { // This is the apk session for a staged session. We have already // This is the apk session for a staged session. We do not need to create a new rollback // backed up the apks, we just need to do user data backup. // for this session. PackageParser.PackageLite newPackage = null; PackageParser.PackageLite newPackage = null; try { try { newPackage = PackageParser.parsePackageLite( newPackage = PackageParser.parsePackageLite( Loading @@ -937,8 +937,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { for (PackageRollbackInfo info : rd.info.getPackages()) { for (PackageRollbackInfo info : rd.info.getPackages()) { if (info.getPackageName().equals(packageName)) { if (info.getPackageName().equals(packageName)) { info.getInstalledUsers().addAll(IntArray.wrap(installedUsers)); info.getInstalledUsers().addAll(IntArray.wrap(installedUsers)); mAppDataRollbackHelper.snapshotAppData(rd.info.getRollbackId(), info); saveRollbackData(rd); return true; return true; } } } } Loading @@ -959,8 +957,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } } newRollback.addToken(token); newRollback.addToken(token); return enableRollbackForPackageSession(newRollback.data, packageSession, return enableRollbackForPackageSession(newRollback.data, packageSession, installedUsers); installedUsers, /* snapshotUserData*/ true); } } /** /** Loading @@ -971,8 +968,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { * @return true on success, false on failure. * @return true on success, false on failure. */ */ private boolean enableRollbackForPackageSession(RollbackData data, private boolean enableRollbackForPackageSession(RollbackData data, PackageInstaller.SessionInfo session, @NonNull int[] installedUsers, PackageInstaller.SessionInfo session, @NonNull int[] installedUsers) { boolean snapshotUserData) { // TODO: Don't attempt to enable rollback for split installs. // TODO: Don't attempt to enable rollback for split installs. final int installFlags = session.installFlags; final int installFlags = session.installFlags; if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) { if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) { Loading Loading @@ -1033,10 +1029,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { isApex, IntArray.wrap(installedUsers), isApex, IntArray.wrap(installedUsers), new SparseLongArray() /* ceSnapshotInodes */); new SparseLongArray() /* ceSnapshotInodes */); if (snapshotUserData && !isApex) { mAppDataRollbackHelper.snapshotAppData(data.info.getRollbackId(), packageRollbackInfo); } try { try { ApplicationInfo appInfo = pkgInfo.applicationInfo; ApplicationInfo appInfo = pkgInfo.applicationInfo; RollbackStore.backupPackageCodePath(data, packageName, appInfo.sourceDir); RollbackStore.backupPackageCodePath(data, packageName, appInfo.sourceDir); Loading @@ -1057,13 +1049,15 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } } @Override @Override public void restoreUserData(String packageName, int[] userIds, int appId, long ceDataInode, public void snapshotAndRestoreUserData(String packageName, int[] userIds, int appId, String seInfo, int token) { long ceDataInode, String seInfo, int token) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("restoreUserData may only be called by the system."); throw new SecurityException( "snapshotAndRestoreUserData may only be called by the system."); } } getHandler().post(() -> { getHandler().post(() -> { snapshotUserDataInternal(packageName); restoreUserDataInternal(packageName, userIds, appId, ceDataInode, seInfo, token); restoreUserDataInternal(packageName, userIds, appId, ceDataInode, seInfo, token); final PackageManagerInternal pmi = LocalServices.getService( final PackageManagerInternal pmi = LocalServices.getService( PackageManagerInternal.class); PackageManagerInternal.class); Loading @@ -1071,6 +1065,38 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { }); }); } } private void snapshotUserDataInternal(String packageName) { synchronized (mLock) { // staged installs ensureRollbackDataLoadedLocked(); for (int i = 0; i < mRollbacks.size(); i++) { RollbackData data = mRollbacks.get(i); if (data.state != RollbackData.ROLLBACK_STATE_ENABLING) { continue; } for (PackageRollbackInfo info : data.info.getPackages()) { if (info.getPackageName().equals(packageName)) { mAppDataRollbackHelper.snapshotAppData(data.info.getRollbackId(), info); saveRollbackData(data); return; } } } // non-staged installs PackageRollbackInfo info; for (NewRollback rollback : mNewRollbacks) { info = getPackageRollbackInfo(rollback.data, packageName); if (info != null) { mAppDataRollbackHelper.snapshotAppData(rollback.data.info.getRollbackId(), info); saveRollbackData(rollback.data); return; } } } } private void restoreUserDataInternal(String packageName, int[] userIds, int appId, private void restoreUserDataInternal(String packageName, int[] userIds, int appId, long ceDataInode, String seInfo, int token) { long ceDataInode, String seInfo, int token) { PackageRollbackInfo info = null; PackageRollbackInfo info = null; Loading Loading @@ -1130,7 +1156,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { if (!session.isMultiPackage()) { if (!session.isMultiPackage()) { if (!enableRollbackForPackageSession(newRollback.data, session, if (!enableRollbackForPackageSession(newRollback.data, session, new int[0], /* snapshotUserData */ false)) { new int[0])) { Log.e(TAG, "Unable to enable rollback for session: " + sessionId); Log.e(TAG, "Unable to enable rollback for session: " + sessionId); result.offer(false); result.offer(false); return; return; Loading @@ -1145,7 +1171,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { return; return; } } if (!enableRollbackForPackageSession(newRollback.data, childSession, if (!enableRollbackForPackageSession(newRollback.data, childSession, new int[0], /* snapshotUserData */ false)) { new int[0])) { Log.e(TAG, "Unable to enable rollback for session: " + sessionId); Log.e(TAG, "Unable to enable rollback for session: " + sessionId); result.offer(false); result.offer(false); return; return; Loading Loading
core/java/android/content/rollback/IRollbackManager.aidl +2 −2 Original line number Original line Diff line number Diff line Loading @@ -30,9 +30,9 @@ interface IRollbackManager { String callerPackageName, in IntentSender statusReceiver); String callerPackageName, in IntentSender statusReceiver); // Exposed for use from the system server only. Callback from the package // Exposed for use from the system server only. Callback from the package // manager during the install flow when user data can be restored for a given // manager during the install flow when user data can be backed up and restored for a given // package. // package. void restoreUserData(String packageName, in int[] userIds, int appId, long ceDataInode, void snapshotAndRestoreUserData(String packageName, in int[] userIds, int appId, long ceDataInode, String seInfo, int token); String seInfo, int token); // Exposed for test purposes only. // Exposed for test purposes only. Loading
services/core/java/com/android/server/pm/PackageManagerService.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -14758,7 +14758,7 @@ public class PackageManagerService extends IPackageManager.Stub if (ps != null) { if (ps != null) { try { try { rm.restoreUserData(packageName, installedUsers, appId, ceDataInode, rm.snapshotAndRestoreUserData(packageName, installedUsers, appId, ceDataInode, seInfo, token); seInfo, token); } catch (RemoteException re) { } catch (RemoteException re) { // Cannot happen, the RollbackManager is hosted in the same process. // Cannot happen, the RollbackManager is hosted in the same process.
services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +43 −17 Original line number Original line Diff line number Diff line Loading @@ -923,8 +923,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } } if (rd != null) { if (rd != null) { // This is the apk session for a staged session. We have already // This is the apk session for a staged session. We do not need to create a new rollback // backed up the apks, we just need to do user data backup. // for this session. PackageParser.PackageLite newPackage = null; PackageParser.PackageLite newPackage = null; try { try { newPackage = PackageParser.parsePackageLite( newPackage = PackageParser.parsePackageLite( Loading @@ -937,8 +937,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { for (PackageRollbackInfo info : rd.info.getPackages()) { for (PackageRollbackInfo info : rd.info.getPackages()) { if (info.getPackageName().equals(packageName)) { if (info.getPackageName().equals(packageName)) { info.getInstalledUsers().addAll(IntArray.wrap(installedUsers)); info.getInstalledUsers().addAll(IntArray.wrap(installedUsers)); mAppDataRollbackHelper.snapshotAppData(rd.info.getRollbackId(), info); saveRollbackData(rd); return true; return true; } } } } Loading @@ -959,8 +957,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } } newRollback.addToken(token); newRollback.addToken(token); return enableRollbackForPackageSession(newRollback.data, packageSession, return enableRollbackForPackageSession(newRollback.data, packageSession, installedUsers); installedUsers, /* snapshotUserData*/ true); } } /** /** Loading @@ -971,8 +968,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { * @return true on success, false on failure. * @return true on success, false on failure. */ */ private boolean enableRollbackForPackageSession(RollbackData data, private boolean enableRollbackForPackageSession(RollbackData data, PackageInstaller.SessionInfo session, @NonNull int[] installedUsers, PackageInstaller.SessionInfo session, @NonNull int[] installedUsers) { boolean snapshotUserData) { // TODO: Don't attempt to enable rollback for split installs. // TODO: Don't attempt to enable rollback for split installs. final int installFlags = session.installFlags; final int installFlags = session.installFlags; if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) { if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) { Loading Loading @@ -1033,10 +1029,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { isApex, IntArray.wrap(installedUsers), isApex, IntArray.wrap(installedUsers), new SparseLongArray() /* ceSnapshotInodes */); new SparseLongArray() /* ceSnapshotInodes */); if (snapshotUserData && !isApex) { mAppDataRollbackHelper.snapshotAppData(data.info.getRollbackId(), packageRollbackInfo); } try { try { ApplicationInfo appInfo = pkgInfo.applicationInfo; ApplicationInfo appInfo = pkgInfo.applicationInfo; RollbackStore.backupPackageCodePath(data, packageName, appInfo.sourceDir); RollbackStore.backupPackageCodePath(data, packageName, appInfo.sourceDir); Loading @@ -1057,13 +1049,15 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { } } @Override @Override public void restoreUserData(String packageName, int[] userIds, int appId, long ceDataInode, public void snapshotAndRestoreUserData(String packageName, int[] userIds, int appId, String seInfo, int token) { long ceDataInode, String seInfo, int token) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("restoreUserData may only be called by the system."); throw new SecurityException( "snapshotAndRestoreUserData may only be called by the system."); } } getHandler().post(() -> { getHandler().post(() -> { snapshotUserDataInternal(packageName); restoreUserDataInternal(packageName, userIds, appId, ceDataInode, seInfo, token); restoreUserDataInternal(packageName, userIds, appId, ceDataInode, seInfo, token); final PackageManagerInternal pmi = LocalServices.getService( final PackageManagerInternal pmi = LocalServices.getService( PackageManagerInternal.class); PackageManagerInternal.class); Loading @@ -1071,6 +1065,38 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { }); }); } } private void snapshotUserDataInternal(String packageName) { synchronized (mLock) { // staged installs ensureRollbackDataLoadedLocked(); for (int i = 0; i < mRollbacks.size(); i++) { RollbackData data = mRollbacks.get(i); if (data.state != RollbackData.ROLLBACK_STATE_ENABLING) { continue; } for (PackageRollbackInfo info : data.info.getPackages()) { if (info.getPackageName().equals(packageName)) { mAppDataRollbackHelper.snapshotAppData(data.info.getRollbackId(), info); saveRollbackData(data); return; } } } // non-staged installs PackageRollbackInfo info; for (NewRollback rollback : mNewRollbacks) { info = getPackageRollbackInfo(rollback.data, packageName); if (info != null) { mAppDataRollbackHelper.snapshotAppData(rollback.data.info.getRollbackId(), info); saveRollbackData(rollback.data); return; } } } } private void restoreUserDataInternal(String packageName, int[] userIds, int appId, private void restoreUserDataInternal(String packageName, int[] userIds, int appId, long ceDataInode, String seInfo, int token) { long ceDataInode, String seInfo, int token) { PackageRollbackInfo info = null; PackageRollbackInfo info = null; Loading Loading @@ -1130,7 +1156,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { if (!session.isMultiPackage()) { if (!session.isMultiPackage()) { if (!enableRollbackForPackageSession(newRollback.data, session, if (!enableRollbackForPackageSession(newRollback.data, session, new int[0], /* snapshotUserData */ false)) { new int[0])) { Log.e(TAG, "Unable to enable rollback for session: " + sessionId); Log.e(TAG, "Unable to enable rollback for session: " + sessionId); result.offer(false); result.offer(false); return; return; Loading @@ -1145,7 +1171,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { return; return; } } if (!enableRollbackForPackageSession(newRollback.data, childSession, if (!enableRollbackForPackageSession(newRollback.data, childSession, new int[0], /* snapshotUserData */ false)) { new int[0])) { Log.e(TAG, "Unable to enable rollback for session: " + sessionId); Log.e(TAG, "Unable to enable rollback for session: " + sessionId); result.offer(false); result.offer(false); return; return; Loading