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

Commit fb171114 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 7035473 from acde7545 to sc-release

Change-Id: I130eb5be086d362eae3230a923f731a86616f3c0
parents a3366fb4 acde7545
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -237,6 +237,9 @@ cc_library_shared {
        "liblog",
        "liblog",
        "libnativehelper_compat_libc++",
        "libnativehelper_compat_libc++",
    ],
    ],
    static_libs: [
        "libnetjniutils",
    ],


    // We cannot use plain "libc++" here to link libc++ dynamically because it results in:
    // We cannot use plain "libc++" here to link libc++ dynamically because it results in:
    //   java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
    //   java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
+5 −74
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@
#include <string>
#include <string>


#include <nativehelper/JNIHelp.h>
#include <nativehelper/JNIHelp.h>
#include <netjniutils/netjniutils.h>


#include <android/log.h>
#include <android/log.h>


@@ -58,76 +59,6 @@ static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void*
    return true;
    return true;
}
}


static bool isAtLeastS() {
    static bool atLeastS = false;
    static bool doProbe = true;

    if (!doProbe) {
        return atLeastS;
    }

    atLeastS = (android_get_device_api_level() > __ANDROID_API_R__);
    if (!atLeastS) {
        // Check if this is a device with Android S dogfood build.
        static constexpr const char* kCodenameProperty = "ro.build.version.codename";
        char codename[PROP_VALUE_MAX] = { 0 };
        // SDK may be 30 (R) with codename T if S SDK was finalized but not yet merged in the
        // branch, and T development started.
        atLeastS = (__system_property_get(kCodenameProperty, codename) > 0 &&
                    (strncmp(codename, "S", 2) == 0 || strncmp(codename, "T", 2) == 0));
    }
    doProbe = false;

    return atLeastS;
}

static int getNativeFileDescriptorWithoutNdk(JNIEnv* env, jobject javaFd) {
    // Prior to Android S, we need to find the descriptor field in the FileDescriptor class. The
    // symbol name has been stable in libcore, but is a private implementation detail.
    // Older libnativehelper_compat_c++ versions had a jniGetFdFromFileDescriptor method, but this
    // was removed in S to replace it with the NDK API in libnativehelper.
    // The code is copied here instead. This code can be removed once R is not supported anymore.
    static jfieldID descriptorFieldID = nullptr;
    if (descriptorFieldID == nullptr) {
        jclass fileDescriptorClass = env->FindClass("java/io/FileDescriptor");
        descriptorFieldID = env->GetFieldID(fileDescriptorClass, "descriptor", "I");
        env->DeleteLocalRef(fileDescriptorClass);
        if (descriptorFieldID == nullptr) {
            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to get descriptor field.");
            return -1;
        }
    }
    return javaFd != nullptr ? env->GetIntField(javaFd, descriptorFieldID) : -1;
}

static int getNativeFileDescriptorWithNdk(JNIEnv* env, jobject javaFd) {
    // Since Android S, there is an NDK API to get a file descriptor present in libnativehelper.so.
    // libnativehelper is loaded into all processes by the zygote since the zygote uses it
    // to load the Android Runtime and is also a public library (because of the NDK API).
    static int (*ndkGetFD)(JNIEnv*, jobject) = nullptr;
    if (ndkGetFD == nullptr) {
        void* handle = dlopen("libnativehelper.so", RTLD_NOLOAD | RTLD_NODELETE);
        ndkGetFD = reinterpret_cast<decltype(ndkGetFD)>(dlsym(handle, "AFileDescriptor_getFD"));
        if (ndkGetFD == nullptr) {
            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
                                "Failed to dlsym(AFileDescriptor_getFD): %s", dlerror());
            dlclose(handle);
            return -1;
        }
        dlclose(handle);
    }
    return javaFd != nullptr ? ndkGetFD(env, javaFd) : -1;
}

static int getNativeFileDescriptor(JNIEnv* env, jobject javaFd) {
    // Check if we should use the NDK File Descriptor API introduced in S.
    if (isAtLeastS()) {
        return getNativeFileDescriptorWithNdk(env, javaFd);
    } else {
        return getNativeFileDescriptorWithoutNdk(env, javaFd);
    }
}

static void network_stack_utils_addArpEntry(JNIEnv *env, jobject thiz, jbyteArray ethAddr,
static void network_stack_utils_addArpEntry(JNIEnv *env, jobject thiz, jbyteArray ethAddr,
        jbyteArray ipv4Addr, jstring ifname, jobject javaFd) {
        jbyteArray ipv4Addr, jstring ifname, jobject javaFd) {
    arpreq req = {};
    arpreq req = {};
@@ -155,7 +86,7 @@ static void network_stack_utils_addArpEntry(JNIEnv *env, jobject thiz, jbyteArra
    env->GetStringUTFRegion(ifname, 0, ifLen, req.arp_dev);
    env->GetStringUTFRegion(ifname, 0, ifLen, req.arp_dev);


    req.arp_flags = ATF_COM;  // Completed entry (ha valid)
    req.arp_flags = ATF_COM;  // Completed entry (ha valid)
    int fd = getNativeFileDescriptor(env, javaFd);
    int fd = netjniutils::GetNativeFileDescriptor(env, javaFd);
    if (fd < 0) {
    if (fd < 0) {
        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
        return;
        return;
@@ -193,7 +124,7 @@ static void network_stack_utils_attachDhcpFilter(JNIEnv *env, jobject clazz, job
        filter_code,
        filter_code,
    };
    };


    int fd = getNativeFileDescriptor(env, javaFd);
    int fd = netjniutils::GetNativeFileDescriptor(env, javaFd);
    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
        jniThrowExceptionFmt(env, "java/net/SocketException",
        jniThrowExceptionFmt(env, "java/net/SocketException",
                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
@@ -226,7 +157,7 @@ static void network_stack_utils_attachRaFilter(JNIEnv *env, jobject clazz, jobje
        filter_code,
        filter_code,
    };
    };


    int fd = getNativeFileDescriptor(env, javaFd);
    int fd = netjniutils::GetNativeFileDescriptor(env, javaFd);
    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
        jniThrowExceptionFmt(env, "java/net/SocketException",
        jniThrowExceptionFmt(env, "java/net/SocketException",
                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
@@ -301,7 +232,7 @@ static void network_stack_utils_attachControlPacketFilter(
        filter_code,
        filter_code,
    };
    };


    int fd = getNativeFileDescriptor(env, javaFd);
    int fd = netjniutils::GetNativeFileDescriptor(env, javaFd);
    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
        jniThrowExceptionFmt(env, "java/net/SocketException",
        jniThrowExceptionFmt(env, "java/net/SocketException",
                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));