Bug 793558 - Time API: changes does not persist after a restart. r=mwu
authorVincent Chang <vchang@mozilla.com>
Fri, 28 Sep 2012 14:38:50 +0800
changeset 108747 c0ab627c99dda912c362eed31f70240a5adcabd2
parent 108746 be23db843f5075b9c4a6aeeda7bcb0fea5df49ba
child 108748 3f5390b6970e29a951e6c8c4455ac08b4d659334
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersmwu
bugs793558
milestone18.0a1
Bug 793558 - Time API: changes does not persist after a restart. r=mwu
hal/gonk/GonkHal.cpp
--- a/hal/gonk/GonkHal.cpp
+++ b/hal/gonk/GonkHal.cpp
@@ -51,17 +51,17 @@
 #include "nsThreadUtils.h"
 #include "nsThreadUtils.h"
 #include "nsIThread.h"
 #include "nsXULAppAPI.h"
 #include "OrientationObserver.h"
 #include "UeventPoller.h"
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
-#define NsecPerMsec  1000000
+#define NsecPerMsec  1000000LL
 #define NsecPerSec   1000000000
 
 // The header linux/oom.h is not available in bionic libc. We
 // redefine some of its constants here.
 
 #ifndef OOM_DISABLE
 #define OOM_DISABLE  (-17)
 #endif
@@ -598,55 +598,52 @@ GetLight(hal::LightType light, hal::Ligh
   aConfig->flash() = hal::FlashMode(state.flashMode);
   aConfig->flashOnMS() = state.flashOnMS;
   aConfig->flashOffMS() = state.flashOffMS;
   aConfig->mode() = hal::LightMode(state.brightnessMode);
 
   return true;
 }
 
-/**
- * clock_settime() is not exposed through bionic.
- * we define the new function to set system time.
- * The result is the same as using clock_settime() system call.
- */
-static int
-sys_clock_settime(clockid_t clk_id, const struct timespec *tp)
-{
-  return syscall(__NR_clock_settime, clk_id, tp);
-}
-
 void
 AdjustSystemClock(int64_t aDeltaMilliseconds)
 {
+  int fd;
+  struct timespec now;
+
   if (aDeltaMilliseconds == 0) {
     return;
   }
 
-  struct timespec now;
-
   // Preventing context switch before setting system clock
   sched_yield();
   clock_gettime(CLOCK_REALTIME, &now);
-  now.tv_sec += aDeltaMilliseconds / 1000;
-  now.tv_nsec += (aDeltaMilliseconds % 1000) * NsecPerMsec;
-  if (now.tv_nsec >= NsecPerSec)
-  {
+  now.tv_sec += (time_t)(aDeltaMilliseconds / 1000LL);
+  now.tv_nsec += (long)((aDeltaMilliseconds % 1000LL) * NsecPerMsec);
+  if (now.tv_nsec >= NsecPerSec) {
     now.tv_sec += 1;
     now.tv_nsec -= NsecPerSec;
   }
 
-  if (now.tv_nsec < 0)
-  {
+  if (now.tv_nsec < 0) {
     now.tv_nsec += NsecPerSec;
     now.tv_sec -= 1;
   }
-  // we need to have root privilege.
-  if (sys_clock_settime(CLOCK_REALTIME, &now) != 0) {
-    NS_ERROR("sys_clock_settime failed");
+
+  do {
+    fd = open("/dev/alarm", O_RDWR);
+  } while (fd == -1 && errno == EINTR);
+  ScopedClose autoClose(fd);
+  if (fd < 0) {
+    HAL_LOG(("Failed to open /dev/alarm: %s", strerror(errno)));
+    return;
+  }
+
+  if (ioctl(fd, ANDROID_ALARM_SET_RTC, &now) < 0) {
+    HAL_LOG(("ANDROID_ALARM_SET_RTC failed: %s", strerror(errno)));
     return;
   }
 
   hal::NotifySystemTimeChange(hal::SYS_TIME_CHANGE_CLOCK);
 }
 
 void
 SetTimezone(const nsCString& aTimezoneSpec)