Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97291183 authored by Brett Chabot's avatar Brett Chabot
Browse files

Cross platform native resources support.

This commit unlocks mac and windows host support for the
AssetManager and ApkAssets JNI bindings.

Included in this change is:
- remove obsolete references to linux only headers like signal.h and
  linux/capability
- use the DupFdCloExec wrapper instead of fcntl calls directly
- Instead of using ParcelFileDescritor#adoptFd, create FileDescriptors
  via the constructor. This is not strictly necessary but it avoids
  use of the android-only FileDescriptor#setInt$ method.
- Also set the FileDescriptor.handle when on windows

Flag: NONE host-only change
Test: atest CtsResourcesTestCasesRavenwood
Change-Id: Ifd4090ca2c5cb746f88280f675b31642aec35769
parent da55b812
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -73,10 +73,12 @@ cc_library_shared_for_libandroid_runtime {

    srcs: [
        "android_animation_PropertyValuesHolder.cpp",
        "android_content_res_ApkAssets.cpp",
        "android_os_SystemClock.cpp",
        "android_os_SystemProperties.cpp",
        "android_os_Trace.cpp",
        "android_text_AndroidCharacter.cpp",
        "android_util_AssetManager.cpp",
        "android_util_EventLog.cpp",
        "android_util_Log.cpp",
        "android_util_StringBlock.cpp",
@@ -203,7 +205,6 @@ cc_library_shared_for_libandroid_runtime {
                "android_os_incremental_IncrementalManager.cpp",
                "android_net_LocalSocketImpl.cpp",
                "android_service_DataLoaderService.cpp",
                "android_util_AssetManager.cpp",
                "android_util_Binder.cpp",
                "android_util_CharsetUtils.cpp",
                "android_util_MemoryIntArray.cpp",
@@ -250,7 +251,6 @@ cc_library_shared_for_libandroid_runtime {
                "android_backup_FileBackupHelperBase.cpp",
                "android_backup_BackupHelperDispatcher.cpp",
                "android_app_backup_FullBackup.cpp",
                "android_content_res_ApkAssets.cpp",
                "android_content_res_ObbScanner.cpp",
                "android_content_res_Configuration.cpp",
                "android_content_res_ResourceTimer.cpp",
@@ -442,7 +442,6 @@ cc_library_shared_for_libandroid_runtime {
        },
        host_linux: {
            srcs: [
                "android_content_res_ApkAssets.cpp",
                "android_database_CursorWindow.cpp",
                "android_database_SQLiteCommon.cpp",
                "android_database_SQLiteConnection.cpp",
@@ -457,7 +456,6 @@ cc_library_shared_for_libandroid_runtime {
                "android_view_InputEventReceiver.cpp",
                "android_view_InputEventSender.cpp",

                "android_util_AssetManager.cpp",
                "android_util_Binder.cpp",

                "android_util_FileObserver.cpp",
+21 −8
Original line number Diff line number Diff line
@@ -16,22 +16,21 @@

#define ATRACE_TAG ATRACE_TAG_RESOURCES

#include <mutex>
#include "android_content_res_ApkAssets.h"

#include "signal.h"
#include <mutex>

#include "android-base/logging.h"
#include "android-base/macros.h"
#include "android-base/stringprintf.h"
#include "android-base/unique_fd.h"
#include "androidfw/ApkAssets.h"
#include "utils/misc.h"
#include "utils/Trace.h"

#include "android_content_res_ApkAssets.h"
#include "core_jni_helpers.h"
#include "jni.h"
#include "nativehelper/ScopedUtfChars.h"
#include "signal.h"
#include "utils/Trace.h"
#include "utils/misc.h"

using ::android::base::unique_fd;

@@ -266,6 +265,20 @@ static jlong NativeLoad(JNIEnv* env, jclass /*clazz*/, const format_type_t forma
  return CreateGuardedApkAssets(std::move(apk_assets));
}

#if defined(_WIN32)
int DupFdCloExec(int fd) {
    int newfd = dup(fd);
    fprintf(stderr, "duping %d to %d", fd, newfd);
    return newfd;
}
#else
int DupFdCloExec(int fd) {
    int newfd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
    fprintf(stderr, "duping %d to %d", fd, newfd);
    return newfd;
}
#endif

static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, const format_type_t format,
                              jobject file_descriptor, jstring friendly_name,
                              const jint property_flags, jobject assets_provider) {
@@ -282,7 +295,7 @@ static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, const format_type_t
    return 0;
  }

  unique_fd dup_fd(::fcntl(fd, F_DUPFD_CLOEXEC, 0));
  unique_fd dup_fd(DupFdCloExec(fd));
  if (dup_fd < 0) {
    jniThrowIOException(env, errno);
    return 0;
@@ -349,7 +362,7 @@ static jlong NativeLoadFromFdOffset(JNIEnv* env, jclass /*clazz*/, const format_
    return 0;
  }

  unique_fd dup_fd(::fcntl(fd, F_DUPFD_CLOEXEC, 0));
  unique_fd dup_fd(DupFdCloExec(fd));
  if (dup_fd < 0) {
    jniThrowIOException(env, errno);
    return 0;
+32 −12
Original line number Diff line number Diff line
@@ -21,11 +21,9 @@

#include <errno.h>
#include <inttypes.h>
#include <linux/capability.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <sstream>
@@ -55,9 +53,6 @@
#include "utils/Trace.h"
#include "utils/misc.h"

extern "C" int capget(cap_user_header_t hdrp, cap_user_data_t datap);
extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap);

using ::android::base::StringPrintf;

namespace android {
@@ -105,11 +100,22 @@ static struct arraymap_offsets_t {

static struct parcel_file_descriptor_offsets_t {
  jclass mClass;
  jmethodID mAdoptFd;
  jmethodID mConstructor;
} gParcelFileDescriptorOffsets;

static struct file_descriptor_offsets_t {
    jclass mClass;
    jmethodID mConstructor;
    jfieldID mHandle;
} gFileDescriptorOffsets;

static jclass g_stringClass = nullptr;

// Duplicates a file descriptor. On Linux/Mac, this wraps fcntl(fd, F_DUPFD_CLOEXEC).
// On windows, since file descriptors are not inherited by child processes by default, this
// wraps dup()
extern int DupFdCloExec(int fd);

// ----------------------------------------------------------------------------

// Java asset cookies have 0 as an invalid cookie, but TypedArray expects < 0.
@@ -272,9 +278,14 @@ static jobject ReturnParcelFileDescriptor(JNIEnv* env, std::unique_ptr<Asset> as

  env->ReleasePrimitiveArrayCritical(out_offsets, offsets, 0);

  return env->CallStaticObjectMethod(gParcelFileDescriptorOffsets.mClass,
                                     gParcelFileDescriptorOffsets.mAdoptFd,
                                     fd);
  jobject fdescObj =
          env->NewObject(gFileDescriptorOffsets.mClass, gFileDescriptorOffsets.mConstructor, fd);
#ifdef _WIN32
  env->SetLongField(fdescObj, gFileDescriptorOffsets.mHandle, _get_osfhandle(fd));
#endif

  return env->NewObject(gParcelFileDescriptorOffsets.mClass,
                        gParcelFileDescriptorOffsets.mConstructor, fdescObj);
}

static jint NativeGetGlobalAssetCount(JNIEnv* /*env*/, jobject /*clazz*/) {
@@ -644,7 +655,7 @@ static jlong NativeOpenXmlAssetFd(JNIEnv* env, jobject /*clazz*/, jlong ptr, int
    return 0;
  }

  base::unique_fd dup_fd(::fcntl(fd, F_DUPFD_CLOEXEC, 0));
  base::unique_fd dup_fd(DupFdCloExec(fd));
  if (dup_fd < 0) {
    jniThrowIOException(env, errno);
    return 0;
@@ -1682,8 +1693,17 @@ int register_android_content_AssetManager(JNIEnv* env) {

  jclass pfdClass = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
  gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, pfdClass);
  gParcelFileDescriptorOffsets.mAdoptFd =
      GetStaticMethodIDOrDie(env, pfdClass, "adoptFd", "(I)Landroid/os/ParcelFileDescriptor;");
  gParcelFileDescriptorOffsets.mConstructor =
          GetMethodIDOrDie(env, pfdClass, "<init>", "(Ljava/io/FileDescriptor;)V");

  jclass fdClass = FindClassOrDie(env, "java/io/FileDescriptor");
  gFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, fdClass);
  gFileDescriptorOffsets.mConstructor =
          GetMethodIDOrDie(env, gFileDescriptorOffsets.mClass, "<init>", "(I)V");
#ifdef _WIN32
  gFileDescriptorOffsets.mHandle =
          GetFieldIDOrDie(env, gFileDescriptorOffsets.mClass, "handle", "J");
#endif

  return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
                              NELEM(gAssetManagerMethods));
+0 −2
Original line number Diff line number Diff line
@@ -114,10 +114,8 @@ struct RegJNIRec {
static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
        {"android.animation.PropertyValuesHolder",
         REG_JNI(register_android_animation_PropertyValuesHolder)},
#ifdef __linux__
        {"android.content.res.ApkAssets", REG_JNI(register_android_content_res_ApkAssets)},
        {"android.content.res.AssetManager", REG_JNI(register_android_content_AssetManager)},
#endif
        {"android.content.res.StringBlock", REG_JNI(register_android_content_StringBlock)},
        {"android.content.res.XmlBlock", REG_JNI(register_android_content_XmlBlock)},
#ifdef __linux__