final boolean extractNativeLibs;
final boolean debuggable;
final String pkgName;
+ final String apkDir;
public static Handle create(File packageFile) throws IOException {
try {
}
public static Handle create(Package pkg) throws IOException {
+ String apkdir;
+ if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ apkdir = null;
+ } else {
+ apkdir = pkg.codePath;
+ }
return create(pkg.getAllCodePaths(),
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0,
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0,
- (pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0, pkg.packageName);
+ (pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0, pkg.packageName, apkdir);
}
public static Handle create(PackageLite lite) throws IOException {
+ String apkdir;
+ if (lite.codePath == null ||
+ lite.codePath.startsWith("/system/") ||
+ lite.codePath.startsWith("/vendor/") ||
+ lite.codePath.startsWith("/oem/")) {
+ apkdir = null;
+ } else {
+ apkdir = lite.codePath;
+ }
return create(lite.getAllCodePaths(), lite.multiArch, lite.extractNativeLibs,
- lite.debuggable, lite.packageName);
+ lite.debuggable, lite.packageName, apkdir);
}
private static Handle create(List<String> codePaths, boolean multiArch,
- boolean extractNativeLibs, boolean debuggable, String pkgName) throws IOException {
+ boolean extractNativeLibs, boolean debuggable, String pkgName, String apkdir) throws IOException {
final int size = codePaths.size();
final long[] apkHandles = new long[size];
for (int i = 0; i < size; i++) {
}
}
- return new Handle(apkHandles, multiArch, extractNativeLibs, debuggable, pkgName);
+ return new Handle(apkHandles, multiArch, extractNativeLibs, debuggable, pkgName, apkdir);
}
Handle(long[] apkHandles, boolean multiArch, boolean extractNativeLibs,
- boolean debuggable, String pkgName) {
+ boolean debuggable, String pkgName, String apkdir) {
this.apkHandles = apkHandles;
this.multiArch = multiArch;
this.extractNativeLibs = extractNativeLibs;
this.debuggable = debuggable;
this.pkgName = pkgName;
+ this.apkDir = apkdir;
mGuard.open("close");
}
public static int findSupportedAbi(Handle handle, String[] supportedAbis) {
int finalRes = NO_NATIVE_LIBRARIES;
for (long apkHandle : handle.apkHandles) {
- int res;
- if (true) {
- res = nativeFindSupportedAbiReplace(apkHandle, supportedAbis, handle.debuggable, handle.pkgName);
- } else {
- res = nativeFindSupportedAbi(apkHandle, supportedAbis, handle.debuggable);
- }
+ final int res = nativeFindSupportedAbiReplace(apkHandle, supportedAbis,
+ handle.debuggable, handle.pkgName, handle.apkDir);
if (res == NO_NATIVE_LIBRARIES) {
// No native code, keep looking through all APKs.
return finalRes;
}
- private native static int nativeFindSupportedAbi(long handle, String[] supportedAbis,
- boolean debuggable);
-
private native static int nativeFindSupportedAbiReplace(long handle, String[] supportedAbis,
- boolean debuggable, String pkgName);
+ boolean debuggable, String pkgName, String apkdir);
// Convenience method to call removeNativeBinariesFromDirLI(File)
public static void removeNativeBinariesLI(String nativeLibraryPath) {
static bool whiteload = false;
static bool blackload = false;
-static const char* iaRelated[] = {"intel", "atom", "x86", "x64"};
+static const char* iaRelated[] = {"intel", "intl", "atom", "x86", "x64"};
//////////////////////////////////////////////////////////////////////
void getConfig(const char* cfgFile , Vector<char*>& cfgVec) {
FILE* fp = fopen(cfgFile, "r");
+ assert(fp != NULL);
int read = -1;
char *line = NULL;
size_t len = 0;
int len = ARR_SIZE(iaRelated);
for (unsigned i = 0; i < sz; i++) {
for (int j=0; j < len; j++) {
- if (NULL != strstr(libList[i], iaRelated[j])) {
- return true;
+ char* p = NULL;
+ if (NULL != (p = strcasestr(libList[i], iaRelated[j]))) {
+ int lenIA = strlen(iaRelated[j]);
+ if (!isalpha(*(p+lenIA))) {
+ if (!isalpha(*(p-1)) || (p == (libList[i] + 3))) {
+ return true;
+ }
+ }
}
}
}
return mixed;
}
+// compare the given string with the length, igonre upper and lower
+// len must be less than the length of two string
+static bool ignoreCmp(const char* str1, const char* str2, int len){
+ assert (str1 != NULL && str2 != NULL);
+ assert ((len <= strlen(str1)) && (len <= strlen(str2)));
+ for (int i = 0 ; i < len; i++) {
+ if (str1[i] != str2[i]) {
+ if(isalpha(str1[i]) && isalpha(str2[i])
+ && (abs((str1[i]-str2[i])) == 32)) {
+ continue;
+ }
+ return false;
+ }
+ }
+ return true;
+}
+
static bool isInThirdPartySOList(char* libName) {
- if (!libName) return false;
+ assert (libName != NULL);
size_t libLen = strlen(libName);
- bool ret = false;
size_t sz = thirdPartySO.size();
for (size_t i = 0; i < sz; i++) {
+ // thirdPartySO[i] won't be NULL
size_t n = strlen(thirdPartySO[i]);
- // three for prefix "lib", and 3 for suffix ".so"
- if ((libLen == (n+6))&&(0 == strncmp(libName + 3, thirdPartySO[i], n))) {
- ret = true;
- break;
+ // three char for ".so"
+ int j = libLen - 4;
+ // now only '-' '-' and '.'found
+ while((j >= 0) && (isdigit(libName[j]) || (libName[j] == '-')
+ || (libName[j] == '_') || (libName[j] == '.'))) {
+ j--;
}
+ // three char for "lib" and include the name with no letters
+ if ((j == 2) || ((size_t)j == (n+2))) {
+ if (ignoreCmp(libName+3, thirdPartySO[i], n)) {
+ P_LOG("ABIpicker libName %s,In Third", libName);
+ return true;
+ }
+ }
+
}
- P_LOG("ABIpicker libName %s,In Third %d", libName, ret);
- return ret;
+ return false;
}
static void insertionSort(Vector<char*>& list) {
//////////////////////////////////////////////////////////////////////
// Use armRef as a reference, compare all libraries of iaRef with all
-// libraries of armRef. If both are match, iaRef will be returned with
-// *result and true is return value. Or else, *result is rawResult and
-// false is return value
+// libraries of armRef.If the two are match or iaRef is more, iaRef
+// will be returned with *result and true is return value. Or else,
+// *result is rawResult and false is return value
bool ABIPicker::compare(char* armRef, char* iaRef,
char* rawResult, char** result) {
bool ret = true;
Vector<char*>* armRefList = getLibList(armRef);
// if contains the key words in iaRelated, just return true
+ assert(iaRefList != NULL);
+ assert(armRefList != NULL);
if (isReliableLib(*iaRefList)) {
*result = iaRef;
break;
*result = armRef;
ret = false;
- } while (false);
+ } while (0);
ALOGV("%s Vs. %s, return %s\n",
iaRef ? iaRef : "NULL",
bool ABIPicker::compareLibList(Vector<char*>& iaRefList,
Vector<char*>& armRefList) {
- if (iaRefList.size() != armRefList.size()) {
+
+ unsigned iaSize = iaRefList.size();
+ unsigned armSize = armRefList.size();
+ if (iaSize < armSize) {
return false;
+ } else if (iaSize == 0 && armSize == 0) {
+ return true;
}
+ int iaNum = 0;
+ int armNum = 0;
Vector<char*>::iterator itIa = iaRefList.begin();
Vector<char*>::iterator itArm = armRefList.begin();
+ bool isEqual = false;
while (itIa != iaRefList.end() && itArm != armRefList.end()) {
- char* iaLibName = *itIa;
- char* armLibName = *itArm;
-
- // NOTE:
- // WIN treats file names in-case-sensitive,
- // but LINUX treats them case-sensitive.
- if (0 != strcmp(iaLibName, armLibName)) {
+ if ((iaSize-iaNum) < (armSize-armNum)) {
return false;
}
-
- itIa++;
+ isEqual = false ;
+ char* armLibName = *itArm;
+ int armLen = strlen (armLibName);
+ armNum++;
+
+ while (itIa != iaRefList.end() && !isEqual) {
+ char* iaLibName = *itIa;
+ iaNum++;
+ int iaLen = strlen (iaLibName);
+ if (iaLen == armLen) {
+ if (ignoreCmp(iaLibName, armLibName, iaLen)) {
+ isEqual = true;
+ }
+ }
+ itIa++;
+ }
itArm++;
}
-
- return true;
+ // till the end, and the last result is equal
+ if (itArm == armRefList.end() && isEqual){
+ return true;
+ } else {
+ return false;
+ }
}
bool ABIPicker::compare3rdPartyLibList(
size_t* iaIsvLibCount, size_t* armIsvLibCount) {
Vector<char*>* iaRefList = getLibList(iaRef);
Vector<char*>* armRefList = getLibList(armRef);
+ assert(iaRefList != NULL);
+ assert(armRefList != NULL);
Vector<char*>* armRef3rdPartyLibList = new Vector<char*>();
Vector<char*>::iterator itArm = armRefList->begin();
itIa++;
}
- return compareLibList(*iaRef3rdPartyLibList, *armRef3rdPartyLibList);
+ bool result = compareLibList(*iaRef3rdPartyLibList, *armRef3rdPartyLibList);
+
+ //release the memory
+ free(armRef3rdPartyLibList);
+ free(iaRef3rdPartyLibList);
+ return result;
}
char* ABIPicker::getAbiName(int abi) {
if (!mpkgName) {
P_LOG("ABIPicker Construct Allocated space fails");
} else {
- strcpy(mpkgName, pkgName);
+ snprintf(mpkgName, strlen(pkgName)+1, "%s", pkgName);
}
Vector<ScopedUtfChars*>::iterator it = abiList.begin();
while (it != abiList.end()) {
it++;
}
mLibList->clear();
+ delete(mLibList);
}
bool ABIPicker::buildNativeLibList(void* apkHandle) {
ret = false;
break;
}
-
+ memset(unCompBuff, 0, unCompLen);
// THE MOST TIME COST OPERATION
if (!zipFile->uncompressEntry(next, unCompBuff, unCompLen)) {
ALOGE("%s: uncompress failed\n", fileName);
ret = false;
break;
}
- strcpy(mixedLib, (char*)IMPOSSIBLE_LIB_NAME);
+ snprintf(mixedLib, (IMPOSSIBLE_LIB_LEN+1), "%s", IMPOSSIBLE_LIB_NAME);
mixedLib[IMPOSSIBLE_LIB_LEN] ='\0';
libListOfCurAbi->push_back(mixedLib);
continue;
ret = false;
break;
}
- strcpy(curLibName, lastSlash);
+ snprintf(curLibName,libNameSize+1, "%s", lastSlash);
curLibName[libNameSize] = '\0';
libListOfCurAbi->push_back(curLibName);
if (is64BitPrefer) {
if (!compare(arm64Ref, ia64Ref, sysPreferAbiName, &retAbiName)) {
char rawRes[ABI_NAME_MAX_LENGTH];
- strcpy(rawRes, retAbiName);
+ snprintf(rawRes, ABI_NAME_MAX_LENGTH, "%s", retAbiName);
compare(arm32Ref, ia32Ref, rawRes, &retAbiName);
}
} else {
compare(arm32Ref, ia32Ref, sysPreferAbiName, &retAbiName);
}
- } while (false);
+ } while (0);
int ret = getAbiIndex(retAbiName);
ALOGI("selected abi %s(%d) for %s", retAbiName, ret, mpkgName);
return ret;
}
static jint
-com_android_internal_content_NativeLibraryHelper_findSupportedAbi(JNIEnv *env, jclass clazz,
- jlong apkHandle, jobjectArray javaCpuAbisToSearch, jboolean debuggable)
-{
- return (jint) findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable);
-}
-
-static jint
com_android_internal_content_NativeLibraryHelper_findSupportedAbi_replace(
JNIEnv *env,
jclass clazz,
jlong apkHandle,
jobjectArray javaCpuAbisToSearch,
jboolean debuggable,
- jstring apkPkgName)
+ jstring apkPkgName,
+ jstring apkDir)
{
#ifdef _PRC_COMPATIBILITY_PACKAGE_
+
+ int abiType = findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable);
+ if (apkDir == NULL) {
+ return (jint)abiType;
+ }
+
+ char abiFlag[256] = {'\0'};
+ ScopedUtfChars apkdir(env, apkDir);
+ size_t apkdir_size = apkdir.size();
const int numAbis = env->GetArrayLength(javaCpuAbisToSearch);
Vector<ScopedUtfChars*> supportedAbis;
+
+ assert(apkdir_size < 256 - 15);
+ strcpy(abiFlag, apkdir.c_str());
+ abiFlag[apkdir_size] = '/';
+ abiFlag[apkdir_size + 1] = '.';
for (int i = 0; i < numAbis; i++) {
ScopedUtfChars* abiName = new ScopedUtfChars(env,
- (jstring)env->GetObjectArrayElement(
- javaCpuAbisToSearch, i));
+ (jstring)env->GetObjectArrayElement(javaCpuAbisToSearch, i));
+ if (strlcpy(abiFlag + apkdir_size + 2, abiName->c_str(), 256 - apkdir_size - 2)
+ == abiName->size()) {
+ if (access(abiFlag, F_OK) == 0) {
+ abiType = i;
+ for (int j = 0; j < i; ++j) {
+ delete supportedAbis[j];
+ }
+ delete abiName;
+ return (jint)abiType;
+ }
+ }
+
supportedAbis.push_back(abiName);
}
- int abiType = findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable);
do {
+ if (abiType < 0 || abiType >= numAbis ) {
+ break;
+ }
+
+ if (0 != strcmp(supportedAbis[abiType]->c_str(), X86ABI) &&
+ 0 != strcmp(supportedAbis[abiType]->c_str(), X8664ABI)) {
+ break;
+ }
- if (abiType < 0 || abiType >= numAbis ) break ;
- // if one package's name is on OEM's specific white list, then the
- // package should be installed as default
ScopedUtfChars name(env, apkPkgName);
- if (isInOEMWhiteList(name.c_str())) {
+ if (NULL == name.c_str()) {
break;
}
- if (0 != strcmp(supportedAbis[abiType]->c_str(), X86ABI) &&
- 0 != strcmp(supportedAbis[abiType]->c_str(), X8664ABI)){
+ if (isInOEMWhiteList(name.c_str())) {
break;
}
+
ABIPicker picker(name.c_str(),supportedAbis);
if (!picker.buildNativeLibList((void*)apkHandle)) {
break;
}
abiType = picker.pickupRightABI(abiType);
- } while (false);
+ if (abiType >= 0 && abiType < numAbis &&
+ (strlcpy(abiFlag + apkdir_size + 2, supportedAbis[abiType]->c_str(),
+ 256 - apkdir_size - 2) == supportedAbis[abiType]->size())) {
+ creat(abiFlag, 0644);
+ }
+
+ } while(0);
for (int i = 0; i < numAbis; ++i) {
delete supportedAbis[i];
{"nativeSumNativeBinaries",
"(JLjava/lang/String;Z)J",
(void *)com_android_internal_content_NativeLibraryHelper_sumNativeBinaries},
- {"nativeFindSupportedAbi",
- "(J[Ljava/lang/String;Z)I",
- (void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi},
{"nativeFindSupportedAbiReplace",
- "(J[Ljava/lang/String;ZLjava/lang/String;)I",
+ "(J[Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)I",
(void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi_replace},
{"hasRenderscriptBitcode", "(J)I",
(void *)com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode},