com_android_server_AlarmManagerService.cpp revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
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#define ONE_NANOSECOND 1000000000LL 42#define NANOSECONDS_TO_SECONDS(x) (x / ONE_NANOSECOND) 43#define SECONDS_TO_NANOSECONDS(x) (x * ONE_NANOSECOND) 44 45namespace android { 46 47static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv* env, jobject obj, jint fd, jint minswest) 48{ 49#if HAVE_ANDROID_OS 50 struct timezone tz; 51 52 tz.tz_minuteswest = minswest; 53 tz.tz_dsttime = 0; 54 55 int result = settimeofday(NULL, &tz); 56 if (result < 0) { 57 LOGE("Unable to set kernel timezone to %d: %s\n", minswest, strerror(errno)); 58 return -1; 59 } else { 60 LOGD("Kernel timezone updated to %d minutes west of GMT\n", minswest); 61 } 62 63 return 0; 64#else 65 return -ENOSYS; 66#endif 67} 68 69static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj) 70{ 71#if HAVE_ANDROID_OS 72 return open("/dev/alarm", O_RDWR); 73#else 74 return -1; 75#endif 76} 77 78static void android_server_AlarmManagerService_close(JNIEnv* env, jobject obj, jint fd) 79{ 80#if HAVE_ANDROID_OS 81 close(fd); 82#endif 83} 84 85static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong nanoseconds) 86{ 87#if HAVE_ANDROID_OS 88 struct timespec ts; 89 ts.tv_sec = NANOSECONDS_TO_SECONDS(nanoseconds); 90 ts.tv_nsec = nanoseconds - SECONDS_TO_NANOSECONDS(ts.tv_sec); 91 92 int result = ioctl(fd, ANDROID_ALARM_SET(type), &ts); 93 if (result < 0) 94 { 95 LOGE("Unable to set alarm to %lld: %s\n", nanoseconds, strerror(errno)); 96 } 97#endif 98} 99 100static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd) 101{ 102#if HAVE_ANDROID_OS 103 int result = 0; 104 105 do 106 { 107 result = ioctl(fd, ANDROID_ALARM_WAIT); 108 } while (result < 0 && errno == EINTR); 109 110 if (result < 0) 111 { 112 LOGE("Unable to wait on alarm: %s\n", strerror(errno)); 113 return 0; 114 } 115 116 return result; 117#endif 118} 119 120static JNINativeMethod sMethods[] = { 121 /* name, signature, funcPtr */ 122 {"init", "()I", (void*)android_server_AlarmManagerService_init}, 123 {"close", "(I)V", (void*)android_server_AlarmManagerService_close}, 124 {"set", "(IIJ)V", (void*)android_server_AlarmManagerService_set}, 125 {"waitForAlarm", "(I)I", (void*)android_server_AlarmManagerService_waitForAlarm}, 126 {"setKernelTimezone", "(II)I", (void*)android_server_AlarmManagerService_setKernelTimezone}, 127}; 128 129int register_android_server_AlarmManagerService(JNIEnv* env) 130{ 131 jclass clazz = env->FindClass("com/android/server/AlarmManagerService"); 132 133 if (clazz == NULL) 134 { 135 LOGE("Can't find com/android/server/AlarmManagerService"); 136 return -1; 137 } 138 139 return jniRegisterNativeMethods(env, "com/android/server/AlarmManagerService", 140 sMethods, NELEM(sMethods)); 141} 142 143} /* namespace android */ 144