diff options
author | Christopher R. Palmer <crpalmer@gmail.com> | 2015-12-29 11:11:35 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit@cyanogenmod.org> | 2016-03-10 17:13:27 -0800 |
commit | 564f10b8f05ddf4d9ea2c0e64f1b113fe6dad4b8 (patch) | |
tree | 15abb71476b559699dde3f2a0c0087fefcd76eca /core/jni | |
parent | 4718479d82557510c0dc864618af77631c60eb4b (diff) | |
download | frameworks_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.mk | 4 | ||||
-rw-r--r-- | core/jni/com_android_internal_content_NativeLibraryHelper.cpp | 18 |
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 } } } |