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

Commit e1a6299b authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Relax locking when scanning private volumes.

Private volumes with many large apps can take a long time to scan,
which currently happens on the main thread with several large locks
held, making it likely to trigger the system-wide watchdog.

This change relaxes this locking by scanning on the PackageManager
worker thread, and by only holding locks when required.  In
particular, we release the installer lock between each scan to give
other apps waiting to dexopt a chance to breathe.

Bug: 24172036
Change-Id: Ie28d3ff72d6be28fa2f72c57d5e4146c768df89d
parent ad0acf1d
Loading
Loading
Loading
Loading
+31 −7
Original line number Diff line number Diff line
@@ -15664,14 +15664,28 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
    }
    private void loadPrivatePackages(VolumeInfo vol) {
    private void loadPrivatePackages(final VolumeInfo vol) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                loadPrivatePackagesInner(vol);
            }
        });
    }
    private void loadPrivatePackagesInner(VolumeInfo vol) {
        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
        synchronized (mInstallLock) {
        final VersionInfo ver;
        final List<PackageSetting> packages;
        synchronized (mPackages) {
            final VersionInfo ver = mSettings.findOrCreateVersion(vol.fsUuid);
            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
            ver = mSettings.findOrCreateVersion(vol.fsUuid);
            packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
        }
        for (PackageSetting ps : packages) {
            synchronized (mInstallLock) {
                final PackageParser.Package pkg;
                try {
                    pkg = scanPackageLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null);
@@ -15684,7 +15698,9 @@ public class PackageManagerService extends IPackageManager.Stub {
                    deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
                }
            }
        }
        synchronized (mPackages) {
            int updateFlags = UPDATE_PERMISSIONS_ALL;
            if (ver.sdkVersion != mSdkVersion) {
                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
@@ -15698,13 +15714,21 @@ public class PackageManagerService extends IPackageManager.Stub {
            mSettings.writeLPr();
        }
        }
        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
        sendResourcesChangedBroadcast(true, false, loaded, null);
    }
    private void unloadPrivatePackages(VolumeInfo vol) {
    private void unloadPrivatePackages(final VolumeInfo vol) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                unloadPrivatePackagesInner(vol);
            }
        });
    }
    private void unloadPrivatePackagesInner(VolumeInfo vol) {
        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
        synchronized (mInstallLock) {
        synchronized (mPackages) {