Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  *
     16  */
     17 
     18 #define LOG_TAG "SyncTest"
     19 
     20 #include <errno.h>
     21 #include <poll.h>
     22 #include <unistd.h>
     23 
     24 #include <array>
     25 #include <memory>
     26 
     27 #include <jni.h>
     28 
     29 #include <android/sync.h>
     30 
     31 namespace {
     32 
     33 enum {
     34     STATUS_ERROR = -1,
     35     STATUS_UNSIGNALED = 0,
     36     STATUS_SIGNALED = 1,
     37 };
     38 
     39 jboolean syncPoll(JNIEnv* env, jclass /*clazz*/, jintArray fds_array, jintArray status_array) {
     40     jsize n = env->GetArrayLength(fds_array);
     41     if (env->GetArrayLength(status_array) != n)
     42         return JNI_FALSE;
     43     std::unique_ptr<pollfd[]> pollfds = std::make_unique<pollfd[]>(n);
     44 
     45     jint* fds = static_cast<jint*>(env->GetPrimitiveArrayCritical(fds_array, nullptr));
     46     for (jsize i = 0; i < n; i++) {
     47         pollfds[i].fd = fds[i];
     48         pollfds[i].events = POLLIN;
     49     }
     50     env->ReleasePrimitiveArrayCritical(fds_array, fds, 0);
     51 
     52     int ret;
     53     do {
     54         ret = poll(pollfds.get(), n, -1 /* infinite timeout */);
     55     } while (ret == -1 && errno == EINTR);
     56     if (ret == -1)
     57         return JNI_FALSE;
     58 
     59     jint* status = static_cast<jint*>(env->GetPrimitiveArrayCritical(status_array, nullptr));
     60     for (jsize i = 0; i < n; i++) {
     61         if (pollfds[i].fd < 0)
     62             continue;
     63         if ((pollfds[i].revents & (POLLERR | POLLNVAL)) != 0)
     64             status[i] = STATUS_ERROR;
     65         else if ((pollfds[i].revents & POLLIN) != 0)
     66             status[i] = STATUS_SIGNALED;
     67         else
     68             status[i] = STATUS_UNSIGNALED;
     69     }
     70     env->ReleasePrimitiveArrayCritical(status_array, status, 0);
     71 
     72     return JNI_TRUE;
     73 }
     74 
     75 jint syncMerge(JNIEnv* env, jclass /*clazz*/, jstring nameStr, jint fd1, jint fd2) {
     76     const char* name = env->GetStringUTFChars(nameStr, nullptr);
     77     int32_t result_fd = sync_merge(name, fd1, fd2);
     78     env->ReleaseStringUTFChars(nameStr, name);
     79     return result_fd;
     80 }
     81 
     82 jobject syncFileInfo(JNIEnv* /*env*/, jclass /*clazz*/, jint fd) {
     83     auto info = sync_file_info(fd);
     84     if (!info) return nullptr;
     85     // TODO: convert to SyncFileInfo
     86     sync_file_info_free(info);
     87     return nullptr;
     88 }
     89 
     90 void syncClose(int fd) {
     91     close(fd);
     92 }
     93 
     94 const std::array<JNINativeMethod, 4> JNI_METHODS = {{
     95     { "nSyncPoll", "([I[I)Z", (void*)syncPoll },
     96     { "nSyncMerge", "(Ljava/lang/String;II)I", (void*)syncMerge },
     97     { "nSyncFileInfo", "(I)Landroid/graphics/cts/SyncTest/SyncFileInfo;", (void*)syncFileInfo },
     98     { "nSyncClose", "(I)V", (void*)syncClose },
     99 }};
    100 
    101 }
    102 
    103 int register_android_graphics_cts_SyncTest(JNIEnv* env) {
    104     jclass clazz = env->FindClass("android/graphics/cts/SyncTest");
    105     return env->RegisterNatives(clazz, JNI_METHODS.data(), JNI_METHODS.size());
    106 }
    107