summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageManager.java11
-rw-r--r--services/core/java/com/android/server/pm/PackageAbiHelperImpl.java90
2 files changed, 89 insertions, 12 deletions
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 49c8a7cad57a..2a673530578a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2554,6 +2554,15 @@ public abstract class PackageManager {
public static final int INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST = -130;
/**
+ * Installation failed return code: if the system failed to install the package that
+ * {@link android.R.attr#multiArch} is true in its manifest because its packaged
+ * native code did not match all of the natively ABIs supported by the system.
+ *
+ * @hide
+ */
+ public static final int INSTALL_FAILED_MULTI_ARCH_NOT_MATCH_ALL_NATIVE_ABIS = -131;
+
+ /**
* App minimum aspect ratio set by the user which will override app-defined aspect ratio.
*
* @hide
@@ -10452,6 +10461,8 @@ public abstract class PackageManager {
case INSTALL_FAILED_SESSION_INVALID: return "INSTALL_FAILED_SESSION_INVALID";
case INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST:
return "INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST";
+ case INSTALL_FAILED_MULTI_ARCH_NOT_MATCH_ALL_NATIVE_ABIS:
+ return "INSTALL_FAILED_MULTI_ARCH_NOT_MATCH_ALL_NATIVE_ABIS";
default: return Integer.toString(status);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
index 85d2df320fc9..bbce26c85549 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -27,11 +27,14 @@ import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
+import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.pm.Flags;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.FileUtils;
+import android.os.SystemProperties;
import android.os.Trace;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -50,9 +53,15 @@ import libcore.io.IoUtils;
import java.io.File;
import java.io.IOException;
+import java.util.Set;
final class PackageAbiHelperImpl implements PackageAbiHelper {
+ @Nullable
+ private static String[] sNativelySupported32BitAbis = null;
+ @Nullable
+ private static String[] sNativelySupported64BitAbis = null;
+
private static String calculateBundledApkRoot(final String codePathString) {
final File codePath = new File(codePathString);
final File codeRoot;
@@ -122,13 +131,20 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
}
}
- private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
- PackageManagerException {
+ private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet,
+ boolean forceMatch) throws PackageManagerException {
if (copyRet < 0) {
if (copyRet != PackageManager.NO_NATIVE_LIBRARIES
&& copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
throw new PackageManagerException(copyRet, message);
}
+
+ if (forceMatch && copyRet == PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
+ throw new PackageManagerException(
+ PackageManager.INSTALL_FAILED_MULTI_ARCH_NOT_MATCH_ALL_NATIVE_ABIS,
+ "The multiArch app's native libs don't support all the natively"
+ + " supported ABIs of the device.");
+ }
}
}
@@ -296,7 +312,40 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
return new Abis(primaryCpuAbi, secondaryCpuAbi);
}
+ @NonNull
+ private static String[] getNativelySupportedAbis(@NonNull String[] supportedAbis) {
+ Set<String> nativelySupportedAbis = new ArraySet<>();
+ for (int i = 0; i < supportedAbis.length; i++) {
+ final String currentAbi = supportedAbis[i];
+ // In presence of a native bridge this means the Abi is emulated.
+ final String currentIsa = VMRuntime.getInstructionSet(currentAbi);
+ if (TextUtils.isEmpty(SystemProperties.get("ro.dalvik.vm.isa." + currentIsa))) {
+ nativelySupportedAbis.add(currentAbi);
+ }
+ }
+ return nativelySupportedAbis.toArray(new String[0]);
+ }
+
+ private static String[] getNativelySupported32BitAbis() {
+ if (sNativelySupported32BitAbis != null) {
+ return sNativelySupported32BitAbis;
+ }
+
+ sNativelySupported32BitAbis = getNativelySupportedAbis(Build.SUPPORTED_32_BIT_ABIS);
+ return sNativelySupported32BitAbis;
+ }
+
+ private static String[] getNativelySupported64BitAbis() {
+ if (sNativelySupported64BitAbis != null) {
+ return sNativelySupported64BitAbis;
+ }
+
+ sNativelySupported64BitAbis = getNativelySupportedAbis(Build.SUPPORTED_64_BIT_ABIS);
+ return sNativelySupported64BitAbis;
+ }
+
@Override
+ @SuppressWarnings("AndroidFrameworkCompatChange") // the check is before the apk is installed
public Pair<Abis, NativeLibraryPaths> derivePackageAbi(AndroidPackage pkg, boolean isSystemApp,
boolean isUpdatedSystemApp, String cpuAbiOverride, File appLib32InstallDir)
throws PackageManagerException {
@@ -334,18 +383,33 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
primaryCpuAbi = null;
secondaryCpuAbi = null;
if (pkg.isMultiArch()) {
+ // Force the match for these cases
+ // 1. pkg.getTargetSdkVersion >= Build.VERSION_CODES.VANILLA_ICE_CREAM
+ // 2. cpuAbiOverride is null. If it is non-null, it is set via shell for testing
+ final boolean forceMatch = Flags.forceMultiArchNativeLibsMatch()
+ && pkg.getTargetSdkVersion() >= Build.VERSION_CODES.VANILLA_ICE_CREAM
+ && cpuAbiOverride == null;
+
+ String[] supported32BitAbis = forceMatch ? getNativelySupported32BitAbis()
+ : Build.SUPPORTED_32_BIT_ABIS;
+ String[] supported64BitAbis = forceMatch ? getNativelySupported64BitAbis()
+ : Build.SUPPORTED_64_BIT_ABIS;
+
+ final boolean systemSupports32BitAbi = supported32BitAbis.length > 0;
+ final boolean systemSupports64BitAbi = supported64BitAbis.length > 0;
+
int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
- if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
+ if (systemSupports32BitAbi) {
if (extractLibs) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
- nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
+ nativeLibraryRoot, supported32BitAbis,
useIsaSpecificSubdirs, onIncremental);
} else {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
abi32 = NativeLibraryHelper.findSupportedAbi(
- handle, Build.SUPPORTED_32_BIT_ABIS);
+ handle, supported32BitAbis);
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
@@ -357,24 +421,26 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
}
maybeThrowExceptionForMultiArchCopy(
- "Error unpackaging 32 bit native libs for multiarch app.", abi32);
+ "Error unpackaging 32 bit native libs for multiarch app.", abi32,
+ forceMatch && systemSupports32BitAbi);
- if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
+ if (systemSupports64BitAbi) {
if (extractLibs) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
- nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
+ nativeLibraryRoot, supported64BitAbis,
useIsaSpecificSubdirs, onIncremental);
} else {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
abi64 = NativeLibraryHelper.findSupportedAbi(
- handle, Build.SUPPORTED_64_BIT_ABIS);
+ handle, supported64BitAbis);
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
maybeThrowExceptionForMultiArchCopy(
- "Error unpackaging 64 bit native libs for multiarch app.", abi64);
+ "Error unpackaging 64 bit native libs for multiarch app.", abi64,
+ forceMatch && systemSupports64BitAbi);
if (abi64 >= 0) {
// Shared library native libs should be in the APK zip aligned
@@ -382,11 +448,11 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
"Shared library native lib extraction not supported");
}
- primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
+ primaryCpuAbi = supported64BitAbis[abi64];
}
if (abi32 >= 0) {
- final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
+ final String abi = supported32BitAbis[abi32];
if (abi64 >= 0) {
if (pkg.is32BitAbiPreferred()) {
secondaryCpuAbi = primaryCpuAbi;