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

Commit ebb93a41 authored by Song Chun Fan's avatar Song Chun Fan
Browse files

[pm] move extractNativeLibraries out of lock

This operation can take long and block other accesses of mLock such
as getPackageName. Move it out of the synchronized block, and use
mStageDirInUse to prevent the stage dir from being modified.

BUG: 393698598
FIXES: 393698598
Test: presubmit
FLAG: EXEMPT refactor

Change-Id: I9eb5442c5c4e3e86826635d4eb0be2418ee736c5
parent 79d84ec1
Loading
Loading
Loading
Loading
+43 −30
Original line number Diff line number Diff line
@@ -2937,10 +2937,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                List<PackageInstallerSession> children = getChildSessions();
                if (isMultiPackage()) {
                    for (PackageInstallerSession child : children) {
                        child.extractNativeLibraries();
                        final File libDir = child.prepareExtractNativeLibraries();
                        if (libDir != null) {
                            child.extractNativeLibraries(libDir);
                        }
                    }
                } else {
                    extractNativeLibraries();
                    final File libDir = prepareExtractNativeLibraries();
                    if (libDir != null) {
                        extractNativeLibraries(libDir);
                    }
                }
                mHandler.obtainMessage(MSG_ON_NATIVE_LIBS_EXTRACTED).sendToTarget();
            } catch (PackageManagerException e) {
@@ -3099,10 +3105,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    }

    @WorkerThread
    private void extractNativeLibraries() throws PackageManagerException {
    private File prepareExtractNativeLibraries() throws PackageManagerException {
        synchronized (mLock) {
            if (mPackageLite != null) {
                if (!isApexSession()) {
            if (mPackageLite == null) {
                return null;
            }
            if (isApexSession()) {
                return null;
            }
            synchronized (mProgressLock) {
                mInternalProgress = 0.5f;
                computeProgressLocked(true);
@@ -3114,12 +3124,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            }
            // Skip native libraries processing for archival installation.
            if (isArchivedInstallation()) {
                        return;
                    }
                    extractNativeLibraries(
                            mPackageLite, libDir, params.abiOverride);
                }
                return null;
            }
            return libDir;
        }
    }

@@ -4509,22 +4516,28 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        Slog.d(TAG, "Copied " + fromFiles.size() + " files into " + toDir);
    }

    private void extractNativeLibraries(PackageLite packageLite, File libDir,
            String abiOverride)
            throws PackageManagerException {
        Objects.requireNonNull(packageLite);
    @WorkerThread
    private void extractNativeLibraries(File libDir) throws PackageManagerException {
        NativeLibraryHelper.Handle handle = null;
        try {
            handle = NativeLibraryHelper.Handle.create(packageLite);
            synchronized (mLock) {
                Objects.requireNonNull(mPackageLite);
                try {
                    handle = NativeLibraryHelper.Handle.create(mPackageLite);
                } catch (IOException e) {
                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
                            "Failed to extract native libraries", e);
                }
                // Release the mLock before starting the native lib extraction.
                // Use mStageDirInUse to prevent stage dir from being deleted during the extraction.
                markStageDirInUseLocked();
            }
            final int res = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libDir,
                    abiOverride, isIncrementalInstallation());
                    params.abiOverride, isIncrementalInstallation());
            if (res != INSTALL_SUCCEEDED) {
                throw new PackageManagerException(res,
                        "Failed to extract native libraries, res=" + res);
            }
        } catch (IOException e) {
            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
                    "Failed to extract native libraries", e);
        } finally {
            IoUtils.closeQuietly(handle);
        }