summaryrefslogtreecommitdiffstats
path: root/core/jni
diff options
context:
space:
mode:
authorChristopher R. Palmer <crpalmer@gmail.com>2015-12-29 11:11:35 -0500
committerGerrit Code Review <gerrit@cyanogenmod.org>2016-03-10 17:13:27 -0800
commit564f10b8f05ddf4d9ea2c0e64f1b113fe6dad4b8 (patch)
tree15abb71476b559699dde3f2a0c0087fefcd76eca /core/jni
parent4718479d82557510c0dc864618af77631c60eb4b (diff)
downloadframeworks_base-564f10b8f05ddf4d9ea2c0e64f1b113fe6dad4b8.zip
frameworks_base-564f10b8f05ddf4d9ea2c0e64f1b113fe6dad4b8.tar.gz
frameworks_base-564f10b8f05ddf4d9ea2c0e64f1b113fe6dad4b8.tar.bz2
intel: Pick the best ABI based on number of libs, not just priority
The normal package loading will open the APK and find the highest priority ABI that contains one or more native libraries. This works well for 64-bit vs. 32-bit but doesn't work very well for ARM vs. Intel ABIs. There are many broken apps in the market which fail to run when installed as x86. I believe that there are so many apps because an app that doesn't itself have native x86 libs but imports a 3rd party lib that does support x86 will end up installin the x86 libs for the support library which fools the package installer. As a simple heuristic, pick the ABI that contains the most shared libraries. That works around the common case of missing the app's own shared libraries. Note: the consequences of picking incorrectly are actually quite small since the app should still run, although it will run less efficiently because it is emulated. Note: if two ABIs have the same number of libs, we pick the higher priority one as a tie-breaker. Change-Id: Ie4880810f46875869ce054b3c46acac64b953996
Diffstat (limited to 'core/jni')
-rw-r--r--core/jni/Android.mk4
-rw-r--r--core/jni/com_android_internal_content_NativeLibraryHelper.cpp18
2 files changed, 20 insertions, 2 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index ad52bd6..42b10c4 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -16,6 +16,10 @@ else
LOCAL_CFLAGS += -DPACKED=""
endif
+ifeq ($(TARGET_ARCH), x86)
+ LOCAL_CFLAGS += -DPICK_SUPPORTED_ABI_WITH_MAX_LIBS
+endif
+
ifneq ($(ENABLE_CPUSETS),)
LOCAL_CFLAGS += -DENABLE_CPUSETS
endif
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index c830ffd..91765f9 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -457,6 +457,10 @@ iterateOverNativeFiles(JNIEnv *env, jlong apkHandle, jstring javaCpuAbi,
static int findSupportedAbi(JNIEnv *env, jlong apkHandle, jobjectArray supportedAbisArray) {
const int numAbis = env->GetArrayLength(supportedAbisArray);
Vector<ScopedUtfChars*> supportedAbis;
+#ifdef PICK_SUPPORTED_ABI_WITH_MAX_LIBS
+ int numLibs[numAbis+1] = {0}; // +1 to avoid 0 sized array
+ int maxLibs = 0;
+#endif
for (int i = 0; i < numAbis; ++i) {
supportedAbis.add(new ScopedUtfChars(env,
@@ -492,10 +496,20 @@ static int findSupportedAbi(JNIEnv *env, jlong apkHandle, jobjectArray supported
for (int i = 0; i < numAbis; i++) {
const ScopedUtfChars* abi = supportedAbis[i];
if (abi->size() == abiSize && !strncmp(abiOffset, abi->c_str(), abiSize)) {
- // The entry that comes in first (i.e. with a lower index) has the higher priority.
- if (((i < status) && (status >= 0)) || (status < 0) ) {
+#ifdef PICK_SUPPORTED_ABI_WITH_MAX_LIBS
+ numLibs[i]++;
+ if (numLibs[i] > maxLibs) {
+ maxLibs = numLibs[i];
status = i;
+ } else if (numLibs[i] == maxLibs) {
+#endif
+ // The entry that comes in first (i.e. with a lower index) has the higher priority.
+ if (((i < status) && (status >= 0)) || (status < 0) ) {
+ status = i;
+ }
+#ifdef PICK_SUPPORTED_ABI_WITH_MAX_LIBS
}
+#endif
}
}
}