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

Commit 1e7589af authored by Joanne Chung's avatar Joanne Chung
Browse files

Fix deadlock between PackageManager and DisplayManager

UpdateOwnershipHelper#readUpdateOwnerDenyList calls getResources()
that will call getDisplayMetrics. In DisplayMetrics() that needs to
access a lock in DisplayManagerGlobal. When calling this method
inside mPm.mLock, it may trigger the deadlock between PackageManager
and DisplayManager.

To fix this issue, try to get the denylist in the handler thread and
outside the mPm.mLock.

Bug: 305615356
Test: manual. Add logs to make sure getResources() doesn't be called
inside mPm.mLock

Change-Id: I3dea7b1df6f115d7c1cffda6a9d51070a5d7dd80
parent 5ea095ca
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -476,20 +476,30 @@ final class InstallPackageHelper {
            pkgSetting.setLoadingProgress(1f);
        }

        // TODO: passes the package name as an argument in a message to the handler for V+
        //  so we don't need to rely on creating lambda objects so frequently.
        if (UpdateOwnershipHelper.hasValidOwnershipDenyList(pkgSetting)) {
            mPm.mHandler.post(() -> handleUpdateOwnerDenyList(pkgSetting));
        }
        return pkg;
    }

    private void handleUpdateOwnerDenyList(PackageSetting pkgSetting) {
        ArraySet<String> listItems = mUpdateOwnershipHelper.readUpdateOwnerDenyList(pkgSetting);
        if (listItems != null && !listItems.isEmpty()) {
            mUpdateOwnershipHelper.addToUpdateOwnerDenyList(pkgSetting.getPackageName(), listItems);
            mUpdateOwnershipHelper.addToUpdateOwnerDenyList(pkgSetting.getPackageName(),
                    listItems);
            SystemConfig config = SystemConfig.getInstance();
            synchronized (mPm.mLock) {
                for (String unownedPackage : listItems) {
                    PackageSetting unownedSetting = mPm.mSettings.getPackageLPr(unownedPackage);
                SystemConfig config = SystemConfig.getInstance();
                    if (unownedSetting != null
                            && config.getSystemAppUpdateOwnerPackageName(unownedPackage) == null) {
                        unownedSetting.setUpdateOwnerPackage(null);
                    }
                }
            }

        return pkg;
        }
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ public class UpdateOwnershipHelper {

    private final Object mLock = new Object();

    private static boolean hasValidOwnershipDenyList(PackageSetting pkgSetting) {
    static boolean hasValidOwnershipDenyList(PackageSetting pkgSetting) {
        AndroidPackage pkg = pkgSetting.getPkg();
        // we're checking for uses-permission for these priv permissions instead of grant as we're
        // only considering system apps to begin with, so presumed to be granted.