Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

frameworks-base: Commit

frameworks/base


Commit MetaInfo

Revisión280957b03c2c36535975d43ef5c0b0a1b8ad2c87 (tree)
Tiempo2020-04-14 23:46:50
Autorxiajiang <xia1.jiang@inte...>
CommiterChih-Wei Huang

Log Message

Enable the PRC compatibility package feature for PRC market

In PRC market, some APKs are packed in non-standard way, that is,
the x86(_64) libraries aren't workable although they're found in the APK.
This patch intends to relieve the impact from below 2 defects,
which is based-on the heuristic algorithm.

NOTE: To enable this feature, set "PRC_COMPATIBILITY_PACKAGE := true"
in device BoardConfig.mk before enabling houdini.

1. Missing x86(_64) libraries: The x86(_64) libraries are ported and

existing in the APK. But it's incomplete, and not workable.

2. Mixed arm(64) libraries: Several libraries are existing in lib/x86(_64)/

directory in the APK. But some of them are arm(64) libraries,
instead of x86(_64) ones.

All of above always cause APP crash if installed x86(_64) libraries
by PackageManager.

This patch aims to improve PackageManager to figure out these defects
and install arm(64) libraries to run the APP with houdini support.
The basic idea is to compare x86(_64) libraries with arm(64) alternatives
to determine which one should be workable.

To customize it for specific APPs, 3 lists are provided under
/system/vendor/etc/misc/ on the device.

1. /system/vendor/etc/misc/.OEMWhiteList:

This patch will be disabled for the APPs containing in the OEMWhiteList

2. /system/vendor/etc/misc/.OEMBlackList:

The APP is enforced to install the arm(64) libraries if existed.

3. /system/vendor/etc/misc/.ThirdPartySO:

This is another list which contains the names of all 3rd-party libraries,
which will impact on the final decision of APP installation.

Change-Id: I2613d9ebc8fe012c801f4a38fc5dede413f15a91
Tracked-On: https://jira01.devtools.intel.com/browse/OAM-20470
Signed-off-by: xiajiang <xia1.jiang@intel.com>
Reviewed-on: https://android.intel.com:443/471490

Cambiar Resumen

Diferencia incremental

--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -78,6 +78,7 @@ public class NativeLibraryHelper {
7878 final boolean multiArch;
7979 final boolean extractNativeLibs;
8080 final boolean debuggable;
81+ final String pkgName;
8182
8283 public static Handle create(File packageFile) throws IOException {
8384 try {
@@ -92,16 +93,16 @@ public class NativeLibraryHelper {
9293 return create(pkg.getAllCodePaths(),
9394 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0,
9495 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0,
95- (pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
96+ (pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0, pkg.packageName);
9697 }
9798
9899 public static Handle create(PackageLite lite) throws IOException {
99100 return create(lite.getAllCodePaths(), lite.multiArch, lite.extractNativeLibs,
100- lite.debuggable);
101+ lite.debuggable, lite.packageName);
101102 }
102103
103104 private static Handle create(List<String> codePaths, boolean multiArch,
104- boolean extractNativeLibs, boolean debuggable) throws IOException {
105+ boolean extractNativeLibs, boolean debuggable, String pkgName) throws IOException {
105106 final int size = codePaths.size();
106107 final long[] apkHandles = new long[size];
107108 for (int i = 0; i < size; i++) {
@@ -116,7 +117,7 @@ public class NativeLibraryHelper {
116117 }
117118 }
118119
119- return new Handle(apkHandles, multiArch, extractNativeLibs, debuggable);
120+ return new Handle(apkHandles, multiArch, extractNativeLibs, debuggable, pkgName);
120121 }
121122
122123 public static Handle createFd(PackageLite lite, FileDescriptor fd) throws IOException {
@@ -127,15 +128,16 @@ public class NativeLibraryHelper {
127128 throw new IOException("Unable to open APK " + path + " from fd " + fd);
128129 }
129130
130- return new Handle(apkHandles, lite.multiArch, lite.extractNativeLibs, lite.debuggable);
131+ return new Handle(apkHandles, lite.multiArch, lite.extractNativeLibs, lite.debuggable, lite.packageName);
131132 }
132133
133134 Handle(long[] apkHandles, boolean multiArch, boolean extractNativeLibs,
134- boolean debuggable) {
135+ boolean debuggable, String pkgName) {
135136 this.apkHandles = apkHandles;
136137 this.multiArch = multiArch;
137138 this.extractNativeLibs = extractNativeLibs;
138139 this.debuggable = debuggable;
140+ this.pkgName = pkgName;
139141 mGuard.open("close");
140142 }
141143
@@ -210,7 +212,13 @@ public class NativeLibraryHelper {
210212 public static int findSupportedAbi(Handle handle, String[] supportedAbis) {
211213 int finalRes = NO_NATIVE_LIBRARIES;
212214 for (long apkHandle : handle.apkHandles) {
213- final int res = nativeFindSupportedAbi(apkHandle, supportedAbis, handle.debuggable);
215+ int res;
216+ if (true) {
217+ res = nativeFindSupportedAbiReplace(apkHandle, supportedAbis, handle.debuggable, handle.pkgName);
218+ } else {
219+ res = nativeFindSupportedAbi(apkHandle, supportedAbis, handle.debuggable);
220+ }
221+
214222 if (res == NO_NATIVE_LIBRARIES) {
215223 // No native code, keep looking through all APKs.
216224 } else if (res == INSTALL_FAILED_NO_MATCHING_ABIS) {
@@ -235,6 +243,9 @@ public class NativeLibraryHelper {
235243 private native static int nativeFindSupportedAbi(long handle, String[] supportedAbis,
236244 boolean debuggable);
237245
246+ private native static int nativeFindSupportedAbiReplace(long handle, String[] supportedAbis,
247+ boolean debuggable, String pkgName);
248+
238249 // Convenience method to call removeNativeBinariesFromDirLI(File)
239250 public static void removeNativeBinariesLI(String nativeLibraryPath) {
240251 if (nativeLibraryPath == null) return;
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -21,6 +21,7 @@ cc_library_shared {
2121 "-DEGL_EGLEXT_PROTOTYPES",
2222
2323 "-DU_USING_ICU_NAMESPACE=0",
24+ "-D_PRC_COMPATIBILITY_PACKAGE_",
2425
2526 "-Wall",
2627 "-Werror",
@@ -36,6 +37,7 @@ cc_library_shared {
3637 "com_android_internal_content_NativeLibraryHelper.cpp",
3738 "com_google_android_gles_jni_EGLImpl.cpp",
3839 "com_google_android_gles_jni_GLImpl.cpp", // TODO: .arm
40+ "abipicker/ABIPicker.cpp",
3941 "android_app_Activity.cpp",
4042 "android_app_ActivityThread.cpp",
4143 "android_app_NativeActivity.cpp",
--- /dev/null
+++ b/core/jni/abipicker/ABIPicker.cpp
@@ -0,0 +1,694 @@
1+#define LOG_TAG "ABIPicker"
2+
3+#include "abipicker/ABIPicker.h"
4+#include "abipicker/ELFLite.h"
5+
6+#include <androidfw/ZipFileRO.h>
7+#include <androidfw/ZipUtils.h>
8+
9+namespace android {
10+#define ARR_SIZE(x) (sizeof(x)/sizeof(x[0]))
11+
12+#define SO_NAME_MAX (4096)
13+#define IMPOSSIBLE_LIB_NAME "/mixed/"
14+#define IMPOSSIBLE_LIB_LEN (sizeof(IMPOSSIBLE_LIB_NAME)-1)
15+#define ARMABI "armeabi"
16+#define ARMV7ABI "armeabi-v7a"
17+#define ARM64ABI "arm64-v8a"
18+#define X86ABI "x86"
19+#define X8664ABI "x86_64"
20+#define ARMABI_NAME_PREFIX "arm"
21+
22+#define APK_LIB "lib/"
23+#define APK_LIB_LEN (sizeof(APK_LIB) - 1)
24+//#define PICK_LOGGER //flag to debug
25+#ifdef PICK_LOGGER
26+#define P_LOG(...) ALOGI(__VA_ARGS__)
27+#else
28+#define P_LOG(...)
29+#endif
30+
31+#define OEMWHITE "/vendor/etc/misc/.OEMWhiteList"
32+#define OEMBLACK "/vendor/etc/misc/.OEMBlackList"
33+#define THIRDPARTY "/vendor/etc/misc/.ThirdPartySO"
34+
35+// load once, hold until poweroff
36+static Vector <char*> thirdPartySO;
37+static Vector <char*> cfgWhite;
38+static Vector <char*> cfgBlack;
39+static bool thirdload = false;
40+static bool whiteload = false;
41+static bool blackload = false;
42+
43+static const char* iaRelated[] = {"intel", "atom", "x86", "x64"};
44+
45+//////////////////////////////////////////////////////////////////////
46+void getConfig(const char* cfgFile , Vector<char*>& cfgVec) {
47+ FILE* fp = fopen(cfgFile, "r");
48+ int read = -1;
49+ char *line = NULL;
50+ size_t len = 0;
51+
52+ while ((read = getline(&line, &len, fp)) != -1) {
53+ int i = 0 , j = 0;
54+ char *cfgline = (char*)malloc(len);
55+ if (!cfgline) {
56+ P_LOG("malloc error");
57+ break;
58+ }
59+ for (i = 0; i < read; i++) {
60+ if (!isspace(line[i])) {
61+ cfgline[j++] = line[i];
62+ }
63+ }
64+ cfgline[j] = '\0';
65+ cfgVec.push_back(cfgline);
66+ P_LOG("orignal %s , vec: %s ", line, cfgline);
67+ }
68+ free(line);
69+ fclose(fp);
70+}
71+
72+//////////////////////////////////////////////////////////////////////
73+void freeAllString(Vector<char*>& list) {
74+ Vector<char*>::iterator it = list.begin();
75+ while (it != list.end()) {
76+ if (*it != NULL) {
77+ P_LOG("freeAllSring %p , %s", it, *it);
78+ free(*it);
79+ *it = NULL;
80+ }
81+ it++;
82+ }
83+}
84+
85+//////////////////////////////////////////////////////////////////////
86+bool isInOEMWhiteList(const char* pkgName) {
87+ bool result = false;
88+ if (!pkgName) return result;
89+
90+ if (!whiteload) {
91+ getConfig(OEMWHITE, cfgWhite);
92+ whiteload = true;
93+ }
94+
95+ Vector<char*>::iterator it = cfgWhite.begin();
96+ for (; it != cfgWhite.end(); it++) {
97+ P_LOG("whitelist : %s", *it);
98+ if (0 == strcmp(pkgName, *it)) {
99+ ALOGI("found %s in whitelist", pkgName);
100+ result = true;
101+ break;
102+ }
103+ }
104+ return result;
105+}
106+
107+//////////////////////////////////////////////////////////////////////
108+bool isInOEMBlackList(const char* pkgName) {
109+ bool result = false;
110+ if (!pkgName) return result;
111+
112+ if (!blackload) {
113+ getConfig(OEMBLACK, cfgBlack);
114+ blackload = true;
115+ }
116+
117+ Vector<char*>::iterator it = cfgBlack.begin();
118+ for (; it != cfgBlack.end(); it++) {
119+ if (0 == strcmp(pkgName, *it)) {
120+ ALOGI("found %s in blacklist", pkgName);
121+ result = true;
122+ break;
123+ }
124+ }
125+ return result;
126+}
127+
128+
129+//////////////////////////////////////////////////////////////////////
130+bool isReliableLib(Vector<char*>& libList) {
131+ unsigned sz = libList.size();
132+ int len = ARR_SIZE(iaRelated);
133+ for (unsigned i = 0; i < sz; i++) {
134+ for (int j=0; j < len; j++) {
135+ if (NULL != strstr(libList[i], iaRelated[j])) {
136+ return true;
137+ }
138+ }
139+ }
140+
141+ return false;
142+}
143+
144+
145+//////////////////////////////////////////////////////////////////////
146+static bool isValidELF(char* buffer) {
147+ if (buffer[EI_MAG0] != ELFMAG0 &&
148+ buffer[EI_MAG1] != ELFMAG1 &&
149+ buffer[EI_MAG2] != ELFMAG2 &&
150+ buffer[EI_MAG3] != ELFMAG3) {
151+ return false;
152+ }
153+ return true;
154+}
155+
156+// assume that x86 has the only machine-code 3, and x86_64 62
157+static bool isMixedLib(char* libCur, char* buffer) {
158+ bool isX86_64 = (0 == strcmp(libCur, X8664ABI)) ? true: false;
159+ uint16_t machine_code = *((uint16_t*)(&buffer[ELF_MACHINE_OFFSET]));
160+ bool mixed = false;
161+ if (isX86_64) {
162+ if (machine_code != EM_X86_64)
163+ mixed = true;
164+ } else {
165+ if (machine_code != EM_386)
166+ mixed = true;
167+ }
168+ return mixed;
169+}
170+
171+static bool isInThirdPartySOList(char* libName) {
172+ if (!libName) return false;
173+ size_t libLen = strlen(libName);
174+ bool ret = false;
175+ size_t sz = thirdPartySO.size();
176+ for (size_t i = 0; i < sz; i++) {
177+ size_t n = strlen(thirdPartySO[i]);
178+ // three for prefix "lib", and 3 for suffix ".so"
179+ if ((libLen == (n+6))&&(0 == strncmp(libName + 3, thirdPartySO[i], n))) {
180+ ret = true;
181+ break;
182+ }
183+ }
184+ P_LOG("ABIpicker libName %s,In Third %d", libName, ret);
185+ return ret;
186+}
187+
188+static void insertionSort(Vector<char*>& list) {
189+ P_LOG("in insertionSort, list size = %d\n", list.size());
190+
191+ for (size_t i = 1; i < list.size(); i++) {
192+ char* x = list[i];
193+
194+ int j = i - 1;
195+ P_LOG("sort 1. x=%s, i=%d, j=%d\n", x, i, j);
196+ while (j >= 0 && (strcmp(list[j], x) > 0)) {
197+ list.replaceAt(list[j], j + 1);
198+ j--;
199+ }
200+ list.replaceAt(x, j + 1);
201+ }
202+}
203+
204+
205+
206+//////////////////////////////////////////////////////////////////////
207+// Use armRef as a reference, compare all libraries of iaRef with all
208+// libraries of armRef. If both are match, iaRef will be returned with
209+// *result and true is return value. Or else, *result is rawResult and
210+// false is return value
211+bool ABIPicker::compare(char* armRef, char* iaRef,
212+ char* rawResult, char** result) {
213+ bool ret = true;
214+ *result = rawResult;
215+
216+ do {
217+ assert(armRef != NULL);
218+ if (0 == strlen(armRef)) {
219+ *result = strlen(iaRef) > 0 ? iaRef : rawResult;
220+ ret = strlen(iaRef) > 0 ? true : false;
221+ break;
222+ }
223+ assert(iaRef != NULL);
224+ if (0 == strlen(iaRef)) {
225+ *result = armRef;
226+ ret = false;
227+ break;
228+ }
229+
230+ Vector<char*>* iaRefList = getLibList(iaRef);
231+ Vector<char*>* armRefList = getLibList(armRef);
232+
233+ // if contains the key words in iaRelated, just return true
234+ if (isReliableLib(*iaRefList)) {
235+ *result = iaRef;
236+ break;
237+ }
238+
239+ if (compareLibList(*iaRefList, *armRefList)) {
240+ *result = iaRef;
241+ break;
242+ }
243+
244+ size_t iaIsvLibCount = 0;
245+ size_t armIsvLibCount = 0;
246+ if (!compare3rdPartyLibList(iaRef, armRef,
247+ &iaIsvLibCount, &armIsvLibCount)) {
248+ *result = armRef;
249+ ret = false;
250+ break;
251+ }
252+
253+ if (iaIsvLibCount > 0) {
254+ *result = iaRef;
255+ break;
256+ }
257+
258+ *result = armRef;
259+ ret = false;
260+ } while (false);
261+
262+ ALOGV("%s Vs. %s, return %s\n",
263+ iaRef ? iaRef : "NULL",
264+ armRef ? armRef : "NULL", *result);
265+ return ret;
266+}
267+
268+bool ABIPicker::compareLibList(Vector<char*>& iaRefList,
269+ Vector<char*>& armRefList) {
270+ if (iaRefList.size() != armRefList.size()) {
271+ return false;
272+ }
273+
274+ Vector<char*>::iterator itIa = iaRefList.begin();
275+ Vector<char*>::iterator itArm = armRefList.begin();
276+ while (itIa != iaRefList.end() && itArm != armRefList.end()) {
277+ char* iaLibName = *itIa;
278+ char* armLibName = *itArm;
279+
280+ // NOTE:
281+ // WIN treats file names in-case-sensitive,
282+ // but LINUX treats them case-sensitive.
283+ if (0 != strcmp(iaLibName, armLibName)) {
284+ return false;
285+ }
286+
287+ itIa++;
288+ itArm++;
289+ }
290+
291+ return true;
292+}
293+
294+bool ABIPicker::compare3rdPartyLibList(
295+ char* iaRef, char* armRef,
296+ size_t* iaIsvLibCount, size_t* armIsvLibCount) {
297+ Vector<char*>* iaRefList = getLibList(iaRef);
298+ Vector<char*>* armRefList = getLibList(armRef);
299+
300+ Vector<char*>* armRef3rdPartyLibList = new Vector<char*>();
301+ Vector<char*>::iterator itArm = armRefList->begin();
302+
303+ // Load thirdPartyso
304+ if (!thirdload) {
305+ getConfig(THIRDPARTY, thirdPartySO);
306+ thirdload = true;
307+ }
308+ while (itArm != armRefList->end()) {
309+ char* armLibName = *itArm;
310+ if (isInThirdPartySOList(armLibName)) {
311+ armRef3rdPartyLibList->push_back(armLibName);
312+ } else {
313+ (*armIsvLibCount)++;
314+ }
315+
316+ itArm++;
317+ }
318+
319+ Vector<char*>::iterator itIa = iaRefList->begin();
320+ Vector<char*>* iaRef3rdPartyLibList = new Vector<char*>();
321+ while (itIa != iaRefList->end()) {
322+ char* iaLibName = *itIa;
323+ if (isInThirdPartySOList(iaLibName)) {
324+ iaRef3rdPartyLibList->push_back(iaLibName);
325+ } else {
326+ (*iaIsvLibCount)++;
327+ }
328+
329+ itIa++;
330+ }
331+ return compareLibList(*iaRef3rdPartyLibList, *armRef3rdPartyLibList);
332+}
333+
334+char* ABIPicker::getAbiName(int abi) {
335+ if (abi < 0 || (unsigned)abi >= mLibList->size()) {
336+ return NULL;
337+ }
338+
339+ char* ret = NULL;
340+ int index = 0;
341+ Vector<struct libInfo*>::iterator it = mLibList->begin();
342+ while (it != mLibList->end()) {
343+ if (index == abi) {
344+ ret = (*it)->abiName;
345+ break;
346+ }
347+
348+ index++;
349+ it++;
350+ }
351+
352+ return ret;
353+}
354+
355+int ABIPicker::getAbiIndex(const char* abiName) {
356+ int ret = -1;
357+
358+ int index = 0;
359+ Vector<struct libInfo*>::iterator it = mLibList->begin();
360+ while (it != mLibList->end()) {
361+ if (0 == strcmp(abiName, (*it)->abiName)) {
362+ ret = index;
363+ break;
364+ }
365+
366+ index++;
367+ it++;
368+ }
369+
370+ return ret;
371+}
372+
373+Vector<char*>* ABIPicker::getLibList(const char* abiName) {
374+ Vector<char*>* ret = NULL;
375+ Vector<struct libInfo*>::iterator it = mLibList->begin();
376+ while (it != mLibList->end()) {
377+ if (0 == strcmp(abiName, (*it)->abiName)) {
378+ ret = (*it)->libNameList;
379+ break;
380+ }
381+ it++;
382+ }
383+ P_LOG("getLibList of %s return %p\n", abiName, ret);
384+ return ret;
385+}
386+
387+
388+size_t ABIPicker::getSpecficABILibCount(const char* abiName) {
389+ Vector<char*>* specificAbiLibList = getLibList(abiName);
390+ return specificAbiLibList && specificAbiLibList->size();
391+}
392+
393+bool ABIPicker::foundMixedELF(const char* abiName) {
394+ Vector<char*>* libNameList = getLibList(abiName);
395+ if (!libNameList) {
396+ return false;
397+ }
398+ if (libNameList->size() == 0) {
399+ return false;
400+ }
401+
402+ if (0 != strcasecmp(*(libNameList->begin()), IMPOSSIBLE_LIB_NAME)) {
403+ return false;
404+ }
405+
406+ return true;
407+}
408+
409+
410+//////////////////////////////////////////////////////////////////////
411+ABIPicker::ABIPicker(const char* pkgName, Vector<ScopedUtfChars*> abiList) {
412+ mLibList = new Vector<struct libInfo*>();
413+ mpkgName = (char*)malloc(strlen(pkgName)+1);
414+ if (!mpkgName) {
415+ P_LOG("ABIPicker Construct Allocated space fails");
416+ } else {
417+ strcpy(mpkgName, pkgName);
418+ }
419+ Vector<ScopedUtfChars*>::iterator it = abiList.begin();
420+ while (it != abiList.end()) {
421+ if (!(*it)) {
422+ break;
423+ }
424+
425+ struct libInfo* tmp = (struct libInfo*)calloc(1,
426+ sizeof(struct libInfo));
427+ if (!tmp) {
428+ P_LOG("ABIPicker Construct Allocated space fail %s", (*it)->c_str());
429+ break;
430+ }
431+
432+ snprintf(tmp->abiName, (*it)->size() + 1, "%s", (*it)->c_str());
433+ tmp->libNameList = new Vector<char*>();
434+ P_LOG("ABIPicker Construct %s , libNameList: %p",
435+ tmp->abiName, tmp->libNameList);
436+ mLibList->push_back(tmp);
437+ it++;
438+ }
439+}
440+
441+ABIPicker::~ABIPicker(void) {
442+ free(mpkgName);
443+ mpkgName = NULL;
444+ Vector<struct libInfo*>::iterator it = mLibList->begin();
445+ while (it != mLibList->end()) {
446+ freeAllString(*((*it)->libNameList));
447+ (*it)->libNameList->clear();
448+ delete (*it)->libNameList;
449+ (*it)->libNameList = NULL;
450+
451+ free(*it);
452+ *it = NULL;
453+ it++;
454+ }
455+ mLibList->clear();
456+}
457+
458+bool ABIPicker::buildNativeLibList(void* apkHandle) {
459+ bool ret = false;
460+
461+ if (!apkHandle) {
462+ ALOGE("apkHandle is NULL\n");
463+ return ret;
464+ }
465+
466+ ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
467+ void* cookie = NULL;
468+ if (!zipFile->startIteration(&cookie)) {
469+ ALOGE("apk file is broken\n");
470+ return ret;
471+ }
472+
473+ ZipEntryRO next = NULL;
474+ char* unCompBuff = NULL;
475+ char fileName[SO_NAME_MAX + 1];
476+ while ((next = zipFile->nextEntry(cookie))) {
477+ if (zipFile->getEntryFileName(next, fileName, SO_NAME_MAX)) {
478+ ALOGE("apk file is broken, can not get entry name\n");
479+ ret = false;
480+ break;
481+ }
482+ fileName[SO_NAME_MAX] = '\0';
483+
484+ // Make sure we're in the lib directory of the ZIP.
485+ // find out entries with such names: "lib/xxxxxxx" or "lib/"
486+ if (strncmp(fileName, APK_LIB, APK_LIB_LEN)) {
487+ continue;
488+ }
489+
490+ // find out any invalid ELF file
491+ uint32_t unCompLen = 0;
492+ if (!zipFile->getEntryInfo(next, NULL, &unCompLen, NULL, NULL, NULL,
493+ NULL)) {
494+ ALOGE("apk file is broken, can not get entry info\n");
495+ ret = false;
496+ break;
497+ }
498+
499+ if (unCompLen == 0) {
500+ ALOGV("skip a empty file(%s)\n", fileName);
501+ continue;
502+ }
503+
504+ free(unCompBuff);
505+ unCompBuff = NULL;
506+
507+ unCompBuff = (char*)malloc(unCompLen);
508+ if (!unCompBuff) {
509+ ALOGE("malloc failed size %d\n", unCompLen);
510+ ret = false;
511+ break;
512+ }
513+
514+ // THE MOST TIME COST OPERATION
515+ if (!zipFile->uncompressEntry(next, unCompBuff, unCompLen)) {
516+ ALOGE("%s: uncompress failed\n", fileName);
517+ ret = false;
518+ break;
519+ }
520+
521+ if (!isValidELF(unCompBuff)) {
522+ ALOGI("skip a fake .ELF file(%s)\n", fileName);
523+ continue;
524+ }
525+
526+ // It is a real .so file, prepare to record
527+ // find abi name and focus on what we care: arm(s) and x86(s)
528+ // at least lastSlash points to the end of "lib/"
529+ const char* lastSlash = strrchr(fileName, '/');
530+ const char* cpuAbiOffset = fileName + APK_LIB_LEN;
531+ // just in case if fileName is in an abnormal format, like lib/libname,
532+ // lib//libname
533+ if (lastSlash <= cpuAbiOffset) {
534+ ALOGI("skip a invalid lib file(%s)\n", fileName);
535+ continue;
536+ }
537+
538+ const size_t cpuAbiRegionSize = lastSlash - cpuAbiOffset;
539+ char curAbiName[ABI_NAME_MAX_LENGTH];
540+ if (cpuAbiRegionSize >= ABI_NAME_MAX_LENGTH) {
541+ continue;
542+ }
543+ snprintf(curAbiName, cpuAbiRegionSize + 1, "%s", cpuAbiOffset);
544+
545+ Vector<char*>* libListOfCurAbi = getLibList(curAbiName);
546+ if (!libListOfCurAbi) {
547+ P_LOG("getLibList of %s return NULL\n", curAbiName);
548+ continue;
549+ }
550+
551+ // mixed arm elf in lib/x86 or lib/x86_64
552+ // but we don't consider a compareable scenario in lib/arm*
553+ if (0 == strcmp(curAbiName, X86ABI) ||
554+ 0 == strcmp(curAbiName, X8664ABI)) {
555+ if (!libListOfCurAbi->empty()) {
556+ char* firstElement = libListOfCurAbi->itemAt(0);
557+ if (0 == strcmp(firstElement, IMPOSSIBLE_LIB_NAME)) {
558+ // won't add any new into the list if found mixed
559+ // lib before
560+ P_LOG("won't count count if found mixed lib before");
561+ continue;
562+ }
563+ }
564+
565+ if (isMixedLib(curAbiName, unCompBuff)) {
566+ P_LOG("found mixed lib(%s) in lib/%s/", curAbiName, fileName);
567+ freeAllString(*libListOfCurAbi);
568+ libListOfCurAbi->clear();
569+ char* mixedLib = (char*)malloc(IMPOSSIBLE_LIB_LEN+1);
570+ if (!mixedLib) {
571+ ALOGE("malloc failed size %zu", IMPOSSIBLE_LIB_LEN + 1);
572+ ret = false;
573+ break;
574+ }
575+ strcpy(mixedLib, (char*)IMPOSSIBLE_LIB_NAME);
576+ mixedLib[IMPOSSIBLE_LIB_LEN] ='\0';
577+ libListOfCurAbi->push_back(mixedLib);
578+ continue;
579+ }
580+ }
581+
582+ // now, lastSlash should point to lib name
583+ lastSlash++;
584+ const size_t libNameSize = strlen(lastSlash);
585+ char* curLibName = (char*)malloc(libNameSize+1);
586+ if (!curLibName) {
587+ ALOGE("malloc failed size %zu\n", libNameSize+1);
588+ ret = false;
589+ break;
590+ }
591+ strcpy(curLibName, lastSlash);
592+ curLibName[libNameSize] = '\0';
593+
594+ libListOfCurAbi->push_back(curLibName);
595+
596+ ret = true;
597+ }
598+
599+ free(unCompBuff);
600+ unCompBuff = NULL;
601+
602+ zipFile->endIteration(cookie);
603+
604+ for (unsigned i = 0; i < mLibList->size(); i++) {
605+ struct libInfo* tmp = mLibList->itemAt(i);
606+ insertionSort(*(tmp->libNameList));
607+ }
608+ return ret;
609+}
610+
611+int ABIPicker::pickupRightABI(int sysPrefer) {
612+ char* sysPreferAbiName = getAbiName(sysPrefer);
613+ if (!sysPreferAbiName) {
614+ return sysPrefer;
615+ }
616+
617+ bool is64BitPrefer = (0 == strcmp(sysPreferAbiName, X8664ABI));
618+ bool x8664HasMixedELF = foundMixedELF(X8664ABI);
619+ bool x86HasMixedELF = foundMixedELF(X86ABI);
620+
621+ size_t armv7LibCount = getSpecficABILibCount(ARMV7ABI);
622+ size_t armv5LibCount = getSpecficABILibCount(ARMABI);
623+ size_t armv8LibCount = getSpecficABILibCount(ARM64ABI);
624+ size_t x86LibCount = x86HasMixedELF ? 0 : getSpecficABILibCount(X86ABI);
625+ size_t x8664LibCount = x8664HasMixedELF ? 0 : getSpecficABILibCount(X8664ABI);
626+ P_LOG("armv7LibCount:%d armv5LibCount:%d armv8LibCount:%d x86LibCount:%d x8664LibCount:%d", armv7LibCount, armv5LibCount, armv8LibCount, x86LibCount, x8664LibCount);
627+
628+ // in OEMBlackList, need to be supported by bt
629+ // but in case of armlib doesn't exist, we choose x86 or x86_64
630+ if (isInOEMBlackList(mpkgName)) {
631+ if (armv7LibCount > 0) {
632+ return getAbiIndex(ARMV7ABI);
633+ } else if (armv5LibCount > 0) {
634+ return getAbiIndex(ARMABI);
635+ } else if (armv8LibCount > 0) {
636+ return getAbiIndex(ARM64ABI);
637+ }
638+ }
639+
640+ char arm64Ref[ABI_NAME_MAX_LENGTH];
641+ if (armv8LibCount > 0) {
642+ snprintf(arm64Ref, sizeof(ARM64ABI), "%s", ARM64ABI);
643+ } else {
644+ arm64Ref[0] = '\0';
645+ }
646+
647+ char arm32Ref[ABI_NAME_MAX_LENGTH];
648+ if (armv7LibCount > 0) {
649+ snprintf(arm32Ref, sizeof(ARMV7ABI), "%s", ARMV7ABI);
650+ } else if (armv5LibCount > 0) {
651+ snprintf(arm32Ref, sizeof(ARMABI), "%s", ARMABI);
652+ } else {
653+ arm32Ref[0] = '\0';
654+ }
655+
656+ char ia32Ref[ABI_NAME_MAX_LENGTH];
657+ if (x86LibCount > 0) {
658+ snprintf(ia32Ref, sizeof(X86ABI), "%s", X86ABI);
659+ } else {
660+ ia32Ref[0] = '\0';
661+ }
662+
663+ char ia64Ref[ABI_NAME_MAX_LENGTH];
664+ if (x8664LibCount > 0) {
665+ snprintf(ia64Ref, ABI_NAME_MAX_LENGTH, "%s", X8664ABI);
666+ } else {
667+ ia64Ref[0] = '\0';
668+ }
669+
670+ char* retAbiName = sysPreferAbiName;
671+ do {
672+ // # The basic rule is:
673+ // - on 32 bit system, compare ia32Ref native libraries with
674+ // arm32Ref native libraries. If pass, return ia32Ref .
675+ // If fail, return arm32Ref.
676+ // - on 64 bit system, IA has two chances. if ia64Ref native
677+ // libraries can't pass the comparation with arm64Ref, we should
678+ // run the comparation again with ia32Ref
679+ if (is64BitPrefer) {
680+ if (!compare(arm64Ref, ia64Ref, sysPreferAbiName, &retAbiName)) {
681+ char rawRes[ABI_NAME_MAX_LENGTH];
682+ strcpy(rawRes, retAbiName);
683+ compare(arm32Ref, ia32Ref, rawRes, &retAbiName);
684+ }
685+ } else {
686+ compare(arm32Ref, ia32Ref, sysPreferAbiName, &retAbiName);
687+ }
688+ } while (false);
689+ int ret = getAbiIndex(retAbiName);
690+ ALOGI("selected abi %s(%d) for %s", retAbiName, ret, mpkgName);
691+ return ret;
692+}
693+
694+} // namespace android
--- /dev/null
+++ b/core/jni/abipicker/ABIPicker.h
@@ -0,0 +1,55 @@
1+#ifndef _ABIPICKER_H_
2+#define _ABIPICKER_H_
3+
4+#include <jni.h>
5+#include <stdlib.h>
6+#include <utils/Vector.h>
7+#include <sys/types.h>
8+
9+#include <nativehelper/ScopedUtfChars.h>
10+
11+namespace android {
12+// assumption: the length of name of any abi type in abi list,
13+// like armeabi-v7a, armeabi, x86, is not longer than 64
14+#define ABI_NAME_MAX_LENGTH (64)
15+/*
16+class LibInfo {
17+ public:
18+ LibInfo(char* s, List<char*> list);
19+ ~LibInfo(void);
20+
21+ private:
22+ char abiName[ABI_NAME_MAX_LENGTH];
23+ List<char*> libNameList;
24+};
25+*/
26+
27+class ABIPicker {
28+ public:
29+ explicit ABIPicker(const char* pkgName,Vector<ScopedUtfChars*> abiList);
30+ ~ABIPicker(void);
31+
32+ bool buildNativeLibList(void* apkHandle);
33+ int pickupRightABI(int sysPrefer);
34+ private:
35+ struct libInfo{
36+ char abiName[ABI_NAME_MAX_LENGTH];
37+ Vector<char*>* libNameList;
38+ };
39+ Vector<struct libInfo*>* mLibList;
40+ char* mpkgName;
41+
42+ bool foundMixedELF(const char* abiName);
43+ bool compare(char* armRef, char* iaRef, char* rawResult, char** result);
44+ bool compareLibList(Vector<char*>& iaRefList, Vector<char*>& armRefList);
45+ bool compare3rdPartyLibList( char* iaRef, char* armRef,
46+ size_t* iaIsvLibCount, size_t* armIsvLibCount);
47+ char* getAbiName(int abi);
48+ int getAbiIndex(const char* abiName);
49+ size_t getSpecficABILibCount(const char* abiName);
50+ Vector<char*>* getLibList(const char* abiName);
51+};
52+
53+bool isInOEMWhiteList(const char* pkgName);
54+} // namespace android
55+#endif // _ABIPICKER_H_
--- /dev/null
+++ b/core/jni/abipicker/ELFLite.h
@@ -0,0 +1,58 @@
1+#ifndef _ELFLITE_H__
2+#define _ELFLITE_H__
3+
4+#include <ctype.h>
5+#include <fcntl.h>
6+#include <stdio.h>
7+#include <stdlib.h>
8+#include <unistd.h>
9+
10+namespace android {
11+#define EI_NIDENT 16 /* Size of e_ident[] */
12+
13+/*
14+ * Fields in e_ident[]
15+ */
16+#define EI_MAG0 0 /* File identification byte 0 index */
17+#define ELFMAG0 0x7F /* Magic number byte 0 */
18+#define EI_MAG1 1 /* File identification byte 1 index */
19+#define ELFMAG1 'E' /* Magic number byte 1 */
20+#define EI_MAG2 2 /* File identification byte 2 index */
21+#define ELFMAG2 'L' /* Magic number byte 2 */
22+#define EI_MAG3 3 /* File identification byte 3 index */
23+#define ELFMAG3 'F' /* Magic number byte 3 */
24+
25+/*
26+ * according to implementations of ELF Header
27+ * unsigned char e_ident[16]; // ELF "magic number"
28+ * unsigned char e_type[2]; // Identifies object file type
29+ * unsigned char e_machine[2]; // Specifies required architecture
30+ */
31+#define ELF_MACHINE_OFFSET 18
32+
33+/*
34+ * Values for e_machine, which identifies the architecture. These numbers
35+ * are officially assigned by registry@sco.com. See below for a list of
36+ * ad-hoc numbers used during initial development.
37+ * Please always sync them.
38+ */
39+#define EM_386 3 /* Intel 80386 */
40+#define EM_486 6 /* Intel 80486 */
41+#define EM_860 7 /* Intel 80860 */
42+#define EM_960 19 /* Intel 80960 */
43+#define EM_ARM 40 /* ARM */
44+#define EM_IA_64 50 /* Intel IA-64 Processor */
45+#define EM_X86_64 62 /* AMD x86-64 architecture */
46+#define EM_8051 165 /* Intel 8051 and variants */
47+#define EM_L1OM 180 /* Intel L1OM */
48+#define EM_K1OM 181 /* Intel K1OM */
49+#define EM_INTEL182 182 /* Reserved by Intel */
50+#define EM_AARCH64 183 /* ARM 64-bit architecture */
51+#define EM_ARM184 184 /* Reserved by ARM */
52+#define EM_INTEL205 205 /* Reserved by Intel */
53+#define EM_INTEL206 206 /* Reserved by Intel */
54+#define EM_INTEL207 207 /* Reserved by Intel */
55+#define EM_INTEL208 208 /* Reserved by Intel */
56+#define EM_INTEL209 209 /* Reserved by Intel */
57+} // namespace android
58+#endif // _ELFLITE_H__
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -39,6 +39,10 @@
3939
4040 #include <memory>
4141
42+#ifdef _PRC_COMPATIBILITY_PACKAGE_
43+#include "abipicker/ABIPicker.h"
44+#endif
45+
4246 #define APK_LIB "lib/"
4347 #define APK_LIB_LEN (sizeof(APK_LIB) - 1)
4448
@@ -53,6 +57,11 @@
5357 #define TMP_FILE_PATTERN "/tmp.XXXXXX"
5458 #define TMP_FILE_PATTERN_LEN (sizeof(TMP_FILE_PATTERN) - 1)
5559
60+#ifdef _PRC_COMPATIBILITY_PACKAGE_
61+#define X86ABI "x86"
62+#define X8664ABI "x86_64"
63+#endif
64+
5665 namespace android {
5766
5867 // These match PackageManager.java install codes
@@ -511,6 +520,57 @@ com_android_internal_content_NativeLibraryHelper_findSupportedAbi(JNIEnv *env, j
511520 return (jint) findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable);
512521 }
513522
523+static jint
524+com_android_internal_content_NativeLibraryHelper_findSupportedAbi_replace(
525+ JNIEnv *env,
526+ jclass clazz,
527+ jlong apkHandle,
528+ jobjectArray javaCpuAbisToSearch,
529+ jboolean debuggable,
530+ jstring apkPkgName)
531+{
532+#ifdef _PRC_COMPATIBILITY_PACKAGE_
533+ const int numAbis = env->GetArrayLength(javaCpuAbisToSearch);
534+ Vector<ScopedUtfChars*> supportedAbis;
535+ for (int i = 0; i < numAbis; i++) {
536+ ScopedUtfChars* abiName = new ScopedUtfChars(env,
537+ (jstring)env->GetObjectArrayElement(
538+ javaCpuAbisToSearch, i));
539+ supportedAbis.push_back(abiName);
540+ }
541+
542+ int abiType = findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable);
543+ do {
544+
545+ if (abiType < 0 || abiType >= numAbis ) break ;
546+ // if one package's name is on OEM's specific white list, then the
547+ // package should be installed as default
548+ ScopedUtfChars name(env, apkPkgName);
549+ if (isInOEMWhiteList(name.c_str())) {
550+ break;
551+ }
552+
553+ if (0 != strcmp(supportedAbis[abiType]->c_str(), X86ABI) &&
554+ 0 != strcmp(supportedAbis[abiType]->c_str(), X8664ABI)){
555+ break;
556+ }
557+ ABIPicker picker(name.c_str(),supportedAbis);
558+ if (!picker.buildNativeLibList((void*)apkHandle)) {
559+ break;
560+ }
561+
562+ abiType = picker.pickupRightABI(abiType);
563+ } while (false);
564+
565+ for (int i = 0; i < numAbis; ++i) {
566+ delete supportedAbis[i];
567+ }
568+ return (jint)abiType;
569+#else
570+ return (jint)findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable);
571+#endif
572+}
573+
514574 enum bitcode_scan_result_t {
515575 APK_SCAN_ERROR = -1,
516576 NO_BITCODE_PRESENT = 0,
@@ -602,6 +662,9 @@ static const JNINativeMethod gMethods[] = {
602662 {"nativeFindSupportedAbi",
603663 "(J[Ljava/lang/String;Z)I",
604664 (void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi},
665+ {"nativeFindSupportedAbiReplace",
666+ "(J[Ljava/lang/String;ZLjava/lang/String;)I",
667+ (void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi_replace},
605668 {"hasRenderscriptBitcode", "(J)I",
606669 (void *)com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode},
607670 };
Show on old repository browser