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

Commit 7dba6eb3 authored by Narayan Kamath's avatar Narayan Kamath
Browse files

Adjust nativeLibraryDir for package contexts of multiArch installs.

When we're creating a package context for a multi-arch app,
adjust the native library directory to match the bitness of
the process creating the context.

This change also removes apkRoot (which wasn't really being used)
and replaces it with a fully constructed secondary library path.
The secondary library path is a transitional measure until we
can reorganize the system image so that we can use nativeLibraryRoot
for system paths as well (nativeLibraryRootRequiresIsa will then
be true for all packages except for legacy installs).

bug: 16013931

Change-Id: I5ae090334b377b9e087aecf40075fab81b20b132
parent 1d935abd
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.view.DisplayAdjustments;
import android.view.Display;
import dalvik.system.VMRuntime;

import java.io.File;
import java.io.IOException;
@@ -121,6 +122,8 @@ public final class LoadedApk {
            CompatibilityInfo compatInfo, ClassLoader baseLoader,
            boolean securityViolation, boolean includeCode) {
        final int myUid = Process.myUid();
        aInfo = adjustNativeLibraryPaths(aInfo);

        mActivityThread = activityThread;
        mApplicationInfo = aInfo;
        mPackageName = aInfo.packageName;
@@ -143,6 +146,27 @@ public final class LoadedApk {
        mDisplayAdjustments.setCompatibilityInfo(compatInfo);
    }

    private static ApplicationInfo adjustNativeLibraryPaths(ApplicationInfo info) {
        // If we're dealing with a multi-arch application that has both
        // 32 and 64 bit shared libraries, we might need to choose the secondary
        // depending on what the current runtime's instruction set is.
        if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
            final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
            final String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);

            // If the runtimeIsa is the same as the primary isa, then we do nothing.
            // Everything will be set up correctly because info.nativeLibraryDir will
            // correspond to the right ISA.
            if (runtimeIsa.equals(secondaryIsa)) {
                final ApplicationInfo modified = new ApplicationInfo(info);
                modified.nativeLibraryDir = modified.secondaryNativeLibraryDir;
                return modified;
            }
        }

        return info;
    }

    /**
     * Create information about the system package.
     * Must call {@link #installSystemApplicationInfo} later.
+20 −20
Original line number Diff line number Diff line
@@ -490,6 +490,23 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
     */
    public String nativeLibraryDir;

    /**
     * Full path where unpacked native libraries for {@link #secondaryCpuAbi}
     * are stored, if present.
     *
     * The main reason this exists is for bundled multi-arch apps, where
     * it's not trivial to calculate the location of libs for the secondary abi
     * given the location of the primary.
     *
     * TODO: Change the layout of bundled installs so that we can use
     * nativeLibraryRootDir & nativeLibraryRootRequiresIsa there as well.
     * (e.g {@code [ "/system/app-lib/Foo/arm", "/system/app-lib/Foo/arm64" ]}
     * instead of {@code [ "/system/lib/Foo", "/system/lib64/Foo" ]}.
     *
     * @hide
     */
    public String secondaryNativeLibraryDir;

    /**
     * The root path where unpacked native libraries are stored.
     * <p>
@@ -529,23 +546,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
     */
    public String secondaryCpuAbi;

    /**
     * The derived APK "root" for the given package. Will be non-null for bundled and
     * updated system apps. This will be a top level path under which apks and libraries
     * are installed, for eg. {@code /system}, {@code /oem} or {@code /vendor}. This is
     * used to calculate the location of native code for a given package, for e.g
     * {@code /vendor/lib} or {@code /vendor/lib64}.
     *
     * For app updates or fresh app installs, this will be {@code null} and we will use
     * {@code legacyNativeLibraryDir}
     *
     * NOTE: This can be removed if we have a unified layout for bundled and installed
     * apps.
     *
     * {@hide}
     */
    public String apkRoot;

    /**
     * The kernel user-ID that has been assigned to this application;
     * currently this is not a unique ID (multiple applications can have
@@ -688,11 +688,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
        splitSourceDirs = orig.splitSourceDirs;
        splitPublicSourceDirs = orig.splitPublicSourceDirs;
        nativeLibraryDir = orig.nativeLibraryDir;
        secondaryNativeLibraryDir = orig.secondaryNativeLibraryDir;
        nativeLibraryRootDir = orig.nativeLibraryRootDir;
        nativeLibraryRootRequiresIsa = orig.nativeLibraryRootRequiresIsa;
        primaryCpuAbi = orig.primaryCpuAbi;
        secondaryCpuAbi = orig.secondaryCpuAbi;
        apkRoot = orig.apkRoot;
        resourceDirs = orig.resourceDirs;
        seinfo = orig.seinfo;
        sharedLibraryFiles = orig.sharedLibraryFiles;
@@ -736,11 +736,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
        dest.writeStringArray(splitSourceDirs);
        dest.writeStringArray(splitPublicSourceDirs);
        dest.writeString(nativeLibraryDir);
        dest.writeString(secondaryNativeLibraryDir);
        dest.writeString(nativeLibraryRootDir);
        dest.writeInt(nativeLibraryRootRequiresIsa ? 1 : 0);
        dest.writeString(primaryCpuAbi);
        dest.writeString(secondaryCpuAbi);
        dest.writeString(apkRoot);
        dest.writeStringArray(resourceDirs);
        dest.writeString(seinfo);
        dest.writeStringArray(sharedLibraryFiles);
@@ -783,11 +783,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
        splitSourceDirs = source.readStringArray();
        splitPublicSourceDirs = source.readStringArray();
        nativeLibraryDir = source.readString();
        secondaryNativeLibraryDir = source.readString();
        nativeLibraryRootDir = source.readString();
        nativeLibraryRootRequiresIsa = source.readInt() != 0;
        primaryCpuAbi = source.readString();
        secondaryCpuAbi = source.readString();
        apkRoot = source.readString();
        resourceDirs = source.readStringArray();
        seinfo = source.readString();
        sharedLibraryFiles = source.readStringArray();
+20 −8
Original line number Diff line number Diff line
@@ -6181,13 +6181,18 @@ public class PackageManagerService extends IPackageManager.Stub {
        final ApplicationInfo info = pkg.applicationInfo;
        final String codePath = pkg.codePath;
        final File codeFile = new File(codePath);
        // If "/system/lib64/apkname" exists, assume that is the per-package
        // native library directory to use; otherwise use "/system/lib/apkname".
        final String apkRoot = calculateApkRoot(info.sourceDir);
        final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info);
        final boolean asecApp = isForwardLocked(info) || isExternal(info);
        info.nativeLibraryRootDir = null;
        info.nativeLibraryRootRequiresIsa = false;
        info.nativeLibraryDir = null;
        info.secondaryNativeLibraryDir = null;
        if (bundledApp) {
            // Monolithic bundled install
@@ -6201,35 +6206,43 @@ public class PackageManagerService extends IPackageManager.Stub {
            // is just the default path.
            final String apkName = deriveCodePathName(codePath);
            final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
            info.nativeLibraryRootDir = Environment.buildPath(new File(info.apkRoot), libDir,
            info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
                    apkName).getAbsolutePath();
            info.nativeLibraryRootRequiresIsa = false;
            info.nativeLibraryDir = info.nativeLibraryRootDir;
            if (info.secondaryCpuAbi != null) {
                final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
                info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
                        secondaryLibDir, apkName).getAbsolutePath();
            }
        } else if (isApkFile(codeFile)) {
            // Monolithic install
            if (asecApp) {
                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
                        .getAbsolutePath();
                info.nativeLibraryRootRequiresIsa = false;
            } else {
                final String apkName = deriveCodePathName(codePath);
                info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
                        .getAbsolutePath();
                info.nativeLibraryRootRequiresIsa = false;
            }
            info.nativeLibraryRootRequiresIsa = false;
            info.nativeLibraryDir = info.nativeLibraryRootDir;
        } else {
            // Cluster install
            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
            info.nativeLibraryRootRequiresIsa = true;
        }
        if (info.nativeLibraryRootRequiresIsa) {
            if (info.primaryCpuAbi != null) {
                info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
                        VMRuntime.getInstructionSet(info.primaryCpuAbi)).getAbsolutePath();
            }
        } else {
            info.nativeLibraryDir = info.nativeLibraryRootDir;
            if (info.secondaryCpuAbi != null) {
                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
            }
        }
    }
@@ -6247,7 +6260,6 @@ public class PackageManagerService extends IPackageManager.Stub {
        // If "/system/lib64/apkname" exists, assume that is the per-package
        // native library directory to use; otherwise use "/system/lib/apkname".
        final String apkRoot = calculateApkRoot(pkg.applicationInfo.sourceDir);
        pkg.applicationInfo.apkRoot = apkRoot;
        setBundledAppAbi(pkg, apkRoot, apkName);
        // pkgSetting might be null during rescan following uninstall of updates
        // to a bundled app, so accommodate that possibility.  The settings in