1 /* //device/libs/android_runtime/android_server_AlarmManagerService.cpp 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #define LOG_TAG "AlarmManagerService" 19 20 #include "JNIHelp.h" 21 #include "jni.h" 22 #include <utils/Log.h> 23 #include <utils/misc.h> 24 25 #include <fcntl.h> 26 #include <stdio.h> 27 #include <string.h> 28 #include <sys/types.h> 29 #include <sys/socket.h> 30 #include <arpa/inet.h> 31 #include <netinet/in.h> 32 #include <stdlib.h> 33 #include <errno.h> 34 #include <unistd.h> 35 36 #if HAVE_ANDROID_OS 37 #include <linux/ioctl.h> 38 #include <linux/android_alarm.h> 39 #endif 40 41 namespace android { 42 43 static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv* env, jobject obj, jint fd, jint minswest) 44 { 45 #if HAVE_ANDROID_OS 46 struct timezone tz; 47 48 tz.tz_minuteswest = minswest; 49 tz.tz_dsttime = 0; 50 51 int result = settimeofday(NULL, &tz); 52 if (result < 0) { 53 LOGE("Unable to set kernel timezone to %d: %s\n", minswest, strerror(errno)); 54 return -1; 55 } else { 56 LOGD("Kernel timezone updated to %d minutes west of GMT\n", minswest); 57 } 58 59 return 0; 60 #else 61 return -ENOSYS; 62 #endif 63 } 64 65 static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj) 66 { 67 #if HAVE_ANDROID_OS 68 return open("/dev/alarm", O_RDWR); 69 #else 70 return -1; 71 #endif 72 } 73 74 static void android_server_AlarmManagerService_close(JNIEnv* env, jobject obj, jint fd) 75 { 76 #if HAVE_ANDROID_OS 77 close(fd); 78 #endif 79 } 80 81 static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong seconds, jlong nanoseconds) 82 { 83 #if HAVE_ANDROID_OS 84 struct timespec ts; 85 ts.tv_sec = seconds; 86 ts.tv_nsec = nanoseconds; 87 88 int result = ioctl(fd, ANDROID_ALARM_SET(type), &ts); 89 if (result < 0) 90 { 91 LOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno)); 92 } 93 #endif 94 } 95 96 static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd) 97 { 98 #if HAVE_ANDROID_OS 99 int result = 0; 100 101 do 102 { 103 result = ioctl(fd, ANDROID_ALARM_WAIT); 104 } while (result < 0 && errno == EINTR); 105 106 if (result < 0) 107 { 108 LOGE("Unable to wait on alarm: %s\n", strerror(errno)); 109 return 0; 110 } 111 112 return result; 113 #endif 114 } 115 116 static JNINativeMethod sMethods[] = { 117 /* name, signature, funcPtr */ 118 {"init", "()I", (void*)android_server_AlarmManagerService_init}, 119 {"close", "(I)V", (void*)android_server_AlarmManagerService_close}, 120 {"set", "(IIJJ)V", (void*)android_server_AlarmManagerService_set}, 121 {"waitForAlarm", "(I)I", (void*)android_server_AlarmManagerService_waitForAlarm}, 122 {"setKernelTimezone", "(II)I", (void*)android_server_AlarmManagerService_setKernelTimezone}, 123 }; 124 125 int register_android_server_AlarmManagerService(JNIEnv* env) 126 { 127 jclass clazz = env->FindClass("com/android/server/AlarmManagerService"); 128 129 if (clazz == NULL) 130 { 131 LOGE("Can't find com/android/server/AlarmManagerService"); 132 return -1; 133 } 134 135 return jniRegisterNativeMethods(env, "com/android/server/AlarmManagerService", 136 sMethods, NELEM(sMethods)); 137 } 138 139 } /* namespace android */ 140