Merge "Install all files from the lib directory for debuggable apps"

am: c0cc7c646c

Change-Id: Idc3b17fa4044ab0dd50fa141f1ec5ec8a47810b0
This commit is contained in:
Tamas Berghammer
2016-12-16 00:48:21 +00:00
committed by android-build-merger
3 changed files with 59 additions and 45 deletions

View File

@@ -342,6 +342,7 @@ public class PackageParser {
public final int[] splitRevisionCodes; public final int[] splitRevisionCodes;
public final boolean coreApp; public final boolean coreApp;
public final boolean debuggable;
public final boolean multiArch; public final boolean multiArch;
public final boolean use32bitAbi; public final boolean use32bitAbi;
public final boolean extractNativeLibs; public final boolean extractNativeLibs;
@@ -359,6 +360,7 @@ public class PackageParser {
this.baseRevisionCode = baseApk.revisionCode; this.baseRevisionCode = baseApk.revisionCode;
this.splitRevisionCodes = splitRevisionCodes; this.splitRevisionCodes = splitRevisionCodes;
this.coreApp = baseApk.coreApp; this.coreApp = baseApk.coreApp;
this.debuggable = baseApk.debuggable;
this.multiArch = baseApk.multiArch; this.multiArch = baseApk.multiArch;
this.use32bitAbi = baseApk.use32bitAbi; this.use32bitAbi = baseApk.use32bitAbi;
this.extractNativeLibs = baseApk.extractNativeLibs; this.extractNativeLibs = baseApk.extractNativeLibs;
@@ -388,6 +390,7 @@ public class PackageParser {
public final Signature[] signatures; public final Signature[] signatures;
public final Certificate[][] certificates; public final Certificate[][] certificates;
public final boolean coreApp; public final boolean coreApp;
public final boolean debuggable;
public final boolean multiArch; public final boolean multiArch;
public final boolean use32bitAbi; public final boolean use32bitAbi;
public final boolean extractNativeLibs; public final boolean extractNativeLibs;
@@ -395,7 +398,8 @@ public class PackageParser {
public ApkLite(String codePath, String packageName, String splitName, int versionCode, public ApkLite(String codePath, String packageName, String splitName, int versionCode,
int revisionCode, int installLocation, List<VerifierInfo> verifiers, int revisionCode, int installLocation, List<VerifierInfo> verifiers,
Signature[] signatures, Certificate[][] certificates, boolean coreApp, Signature[] signatures, Certificate[][] certificates, boolean coreApp,
boolean multiArch, boolean use32bitAbi, boolean extractNativeLibs) { boolean debuggable, boolean multiArch, boolean use32bitAbi,
boolean extractNativeLibs) {
this.codePath = codePath; this.codePath = codePath;
this.packageName = packageName; this.packageName = packageName;
this.splitName = splitName; this.splitName = splitName;
@@ -406,6 +410,7 @@ public class PackageParser {
this.signatures = signatures; this.signatures = signatures;
this.certificates = certificates; this.certificates = certificates;
this.coreApp = coreApp; this.coreApp = coreApp;
this.debuggable = debuggable;
this.multiArch = multiArch; this.multiArch = multiArch;
this.use32bitAbi = use32bitAbi; this.use32bitAbi = use32bitAbi;
this.extractNativeLibs = extractNativeLibs; this.extractNativeLibs = extractNativeLibs;
@@ -1440,6 +1445,7 @@ public class PackageParser {
int versionCode = 0; int versionCode = 0;
int revisionCode = 0; int revisionCode = 0;
boolean coreApp = false; boolean coreApp = false;
boolean debuggable = false;
boolean multiArch = false; boolean multiArch = false;
boolean use32bitAbi = false; boolean use32bitAbi = false;
boolean extractNativeLibs = true; boolean extractNativeLibs = true;
@@ -1479,6 +1485,9 @@ public class PackageParser {
if (parser.getDepth() == searchDepth && "application".equals(parser.getName())) { if (parser.getDepth() == searchDepth && "application".equals(parser.getName())) {
for (int i = 0; i < attrs.getAttributeCount(); ++i) { for (int i = 0; i < attrs.getAttributeCount(); ++i) {
final String attr = attrs.getAttributeName(i); final String attr = attrs.getAttributeName(i);
if ("debuggable".equals(attr)) {
debuggable = attrs.getAttributeBooleanValue(i, false);
}
if ("multiArch".equals(attr)) { if ("multiArch".equals(attr)) {
multiArch = attrs.getAttributeBooleanValue(i, false); multiArch = attrs.getAttributeBooleanValue(i, false);
} }
@@ -1494,7 +1503,7 @@ public class PackageParser {
return new ApkLite(codePath, packageSplit.first, packageSplit.second, versionCode, return new ApkLite(codePath, packageSplit.first, packageSplit.second, versionCode,
revisionCode, installLocation, verifiers, signatures, certificates, coreApp, revisionCode, installLocation, verifiers, signatures, certificates, coreApp,
multiArch, use32bitAbi, extractNativeLibs); debuggable, multiArch, use32bitAbi, extractNativeLibs);
} }
/** /**

View File

@@ -76,6 +76,7 @@ public class NativeLibraryHelper {
final long[] apkHandles; final long[] apkHandles;
final boolean multiArch; final boolean multiArch;
final boolean extractNativeLibs; final boolean extractNativeLibs;
final boolean debuggable;
public static Handle create(File packageFile) throws IOException { public static Handle create(File packageFile) throws IOException {
try { try {
@@ -89,15 +90,17 @@ public class NativeLibraryHelper {
public static Handle create(Package pkg) throws IOException { public static Handle create(Package pkg) throws IOException {
return create(pkg.getAllCodePaths(), return create(pkg.getAllCodePaths(),
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0, (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0,
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0); (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0,
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
} }
public static Handle create(PackageLite lite) throws IOException { public static Handle create(PackageLite lite) throws IOException {
return create(lite.getAllCodePaths(), lite.multiArch, lite.extractNativeLibs); return create(lite.getAllCodePaths(), lite.multiArch, lite.extractNativeLibs,
lite.debuggable);
} }
private static Handle create(List<String> codePaths, boolean multiArch, private static Handle create(List<String> codePaths, boolean multiArch,
boolean extractNativeLibs) throws IOException { boolean extractNativeLibs, boolean debuggable) throws IOException {
final int size = codePaths.size(); final int size = codePaths.size();
final long[] apkHandles = new long[size]; final long[] apkHandles = new long[size];
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@@ -112,13 +115,15 @@ public class NativeLibraryHelper {
} }
} }
return new Handle(apkHandles, multiArch, extractNativeLibs); return new Handle(apkHandles, multiArch, extractNativeLibs, debuggable);
} }
Handle(long[] apkHandles, boolean multiArch, boolean extractNativeLibs) { Handle(long[] apkHandles, boolean multiArch, boolean extractNativeLibs,
boolean debuggable) {
this.apkHandles = apkHandles; this.apkHandles = apkHandles;
this.multiArch = multiArch; this.multiArch = multiArch;
this.extractNativeLibs = extractNativeLibs; this.extractNativeLibs = extractNativeLibs;
this.debuggable = debuggable;
mGuard.open("close"); mGuard.open("close");
} }
@@ -149,15 +154,17 @@ public class NativeLibraryHelper {
private static native long nativeOpenApk(String path); private static native long nativeOpenApk(String path);
private static native void nativeClose(long handle); private static native void nativeClose(long handle);
private static native long nativeSumNativeBinaries(long handle, String cpuAbi); private static native long nativeSumNativeBinaries(long handle, String cpuAbi,
boolean debuggable);
private native static int nativeCopyNativeBinaries(long handle, String sharedLibraryPath, private native static int nativeCopyNativeBinaries(long handle, String sharedLibraryPath,
String abiToCopy, boolean extractNativeLibs, boolean hasNativeBridge); String abiToCopy, boolean extractNativeLibs, boolean hasNativeBridge,
boolean debuggable);
private static long sumNativeBinaries(Handle handle, String abi) { private static long sumNativeBinaries(Handle handle, String abi) {
long sum = 0; long sum = 0;
for (long apkHandle : handle.apkHandles) { for (long apkHandle : handle.apkHandles) {
sum += nativeSumNativeBinaries(apkHandle, abi); sum += nativeSumNativeBinaries(apkHandle, abi, handle.debuggable);
} }
return sum; return sum;
} }
@@ -173,7 +180,7 @@ public class NativeLibraryHelper {
public static int copyNativeBinaries(Handle handle, File sharedLibraryDir, String abi) { public static int copyNativeBinaries(Handle handle, File sharedLibraryDir, String abi) {
for (long apkHandle : handle.apkHandles) { for (long apkHandle : handle.apkHandles) {
int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi, int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi,
handle.extractNativeLibs, HAS_NATIVE_BRIDGE); handle.extractNativeLibs, HAS_NATIVE_BRIDGE, handle.debuggable);
if (res != INSTALL_SUCCEEDED) { if (res != INSTALL_SUCCEEDED) {
return res; return res;
} }
@@ -191,7 +198,7 @@ public class NativeLibraryHelper {
public static int findSupportedAbi(Handle handle, String[] supportedAbis) { public static int findSupportedAbi(Handle handle, String[] supportedAbis) {
int finalRes = NO_NATIVE_LIBRARIES; int finalRes = NO_NATIVE_LIBRARIES;
for (long apkHandle : handle.apkHandles) { for (long apkHandle : handle.apkHandles) {
final int res = nativeFindSupportedAbi(apkHandle, supportedAbis); final int res = nativeFindSupportedAbi(apkHandle, supportedAbis, handle.debuggable);
if (res == NO_NATIVE_LIBRARIES) { if (res == NO_NATIVE_LIBRARIES) {
// No native code, keep looking through all APKs. // No native code, keep looking through all APKs.
} else if (res == INSTALL_FAILED_NO_MATCHING_ABIS) { } else if (res == INSTALL_FAILED_NO_MATCHING_ABIS) {
@@ -213,7 +220,8 @@ public class NativeLibraryHelper {
return finalRes; return finalRes;
} }
private native static int nativeFindSupportedAbi(long handle, String[] supportedAbis); private native static int nativeFindSupportedAbi(long handle, String[] supportedAbis,
boolean debuggable);
// Convenience method to call removeNativeBinariesFromDirLI(File) // Convenience method to call removeNativeBinariesFromDirLI(File)
public static void removeNativeBinariesLI(String nativeLibraryPath) { public static void removeNativeBinariesLI(String nativeLibraryPath) {

View File

@@ -49,9 +49,6 @@
#define RS_BITCODE_SUFFIX ".bc" #define RS_BITCODE_SUFFIX ".bc"
#define GDBSERVER "gdbserver"
#define GDBSERVER_LEN (sizeof(GDBSERVER) - 1)
#define TMP_FILE_PATTERN "/tmp.XXXXXX" #define TMP_FILE_PATTERN "/tmp.XXXXXX"
#define TMP_FILE_PATTERN_LEN (sizeof(TMP_FILE_PATTERN) - 1) #define TMP_FILE_PATTERN_LEN (sizeof(TMP_FILE_PATTERN) - 1)
@@ -313,20 +310,20 @@ copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntr
*/ */
class NativeLibrariesIterator { class NativeLibrariesIterator {
private: private:
NativeLibrariesIterator(ZipFileRO* zipFile, void* cookie) NativeLibrariesIterator(ZipFileRO* zipFile, bool debuggable, void* cookie)
: mZipFile(zipFile), mCookie(cookie), mLastSlash(NULL) { : mZipFile(zipFile), mDebuggable(debuggable), mCookie(cookie), mLastSlash(NULL) {
fileName[0] = '\0'; fileName[0] = '\0';
} }
public: public:
static NativeLibrariesIterator* create(ZipFileRO* zipFile) { static NativeLibrariesIterator* create(ZipFileRO* zipFile, bool debuggable) {
void* cookie = NULL; void* cookie = NULL;
// Do not specify a suffix to find both .so files and gdbserver. // Do not specify a suffix to find both .so files and gdbserver.
if (!zipFile->startIteration(&cookie, APK_LIB, NULL /* suffix */)) { if (!zipFile->startIteration(&cookie, APK_LIB, NULL /* suffix */)) {
return NULL; return NULL;
} }
return new NativeLibrariesIterator(zipFile, cookie); return new NativeLibrariesIterator(zipFile, debuggable, cookie);
} }
ZipEntryRO next() { ZipEntryRO next() {
@@ -347,23 +344,19 @@ public:
const char* lastSlash = strrchr(fileName, '/'); const char* lastSlash = strrchr(fileName, '/');
ALOG_ASSERT(lastSlash != NULL, "last slash was null somehow for %s\n", fileName); ALOG_ASSERT(lastSlash != NULL, "last slash was null somehow for %s\n", fileName);
// Exception: If we find the gdbserver binary, return it.
if (!strncmp(lastSlash + 1, GDBSERVER, GDBSERVER_LEN)) {
mLastSlash = lastSlash;
break;
}
// Make sure the filename starts with lib and ends with ".so".
if (strncmp(fileName + fileNameLen - LIB_SUFFIX_LEN, LIB_SUFFIX, LIB_SUFFIX_LEN)
|| strncmp(lastSlash, LIB_PREFIX, LIB_PREFIX_LEN)) {
continue;
}
// Make sure the filename is safe. // Make sure the filename is safe.
if (!isFilenameSafe(lastSlash + 1)) { if (!isFilenameSafe(lastSlash + 1)) {
continue; continue;
} }
if (!mDebuggable) {
// Make sure the filename starts with lib and ends with ".so".
if (strncmp(fileName + fileNameLen - LIB_SUFFIX_LEN, LIB_SUFFIX, LIB_SUFFIX_LEN)
|| strncmp(lastSlash, LIB_PREFIX, LIB_PREFIX_LEN)) {
continue;
}
}
mLastSlash = lastSlash; mLastSlash = lastSlash;
break; break;
} }
@@ -386,19 +379,21 @@ private:
char fileName[PATH_MAX]; char fileName[PATH_MAX];
ZipFileRO* const mZipFile; ZipFileRO* const mZipFile;
const bool mDebuggable;
void* mCookie; void* mCookie;
const char* mLastSlash; const char* mLastSlash;
}; };
static install_status_t static install_status_t
iterateOverNativeFiles(JNIEnv *env, jlong apkHandle, jstring javaCpuAbi, iterateOverNativeFiles(JNIEnv *env, jlong apkHandle, jstring javaCpuAbi,
iterFunc callFunc, void* callArg) { jboolean debuggable, iterFunc callFunc, void* callArg) {
ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle); ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
if (zipFile == NULL) { if (zipFile == NULL) {
return INSTALL_FAILED_INVALID_APK; return INSTALL_FAILED_INVALID_APK;
} }
std::unique_ptr<NativeLibrariesIterator> it(NativeLibrariesIterator::create(zipFile)); std::unique_ptr<NativeLibrariesIterator> it(
NativeLibrariesIterator::create(zipFile, debuggable));
if (it.get() == NULL) { if (it.get() == NULL) {
return INSTALL_FAILED_INVALID_APK; return INSTALL_FAILED_INVALID_APK;
} }
@@ -432,7 +427,8 @@ iterateOverNativeFiles(JNIEnv *env, jlong apkHandle, jstring javaCpuAbi,
} }
static int findSupportedAbi(JNIEnv *env, jlong apkHandle, jobjectArray supportedAbisArray) { static int findSupportedAbi(JNIEnv *env, jlong apkHandle, jobjectArray supportedAbisArray,
jboolean debuggable) {
const int numAbis = env->GetArrayLength(supportedAbisArray); const int numAbis = env->GetArrayLength(supportedAbisArray);
Vector<ScopedUtfChars*> supportedAbis; Vector<ScopedUtfChars*> supportedAbis;
@@ -446,7 +442,8 @@ static int findSupportedAbi(JNIEnv *env, jlong apkHandle, jobjectArray supported
return INSTALL_FAILED_INVALID_APK; return INSTALL_FAILED_INVALID_APK;
} }
std::unique_ptr<NativeLibrariesIterator> it(NativeLibrariesIterator::create(zipFile)); std::unique_ptr<NativeLibrariesIterator> it(
NativeLibrariesIterator::create(zipFile, debuggable));
if (it.get() == NULL) { if (it.get() == NULL) {
return INSTALL_FAILED_INVALID_APK; return INSTALL_FAILED_INVALID_APK;
} }
@@ -488,29 +485,29 @@ static int findSupportedAbi(JNIEnv *env, jlong apkHandle, jobjectArray supported
static jint static jint
com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz, com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi, jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi,
jboolean extractNativeLibs, jboolean hasNativeBridge) jboolean extractNativeLibs, jboolean hasNativeBridge, jboolean debuggable)
{ {
void* args[] = { &javaNativeLibPath, &extractNativeLibs, &hasNativeBridge }; void* args[] = { &javaNativeLibPath, &extractNativeLibs, &hasNativeBridge };
return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi, return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi, debuggable,
copyFileIfChanged, reinterpret_cast<void*>(args)); copyFileIfChanged, reinterpret_cast<void*>(args));
} }
static jlong static jlong
com_android_internal_content_NativeLibraryHelper_sumNativeBinaries(JNIEnv *env, jclass clazz, com_android_internal_content_NativeLibraryHelper_sumNativeBinaries(JNIEnv *env, jclass clazz,
jlong apkHandle, jstring javaCpuAbi) jlong apkHandle, jstring javaCpuAbi, jboolean debuggable)
{ {
size_t totalSize = 0; size_t totalSize = 0;
iterateOverNativeFiles(env, apkHandle, javaCpuAbi, sumFiles, &totalSize); iterateOverNativeFiles(env, apkHandle, javaCpuAbi, debuggable, sumFiles, &totalSize);
return totalSize; return totalSize;
} }
static jint static jint
com_android_internal_content_NativeLibraryHelper_findSupportedAbi(JNIEnv *env, jclass clazz, com_android_internal_content_NativeLibraryHelper_findSupportedAbi(JNIEnv *env, jclass clazz,
jlong apkHandle, jobjectArray javaCpuAbisToSearch) jlong apkHandle, jobjectArray javaCpuAbisToSearch, jboolean debuggable)
{ {
return (jint) findSupportedAbi(env, apkHandle, javaCpuAbisToSearch); return (jint) findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable);
} }
enum bitcode_scan_result_t { enum bitcode_scan_result_t {
@@ -569,13 +566,13 @@ static const JNINativeMethod gMethods[] = {
"(J)V", "(J)V",
(void *)com_android_internal_content_NativeLibraryHelper_close}, (void *)com_android_internal_content_NativeLibraryHelper_close},
{"nativeCopyNativeBinaries", {"nativeCopyNativeBinaries",
"(JLjava/lang/String;Ljava/lang/String;ZZ)I", "(JLjava/lang/String;Ljava/lang/String;ZZZ)I",
(void *)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries}, (void *)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries},
{"nativeSumNativeBinaries", {"nativeSumNativeBinaries",
"(JLjava/lang/String;)J", "(JLjava/lang/String;Z)J",
(void *)com_android_internal_content_NativeLibraryHelper_sumNativeBinaries}, (void *)com_android_internal_content_NativeLibraryHelper_sumNativeBinaries},
{"nativeFindSupportedAbi", {"nativeFindSupportedAbi",
"(J[Ljava/lang/String;)I", "(J[Ljava/lang/String;Z)I",
(void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi}, (void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi},
{"hasRenderscriptBitcode", "(J)I", {"hasRenderscriptBitcode", "(J)I",
(void *)com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode}, (void *)com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode},