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

Commit b80c7c64 authored by TYM Tsai's avatar TYM Tsai
Browse files

Hold a wakelock for the installation

Installation makes no progress during screen off because the phone
suspends, so a wake lock is held to avoid becoming suspended.

Bug: 369147361
Flag: EXEMPT bug fix
Test: atest CtsInstallHostTestCases
Change-Id: Ia45564448268edeffee1544eb6a6cb1677c209fa
parent 2d60b512
Loading
Loading
Loading
Loading
+52 −5
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import static com.android.server.pm.PackageManagerService.SCAN_NO_DEX;
import static com.android.server.pm.PackageManagerService.SCAN_REQUIRE_KNOWN;
import static com.android.server.pm.PackageManagerService.SCAN_UPDATE_SIGNATURE;
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.PackageManagerService.WATCHDOG_TIMEOUT;
import static com.android.server.pm.PackageManagerServiceUtils.comparePackageSignatures;
import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
@@ -133,9 +134,11 @@ import android.os.Build;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
@@ -174,7 +177,6 @@ import com.android.internal.util.CollectionUtils;
import com.android.server.EventLogTags;
import com.android.server.SystemConfig;
import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.parsing.PackageCacher;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
@@ -210,6 +212,10 @@ import java.util.concurrent.ExecutorService;


final class InstallPackageHelper {
    // One minute over PM WATCHDOG_TIMEOUT
    private static final long WAKELOCK_TIMEOUT_MS = WATCHDOG_TIMEOUT + 1000 * 60;
    private static final String INSTALLER_WAKE_LOCK_TAG = "installer:packages";

    private final PackageManagerService mPm;
    private final AppDataHelper mAppDataHelper;
    private final BroadcastHelper mBroadcastHelper;
@@ -218,14 +224,16 @@ final class InstallPackageHelper {
    private final IncrementalManager mIncrementalManager;
    private final ApexManager mApexManager;
    private final DexManager mDexManager;
    private final ArtManagerService mArtManagerService;
    private final Context mContext;
    private final PackageDexOptimizer mPackageDexOptimizer;
    private final PackageAbiHelper mPackageAbiHelper;
    private final SharedLibrariesImpl mSharedLibraries;
    private final PackageManagerServiceInjector mInjector;
    private final UpdateOwnershipHelper mUpdateOwnershipHelper;

    private final Object mInternalLock = new Object();
    @GuardedBy("mInternalLock")
    private PowerManager.WakeLock mInstallingWakeLock;

    // TODO(b/198166813): remove PMS dependency
    InstallPackageHelper(PackageManagerService pm,
                         AppDataHelper appDataHelper,
@@ -241,9 +249,7 @@ final class InstallPackageHelper {
        mIncrementalManager = pm.mInjector.getIncrementalManager();
        mApexManager = pm.mInjector.getApexManager();
        mDexManager = pm.mInjector.getDexManager();
        mArtManagerService = pm.mInjector.getArtManagerService();
        mContext = pm.mInjector.getContext();
        mPackageDexOptimizer = pm.mInjector.getPackageDexOptimizer();
        mPackageAbiHelper = pm.mInjector.getAbiHelper();
        mSharedLibraries = pm.mInjector.getSharedLibrariesImpl();
        mUpdateOwnershipHelper = pm.mInjector.getUpdateOwnershipHelper();
@@ -1013,6 +1019,7 @@ final class InstallPackageHelper {
        boolean success = false;
        final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
        final Map<String, Settings.VersionInfo> versionInfos = new ArrayMap<>(requests.size());
        final long acquireTime = acquireWakeLock(requests.size());
        try {
            CriticalEventLog.getInstance().logInstallPackagesStarted();
            if (prepareInstallPackages(requests)
@@ -1033,6 +1040,46 @@ final class InstallPackageHelper {
        } finally {
            completeInstallProcess(requests, createdAppId, success);
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            releaseWakeLock(acquireTime, requests.size());
        }
    }

    private long acquireWakeLock(int count) {
        if (!mPm.isSystemReady()) {
            return -1;
        }
        synchronized (mInternalLock) {
            if (mInstallingWakeLock == null) {
                PowerManager pwm = mContext.getSystemService(PowerManager.class);
                if (pwm != null) {
                    mInstallingWakeLock = pwm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                            INSTALLER_WAKE_LOCK_TAG);
                } else {
                    Slog.w(TAG, "Unable to obtain power manager while obtaining wake lock");
                    return -1;
                }
            }

            mInstallingWakeLock.acquire(WAKELOCK_TIMEOUT_MS * count);
            return SystemClock.elapsedRealtime();
        }
    }

    private void releaseWakeLock(final long acquireTime, int count) {
        if (acquireTime < 0) {
            return;
        }
        synchronized (mInternalLock) {
            try {
                if (mInstallingWakeLock == null) {
                    return;
                }
                if (mInstallingWakeLock.isHeld()) {
                    mInstallingWakeLock.release();
                }
            } catch (RuntimeException e) {
                Slog.wtf(TAG, "Error while releasing installer lock", e);
            }
        }
    }