File: android_os_NativeHandle.cpp

package info (click to toggle)
android-platform-frameworks-base 1%3A10.0.0%2Br36-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 321,788 kB
  • sloc: java: 962,234; cpp: 274,314; xml: 242,770; python: 5,060; sh: 1,432; ansic: 494; makefile: 47; sed: 19
file content (103 lines) | stat: -rw-r--r-- 3,749 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
 * Copyright (C) 2018 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.
 */

#include "android_os_NativeHandle.h"

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

#include "core_jni_helpers.h"

#define PACKAGE_PATH    "android/os"
#define CLASS_NAME      "NativeHandle"
#define CLASS_PATH      PACKAGE_PATH "/" CLASS_NAME

namespace android {

static struct {
    jclass clazz;
    jmethodID constructID;  // NativeHandle(int[] fds, int[] ints, boolean owns)

    jmethodID getFdsID;  // int[] NativeHandle.getFds()
    jmethodID getIntsID;  // int[] NativeHandle.getInts()
} gNativeHandleFields;

jobject JNativeHandle::MakeJavaNativeHandleObj(
        JNIEnv *env, const native_handle_t *handle) {
    if (handle == nullptr) { return nullptr; }

    const int numFds = handle->numFds;
    ScopedLocalRef<jintArray> fds(env, env->NewIntArray(numFds));
    env->SetIntArrayRegion(fds.get(), 0, numFds, &(handle->data[0]));

    const int numInts = handle->numInts;
    ScopedLocalRef<jintArray> ints(env, env->NewIntArray(numInts));
    env->SetIntArrayRegion(ints.get(), 0, numInts, &(handle->data[numFds]));

    return env->NewObject(gNativeHandleFields.clazz,
            gNativeHandleFields.constructID, fds.get(), ints.get(), false /*own*/);
}

native_handle_t *JNativeHandle::MakeCppNativeHandle(
        JNIEnv *env, jobject jHandle, EphemeralStorage *storage) {
    if (jHandle == nullptr) { return nullptr; }

    if (!env->IsInstanceOf(jHandle, gNativeHandleFields.clazz)) {
        jniThrowException(env, "java/lang/ClassCastException",
                "jHandle must be an instance of NativeHandle.");
        return nullptr;
    }

    ScopedLocalRef<jintArray> fds(env, (jintArray) env->CallObjectMethod(
            jHandle, gNativeHandleFields.getFdsID));

    ScopedLocalRef<jintArray> ints(env, (jintArray) env->CallObjectMethod(
            jHandle, gNativeHandleFields.getIntsID));

    const int numFds = (int) env->GetArrayLength(fds.get());
    const int numInts = (int) env->GetArrayLength(ints.get());

    native_handle_t *handle = (storage == nullptr)
            ? native_handle_create(numFds, numInts)
            : storage->allocTemporaryNativeHandle(numFds, numInts);

    if (handle != nullptr) {
        env->GetIntArrayRegion(fds.get(), 0, numFds, &(handle->data[0]));
        env->GetIntArrayRegion(ints.get(), 0, numInts, &(handle->data[numFds]));
    } else {
        jniThrowException(env, "java/lang/OutOfMemoryError",
                "Failed to allocate memory for native_handle_t.");
    }

    return handle;
}

jobjectArray JNativeHandle::AllocJavaNativeHandleObjArray(JNIEnv *env, jsize length) {
    return env->NewObjectArray(length, gNativeHandleFields.clazz, nullptr);
}

int register_android_os_NativeHandle(JNIEnv *env) {
    jclass clazz = FindClassOrDie(env, CLASS_PATH);
    gNativeHandleFields.clazz = MakeGlobalRefOrDie(env, clazz);

    gNativeHandleFields.constructID = GetMethodIDOrDie(env, clazz, "<init>", "([I[IZ)V");
    gNativeHandleFields.getFdsID = GetMethodIDOrDie(env, clazz, "getFdsAsIntArray", "()[I");
    gNativeHandleFields.getIntsID = GetMethodIDOrDie(env, clazz, "getInts", "()[I");

    return 0;
}

}