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

Commit b273078a authored by Shafik Nassar's avatar Shafik Nassar Committed by Android (Google) Code Review
Browse files

Merge "Fail to enable rollback if enable rollback times out" into qt-dev

parents 117f2d9d 4831ad70
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -2444,6 +2444,18 @@ public class Intent implements Parcelable, Cloneable {
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_PACKAGE_ENABLE_ROLLBACK =
            "android.intent.action.PACKAGE_ENABLE_ROLLBACK";
    /**
     * Broadcast Action: Sent to the system rollback manager when the rollback for a certain
     * package needs to be cancelled.
     *
     * <p class="note">This intent is sent by PackageManagerService to notify RollbackManager
     * that enabling a specific rollback has timed out.
     *
     * @hide
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_CANCEL_ENABLE_ROLLBACK =
            "android.intent.action.CANCEL_ENABLE_ROLLBACK";
    /**
     * Broadcast Action: A rollback has been committed.
     *
+2 −2
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ import java.util.List;
 * used to initiate rollback of those packages for a limited time period after
 * upgrade.
 *
 * @see PackageInstaller.SessionParams#setEnableRollback()
 * @see PackageInstaller.SessionParams#setEnableRollback(boolean)
 * @hide
 */
@SystemApi @TestApi
@@ -52,7 +52,7 @@ public final class RollbackManager {
    /**
     * Lifetime duration of rollback packages in millis. A rollback will be available for
     * at most that duration of time after a package is installed with
     * {@link PackageInstaller.SessionParams#setEnableRollback()}.
     * {@link PackageInstaller.SessionParams#setEnableRollback(boolean)}.
     *
     * <p>If flag value is negative, the default value will be assigned.
     *
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
    <protected-broadcast android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
    <protected-broadcast android:name="android.intent.action.PACKAGE_CHANGED" />
    <protected-broadcast android:name="android.intent.action.PACKAGE_ENABLE_ROLLBACK" />
    <protected-broadcast android:name="android.intent.action.CANCEL_ENABLE_ROLLBACK" />
    <protected-broadcast android:name="android.intent.action.ROLLBACK_COMMITTED" />
    <protected-broadcast android:name="android.intent.action.PACKAGE_RESTARTED" />
    <protected-broadcast android:name="android.intent.action.PACKAGE_DATA_CLEARED" />
+9 −0
Original line number Diff line number Diff line
@@ -1746,6 +1746,15 @@ public class PackageManagerService extends IPackageManager.Stub
                        Trace.asyncTraceEnd(
                                TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
                        params.handleRollbackEnabled();
                        Intent rollbackTimeoutIntent = new Intent(
                                Intent.ACTION_CANCEL_ENABLE_ROLLBACK);
                        rollbackTimeoutIntent.putExtra(
                                PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
                                enableRollbackToken);
                        rollbackTimeoutIntent.addFlags(
                                Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                        mContext.sendBroadcastAsUser(rollbackTimeoutIntent, UserHandle.SYSTEM,
                                android.Manifest.permission.PACKAGE_ROLLBACK_AGENT);
                    }
                    break;
                }
+59 −3
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

                    getHandler().post(() -> {
                        boolean success = enableRollback(installFlags, newPackageCodePath,
                                installedUsers, user);
                                installedUsers, user, token);
                        int ret = PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED;
                        if (!success) {
                            ret = PackageManagerInternal.ENABLE_ROLLBACK_FAILED;
@@ -203,6 +203,27 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            }
        }, enableRollbackFilter, null, getHandler());

        IntentFilter enableRollbackTimedOutFilter = new IntentFilter();
        enableRollbackTimedOutFilter.addAction(Intent.ACTION_CANCEL_ENABLE_ROLLBACK);

        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (Intent.ACTION_CANCEL_ENABLE_ROLLBACK.equals(intent.getAction())) {
                    int token = intent.getIntExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN, -1);
                    synchronized (mLock) {
                        for (NewRollback rollback : mNewRollbacks) {
                            if (rollback.hasToken(token)) {
                                rollback.isCancelled = true;
                                return;
                            }
                        }
                    }
                }
            }
        }, enableRollbackTimedOutFilter, null, getHandler());

        registerTimeChangeReceiver();
    }

@@ -818,10 +839,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
     * @param newPackageCodePath path to the package about to be installed.
     * @param installedUsers the set of users for which a given package is installed.
     * @param user the user that owns the install session to enable rollback on.
     * @param token the distinct rollback token sent by package manager.
     * @return true if enabling the rollback succeeds, false otherwise.
     */
    private boolean enableRollback(int installFlags, File newPackageCodePath,
            int[] installedUsers, @UserIdInt int user) {
            int[] installedUsers, @UserIdInt int user, int token) {

        // Find the session id associated with this install.
        // TODO: It would be nice if package manager or package installer told
@@ -914,6 +936,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                mNewRollbacks.add(newRollback);
            }
        }
        newRollback.addToken(token);

        return enableRollbackForPackageSession(newRollback.data, packageSession,
                installedUsers, /* snapshotUserData*/ true);
@@ -1016,7 +1039,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    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.");
            throw new SecurityException("restoreUserData may only be called by the system.");
        }

        getHandler().post(() -> {
@@ -1272,6 +1295,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            deleteRollback(data);
            return null;
        }
        if (newRollback.isCancelled) {
            Log.e(TAG, "Rollback has been cancelled by PackageManager");
            deleteRollback(data);
            return null;
        }

        // It's safe to access data.info outside a synchronized block because
        // this is running on the handler thread and all changes to the
@@ -1451,6 +1479,13 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    private static class NewRollback {
        public final RollbackData data;

        /**
         * This array holds all of the rollback tokens associated with package sessions included
         * in this rollback. This is used to identify which rollback should be cancelled in case
         * {@link PackageManager} sends an {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} intent.
         */
        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.
@@ -1459,10 +1494,31 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
         */
        public final int[] packageSessionIds;

        /**
         * Flag to determine whether the RollbackData has been cancelled.
         *
         * <p>RollbackData could be invalidated and cancelled if RollbackManager receives
         * {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK} from {@link PackageManager}.
         *
         * <p>The main underlying assumption here is that if enabling the rollback times out, then
         * {@link PackageManager} will NOT send
         * {@link PackageInstaller.SessionCallback#onFinished(int, boolean)} before it broadcasts
         * {@link Intent#ACTION_CANCEL_ENABLE_ROLLBACK}.
         */
        public boolean isCancelled = false;

        NewRollback(RollbackData data, int[] packageSessionIds) {
            this.data = data;
            this.packageSessionIds = packageSessionIds;
        }

        public void addToken(int token) {
            mTokens.add(token);
        }

        public boolean hasToken(int token) {
            return mTokens.indexOf(token) != -1;
        }
    }

    NewRollback createNewRollbackLocked(PackageInstaller.SessionInfo parentSession) {
Loading