resolved conflicts for merge of 9e413bf4 to klp-modular-dev-plus-aosp
Change-Id: Ibc41f0248235afca9546829e00b31003d09f4f7e
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 96063d5..c14ed8b 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -656,12 +656,19 @@
}
@Override
- public void setTime(long millis) {
+ public boolean setTime(long millis) {
getContext().enforceCallingOrSelfPermission(
"android.permission.SET_TIME",
"setTime");
- SystemClock.setCurrentTimeMillis(millis);
+ if (mNativeData == 0) {
+ Slog.w(TAG, "Not setting time since no alarm driver is available.");
+ return false;
+ }
+
+ synchronized (mLock) {
+ return setKernelTime(mNativeData, millis) == 0;
+ }
}
@Override
@@ -1039,6 +1046,7 @@
private native void close(long nativeData);
private native void set(long nativeData, int type, long seconds, long nanoseconds);
private native int waitForAlarm(long nativeData);
+ private native int setKernelTime(long nativeData, long millis);
private native int setKernelTimezone(long nativeData, int minuteswest);
void triggerAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED, long nowRTC) {
diff --git a/services/core/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp
index 342515b..c26a516 100644
--- a/services/core/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/core/jni/com_android_server_AlarmManagerService.cpp
@@ -36,6 +36,7 @@
#include <unistd.h>
#include <linux/ioctl.h>
#include <linux/android_alarm.h>
+#include <linux/rtc.h>
namespace android {
@@ -58,6 +59,7 @@
virtual ~AlarmImpl();
virtual int set(int type, struct timespec *ts) = 0;
+ virtual int setTime(struct timeval *tv) = 0;
virtual int waitForAlarm() = 0;
protected:
@@ -71,6 +73,7 @@
AlarmImplAlarmDriver(int fd) : AlarmImpl(&fd, 1) { }
int set(int type, struct timespec *ts);
+ int setTime(struct timeval *tv);
int waitForAlarm();
};
@@ -82,6 +85,7 @@
~AlarmImplTimerFd();
int set(int type, struct timespec *ts);
+ int setTime(struct timeval *tv);
int waitForAlarm();
private:
@@ -107,6 +111,19 @@
return ioctl(fds[0], ANDROID_ALARM_SET(type), ts);
}
+int AlarmImplAlarmDriver::setTime(struct timeval *tv)
+{
+ struct timespec ts;
+ int res;
+
+ ts.tv_sec = tv->tv_sec;
+ ts.tv_nsec = tv->tv_usec * 1000;
+ res = ioctl(fds[0], ANDROID_ALARM_SET_RTC, &ts);
+ if (res < 0)
+ ALOGV("ANDROID_ALARM_SET_RTC ioctl failed: %s\n", strerror(errno));
+ return res;
+}
+
int AlarmImplAlarmDriver::waitForAlarm()
{
return ioctl(fds[0], ANDROID_ALARM_WAIT);
@@ -140,6 +157,50 @@
return timerfd_settime(fds[type], TFD_TIMER_ABSTIME, &spec, NULL);
}
+int AlarmImplTimerFd::setTime(struct timeval *tv)
+{
+ struct rtc_time rtc;
+ struct tm tm, *gmtime_res;
+ int fd;
+ int res;
+
+ res = settimeofday(tv, NULL);
+ if (res < 0) {
+ ALOGV("settimeofday() failed: %s\n", strerror(errno));
+ return -1;
+ }
+
+ fd = open("/dev/rtc0", O_RDWR);
+ if (fd < 0) {
+ ALOGV("Unable to open RTC driver: %s\n", strerror(errno));
+ return res;
+ }
+
+ gmtime_res = gmtime_r(&tv->tv_sec, &tm);
+ if (!gmtime_res) {
+ ALOGV("gmtime_r() failed: %s\n", strerror(errno));
+ res = -1;
+ goto done;
+ }
+
+ memset(&rtc, 0, sizeof(rtc));
+ rtc.tm_sec = tm.tm_sec;
+ rtc.tm_min = tm.tm_min;
+ rtc.tm_hour = tm.tm_hour;
+ rtc.tm_mday = tm.tm_mday;
+ rtc.tm_mon = tm.tm_mon;
+ rtc.tm_year = tm.tm_year;
+ rtc.tm_wday = tm.tm_wday;
+ rtc.tm_yday = tm.tm_yday;
+ rtc.tm_isdst = tm.tm_isdst;
+ res = ioctl(fd, RTC_SET_TIME, &rtc);
+ if (res < 0)
+ ALOGV("RTC_SET_TIME ioctl failed: %s\n", strerror(errno));
+done:
+ close(fd);
+ return res;
+}
+
int AlarmImplTimerFd::waitForAlarm()
{
epoll_event events[N_ANDROID_TIMERFDS];
@@ -168,6 +229,30 @@
return result;
}
+static jint android_server_AlarmManagerService_setKernelTime(JNIEnv*, jobject, jlong nativeData, jlong millis)
+{
+ AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData);
+ struct timeval tv;
+ int ret;
+
+ if (millis <= 0 || millis / 1000LL >= INT_MAX) {
+ return -1;
+ }
+
+ tv.tv_sec = (time_t) (millis / 1000LL);
+ tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
+
+ ALOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
+
+ ret = impl->setTime(&tv);
+
+ if(ret < 0) {
+ ALOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
+ ret = -1;
+ }
+ return ret;
+}
+
static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobject, jlong, jint minswest)
{
struct timezone tz;
@@ -309,6 +394,7 @@
{"close", "(J)V", (void*)android_server_AlarmManagerService_close},
{"set", "(JIJJ)V", (void*)android_server_AlarmManagerService_set},
{"waitForAlarm", "(J)I", (void*)android_server_AlarmManagerService_waitForAlarm},
+ {"setKernelTime", "(JJ)I", (void*)android_server_AlarmManagerService_setKernelTime},
{"setKernelTimezone", "(JI)I", (void*)android_server_AlarmManagerService_setKernelTimezone},
};