• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
syncPoll(JNIEnv * env,jclass,jintArray fds_array,jintArray status_array)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 
syncMerge(JNIEnv * env,jclass,jstring nameStr,jint fd1,jint fd2)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 
syncFileInfo(JNIEnv *,jclass,jint fd)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 
syncClose(int fd)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 
register_android_graphics_cts_SyncTest(JNIEnv * env)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