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

Commit 6731a623 authored by JW Wang's avatar JW Wang
Browse files

Remove use of locks (5/n)

Now that all state changes happen on the same thread, we don't need
locks anymore.

TODO: fix indentation and method names suffixed with "Locked".

Bug: 145335013
Test: atest CtsRollbackManagerHostTestCases
Test: atest RollbackTest
Test: atest StagedRollbackTest

Change-Id: Ia8e73bea07d0688baef66e95185e0830a9e08cf3
parent a211a54e
Loading
Loading
Loading
Loading
+143 −198
Original line number Diff line number Diff line
@@ -128,32 +128,26 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    private static final long DEFAULT_ROLLBACK_LIFETIME_DURATION_MILLIS =
            TimeUnit.DAYS.toMillis(14);

    // Lock used to synchronize accesses to in-memory rollback data
    // structures. By convention, methods with the suffix "Locked" require
    // mLock is held when they are called.
    private final Object mLock = new Object();

    // No need for guarding with lock because value is only accessed in handler thread
    // and the value will be written on boot complete. Initialization here happens before
    // handler threads are running so that's fine.
    // Accessed on the handler thread only.
    private long mRollbackLifetimeDurationInMillis = DEFAULT_ROLLBACK_LIFETIME_DURATION_MILLIS;

    private static final long HANDLER_THREAD_TIMEOUT_DURATION_MILLIS =
            TimeUnit.MINUTES.toMillis(10);

    // Used for generating rollback IDs.
    // Accessed on the handler thread only.
    private final Random mRandom = new SecureRandom();

    // Set of allocated rollback ids
    @GuardedBy("mLock")
    // Set of allocated rollback ids.
    // Accessed on the handler thread only.
    private final SparseBooleanArray mAllocatedRollbackIds = new SparseBooleanArray();

    // The list of all rollbacks, including available and committed rollbacks.
    @GuardedBy("mLock")
    // Accessed on the handler thread only.
    private final List<Rollback> mRollbacks;

    // Apk sessions from a staged session with no matching rollback.
    @GuardedBy("mLock")
    // Accessed on the handler thread only.
    private final IntArray mOrphanedApkSessionIds = new IntArray();

    private final RollbackStore mRollbackStore;
@@ -173,7 +167,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    // This field stores the difference in Millis between the uptime (millis since device
    // has booted) and current time (device wall clock) - it's used to update rollback
    // timestamps when the time is changed, by the user or by change of timezone.
    // No need for guarding with lock because value is only accessed in handler thread.
    // Accessed on the handler thread only.
    private long  mRelativeBootTime = calculateRelativeBootTime();

    RollbackManagerServiceImpl(Context context) {
@@ -189,7 +183,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        mAppDataRollbackHelper = new AppDataRollbackHelper(mInstaller);

        // Load rollback data from device storage.
        synchronized (mLock) {
        mRollbacks = mRollbackStore.loadRollbacks();
        if (!context.getPackageManager().isDeviceUpgrading()) {
            for (Rollback rollback : mRollbacks) {
@@ -202,7 +195,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            }
            mRollbacks.clear();
        }
        }

        // Kick off and start monitoring the handler thread.
        mHandlerThread = new HandlerThread("RollbackManagerServiceHandler");
@@ -270,7 +262,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                    if (LOCAL_LOGV) {
                        Slog.v(TAG, "broadcast=ACTION_CANCEL_ENABLE_ROLLBACK id=" + sessionId);
                    }
                    synchronized (mLock) {
                    Rollback rollback = getRollbackForSessionLocked(sessionId);
                    if (rollback != null && rollback.isEnabling()) {
                        mRollbacks.remove(rollback);
@@ -278,7 +269,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                    }
                }
            }
            }
        }, enableRollbackTimedOutFilter, null, getHandler());

        IntentFilter userAddedIntentFilter = new IntentFilter(Intent.ACTION_USER_ADDED);
@@ -373,7 +363,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        enforceManageRollbacks("getAvailableRollbacks");
        return awaitResult(() -> {
            assertInWorkerThread();
            synchronized (mLock) {
            List<RollbackInfo> rollbacks = new ArrayList<>();
            for (int i = 0; i < mRollbacks.size(); ++i) {
                Rollback rollback = mRollbacks.get(i);
@@ -382,7 +371,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                }
            }
            return new ParceledListSlice<>(rollbacks);
            }
        });
    }

@@ -394,7 +382,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

        return awaitResult(() -> {
            assertInWorkerThread();
            synchronized (mLock) {
            List<RollbackInfo> rollbacks = new ArrayList<>();
            for (int i = 0; i < mRollbacks.size(); ++i) {
                Rollback rollback = mRollbacks.get(i);
@@ -403,7 +390,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                }
            }
            return new ParceledListSlice<>(rollbacks);
            }
        });
    }

@@ -433,7 +419,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                mRelativeBootTime = calculateRelativeBootTime();
                final long timeDifference = mRelativeBootTime - oldRelativeBootTime;

                synchronized (mLock) {
                Iterator<Rollback> iter = mRollbacks.iterator();
                while (iter.hasNext()) {
                    Rollback rollback = iter.next();
@@ -441,7 +426,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                            rollback.getTimestamp().plusMillis(timeDifference));
                }
            }
            }
        };
        final IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_TIME_CHANGED);
@@ -485,17 +469,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

        awaitResult(() -> {
            assertInWorkerThread();
            synchronized (mLock) {
            mRollbacks.clear();
            mRollbacks.addAll(mRollbackStore.loadRollbacks());
            }
        });
    }

    @WorkerThread
    private void expireRollbackForPackageInternal(String packageName) {
        assertInWorkerThread();
        synchronized (mLock) {
        Iterator<Rollback> iter = mRollbacks.iterator();
        while (iter.hasNext()) {
            Rollback rollback = iter.next();
@@ -505,7 +486,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            }
        }
    }
    }

    @ExtThread
    @Override
@@ -562,9 +542,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        awaitResult(() -> {
            assertInWorkerThread();
            final List<Rollback> rollbacks;
            synchronized (mLock) {
            rollbacks = new ArrayList<>(mRollbacks);
            }

            for (int i = 0; i < rollbacks.size(); i++) {
                Rollback rollback = rollbacks.get(i);
@@ -600,7 +578,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            List<Rollback> enabling = new ArrayList<>();
            List<Rollback> restoreInProgress = new ArrayList<>();
            Set<String> apexPackageNames = new HashSet<>();
            synchronized (mLock) {
            Iterator<Rollback> iter = mRollbacks.iterator();
            while (iter.hasNext()) {
                Rollback rollback = iter.next();
@@ -626,7 +603,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                }
                apexPackageNames.addAll(rollback.getApexPackageNames());
            }
            }

            for (Rollback rollback : enabling) {
                makeRollbackAvailable(rollback);
@@ -644,9 +620,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                onPackageReplaced(apexPackageName);
            }

            synchronized (mLock) {
            mOrphanedApkSessionIds.clear();
            }

            mPackageHealthObserver.onBootCompletedAsync();
        });
@@ -664,7 +638,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        // package that is about to be installed?
        long installedVersion = getInstalledPackageVersion(packageName);

        synchronized (mLock) {
        Iterator<Rollback> iter = mRollbacks.iterator();
        while (iter.hasNext()) {
            Rollback rollback = iter.next();
@@ -677,7 +650,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            }
        }
    }
    }

    /**
     * Called when a package has been completely removed from the device.
@@ -717,7 +689,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        assertInWorkerThread();
        Instant now = Instant.now();
        Instant oldest = null;
        synchronized (mLock) {
        Iterator<Rollback> iter = mRollbacks.iterator();
        while (iter.hasNext()) {
            Rollback rollback = iter.next();
@@ -737,7 +708,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                oldest = rollbackTimestamp;
            }
        }
        }

        if (oldest != null) {
            scheduleExpiration(now.until(oldest.plusMillis(mRollbackLifetimeDurationInMillis),
@@ -799,7 +769,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

        // Check to see if this is the apk session for a staged session with
        // rollback enabled.
        synchronized (mLock) {
        for (int i = 0; i < mRollbacks.size(); ++i) {
            Rollback rollback = mRollbacks.get(i);
            if (rollback.getApkSessionId() == parentSession.getSessionId()) {
@@ -808,20 +777,16 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                return true;
            }
        }
        }

        // Check to see if this is the apk session for a staged session for which rollback was
        // cancelled.
        synchronized (mLock) {
        if (mOrphanedApkSessionIds.indexOf(parentSession.getSessionId()) != -1) {
            Slog.w(TAG, "Not enabling rollback for apk as no matching staged session "
                    + "rollback exists");
            return false;
        }
        }

        Rollback newRollback;
        synchronized (mLock) {
        // See if we already have a Rollback that contains this package
        // session. If not, create a new Rollback for the parent session
        // that we will use for all the packages in the session.
@@ -829,7 +794,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        if (newRollback == null) {
            newRollback = createNewRollbackLocked(parentSession);
        }
        }

        return enableRollbackForPackageSession(newRollback, packageSession);
    }
@@ -962,13 +926,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            Slog.v(TAG, "snapshotUserData pkg=" + packageName
                    + " users=" + Arrays.toString(userIds));
        }
        synchronized (mLock) {
        for (int i = 0; i < mRollbacks.size(); i++) {
            Rollback rollback = mRollbacks.get(i);
            rollback.snapshotUserData(packageName, userIds, mAppDataRollbackHelper);
        }
    }
    }

    @WorkerThread
    private void restoreUserDataInternal(
@@ -978,7 +940,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            Slog.v(TAG, "restoreUserData pkg=" + packageName
                    + " users=" + Arrays.toString(userIds));
        }
        synchronized (mLock) {
        for (int i = 0; i < mRollbacks.size(); ++i) {
            Rollback rollback = mRollbacks.get(i);
            if (rollback.restoreUserDataForPackageIfInProgress(
@@ -987,7 +948,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            }
        }
    }
    }

    @ExtThread
    @Override
@@ -1010,9 +970,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            }

            Rollback newRollback;
            synchronized (mLock) {
            newRollback = createNewRollbackLocked(session);
            }

            if (!session.isMultiPackage()) {
                if (!enableRollbackForPackageSession(newRollback, session)) {
@@ -1051,7 +1009,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        getHandler().post(() -> {
            assertInWorkerThread();
            Rollback rollback = null;
            synchronized (mLock) {
            for (int i = 0; i < mRollbacks.size(); ++i) {
                Rollback candidate = mRollbacks.get(i);
                if (candidate.getStagedSessionId() == originalSessionId) {
@@ -1066,7 +1023,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                        + ". Adding orphaned apk session " + apkSessionId);
                mOrphanedApkSessionIds.add(apkSessionId);
            }
            }

            if (rollback != null) {
                rollback.setApkSessionId(apkSessionId);
@@ -1183,16 +1139,13 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {

            if (success) {
                Rollback rollback;
                synchronized (mLock) {
                rollback = getRollbackForSessionLocked(sessionId);
                }
                if (rollback != null && !rollback.isStaged() && rollback.isEnabling()
                        && rollback.notifySessionWithSuccess()
                        && completeEnableRollback(rollback)) {
                    makeRollbackAvailable(rollback);
                }
            } else {
                synchronized (mLock) {
                Rollback rollback = getRollbackForSessionLocked(sessionId);
                if (rollback != null && rollback.isEnabling()) {
                    Slog.w(TAG, "Delete rollback id=" + rollback.info.getRollbackId()
@@ -1203,7 +1156,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            }
        }
    }
    }

    /**
     * Persist a rollback as enable-completed. It does not make the rollback available yet.
@@ -1270,20 +1222,17 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    @WorkerThread
    private Rollback getRollbackForId(int rollbackId) {
        assertInWorkerThread();
        synchronized (mLock) {
        for (int i = 0; i < mRollbacks.size(); ++i) {
            Rollback rollback = mRollbacks.get(i);
            if (rollback.info.getRollbackId() == rollbackId) {
                return rollback;
            }
        }
        }

        return null;
    }

    @WorkerThread
    @GuardedBy("mLock")
    private int allocateRollbackIdLocked() {
        assertInWorkerThread();
        int n = 0;
@@ -1308,13 +1257,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
        awaitResult(() -> {
            assertInWorkerThread();
            synchronized (mLock) {
            for (Rollback rollback : mRollbacks) {
                rollback.dump(ipw);
            }
            ipw.println();
            PackageWatchdog.getInstance(mContext).dump(ipw);
            }
        });
    }

@@ -1335,7 +1282,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
     * and adds it to {@link #mRollbacks}.
     */
    @WorkerThread
    @GuardedBy("mLock")
    private Rollback createNewRollbackLocked(PackageInstaller.SessionInfo parentSession) {
        assertInWorkerThread();
        int rollbackId = allocateRollbackIdLocked();
@@ -1378,7 +1324,6 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
     * Returns null if not found.
     */
    @WorkerThread
    @GuardedBy("mLock")
    @Nullable
    private Rollback getRollbackForSessionLocked(int sessionId) {
        assertInWorkerThread();