Merge "Load libraries directly from apk"
This commit is contained in:
@@ -547,6 +547,7 @@ package android {
|
||||
field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
|
||||
field public static final int exported = 16842768; // 0x1010010
|
||||
field public static final int extraTension = 16843371; // 0x101026b
|
||||
field public static final int extractNativeLibs = 16843990; // 0x10104d6
|
||||
field public static final int factor = 16843219; // 0x10101d3
|
||||
field public static final int fadeDuration = 16843384; // 0x1010278
|
||||
field public static final int fadeEnabled = 16843390; // 0x101027e
|
||||
@@ -8368,6 +8369,7 @@ package android.content.pm {
|
||||
field public static final int FLAG_ALLOW_TASK_REPARENTING = 32; // 0x20
|
||||
field public static final int FLAG_DEBUGGABLE = 2; // 0x2
|
||||
field public static final int FLAG_EXTERNAL_STORAGE = 262144; // 0x40000
|
||||
field public static final int FLAG_EXTRACT_NATIVE_LIBS = 268435456; // 0x10000000
|
||||
field public static final int FLAG_FACTORY_TEST = 16; // 0x10
|
||||
field public static final int FLAG_FULL_BACKUP_ONLY = 67108864; // 0x4000000
|
||||
field public static final int FLAG_HAS_CODE = 4; // 0x4
|
||||
@@ -17515,7 +17517,7 @@ package android.net.http {
|
||||
method public static android.net.http.HttpResponseCache getInstalled();
|
||||
method public int getNetworkCount();
|
||||
method public int getRequestCount();
|
||||
method public static android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException;
|
||||
method public static synchronized android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException;
|
||||
method public long maxSize();
|
||||
method public java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException;
|
||||
method public long size();
|
||||
@@ -41519,7 +41521,7 @@ package java.lang {
|
||||
method public static double nextUp(double);
|
||||
method public static float nextUp(float);
|
||||
method public static double pow(double, double);
|
||||
method public static synchronized double random();
|
||||
method public static double random();
|
||||
method public static double rint(double);
|
||||
method public static long round(double);
|
||||
method public static int round(float);
|
||||
|
||||
@@ -617,6 +617,7 @@ package android {
|
||||
field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
|
||||
field public static final int exported = 16842768; // 0x1010010
|
||||
field public static final int extraTension = 16843371; // 0x101026b
|
||||
field public static final int extractNativeLibs = 16843990; // 0x10104d6
|
||||
field public static final int factor = 16843219; // 0x10101d3
|
||||
field public static final int fadeDuration = 16843384; // 0x1010278
|
||||
field public static final int fadeEnabled = 16843390; // 0x101027e
|
||||
@@ -8616,6 +8617,7 @@ package android.content.pm {
|
||||
field public static final int FLAG_ALLOW_TASK_REPARENTING = 32; // 0x20
|
||||
field public static final int FLAG_DEBUGGABLE = 2; // 0x2
|
||||
field public static final int FLAG_EXTERNAL_STORAGE = 262144; // 0x40000
|
||||
field public static final int FLAG_EXTRACT_NATIVE_LIBS = 268435456; // 0x10000000
|
||||
field public static final int FLAG_FACTORY_TEST = 16; // 0x10
|
||||
field public static final int FLAG_FULL_BACKUP_ONLY = 67108864; // 0x4000000
|
||||
field public static final int FLAG_HAS_CODE = 4; // 0x4
|
||||
@@ -18843,7 +18845,7 @@ package android.net.http {
|
||||
method public static android.net.http.HttpResponseCache getInstalled();
|
||||
method public int getNetworkCount();
|
||||
method public int getRequestCount();
|
||||
method public static android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException;
|
||||
method public static synchronized android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException;
|
||||
method public long maxSize();
|
||||
method public java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException;
|
||||
method public long size();
|
||||
@@ -44055,7 +44057,7 @@ package java.lang {
|
||||
method public static double nextUp(double);
|
||||
method public static float nextUp(float);
|
||||
method public static double pow(double, double);
|
||||
method public static synchronized double random();
|
||||
method public static double random();
|
||||
method public static double rint(double);
|
||||
method public static long round(double);
|
||||
method public static int round(float);
|
||||
|
||||
@@ -345,6 +345,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
*/
|
||||
public static final int FLAG_USES_CLEARTEXT_TRAFFIC = 1<<27;
|
||||
|
||||
/**
|
||||
* When set installer extracts native libs from .apk files.
|
||||
*/
|
||||
public static final int FLAG_EXTRACT_NATIVE_LIBS = 1<<28;
|
||||
|
||||
/**
|
||||
* Value for {@link #flags}: true if code from this application will need to be
|
||||
* loaded into other applications' processes. On devices that support multiple
|
||||
|
||||
@@ -268,6 +268,7 @@ public class PackageParser {
|
||||
|
||||
public final boolean coreApp;
|
||||
public final boolean multiArch;
|
||||
public final boolean extractNativeLibs;
|
||||
|
||||
public PackageLite(String codePath, ApkLite baseApk, String[] splitNames,
|
||||
String[] splitCodePaths, int[] splitRevisionCodes) {
|
||||
@@ -283,6 +284,7 @@ public class PackageParser {
|
||||
this.splitRevisionCodes = splitRevisionCodes;
|
||||
this.coreApp = baseApk.coreApp;
|
||||
this.multiArch = baseApk.multiArch;
|
||||
this.extractNativeLibs = baseApk.extractNativeLibs;
|
||||
}
|
||||
|
||||
public List<String> getAllCodePaths() {
|
||||
@@ -309,10 +311,12 @@ public class PackageParser {
|
||||
public final Signature[] signatures;
|
||||
public final boolean coreApp;
|
||||
public final boolean multiArch;
|
||||
public final boolean extractNativeLibs;
|
||||
|
||||
public ApkLite(String codePath, String packageName, String splitName, int versionCode,
|
||||
int revisionCode, int installLocation, List<VerifierInfo> verifiers,
|
||||
Signature[] signatures, boolean coreApp, boolean multiArch) {
|
||||
Signature[] signatures, boolean coreApp, boolean multiArch,
|
||||
boolean extractNativeLibs) {
|
||||
this.codePath = codePath;
|
||||
this.packageName = packageName;
|
||||
this.splitName = splitName;
|
||||
@@ -323,6 +327,7 @@ public class PackageParser {
|
||||
this.signatures = signatures;
|
||||
this.coreApp = coreApp;
|
||||
this.multiArch = multiArch;
|
||||
this.extractNativeLibs = extractNativeLibs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1269,6 +1274,7 @@ public class PackageParser {
|
||||
int revisionCode = 0;
|
||||
boolean coreApp = false;
|
||||
boolean multiArch = false;
|
||||
boolean extractNativeLibs = true;
|
||||
|
||||
for (int i = 0; i < attrs.getAttributeCount(); i++) {
|
||||
final String attr = attrs.getAttributeName(i);
|
||||
@@ -1307,14 +1313,17 @@ public class PackageParser {
|
||||
final String attr = attrs.getAttributeName(i);
|
||||
if ("multiArch".equals(attr)) {
|
||||
multiArch = attrs.getAttributeBooleanValue(i, false);
|
||||
break;
|
||||
}
|
||||
if ("extractNativeLibs".equals(attr)) {
|
||||
extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ApkLite(codePath, packageSplit.first, packageSplit.second, versionCode,
|
||||
revisionCode, installLocation, verifiers, signatures, coreApp, multiArch);
|
||||
revisionCode, installLocation, verifiers, signatures, coreApp, multiArch,
|
||||
extractNativeLibs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2567,6 +2576,12 @@ public class PackageParser {
|
||||
ai.flags |= ApplicationInfo.FLAG_MULTIARCH;
|
||||
}
|
||||
|
||||
if (sa.getBoolean(
|
||||
com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs,
|
||||
true)) {
|
||||
ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
|
||||
}
|
||||
|
||||
String str;
|
||||
str = sa.getNonConfigurationString(
|
||||
com.android.internal.R.styleable.AndroidManifestApplication_permission, 0);
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.content.pm.PackageParser.PackageLite;
|
||||
import android.content.pm.PackageParser.PackageParserException;
|
||||
import android.os.Build;
|
||||
import android.os.SELinux;
|
||||
import android.os.SystemProperties;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.util.Slog;
|
||||
@@ -74,6 +75,7 @@ public class NativeLibraryHelper {
|
||||
|
||||
final long[] apkHandles;
|
||||
final boolean multiArch;
|
||||
final boolean extractNativeLibs;
|
||||
|
||||
public static Handle create(File packageFile) throws IOException {
|
||||
try {
|
||||
@@ -86,14 +88,16 @@ public class NativeLibraryHelper {
|
||||
|
||||
public static Handle create(Package pkg) throws IOException {
|
||||
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);
|
||||
}
|
||||
|
||||
public static Handle create(PackageLite lite) throws IOException {
|
||||
return create(lite.getAllCodePaths(), lite.multiArch);
|
||||
return create(lite.getAllCodePaths(), lite.multiArch, lite.extractNativeLibs);
|
||||
}
|
||||
|
||||
private static Handle create(List<String> codePaths, boolean multiArch) throws IOException {
|
||||
private static Handle create(List<String> codePaths, boolean multiArch,
|
||||
boolean extractNativeLibs) throws IOException {
|
||||
final int size = codePaths.size();
|
||||
final long[] apkHandles = new long[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
@@ -108,12 +112,13 @@ public class NativeLibraryHelper {
|
||||
}
|
||||
}
|
||||
|
||||
return new Handle(apkHandles, multiArch);
|
||||
return new Handle(apkHandles, multiArch, extractNativeLibs);
|
||||
}
|
||||
|
||||
Handle(long[] apkHandles, boolean multiArch) {
|
||||
Handle(long[] apkHandles, boolean multiArch, boolean extractNativeLibs) {
|
||||
this.apkHandles = apkHandles;
|
||||
this.multiArch = multiArch;
|
||||
this.extractNativeLibs = extractNativeLibs;
|
||||
mGuard.open("close");
|
||||
}
|
||||
|
||||
@@ -146,8 +151,8 @@ public class NativeLibraryHelper {
|
||||
|
||||
private static native long nativeSumNativeBinaries(long handle, String cpuAbi);
|
||||
|
||||
private native static int nativeCopyNativeBinaries(long handle,
|
||||
String sharedLibraryPath, String abiToCopy);
|
||||
private native static int nativeCopyNativeBinaries(long handle, String sharedLibraryPath,
|
||||
String abiToCopy, boolean extractNativeLibs, boolean hasNativeBridge);
|
||||
|
||||
private static long sumNativeBinaries(Handle handle, String abi) {
|
||||
long sum = 0;
|
||||
@@ -167,7 +172,8 @@ public class NativeLibraryHelper {
|
||||
*/
|
||||
public static int copyNativeBinaries(Handle handle, File sharedLibraryDir, String abi) {
|
||||
for (long apkHandle : handle.apkHandles) {
|
||||
int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi);
|
||||
int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi,
|
||||
handle.extractNativeLibs, HAS_NATIVE_BRIDGE);
|
||||
if (res != INSTALL_SUCCEEDED) {
|
||||
return res;
|
||||
}
|
||||
@@ -218,7 +224,8 @@ public class NativeLibraryHelper {
|
||||
/**
|
||||
* Remove the native binaries of a given package. This deletes the files
|
||||
*/
|
||||
public static void removeNativeBinariesFromDirLI(File nativeLibraryRoot, boolean deleteRootDir) {
|
||||
public static void removeNativeBinariesFromDirLI(File nativeLibraryRoot,
|
||||
boolean deleteRootDir) {
|
||||
if (DEBUG_NATIVE) {
|
||||
Slog.w(TAG, "Deleting native binaries from: " + nativeLibraryRoot.getPath());
|
||||
}
|
||||
@@ -247,7 +254,8 @@ public class NativeLibraryHelper {
|
||||
// asked to or this will prevent installation of future updates.
|
||||
if (deleteRootDir) {
|
||||
if (!nativeLibraryRoot.delete()) {
|
||||
Slog.w(TAG, "Could not delete native binary directory: " + nativeLibraryRoot.getPath());
|
||||
Slog.w(TAG, "Could not delete native binary directory: " +
|
||||
nativeLibraryRoot.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -416,6 +424,9 @@ public class NativeLibraryHelper {
|
||||
// We don't care about the other return values for now.
|
||||
private static final int BITCODE_PRESENT = 1;
|
||||
|
||||
private static final boolean HAS_NATIVE_BRIDGE =
|
||||
!"0".equals(SystemProperties.get("ro.dalvik.vm.native.bridge", "0"));
|
||||
|
||||
private static native int hasRenderscriptBitcode(long apkHandle);
|
||||
|
||||
public static boolean hasRenderscriptBitcode(Handle handle) throws IOException {
|
||||
|
||||
@@ -586,6 +586,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
|
||||
char localeOption[sizeof("-Duser.locale=") + PROPERTY_VALUE_MAX];
|
||||
char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];
|
||||
char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];
|
||||
char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX];
|
||||
|
||||
bool checkJni = false;
|
||||
property_get("dalvik.vm.checkjni", propBuf, "");
|
||||
@@ -859,6 +860,18 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
|
||||
// Dalvik-cache pruning counter.
|
||||
parseRuntimeOption("dalvik.vm.zygote.max-boot-retry", cachePruneBuf,
|
||||
"-Xzygote-max-boot-retry=");
|
||||
#if defined(__LP64__)
|
||||
const char* cpu_abilist_property_name = "ro.product.cpu.abilist64";
|
||||
#else
|
||||
const char* cpu_abilist_property_name = "ro.product.cpu.abilist32";
|
||||
#endif // defined(__LP64__)
|
||||
property_get(cpu_abilist_property_name, propBuf, "");
|
||||
if (propBuf[0] == '\0') {
|
||||
ALOGE("%s is not expected to be empty", cpu_abilist_property_name);
|
||||
return -1;
|
||||
}
|
||||
snprintf(cpuAbiListBuf, sizeof(cpuAbiListBuf), "--cpu-abilist=%s", propBuf);
|
||||
addOption(cpuAbiListBuf);
|
||||
|
||||
initArgs.version = JNI_VERSION_1_4;
|
||||
initArgs.options = mOptions.editArray();
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -173,7 +174,11 @@ sumFiles(JNIEnv*, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char
|
||||
static install_status_t
|
||||
copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName)
|
||||
{
|
||||
jstring* javaNativeLibPath = (jstring*) arg;
|
||||
void** args = reinterpret_cast<void**>(arg);
|
||||
jstring* javaNativeLibPath = (jstring*) args[0];
|
||||
jboolean extractNativeLibs = *(jboolean*) args[1];
|
||||
jboolean hasNativeBridge = *(jboolean*) args[2];
|
||||
|
||||
ScopedUtfChars nativeLibPath(env, *javaNativeLibPath);
|
||||
|
||||
size_t uncompLen;
|
||||
@@ -181,13 +186,31 @@ copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntr
|
||||
long crc;
|
||||
time_t modTime;
|
||||
|
||||
if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, &when, &crc)) {
|
||||
int method;
|
||||
off64_t offset;
|
||||
|
||||
if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, NULL, &offset, &when, &crc)) {
|
||||
ALOGD("Couldn't read zip entry info\n");
|
||||
return INSTALL_FAILED_INVALID_APK;
|
||||
} else {
|
||||
struct tm t;
|
||||
ZipUtils::zipTimeToTimespec(when, &t);
|
||||
modTime = mktime(&t);
|
||||
}
|
||||
|
||||
if (!extractNativeLibs) {
|
||||
// check if library is uncompressed and page-aligned
|
||||
if (method != ZipFileRO::kCompressStored) {
|
||||
ALOGD("Library '%s' is compressed - will not be able to open it directly from apk.\n",
|
||||
fileName);
|
||||
return INSTALL_FAILED_INVALID_APK;
|
||||
}
|
||||
|
||||
if (offset % PAGE_SIZE != 0) {
|
||||
ALOGD("Library '%s' is not page-aligned - will not be able to open it directly from"
|
||||
" apk.\n", fileName);
|
||||
return INSTALL_FAILED_INVALID_APK;
|
||||
}
|
||||
|
||||
if (!hasNativeBridge) {
|
||||
return INSTALL_SUCCEEDED;
|
||||
}
|
||||
}
|
||||
|
||||
// Build local file path
|
||||
@@ -208,6 +231,9 @@ copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntr
|
||||
}
|
||||
|
||||
// Only copy out the native file if it's different.
|
||||
struct tm t;
|
||||
ZipUtils::zipTimeToTimespec(when, &t);
|
||||
modTime = mktime(&t);
|
||||
struct stat64 st;
|
||||
if (!isFileDifferent(localFileName, uncompLen, modTime, crc, &st)) {
|
||||
return INSTALL_SUCCEEDED;
|
||||
@@ -465,10 +491,12 @@ static int findSupportedAbi(JNIEnv *env, jlong apkHandle, jobjectArray supported
|
||||
|
||||
static jint
|
||||
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)
|
||||
{
|
||||
void* args[] = { &javaNativeLibPath, &extractNativeLibs, &hasNativeBridge };
|
||||
return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi,
|
||||
copyFileIfChanged, &javaNativeLibPath);
|
||||
copyFileIfChanged, reinterpret_cast<void*>(args));
|
||||
}
|
||||
|
||||
static jlong
|
||||
@@ -548,7 +576,7 @@ static JNINativeMethod gMethods[] = {
|
||||
"(J)V",
|
||||
(void *)com_android_internal_content_NativeLibraryHelper_close},
|
||||
{"nativeCopyNativeBinaries",
|
||||
"(JLjava/lang/String;Ljava/lang/String;)I",
|
||||
"(JLjava/lang/String;Ljava/lang/String;ZZ)I",
|
||||
(void *)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries},
|
||||
{"nativeSumNativeBinaries",
|
||||
"(JLjava/lang/String;)J",
|
||||
|
||||
@@ -1021,6 +1021,10 @@
|
||||
<p>The default value of this attribute is <code>false</code>. -->
|
||||
<attr name="resumeWhilePausing" format="boolean" />
|
||||
|
||||
<!-- When set installer will extract native libraries. If set to false
|
||||
libraries in the apk must be stored and page-aligned. -->
|
||||
<attr name="extractNativeLibs" format="boolean"/>
|
||||
|
||||
<!-- The <code>manifest</code> tag is the root of an
|
||||
<code>AndroidManifest.xml</code> file,
|
||||
describing the contents of an Android package (.apk) file. One
|
||||
@@ -1151,8 +1155,8 @@
|
||||
@hide -->
|
||||
<attr name="usesCleartextTraffic" />
|
||||
<attr name="multiArch" />
|
||||
<attr name="extractNativeLibs" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- The <code>permission</code> tag declares a security permission that can be
|
||||
used to control access from other packages to specific components or
|
||||
features in your package (or other packages). See the
|
||||
|
||||
@@ -2598,4 +2598,5 @@
|
||||
<public type="style" name="Theme.DeviceDefault.Dialog.Alert" />
|
||||
<public type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" />
|
||||
|
||||
<public type="attr" name="extractNativeLibs" />
|
||||
</resources>
|
||||
|
||||
@@ -23,6 +23,14 @@ LOCAL_SHARED_LIBRARIES := \
|
||||
libnativehelper
|
||||
|
||||
LOCAL_MODULE := libframeworks_coretests_jni
|
||||
|
||||
# this does not prevent build system
|
||||
# from installing library to /system/lib
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
# .. we want to avoid that... so we put it somewhere
|
||||
# bionic linker cant find it without outside help (nativetests):
|
||||
LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
|
||||
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -27,8 +27,8 @@ static JNINativeMethod sMethods[] = {
|
||||
{ "checkFunction", "()I", (void*) checkFunction },
|
||||
};
|
||||
|
||||
int register_com_android_framework_coretests_JNITests(JNIEnv* env) {
|
||||
return jniRegisterNativeMethods(env, "com/android/framework/coretests/JNITests", sMethods,
|
||||
int register_com_android_frameworks_coretests_JNITests(JNIEnv* env) {
|
||||
return jniRegisterNativeMethods(env, "com/android/frameworks/coretests/JNITests", sMethods,
|
||||
NELEM(sMethods));
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ jint JNI_OnLoad(JavaVM *jvm, void *reserved) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
if ((status = android::register_com_android_framework_coretests_JNITests(e)) < 0) {
|
||||
if ((status = android::register_com_android_frameworks_coretests_JNITests(e)) < 0) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||
|
||||
LOCAL_PACKAGE_NAME := install_jni_lib_open_from_apk
|
||||
|
||||
LOCAL_JNI_SHARED_LIBRARIES_ZIP_OPTIONS := -0
|
||||
LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES := true
|
||||
|
||||
include $(FrameworkCoreTests_BUILD_PACKAGE)
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.frameworks.coretests.install_jni_lib_open_from_apk">
|
||||
|
||||
<application android:hasCode="true" android:label="@string/app_name" android:extractNativeLibs="false">
|
||||
<activity android:name="com.android.frameworks.coretests.OpenFromApkActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name">Load From Apk Test</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.android.frameworks.coretests;
|
||||
|
||||
public class JNITests {
|
||||
static {
|
||||
System.loadLibrary("frameworks_coretests_jni");
|
||||
}
|
||||
|
||||
public static native int checkFunction();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.android.frameworks.coretests;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.widget.TextView;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class OpenFromApkActivity extends Activity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
TextView tv = new TextView(this);
|
||||
|
||||
int i = JNITests.checkFunction();
|
||||
|
||||
tv.setText("All is well: i=" + i);
|
||||
|
||||
setContentView(tv);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user