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

Commit 3e8cf0d7 authored by TYM Tsai's avatar TYM Tsai Committed by Pawan Wagh
Browse files

[PM] Fix deadlock between PMS and SettingsProvider

Bug: 443089413
Flag: EXEMPT BUGFIX
Test: atest FrameworksMockingServicesTests_android_server_pm
Test: atest PackageManagerServiceServerTests
Test: atest CtsPackageInstallTestCases
Change-Id: I45fe240f4a2a33485fbf04dc728a51847b7be3e5
parent 1b9e1815
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -4231,9 +4231,9 @@ final class InstallPackageHelper {
        final SharedUserSetting sharedUserSetting;
        SharedUserSetting oldSharedUserSetting = null;

        final boolean isSystemApp = AndroidPackageLegacyUtils.isSystem(parsedPackage);
        synchronized (mPm.mLock) {
            platformPackage = mPm.getPlatformPackage();
            var isSystemApp = AndroidPackageLegacyUtils.isSystem(parsedPackage);
            final String renamedPkgName = mPm.mSettings.getRenamedPackageLPr(
                    AndroidPackageUtils.getRealPackageOrNull(parsedPackage, isSystemApp));
            realPkgName = ScanPackageUtils.getRealPackageName(parsedPackage, renamedPkgName,
@@ -4278,14 +4278,21 @@ final class InstallPackageHelper {

        final boolean isPlatformPackage = platformPackage != null
                && platformPackage.getPackageName().equals(parsedPackage.getPackageName());

        final  String initiatingPackage = installedPkgSetting != null
                ? installedPkgSetting.getInstallSource().mInitiatingPackageName : null;
        // Run 16 KB alignment checks on 4 KB device if evaluated as true for new installations.
        // To prevent deadlock, move the call of SettingsProvider out of mLock block
        final boolean enableAlignmentChecks = ScanPackageUtils.enableAlignmentChecks(
                parsedPackage, mPm.mInjector.getContext(), initiatingPackage,
                isSystemApp, isPlatformPackage, scanFlags);
        return new ScanRequest(parsedPackage, oldSharedUserSetting,
                installedPkgSetting == null ? null : installedPkgSetting.getPkg() /* oldPkg */,
                installedPkgSetting /* packageSetting */,
                sharedUserSetting,
                disabledPkgSetting /* disabledPackageSetting */,
                originalPkgSetting  /* originalPkgSetting */,
                realPkgName, parseFlags, scanFlags, isPlatformPackage, user, cpuAbiOverride);
                realPkgName, parseFlags, scanFlags, isPlatformPackage, user, cpuAbiOverride,
                enableAlignmentChecks);
    }

    private ScanResult scanPackageNew(@NonNull ParsedPackage parsedPackage,
@@ -4318,7 +4325,7 @@ final class InstallPackageHelper {
                    initialScanRequest.mSharedUserSetting, disabledPkgSetting,
                    initialScanRequest.mOriginalPkgSetting, initialScanRequest.mRealPkgName,
                    parseFlags, scanFlags, initialScanRequest.mIsPlatformPackage, user,
                    cpuAbiOverride);
                    cpuAbiOverride, initialScanRequest.mEnableAlignmentChecks);
            return ScanPackageUtils.scanPackageOnly(request, mPm.mInjector, mPm.mFactoryTest,
                    currentTime);
        }
@@ -4345,6 +4352,7 @@ final class InstallPackageHelper {
            final boolean isSystemPkgUpdated;
            final PackageSetting disabledPkgSetting;
            final boolean isUpgrade;

            synchronized (mPm.mLock) {
                isUpgrade = mPm.isDeviceUpgrading();
                if (scanSystemPartition && !pkgAlreadyExists
@@ -4372,7 +4380,8 @@ final class InstallPackageHelper {
                            initialScanRequest.mSharedUserSetting,
                            null /* disabledPkgSetting */, null /* originalPkgSetting */,
                            null, parseFlags, scanFlags,
                            initialScanRequest.mIsPlatformPackage, user, null);
                            initialScanRequest.mIsPlatformPackage, user, null,
                            initialScanRequest.mEnableAlignmentChecks);
                    ScanPackageUtils.applyPolicy(parsedPackage, scanFlags,
                            mPm.getPlatformPackage(), true);
                    final ScanResult scanResult =
+24 −21
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM;
import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM_EXT;
import static com.android.server.pm.PackageManagerService.SCAN_AS_VENDOR;
import static com.android.server.pm.PackageManagerService.SCAN_AS_VIRTUAL_PRELOAD;
import static com.android.server.pm.PackageManagerService.SCAN_BOOTING;
import static com.android.server.pm.PackageManagerService.SCAN_DONT_KILL_APP;
import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE;
import static com.android.server.pm.PackageManagerService.SCAN_MOVE;
@@ -425,25 +424,13 @@ final class ScanPackageUtils {

        boolean is16KbDevice = Os.sysconf(OsConstants._SC_PAGESIZE) == PAGE_SIZE_16KB;

        // Run 16 KB alignment checks on 4 KB device if evaluated as true for new installations.
        boolean enable4kbChecks =  false;
        if ((Build.SUPPORTED_64_BIT_ABIS.length > 0)
                && !isSystemApp
                && !isApex
                && !isPlatformPackage
                && (scanFlags & SCAN_NEW_INSTALL) != 0
        ) {
            enable4kbChecks = enableAlignmentChecks(parsedPackage, injector.getContext(),
                pkgSetting.getInstallSource().mInitiatingPackageName);
        }

        // If package is upgrading, mPageSizeCompatFlags in PackageSetting should be populated
        // according to the upgraded package.
        if (!createNewPackage) {
            pkgSetting.clearPageSizeAppCompatFlags();
        }

        if (Flags.appCompatOption16kb() && (is16KbDevice || enable4kbChecks)) {
        if (Flags.appCompatOption16kb() && (is16KbDevice || request.mEnableAlignmentChecks)) {
            // Alignment checks are used decide whether this app should run in compat mode when
            // nothing was specified in manifest. Manifest should always take precedence over
            // something decided by platform.
@@ -1107,13 +1094,24 @@ final class ScanPackageUtils {
        }
    }

    private static boolean enableAlignmentChecks(@NonNull ParsedPackage parsedPackage,
            Context context, String initiatingPackage) {
    static boolean enableAlignmentChecks(@NonNull ParsedPackage parsedPackage,
            Context context, String initiatingPackage, boolean isSystemApp,
            boolean isPlatformPackage, int scanFlags) {
        // Run alignment checks when feature flag is enabled
        if (!Flags.appCompatWarnings16kb()) {
            return false;
        }

        final boolean isApex = (scanFlags & SCAN_AS_APEX) != 0;
        final boolean isNewInstall = (scanFlags & SCAN_NEW_INSTALL) != 0;
        if ((Build.SUPPORTED_64_BIT_ABIS.length == 0)
                || isSystemApp
                || isApex
                || isPlatformPackage
                || !isNewInstall) {
            return false;
        }

        if (context == null) {
            Slog.w(TAG, "Provided context is null!");
            return false;
@@ -1125,12 +1123,17 @@ final class ScanPackageUtils {
            return false;
        }

        boolean isDebuggable = parsedPackage.isDebuggable();
        boolean isDeveloperMode = android.provider.Settings.Global.getInt(resolver,
                android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
        final boolean isDebuggable = parsedPackage.isDebuggable();
        if (!isDebuggable) {
            return false;
        }
        boolean isInstalledByAdb = PackageManagerServiceUtils.isInstalledByAdb(initiatingPackage);

        return isDebuggable && isDeveloperMode && isInstalledByAdb;
        if (!isInstalledByAdb) {
            return false;
        }
        final boolean isDeveloperMode = android.provider.Settings.Global.getInt(resolver,
                android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
        return isDeveloperMode;
    }

    /** Directory where installed application's 32-bit native libraries are copied. */
+4 −1
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ final class ScanRequest {
    public final boolean mIsPlatformPackage;
    /** Override value for package ABI if set during install */
    @Nullable public final String mCpuAbiOverride;
    public final boolean mEnableAlignmentChecks;

    ScanRequest(
            @NonNull ParsedPackage parsedPackage,
@@ -72,7 +73,8 @@ final class ScanRequest {
            @PackageManagerService.ScanFlags int scanFlags,
            boolean isPlatformPackage,
            @Nullable UserHandle user,
            @Nullable String cpuAbiOverride) {
            @Nullable String cpuAbiOverride,
            boolean enableAlignmentChecks) {
        mParsedPackage = parsedPackage;
        mOldPkg = oldPkg;
        mPkgSetting = pkgSetting;
@@ -87,5 +89,6 @@ final class ScanRequest {
        mIsPlatformPackage = isPlatformPackage;
        mUser = user;
        mCpuAbiOverride = cpuAbiOverride;
        mEnableAlignmentChecks = enableAlignmentChecks;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -118,6 +118,6 @@ class ScanRequestBuilder {
        return new ScanRequest(
                mPkg, mOldSharedUserSetting, mOldPkg, mPkgSetting, mSharedUserSetting,
                mDisabledPkgSetting, mOriginalPkgSetting, mRealPkgName, mParseFlags, mScanFlags,
                mIsPlatformPackage, mUser, mCpuAbiOverride);
                mIsPlatformPackage, mUser, mCpuAbiOverride, /* enableAlignmentChecks= */ false);
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -228,7 +228,7 @@ class SharedLibrariesImplTest {
            staticLibrary = STATIC_LIB_NAME, staticLibraryVersion = 10L)
        val parsedPackage = pair.second as ParsedPackage
        val scanRequest = ScanRequest(parsedPackage, null, null, null, null,
            null, null, null, 0, 0, false, null, null)
            null, null, null, 0, 0, false, null, null, false)
        val scanResult = ScanResult(scanRequest, null, false, 0, null, null, null)
        var installRequest = InstallRequest(parsedPackage, 0, 0, UserHandle(0), scanResult, null)

@@ -334,7 +334,7 @@ class SharedLibrariesImplTest {
            .createBasicSettingBuilder(pair.first.parentFile, parsedPackage.hideAsFinal())
            .setPkgFlags(ApplicationInfo.FLAG_SYSTEM).build()
        val scanRequest = ScanRequest(parsedPackage, null, null, null, null,
            null, null, null, 0, 0, false, null, null)
            null, null, null, 0, 0, false, null, null, false)
        val scanResult = ScanResult(scanRequest, packageSetting, false, 0, null, null,
            listOf(testInfo))
        var installRequest = InstallRequest(parsedPackage, 0, 0, UserHandle(0), scanResult, null)