diff options
| author | 2014-09-30 15:10:48 -0700 | |
|---|---|---|
| committer | 2015-04-07 17:25:23 +0000 | |
| commit | dec4688f40b0018fbd1f00db05581966f531d88f (patch) | |
| tree | 569eedaa5ff26c7889c2585f87087b020715ddba | |
| parent | 97467d82a31964e36cb6bc32ac4cf00e884c190e (diff) | |
Load libraries directly from apk
 Introduced new 'extractNativeLibs' attribute to manifest/application.
 Setting it to false prevents installer from extracting library from apk.
 The default value for extractNativeLibs is true.
Bug: 8076853
(cherry picked from commit ff193d642eea7128faad837d19e347cd25212c27)
Change-Id: I1aa2c039bb2a590ae72f256acc9ba5401c2c59b1
16 files changed, 244 insertions, 37 deletions
| diff --git a/api/current.txt b/api/current.txt index 144f2923b757..ed80e38c184c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -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); diff --git a/api/system-current.txt b/api/system-current.txt index 7ab0e486d0e3..8f1b8b275f92 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -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); diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 05c19db1fd48..0264a0254db0 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -346,6 +346,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       * instruction sets, this implies the code might be loaded into a process that's diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 4952ba1989c8..3de5d7718af1 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -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); diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java index 02f675c3aaac..f479f4feca35 100644 --- a/core/java/com/android/internal/content/NativeLibraryHelper.java +++ b/core/java/com/android/internal/content/NativeLibraryHelper.java @@ -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 { diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index b44adcb2a8ef..24f4b63a2c44 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -536,7 +536,6 @@ bool AndroidRuntime::parseCompilerRuntimeOption(const char* property,   */  int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)  { -    int result = -1;      JavaVMInitArgs initArgs;      char propBuf[PROPERTY_VALUE_MAX];      char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX]; @@ -583,6 +582,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, ""); @@ -701,7 +701,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)      if (!hasFile("/system/etc/preloaded-classes")) {          ALOGE("Missing preloaded-classes file, /system/etc/preloaded-classes not found: %s\n",                strerror(errno)); -        goto bail; +        return -1;      }      addOption("-Ximage-compiler-option");      addOption("--image-classes=/system/etc/preloaded-classes"); @@ -819,6 +819,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(); @@ -834,13 +846,10 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)       */      if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {          ALOGE("JNI_CreateJavaVM failed\n"); -        goto bail; +        return -1;      } -    result = 0; - -bail: -    return result; +    return 0;  }  char* AndroidRuntime::toSlashClassName(const char* className) diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp index 3c1993e8650b..9307ff9081ab 100644 --- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp +++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp @@ -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", diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index ea592cf5d065..f69772ac6b33 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -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 diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 2bb9aa8dc7e8..bfd0d2655e1e 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -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> diff --git a/core/tests/coretests/apks/install_jni_lib/Android.mk b/core/tests/coretests/apks/install_jni_lib/Android.mk index b61ea8edda71..7322e8d6949b 100644 --- a/core/tests/coretests/apks/install_jni_lib/Android.mk +++ b/core/tests/coretests/apks/install_jni_lib/Android.mk @@ -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) diff --git a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp index 957fc4a1f53e..e0b616c16184 100644 --- a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp +++ b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp @@ -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;      } diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk new file mode 100644 index 000000000000..5fa24055d9a8 --- /dev/null +++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk @@ -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) diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml b/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml new file mode 100644 index 000000000000..190f89474405 --- /dev/null +++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml @@ -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> diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml b/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml new file mode 100644 index 000000000000..8c2a0bfbee73 --- /dev/null +++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml @@ -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> diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java new file mode 100644 index 000000000000..4f9176c8f7b8 --- /dev/null +++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java @@ -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(); +} diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java new file mode 100644 index 000000000000..524cad7cfb69 --- /dev/null +++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java @@ -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); +    } + +} |