1 /*
2 * Copyright (C) 2024 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 #include <errno.h>
18 #include <jni.h>
19 #include <nativehelper/JNIHelp.h>
20 #include <nativehelper/scoped_utf_chars.h>
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/epoll.h>
26 #include <sys/timerfd.h>
27 #include <time.h>
28 #include <unistd.h>
29
30 #define MSEC_PER_SEC 1000
31 #define NSEC_PER_MSEC 1000000
32
33 namespace android {
34
35 static jint
com_android_net_module_util_TimerFdUtils_createTimerFd(JNIEnv * env,jclass clazz)36 com_android_net_module_util_TimerFdUtils_createTimerFd(JNIEnv *env,
37 jclass clazz) {
38 int tfd;
39 tfd = timerfd_create(CLOCK_BOOTTIME, 0);
40 if (tfd == -1) {
41 jniThrowErrnoException(env, "createTimerFd", tfd);
42 }
43 return tfd;
44 }
45
46 static void
com_android_net_module_util_TimerFdUtils_setTime(JNIEnv * env,jclass clazz,jint tfd,jlong milliseconds)47 com_android_net_module_util_TimerFdUtils_setTime(JNIEnv *env, jclass clazz,
48 jint tfd, jlong milliseconds) {
49 struct itimerspec new_value;
50 new_value.it_value.tv_sec = milliseconds / MSEC_PER_SEC;
51 new_value.it_value.tv_nsec = (milliseconds % MSEC_PER_SEC) * NSEC_PER_MSEC;
52 // Set the interval time to 0 because it's designed for repeated timer expirations after the
53 // initial expiration, which doesn't fit the current usage.
54 new_value.it_interval.tv_sec = 0;
55 new_value.it_interval.tv_nsec = 0;
56
57 int ret = timerfd_settime(tfd, 0, &new_value, NULL);
58 if (ret == -1) {
59 jniThrowErrnoException(env, "setTime", ret);
60 }
61 }
62
63 /*
64 * JNI registration.
65 */
66 static const JNINativeMethod gMethods[] = {
67 /* name, signature, funcPtr */
68 {"createTimerFd", "()I",
69 (void *)com_android_net_module_util_TimerFdUtils_createTimerFd},
70 {"setTime", "(IJ)V",
71 (void *)com_android_net_module_util_TimerFdUtils_setTime},
72 };
73
register_com_android_net_module_util_TimerFdUtils(JNIEnv * env,char const * class_name)74 int register_com_android_net_module_util_TimerFdUtils(JNIEnv *env,
75 char const *class_name) {
76 return jniRegisterNativeMethods(env, class_name, gMethods, NELEM(gMethods));
77 }
78
79 }; // namespace android
80