diff options
| author | 2014-06-03 13:24:50 +0000 | |
|---|---|---|
| committer | 2014-06-03 13:24:50 +0000 | |
| commit | dd2e9d3386d2d74f99f79bcad951ff5cdefa6fab (patch) | |
| tree | 221b81e8642f3acac78d2934f395dcc52f4b5a30 | |
| parent | 797b109c60bda8e122075b0c2101d3f2a0b67c07 (diff) | |
| parent | 7cb13f8a0a40f3d971a953b330f38bfcfb001c5e (diff) | |
am 7cb13f8a: Merge "Scan for renderscript files before deciding ABIs."
* commit '7cb13f8a0a40f3d971a953b330f38bfcfb001c5e':
Scan for renderscript files before deciding ABIs.
4 files changed, 103 insertions, 16 deletions
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java index ba419f9bf1ab..dab3aff7c721 100644 --- a/core/java/com/android/internal/content/NativeLibraryHelper.java +++ b/core/java/com/android/internal/content/NativeLibraryHelper.java @@ -20,6 +20,7 @@ import android.content.pm.PackageManager; import android.util.Slog; import java.io.File; +import java.io.IOException; /** * Native libraries helper. @@ -141,4 +142,18 @@ public class NativeLibraryHelper { return deletedFiles; } + + // We don't care about the other return values for now. + private static final int BITCODE_PRESENT = 1; + + public static boolean hasRenderscriptBitcode(ApkHandle handle) throws IOException { + final int returnVal = hasRenderscriptBitcode(handle.apkHandle); + if (returnVal < 0) { + throw new IOException("Error scanning APK, code: " + returnVal); + } + + return (returnVal == BITCODE_PRESENT); + } + + private static native int hasRenderscriptBitcode(long apkHandle); } diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp index 200457696d72..8cb897e629a8 100644 --- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp +++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp @@ -46,6 +46,9 @@ #define LIB_SUFFIX ".so" #define LIB_SUFFIX_LEN (sizeof(LIB_SUFFIX) - 1) +#define RS_BITCODE_SUFFIX ".bc" +#define RS_BITCODE_SUFFIX_LEN (sizeof(RS_BITCODE_SUFFIX) -1) + #define GDBSERVER "gdbserver" #define GDBSERVER_LEN (sizeof(GDBSERVER) - 1) @@ -486,6 +489,42 @@ com_android_internal_content_NativeLibraryHelper_findSupportedAbi(JNIEnv *env, j return (jint) findSupportedAbi(env, apkHandle, javaCpuAbisToSearch); } +enum bitcode_scan_result_t { + APK_SCAN_ERROR = -1, + NO_BITCODE_PRESENT = 0, + BITCODE_PRESENT = 1, +}; + +static jint +com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode(JNIEnv *env, jclass clazz, + jlong apkHandle) { + ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle); + void* cookie = NULL; + if (!zipFile->startIteration(&cookie)) { + return APK_SCAN_ERROR; + } + + char fileName[PATH_MAX]; + ZipEntryRO next = NULL; + while ((next = zipFile->nextEntry(cookie)) != NULL) { + if (zipFile->getEntryFileName(next, fileName, sizeof(fileName))) { + continue; + } + + const size_t fileNameLen = strlen(fileName); + const char* lastSlash = strrchr(fileName, '/'); + const char* baseName = (lastSlash == NULL) ? fileName : fileName + 1; + if (!strncmp(fileName + fileNameLen - RS_BITCODE_SUFFIX_LEN, RS_BITCODE_SUFFIX, + RS_BITCODE_SUFFIX_LEN) && isFilenameSafe(baseName)) { + zipFile->endIteration(cookie); + return BITCODE_PRESENT; + } + } + + zipFile->endIteration(cookie); + return NO_BITCODE_PRESENT; +} + static jlong com_android_internal_content_NativeLibraryHelper_openApk(JNIEnv *env, jclass, jstring apkPath) { @@ -517,6 +556,8 @@ static JNINativeMethod gMethods[] = { {"nativeFindSupportedAbi", "(J[Ljava/lang/String;)I", (void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi}, + {"hasRenderscriptBitcode", "(J)I", + (void *)com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode}, }; diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index b02aefc2ed5a..e4de641e6a4b 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -88,7 +88,7 @@ public class DefaultContainerService extends IntentService { private IMediaContainerService.Stub mBinder = new IMediaContainerService.Stub() { /** * Creates a new container and copies resource there. - * @param paackageURI the uri of resource to be copied. Can be either + * @param packageURI the uri of resource to be copied. Can be either * a content uri or a file uri * @param cid the id of the secure container that should * be used for creating a secure container into which the resource @@ -342,9 +342,22 @@ public class DefaultContainerService extends IntentService { // The .apk file String codePath = packageURI.getPath(); File codeFile = new File(codePath); - String[] abiList = (abiOverride != null) ? new String[] { abiOverride } - : Build.SUPPORTED_ABIS; NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codePath); + String[] abiList = Build.SUPPORTED_ABIS; + if (abiOverride != null) { + abiList = new String[] { abiList }; + } else { + try { + if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && + NativeLibraryHelper.hasRenderscriptBitcode(handle)) { + abiList = Build.SUPPORTED_32_BIT_ABIS; + } + } catch (IOException ioe) { + Slog.w(TAG, "Problem determining ABI for: " + codeFile.getPath()); + return null; + } + } + final int abi = NativeLibraryHelper.findSupportedAbi(handle, abiList); // Calculate size of container needed to hold base APK. diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 9edb91636148..95eeb1f942c8 100755 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -5073,12 +5073,23 @@ public class PackageManagerService extends IPackageManager.Stub { if (pkg.applicationInfo.nativeLibraryDir != null) { final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile); try { + // Enable gross and lame hacks for apps that are built with old + // SDK tools. We must scan their APKs for renderscript bitcode and + // not launch them if it's present. Don't bother checking on devices + // that don't have 64 bit support. + String[] abiList = Build.SUPPORTED_ABIS; + boolean hasLegacyRenderscriptBitcode = false; + if (abiOverride != null) { + abiList = new String[] { abiOverride }; + } else if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && + NativeLibraryHelper.hasRenderscriptBitcode(handle)) { + abiList = Build.SUPPORTED_32_BIT_ABIS; + hasLegacyRenderscriptBitcode = true; + } + File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); final String dataPathString = dataPath.getCanonicalPath(); - final String[] abiList = (abiOverride != null) ? new String[] { abiOverride } : - Build.SUPPORTED_ABIS; - if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { /* * Upgrading from a previous version of the OS sometimes @@ -5091,17 +5102,18 @@ public class PackageManagerService extends IPackageManager.Stub { Log.i(TAG, "removed obsolete native libraries for system package " + path); } - if (abiOverride != null) { - pkg.applicationInfo.cpuAbi = abiOverride; + if (abiOverride != null || hasLegacyRenderscriptBitcode) { + pkg.applicationInfo.cpuAbi = abiList[0]; + pkgSetting.cpuAbiString = abiList[0]; } else { setInternalAppAbi(pkg, pkgSetting); } } else { if (!isForwardLocked(pkg) && !isExternal(pkg)) { /* - * Update native library dir if it starts with - * /data/data - */ + * Update native library dir if it starts with + * /data/data + */ if (nativeLibraryDir.getPath().startsWith(dataPathString)) { setInternalAppNativeLibraryPath(pkg, pkgSetting); nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); @@ -5120,8 +5132,8 @@ public class PackageManagerService extends IPackageManager.Stub { // note of what ABI we're using if (copyRet != PackageManager.NO_NATIVE_LIBRARIES) { pkg.applicationInfo.cpuAbi = abiList[copyRet]; - } else if (abiOverride != null) { - pkg.applicationInfo.cpuAbi = abiOverride; + } else if (abiOverride != null || hasLegacyRenderscriptBitcode) { + pkg.applicationInfo.cpuAbi = abiList[0]; } else { pkg.applicationInfo.cpuAbi = null; } @@ -5145,8 +5157,8 @@ public class PackageManagerService extends IPackageManager.Stub { // Note that (non upgraded) system apps will not have any native // libraries bundled in their APK, but we're guaranteed not to be // such an app at this point. - if (abiOverride != null) { - pkg.applicationInfo.cpuAbi = abiOverride; + if (abiOverride != null || hasLegacyRenderscriptBitcode) { + pkg.applicationInfo.cpuAbi = abiList[0]; } else { pkg.applicationInfo.cpuAbi = null; } @@ -8812,9 +8824,15 @@ public class PackageManagerService extends IPackageManager.Stub { } final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codeFile); - final String[] abiList = (abiOverride != null) ? + String[] abiList = (abiOverride != null) ? new String[] { abiOverride } : Build.SUPPORTED_ABIS; try { + if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && + abiOverride == null && + NativeLibraryHelper.hasRenderscriptBitcode(handle)) { + abiList = Build.SUPPORTED_32_BIT_ABIS; + } + int copyRet = copyNativeLibrariesForInternalApp(handle, nativeLibraryFile, abiList); if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { return copyRet; |