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

Commit 43d93da7 authored by guangkui.ren's avatar guangkui.ren Committed by Rubin Xu
Browse files

Fix potential crash issue in NonRequiredPackageDeleteObserver

mLatch.notifyAll() will not help wake the thread which is blocked by
mLatch.await, instead, it will cause system server crash.

So, mark state as failed if any package is failed to be deleted, and let
mLatch.countDown work until it comes to 0 and wake the thread blocked by
await.

Bug: 333845008
Change-Id: Ida1c3c128ddef376aaaacda1358717d0d4e9ca8b
parent 1a1f9bf4
Loading
Loading
Loading
Loading
+13 −14
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.util.Slog;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Awaits the deletion of all the non-required apps.
@@ -33,38 +32,38 @@ import java.util.concurrent.atomic.AtomicInteger;
final class NonRequiredPackageDeleteObserver extends IPackageDeleteObserver.Stub {
    private static final int PACKAGE_DELETE_TIMEOUT_SEC = 30;

    private final AtomicInteger mPackageCount = new AtomicInteger(/* initialValue= */ 0);
    private final CountDownLatch mLatch;
    private boolean mSuccess;
    private boolean mFailed = false;

    NonRequiredPackageDeleteObserver(int packageCount) {
        this.mLatch = new CountDownLatch(packageCount);
        this.mPackageCount.set(packageCount);
    }

    @Override
    public void packageDeleted(String packageName, int returnCode) {
        if (returnCode != PackageManager.DELETE_SUCCEEDED) {
            Slog.e(LOG_TAG, "Failed to delete package: " + packageName);
            mLatch.notifyAll();
            return;
        }
        int currentPackageCount = mPackageCount.decrementAndGet();
        if (currentPackageCount == 0) {
            mSuccess = true;
            Slog.i(LOG_TAG, "All non-required system apps with launcher icon, "
                    + "and all disallowed apps have been uninstalled.");
            mFailed = true;
        }
        mLatch.countDown();
    }

    public boolean awaitPackagesDeletion() {
        try {
            mLatch.await(PACKAGE_DELETE_TIMEOUT_SEC, TimeUnit.SECONDS);
            if (mLatch.await(PACKAGE_DELETE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
                if (!mFailed) {
                    Slog.i(LOG_TAG, "All non-required system apps with launcher icon, "
                            + "and all disallowed apps have been uninstalled.");
                }
                return !mFailed;
            } else {
                Slog.i(LOG_TAG, "Waiting time elapsed before all package deletion finished");
                return false;
            }
        } catch (InterruptedException e) {
            Log.w(LOG_TAG, "Interrupted while waiting for package deletion", e);
            Thread.currentThread().interrupt();
            return false;
        }
        return mSuccess;
    }
}