Add elapsedRealtimeNano(), and use CLOCK_BOOTTIME where possible.

Change-Id: I4231c8ca32663e6e2cb5b7c126d091f837373807
diff --git a/include/utils/SystemClock.h b/include/utils/SystemClock.h
index 7c319be..d75264c 100644
--- a/include/utils/SystemClock.h
+++ b/include/utils/SystemClock.h
@@ -25,6 +25,7 @@
 int setCurrentTimeMillis(int64_t millis);
 int64_t uptimeMillis();
 int64_t elapsedRealtime();
+int64_t elapsedRealtimeNano();
 
 }; // namespace android
 
diff --git a/include/utils/Timers.h b/include/utils/Timers.h
index 8b4d322..92f66c9 100644
--- a/include/utils/Timers.h
+++ b/include/utils/Timers.h
@@ -78,9 +78,10 @@
     SYSTEM_TIME_REALTIME = 0,  // system-wide realtime clock
     SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point
     SYSTEM_TIME_PROCESS = 2,   // high-resolution per-process clock
-    SYSTEM_TIME_THREAD = 3     // high-resolution per-thread clock
+    SYSTEM_TIME_THREAD = 3,    // high-resolution per-thread clock
+    SYSTEM_TIME_BOOTTIME = 4   // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time
 };
-    
+
 // return the system-time according to the specified clock
 #ifdef __cplusplus
 nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);
diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp
index 8b8ac10..53e0626 100644
--- a/libs/utils/SystemClock.cpp
+++ b/libs/utils/SystemClock.cpp
@@ -106,7 +106,22 @@
  */
 int64_t elapsedRealtime()
 {
+	return nanoseconds_to_milliseconds(elapsedRealtimeNano());
+}
+
+/*
+ * native public static long elapsedRealtimeNano();
+ */
+int64_t elapsedRealtimeNano()
+{
 #ifdef HAVE_ANDROID_OS
+    struct timespec ts;
+    int result = clock_gettime(CLOCK_BOOTTIME, &ts);
+    if (result == 0) {
+        return seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
+    }
+
+    // CLOCK_BOOTTIME doesn't exist, fallback to /dev/alarm
     static int s_fd = -1;
 
     if (s_fd == -1) {
@@ -114,25 +129,20 @@
         if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
             close(fd);
         }
+        result = ioctl(s_fd,
+                ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
     }
 
-    struct timespec ts;
-    int result = ioctl(s_fd,
-            ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
-
     if (result == 0) {
-        int64_t when = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
-        return (int64_t) nanoseconds_to_milliseconds(when);
-    } else {
-        // XXX: there was an error, probably because the driver didn't
-        // exist ... this should return
-        // a real error, like an exception!
-        int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
-        return (int64_t) nanoseconds_to_milliseconds(when);
+        return seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
     }
+
+    // XXX: there was an error, probably because the driver didn't
+    // exist ... this should return
+    // a real error, like an exception!
+    return systemTime(SYSTEM_TIME_MONOTONIC);
 #else
-    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
-    return (int64_t) nanoseconds_to_milliseconds(when);
+    return systemTime(SYSTEM_TIME_MONOTONIC);
 #endif
 }
 
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp
index 64b4701..d4f8516 100644
--- a/libs/utils/Timers.cpp
+++ b/libs/utils/Timers.cpp
@@ -39,7 +39,8 @@
             CLOCK_REALTIME,
             CLOCK_MONOTONIC,
             CLOCK_PROCESS_CPUTIME_ID,
-            CLOCK_THREAD_CPUTIME_ID
+            CLOCK_THREAD_CPUTIME_ID,
+            CLOCK_BOOTTIME
     };
     struct timespec t;
     t.tv_sec = t.tv_nsec = 0;