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

Commit d4e13075 authored by Shafik Nassar's avatar Shafik Nassar Committed by android-build-merger
Browse files

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

am: b273078a

Change-Id: I70d3646dcef80e0bc9ba1034a3103808f1079d99
parents f6d0211c b273078a
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