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

Commit 03aee254 authored by JW Wang's avatar JW Wang Committed by Android (Google) Code Review
Browse files

Merge "Add RollbackManagerInternal (4/n)"

parents 11e11290 53669180
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import android.annotation.UserIdInt;
import android.compat.annotation.UnsupportedAppUsage;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * Representation of a user on the device.
@@ -256,6 +258,26 @@ public final class UserHandle implements Parcelable {
        return getAppId(Binder.getCallingUid());
    }

    /** @hide */
    @NonNull
    public static int[] fromUserHandles(@NonNull List<UserHandle> users) {
        int[] userIds = new int[users.size()];
        for (int i = 0; i < userIds.length; ++i) {
            userIds[i] = users.get(i).getIdentifier();
        }
        return userIds;
    }

    /** @hide */
    @NonNull
    public static List<UserHandle> toUserHandles(@NonNull int[] userIds) {
        List<UserHandle> users = new ArrayList<>(userIds.length);
        for (int i = 0; i < userIds.length; ++i) {
            users.add(UserHandle.of(userIds[i]));
        }
        return users;
    }

    /** @hide */
    @TestApi
    @SystemApi
+6 −7
Original line number Diff line number Diff line
@@ -236,7 +236,6 @@ import android.content.pm.parsing.component.ParsedService;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.content.res.Resources;
import android.content.rollback.IRollbackManager;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.hardware.display.DisplayManager;
@@ -367,6 +366,7 @@ import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.permission.PermissionsState;
import com.android.server.policy.PermissionPolicyInternal;
import com.android.server.rollback.RollbackManagerInternal;
import com.android.server.security.VerityUtils;
import com.android.server.storage.DeviceStorageMonitorInternal;
import com.android.server.utils.TimingsTraceAndSlog;
@@ -14314,8 +14314,7 @@ public class PackageManagerService extends IPackageManager.Stub
     */
    private boolean performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res,
            PostInstallData data) {
        IRollbackManager rm = IRollbackManager.Stub.asInterface(
                ServiceManager.getService(Context.ROLLBACK_SERVICE));
        RollbackManagerInternal rm = LocalServices.getService(RollbackManagerInternal.class);
        final String packageName = res.pkg.getPackageName();
        final int[] allUsers = mUserManager.getUserIds();
@@ -14343,9 +14342,9 @@ public class PackageManagerService extends IPackageManager.Stub
        if (ps != null && doSnapshotOrRestore) {
            final String seInfo = AndroidPackageUtils.getSeInfo(res.pkg, ps);
            try {
                rm.snapshotAndRestoreUserData(packageName, installedUsers, appId, ceDataInode,
                        seInfo, token);
            } catch (RemoteException re) {
                rm.snapshotAndRestoreUserData(packageName, UserHandle.toUserHandles(installedUsers),
                        appId, ceDataInode, seInfo, token);
            } catch (RuntimeException re) {
                Log.e(TAG, "Error snapshotting/restoring user data: " + re);
                return false;
            }
@@ -21390,7 +21389,7 @@ public class PackageManagerService extends IPackageManager.Stub
    public void onShellCommand(FileDescriptor in, FileDescriptor out,
            FileDescriptor err, String[] args, ShellCallback callback,
            ResultReceiver resultReceiver) {
        (new PackageManagerShellCommand(this, mPermissionManagerService)).exec(
        (new PackageManagerShellCommand(this, mPermissionManagerService, mContext)).exec(
                this, in, out, err, args, callback, resultReceiver);
    }
+22 −23
Original line number Diff line number Diff line
@@ -66,7 +66,6 @@ import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.content.rollback.IRollbackManager;
import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
@@ -145,6 +144,7 @@ class PackageManagerShellCommand extends ShellCommand {

    final IPackageManager mInterface;
    final IPermissionManager mPermissionManager;
    final Context mShellPackageContext;
    final private WeakHashMap<String, Resources> mResourceCache =
            new WeakHashMap<String, Resources>();
    int mTargetUser;
@@ -153,9 +153,15 @@ class PackageManagerShellCommand extends ShellCommand {
    int mQueryFlags;

    PackageManagerShellCommand(
            PackageManagerService service, IPermissionManager permissionManager) {
            PackageManagerService service, IPermissionManager permissionManager, Context context) {
        mInterface = service;
        mPermissionManager = permissionManager;
        try {
            mShellPackageContext = context.createPackageContext("com.android.shell", 0);
        } catch (NameNotFoundException e) {
            // should not happen
            throw new RuntimeException(e);
        }
    }

    @Override
@@ -460,12 +466,9 @@ class PackageManagerShellCommand extends ShellCommand {
        }

        final LocalIntentReceiver receiver = new LocalIntentReceiver();
        try {
            IRollbackManager rm = IRollbackManager.Stub.asInterface(
                    ServiceManager.getService(Context.ROLLBACK_SERVICE));

        RollbackManager rm = mShellPackageContext.getSystemService(RollbackManager.class);
        RollbackInfo rollback = null;
            for (RollbackInfo r : (List<RollbackInfo>) rm.getAvailableRollbacks().getList()) {
        for (RollbackInfo r : rm.getAvailableRollbacks()) {
            for (PackageRollbackInfo info : r.getPackages()) {
                if (packageName.equals(info.getPackageName())) {
                    rollback = r;
@@ -480,11 +483,7 @@ class PackageManagerShellCommand extends ShellCommand {
        }

        rm.commitRollback(rollback.getRollbackId(),
                    ParceledListSlice.<VersionedPackage>emptyList(),
                    "com.android.shell", receiver.getIntentSender());
        } catch (RemoteException re) {
            // Cannot happen.
        }
                Collections.emptyList(), receiver.getIntentSender());

        final Intent result = receiver.getResult();
        final int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
+15 −17
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import android.content.pm.PackageParser.SigningDetails;
import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
import android.content.pm.ParceledListSlice;
import android.content.pm.parsing.PackageInfoWithoutStateUtils;
import android.content.rollback.IRollbackManager;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
import android.os.Bundle;
@@ -52,7 +51,6 @@ import android.os.ParcelFileDescriptor;
import android.os.ParcelableException;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.os.storage.IStorageManager;
@@ -75,6 +73,7 @@ import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.rollback.RollbackManagerInternal;
import com.android.server.rollback.WatchdogRollbackLogger;

import java.io.File;
@@ -483,8 +482,7 @@ public class StagingManager {

        final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
        final int[] allUsers = um.getUserIds();
        IRollbackManager rm = IRollbackManager.Stub.asInterface(
                ServiceManager.getService(Context.ROLLBACK_SERVICE));
        RollbackManagerInternal rm = LocalServices.getService(RollbackManagerInternal.class);

        for (int i = 0, sessionsSize = apexSessions.size(); i < sessionsSize; i++) {
            final String packageName = apexSessions.get(i).getPackageName();
@@ -500,18 +498,18 @@ public class StagingManager {
    }

    private void snapshotAndRestoreApexUserData(
            String packageName, int[] allUsers, IRollbackManager rm) {
            String packageName, int[] allUsers, RollbackManagerInternal rm) {
        try {
            // appId, ceDataInode, and seInfo are not needed for APEXes
            rm.snapshotAndRestoreUserData(packageName, allUsers, 0, 0,
            rm.snapshotAndRestoreUserData(packageName, UserHandle.toUserHandles(allUsers), 0, 0,
                    null, 0 /*token*/);
        } catch (RemoteException re) {
        } catch (RuntimeException re) {
            Slog.e(TAG, "Error snapshotting/restoring user data: " + re);
        }
    }

    private void snapshotAndRestoreApkInApexUserData(
            String packageName, int[] allUsers, IRollbackManager rm) {
            String packageName, int[] allUsers, RollbackManagerInternal rm) {
        PackageManagerInternal mPmi = LocalServices.getService(PackageManagerInternal.class);
        AndroidPackage pkg = mPmi.getPackage(packageName);
        if (pkg == null) {
@@ -532,9 +530,9 @@ public class StagingManager {

            final String seInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
            try {
                rm.snapshotAndRestoreUserData(packageName, installedUsers, appId, ceDataInode,
                        seInfo, 0 /*token*/);
            } catch (RemoteException re) {
                rm.snapshotAndRestoreUserData(packageName, UserHandle.toUserHandles(installedUsers),
                        appId, ceDataInode, seInfo, 0 /*token*/);
            } catch (RuntimeException re) {
                Slog.e(TAG, "Error snapshotting/restoring user data: " + re);
            }
        }
@@ -878,11 +876,11 @@ public class StagingManager {
        if ((apksToInstall.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
            // If rollback is available for this session, notify the rollback
            // manager of the apk session so it can properly enable rollback.
            final IRollbackManager rm = IRollbackManager.Stub.asInterface(
                    ServiceManager.getService(Context.ROLLBACK_SERVICE));
            final RollbackManagerInternal rm =
                    LocalServices.getService(RollbackManagerInternal.class);
            try {
                rm.notifyStagedApkSession(session.sessionId, apksToInstall.sessionId);
            } catch (RemoteException re) {
            } catch (RuntimeException re) {
                Slog.e(TAG, "Failed to notifyStagedApkSession for session: "
                        + session.sessionId, re);
            }
@@ -1384,8 +1382,8 @@ public class StagingManager {
                // If rollback is enabled for this session, we call through to the RollbackManager
                // with the list of sessions it must enable rollback for. Note that
                // notifyStagedSession is a synchronous operation.
                final IRollbackManager rm = IRollbackManager.Stub.asInterface(
                        ServiceManager.getService(Context.ROLLBACK_SERVICE));
                final RollbackManagerInternal rm =
                        LocalServices.getService(RollbackManagerInternal.class);
                try {
                    // NOTE: To stay consistent with the non-staged install flow, we don't fail the
                    // entire install if rollbacks can't be enabled.
@@ -1395,7 +1393,7 @@ public class StagingManager {
                            mSessionRollbackIds.put(session.sessionId, rollbackId);
                        }
                    }
                } catch (RemoteException re) {
                } catch (RuntimeException re) {
                    Slog.e(TAG, "Failed to notifyStagedSession for session: "
                            + session.sessionId, re);
                }
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.rollback;

import android.annotation.NonNull;
import android.os.UserHandle;

import java.util.List;

/**
 * A partial interface of IRollbackManager used by the system server only.
 *
 * @hide
 */
public interface RollbackManagerInternal {
    /**
     * Exposed for use from the system server only. Callback from the package
     * manager during the install flow when user data can be backed up and restored for a given
     * package.
     *
     * @param packageName Name of the package to restore/backup user data for
     * @param users Users whose data to be restored/backed up
     * @param appId ID of the package to restore/backup user data for
     * @param ceDataInode The index node of CE data to restore/backup
     * @param seInfo The seinfo tag used by SELinux policy
     * @param token Used to inform the package manager that the pending package install is finished
     */
    void snapshotAndRestoreUserData(@NonNull String packageName, @NonNull List<UserHandle> users,
            int appId, long ceDataInode, @NonNull String seInfo, int token);

    /**
     * Used by the staging manager to notify the RollbackManager that a session is
     * being staged. In the case of multi-package sessions, the specified sessionId
     * is that of the parent session.
     *
     * NOTE: This call is synchronous.
     *
     * @param sessionId The session ID that is being staged
     * @return The rollback id if rollback was enabled successfully, or -1 if not.
     */
    int notifyStagedSession(int sessionId);

    /**
     * Used by the staging manager to notify the RollbackManager of the apk
     * session for a staged session.
     *
     * @param originalSessionId The original session ID where this apk session belongs
     * @param apkSessionId The ID of this apk session
     */
    void notifyStagedApkSession(int originalSessionId, int apkSessionId);
}
Loading