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

Commit 623777c2 authored by Songchun Fan's avatar Songchun Fan Committed by Android (Google) Code Review
Browse files

Merge "Refactor to prepare for incremental native lib extraction"

parents a85b3f18 03f92b2a
Loading
Loading
Loading
Loading
+61 −50
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ public class NativeLibraryHelper {
        private final CloseGuard mGuard = CloseGuard.get();
        private volatile boolean mClosed;

        final String[] apkPaths;
        final long[] apkHandles;
        final boolean multiArch;
        final boolean extractNativeLibs;
@@ -103,9 +104,11 @@ public class NativeLibraryHelper {
        private static Handle create(List<String> codePaths, boolean multiArch,
                boolean extractNativeLibs, boolean debuggable) throws IOException {
            final int size = codePaths.size();
            final String[] apkPaths = new String[size];
            final long[] apkHandles = new long[size];
            for (int i = 0; i < size; i++) {
                final String path = codePaths.get(i);
                apkPaths[i] = path;
                apkHandles[i] = nativeOpenApk(path);
                if (apkHandles[i] == 0) {
                    // Unwind everything we've opened so far
@@ -116,7 +119,7 @@ public class NativeLibraryHelper {
                }
            }

            return new Handle(apkHandles, multiArch, extractNativeLibs, debuggable);
            return new Handle(apkPaths, apkHandles, multiArch, extractNativeLibs, debuggable);
        }

        public static Handle createFd(PackageLite lite, FileDescriptor fd) throws IOException {
@@ -127,11 +130,13 @@ public class NativeLibraryHelper {
                throw new IOException("Unable to open APK " + path + " from fd " + fd);
            }

            return new Handle(apkHandles, lite.multiArch, lite.extractNativeLibs, lite.debuggable);
            return new Handle(new String[]{path}, apkHandles, lite.multiArch,
                    lite.extractNativeLibs, lite.debuggable);
        }

        Handle(long[] apkHandles, boolean multiArch, boolean extractNativeLibs,
                boolean debuggable) {
        Handle(String[] apkPaths, long[] apkHandles, boolean multiArch,
                boolean extractNativeLibs, boolean debuggable) {
            this.apkPaths = apkPaths;
            this.apkHandles = apkHandles;
            this.multiArch = multiArch;
            this.extractNativeLibs = extractNativeLibs;
@@ -313,40 +318,58 @@ public class NativeLibraryHelper {
    }

    public static int copyNativeBinariesForSupportedAbi(Handle handle, File libraryRoot,
            String[] abiList, boolean useIsaSubdir) throws IOException {
        createNativeLibrarySubdir(libraryRoot);

            String[] abiList, boolean useIsaSubdir, boolean isIncremental) throws IOException {
        /*
         * If this is an internal application or our nativeLibraryPath points to
         * the app-lib directory, unpack the libraries if necessary.
         */
        int abi = findSupportedAbi(handle, abiList);
        if (abi >= 0) {
        if (abi < 0) {
            return abi;
        }

        /*
         * If we have a matching instruction set, construct a subdir under the native
         * library root that corresponds to this instruction set.
         */
            final String instructionSet = VMRuntime.getInstructionSet(abiList[abi]);
        final String supportedAbi = abiList[abi];
        final String instructionSet = VMRuntime.getInstructionSet(supportedAbi);
        final File subDir;
        if (useIsaSubdir) {
                final File isaSubdir = new File(libraryRoot, instructionSet);
                createNativeLibrarySubdir(isaSubdir);
                subDir = isaSubdir;
            subDir = new File(libraryRoot, instructionSet);
        } else {
            subDir = libraryRoot;
        }

            int copyRet = copyNativeBinaries(handle, subDir, abiList[abi]);
        if (isIncremental) {
            int res =
                    incrementalConfigureNativeBinariesForSupportedAbi(handle, subDir, supportedAbi);
            if (res != PackageManager.INSTALL_SUCCEEDED) {
                // TODO(b/133435829): the caller of this function expects that we return the index
                // to the supported ABI. However, any non-negative integer can be a valid index.
                // We should fix this function and make sure it doesn't accidentally return an error
                // code that can also be a valid index.
                return res;
            }
            return abi;
        }

        // For non-incremental, use regular extraction and copy
        createNativeLibrarySubdir(libraryRoot);
        if (subDir != libraryRoot) {
            createNativeLibrarySubdir(subDir);
        }

        int copyRet = copyNativeBinaries(handle, subDir, supportedAbi);
        if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
            return copyRet;
        }
        }

        return abi;
    }

    public static int copyNativeBinariesWithOverride(Handle handle, File libraryRoot,
            String abiOverride) {
            String abiOverride, boolean isIncremental) {
        try {
            if (handle.multiArch) {
                // Warn if we've set an abiOverride for multi-lib packages..
@@ -359,7 +382,8 @@ public class NativeLibraryHelper {
                int copyRet = PackageManager.NO_NATIVE_LIBRARIES;
                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
                    copyRet = copyNativeBinariesForSupportedAbi(handle, libraryRoot,
                            Build.SUPPORTED_32_BIT_ABIS, true /* use isa specific subdirs */);
                            Build.SUPPORTED_32_BIT_ABIS, true /* use isa specific subdirs */,
                            isIncremental);
                    if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
                            copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
                        Slog.w(TAG, "Failure copying 32 bit native libraries; copyRet=" +copyRet);
@@ -369,7 +393,8 @@ public class NativeLibraryHelper {

                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
                    copyRet = copyNativeBinariesForSupportedAbi(handle, libraryRoot,
                            Build.SUPPORTED_64_BIT_ABIS, true /* use isa specific subdirs */);
                            Build.SUPPORTED_64_BIT_ABIS, true /* use isa specific subdirs */,
                            isIncremental);
                    if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
                            copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
                        Slog.w(TAG, "Failure copying 64 bit native libraries; copyRet=" +copyRet);
@@ -392,7 +417,7 @@ public class NativeLibraryHelper {
                }

                int copyRet = copyNativeBinariesForSupportedAbi(handle, libraryRoot, abiList,
                        true /* use isa specific subdirs */);
                        true /* use isa specific subdirs */, isIncremental);
                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
                    Slog.w(TAG, "Failure copying native libraries [errorCode=" + copyRet + "]");
                    return copyRet;
@@ -449,29 +474,15 @@ public class NativeLibraryHelper {
     * Service will create native library directories and set up native library binary files in the
     * same structure as they are in non-incremental installations.
     *
     * @param pkg The package to be installed, including all the APK files.
     * @param handle The pointer to an zip archive.
     * @param libraryRoot The root directory of the native library files, e.g., lib/
     * @param abiList The list of ABIs that are supported by the current device.
     * @param useIsaSubdir Whether or not to set up a sub dir for the ISA.
     * @return ABI code if installation succeeds or error code if installation fails.
     * @param handle The Handle object that contains all apk paths.
     * @param libSubDir The target directory to put the native library files, e.g., lib/ or lib/arm
     * @param abi The abi that is supported by the current device.
     * @return Integer code if installation succeeds or fails.
     */
    public static int configureNativeBinariesForSupportedAbi(AndroidPackage pkg, Handle handle,
            File libraryRoot, String[] abiList, boolean useIsaSubdir) {
        int abi = findSupportedAbi(handle, abiList);
        if (abi < 0) {
            Slog.e(TAG, "Failed to find find matching ABI.");
            return abi;
        }

        // Currently only support installations that have pre-configured native library files
        // TODO(b/136132412): implement this after incfs supports file mapping
        if (!libraryRoot.exists()) {
            Slog.e(TAG, "Incremental installation currently does not configure native libs");
            return INSTALL_FAILED_NO_MATCHING_ABIS;
        }

        return abi;
    private static int incrementalConfigureNativeBinariesForSupportedAbi(Handle handle,
            File libSubDir, String abi) {
        // TODO(b/136132412): implement this
        return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
    }

    // We don't care about the other return values for now.
+11 −33
Original line number Diff line number Diff line
@@ -344,18 +344,10 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
                    if (extractLibs) {
                        if (onIncremental) {
                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER,
                                    "incrementalNativeBinaries");
                            abi32 = NativeLibraryHelper.configureNativeBinariesForSupportedAbi(pkg,
                                    handle, nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
                                    useIsaSpecificSubdirs);
                        } else {
                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
                                    useIsaSpecificSubdirs);
                        }
                                useIsaSpecificSubdirs, onIncremental);
                    } else {
                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
                        abi32 = NativeLibraryHelper.findSupportedAbi(
@@ -375,18 +367,10 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {

                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
                    if (extractLibs) {
                        if (onIncremental) {
                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER,
                                    "incrementalNativeBinaries");
                            abi64 = NativeLibraryHelper.configureNativeBinariesForSupportedAbi(pkg,
                                    handle, nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
                                    useIsaSpecificSubdirs);
                        } else {
                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
                                    useIsaSpecificSubdirs);
                        }
                                useIsaSpecificSubdirs, onIncremental);
                    } else {
                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
                        abi64 = NativeLibraryHelper.findSupportedAbi(
@@ -437,15 +421,9 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {

                final int copyRet;
                if (extractLibs) {
                    if (onIncremental) {
                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "incrementalNativeBinaries");
                        copyRet = NativeLibraryHelper.configureNativeBinariesForSupportedAbi(pkg,
                                handle, nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
                    } else {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
                                nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
                    }
                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs, onIncremental);
                } else {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
+3 −6
Original line number Diff line number Diff line
@@ -1681,11 +1681,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                mInternalProgress = 0.5f;
                computeProgressLocked(true);

                // Unpack native libraries for non-incremental installation
                if (!isIncrementalInstallation()) {
                extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs());
            }
            }

            // We've reached point of no return; call into PMS to install the stage.
            // Regardless of success or failure we always destroy session.
@@ -2260,7 +2257,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        Slog.d(TAG, "Copied " + fromFiles.size() + " files into " + toDir);
    }

    private static void extractNativeLibraries(File packageDir, String abiOverride, boolean inherit)
    private void extractNativeLibraries(File packageDir, String abiOverride, boolean inherit)
            throws PackageManagerException {
        final File libDir = new File(packageDir, NativeLibraryHelper.LIB_DIR_NAME);
        if (!inherit) {
@@ -2272,7 +2269,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        try {
            handle = NativeLibraryHelper.Handle.create(packageDir);
            final int res = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libDir,
                    abiOverride);
                    abiOverride, isIncrementalInstallation());
            if (res != PackageManager.INSTALL_SUCCEEDED) {
                throw new PackageManagerException(res,
                        "Failed to extract native libraries, res=" + res);
+3 −2
Original line number Diff line number Diff line
@@ -3627,7 +3627,7 @@ public class PackageManagerService extends IPackageManager.Stub
            try {
                handle = NativeLibraryHelper.Handle.create(dstCodePath);
                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
                        null /*abiOverride*/);
                        null /*abiOverride*/, false /*isIncremental*/);
            } catch (IOException e) {
                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
                        + "; pkg: " + packageName);
@@ -14970,12 +14970,13 @@ public class PackageManagerService extends IPackageManager.Stub
                return ret;
            }
            final boolean isIncremental = isIncrementalPath(codeFile.getAbsolutePath());
            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
            NativeLibraryHelper.Handle handle = null;
            try {
                handle = NativeLibraryHelper.Handle.create(codeFile);
                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
                        abiOverride);
                        abiOverride, isIncremental);
            } catch (IOException e) {
                Slog.e(TAG, "Copying native libraries failed", e);
                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;