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 #include <linux/ioctl.h> 36 #include <linux/android_alarm.h> 37 38 namespace android { 39 40 static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv* env, jobject obj, jint fd, jint minswest) 41 { 42 struct timezone tz; 43 44 tz.tz_minuteswest = minswest; 45 tz.tz_dsttime = 0; 46 47 int result = settimeofday(NULL, &tz); 48 if (result < 0) { 49 ALOGE("Unable to set kernel timezone to %d: %s\n", minswest, strerror(errno)); 50 return -1; 51 } else { 52 ALOGD("Kernel timezone updated to %d minutes west of GMT\n", minswest); 53 } 54 55 return 0; 56 } 57 58 static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj) 59 { 60 return open("/dev/alarm", O_RDWR); 61 } 62 63 static void android_server_AlarmManagerService_close(JNIEnv* env, jobject obj, jint fd) 64 { 65 close(fd); 66 } 67 68 static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong seconds, jlong nanoseconds) 69 { 70 struct timespec ts; 71 ts.tv_sec = seconds; 72 ts.tv_nsec = nanoseconds; 73 74 int result = ioctl(fd, ANDROID_ALARM_SET(type), &ts); 75 if (result < 0) 76 { 77 ALOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno)); 78 } 79 } 80 81 static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd) 82 { 83 int result = 0; 84 85 do 86 { 87 result = ioctl(fd, ANDROID_ALARM_WAIT); 88 } while (result < 0 && errno == EINTR); 89 90 if (result < 0) 91 { 92 ALOGE("Unable to wait on alarm: %s\n", strerror(errno)); 93 return 0; 94 } 95 96 return result; 97 } 98 99 static JNINativeMethod sMethods[] = { 100 /* name, signature, funcPtr */ 101 {"init", "()I", (void*)android_server_AlarmManagerService_init}, 102 {"close", "(I)V", (void*)android_server_AlarmManagerService_close}, 103 {"set", "(IIJJ)V", (void*)android_server_AlarmManagerService_set}, 104 {"waitForAlarm", "(I)I", (void*)android_server_AlarmManagerService_waitForAlarm}, 105 {"setKernelTimezone", "(II)I", (void*)android_server_AlarmManagerService_setKernelTimezone}, 106 }; 107 108 int register_android_server_AlarmManagerService(JNIEnv* env) 109 { 110 return jniRegisterNativeMethods(env, "com/android/server/AlarmManagerService", 111 sMethods, NELEM(sMethods)); 112 } 113 114 } /* namespace android */ 115