Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67af327d authored by Narayan Kamath's avatar Narayan Kamath
Browse files

PackageManager: Call RollbackManager API with the right set of installed users.

We know we're operating on an update to an installed app, which is
applied to all previously installed users. Therefore, we must restore
data for those users and not just the user specified in the
InstallParams.

Test: atest RollbackTest
Bug: 112431924

Change-Id: Id95ee5c8e02da71fa3a64b4bf10966f3fb2e5e9c
parent c034fe9e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ interface IRollbackManager {
    // 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
    // package.
    void restoreUserData(String packageName, int userId, int appId, long ceDataInode,
    void restoreUserData(String packageName, in int[] userIds, int appId, long ceDataInode,
            String seInfo, int token);

    // Exposed for test purposes only.
+21 −2
Original line number Diff line number Diff line
@@ -13881,6 +13881,9 @@ public class PackageManagerService extends IPackageManager.Stub
            final String packageName = res.pkg.applicationInfo.packageName;
            final String seInfo = res.pkg.applicationInfo.seInfo;
            final int[] allUsers = sUserManager.getUserIds();
            final int[] installedUsers;
            final PackageSetting ps;
            int appId = -1;
            long ceDataInode = -1;
@@ -13890,11 +13893,16 @@ public class PackageManagerService extends IPackageManager.Stub
                    appId = ps.appId;
                    ceDataInode = ps.getCeDataInode(userId);
                }
                // NOTE: We ignore the user specified in the InstallParam because we know this is
                // an update, and hence need to restore data for all installed users.
                installedUsers = ps.queryInstalledUsers(allUsers, true);
            }
            if (ps != null) {
                try {
                    rm.restoreUserData(packageName, userId, appId, ceDataInode, seInfo, token);
                    rm.restoreUserData(packageName, installedUsers, appId, ceDataInode,
                            seInfo, token);
                } catch (RemoteException re) {
                    // Cannot happen, the RollbackManager is hosted in the same process.
                }
@@ -14591,6 +14599,17 @@ public class PackageManagerService extends IPackageManager.Stub
                            TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
                    mPendingEnableRollback.append(enableRollbackToken, this);
                    final int[] installedUsers;
                    synchronized (mPackages) {
                        PackageSetting ps = mSettings.getPackageLPr(pkgLite.packageName);
                        if (ps != null) {
                            installedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(),
                                    true);
                        } else {
                            installedUsers = new int[0];
                        }
                    }
                    // TODO(ruhler) b/112431924: What user? Test for multi-user.
                    Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
                    enableRollbackIntent.putExtra(
@@ -14601,7 +14620,7 @@ public class PackageManagerService extends IPackageManager.Stub
                            installFlags);
                    enableRollbackIntent.putExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALLED_USERS,
                            resolveUserIds(args.user.getIdentifier()));
                            installedUsers);
                    enableRollbackIntent.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
                            PACKAGE_MIME_TYPE);
                    enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+18 −15
Original line number Diff line number Diff line
@@ -783,7 +783,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    }

    @Override
    public void restoreUserData(String packageName, int userId, int appId, long ceDataInode,
    public void restoreUserData(String packageName, int[] userIds, int appId, long ceDataInode,
            String seInfo, int token) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("restoureUserData may only be called by the system.");
@@ -791,23 +791,26 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

        getHandler().post(() -> {
            final RollbackData rollbackData = getRollbackForPackage(packageName);
            for (int userId : userIds) {
                final boolean changedRollbackData = mUserdataHelper.restoreAppData(packageName,
                        rollbackData, userId, appId, ceDataInode, seInfo);
            final PackageManagerInternal pmi = LocalServices.getService(
                    PackageManagerInternal.class);
            pmi.finishPackageInstall(token, false);

                // We've updated metadata about this rollback, so save it to flash.
                if (changedRollbackData) {
                    try {
                        mRollbackStore.saveAvailableRollback(rollbackData);
                    } catch (IOException ioe) {
                    // TODO(narayan): What is the right thing to do here ? This isn't a fatal error,
                    // since it will only result in us trying to restore data again, which will be
                    // a no-op if there's no data available.
                        // TODO(narayan): What is the right thing to do here ? This isn't a fatal
                        // error, since it will only result in us trying to restore data again,
                        // which will be a no-op if there's no data available.
                        Log.e(TAG, "Unable to save available rollback: " + packageName, ioe);
                    }
                }
            }

            final PackageManagerInternal pmi = LocalServices.getService(
                    PackageManagerInternal.class);
            pmi.finishPackageInstall(token, false);
        });
    }