why Android add an alarm driver?

来源:互联网 发布:curl post请求 json 编辑:程序博客网 时间:2024/05/20 05:09

Android has a new rtc driver implemented in "drivers/rtc/alarm.c".  Why bother adding such a driver? 

 

Android alarm driver provides a monotonic timebase that runs while the device is asleep. It enables an Android application to be run at some point in the future even device is in sleep mode. 

 

According to Android developer document http://developer.android.com/reference/android/os/SystemClock.html, "three different clocks are available, and they should not be confused:"

 

  • System.currentTimeMillis() is the standard "wall" clock (time and date) expressing milliseconds since the epoch. The wall clock can be set by the user or the phone network (see setCurrentTimeMillis(long)), so the time may jump backwards or forwards unpredictably. This clock should only be used when correspondence with real-world dates and times is important, such as in a calendar or alarm clock application. Interval or elapsed time measurements should use a different clock. If you are using System.currentTimeMillis(), consider listening to the ACTION_TIME_TICK,ACTION_TIME_CHANGED and ACTION_TIMEZONE_CHANGED Intent broadcasts to find out when the time changes.

  • uptimeMillis() is counted in milliseconds since the system was booted. This clock stops when the system enters deep sleep (CPU off, display dark, device waiting for external input), but is not affected by clock scaling, idle, or other power saving mechanisms. This is the basis for most interval timing such asThread.sleep(millls)Object.wait(millis), and System.nanoTime(). This clock is guaranteed to be monotonic, and is the recommended basis for the general purpose interval timing of user interface events, performance measurements, and anything else that does not need to measure elapsed time during device sleep. Most methods that accept a timestamp value expect the uptimeMillis() clock.

  • elapsedRealtime() is counted in milliseconds since the system was booted, including deep sleep. This clock should be used when measuring time intervals that may span periods of system sleep.

 

Below these clocks APIs are Linux driver supporting.

  • System.currentTimeMillis() is implemented in Dalvik runtime "dalvik/vm/native/java_lang_System.c".  It invokes gettimeofday() finally.

    *) System.nanoTime() is another related API. It inovkes dvmGetRelativeTimeNsec(), which implemented with clock_gettime().

  • uptimeMillis() and elapsedRealtime() are implemented in "framework/base/libs/utils/SystemClock.cpp". 
    • uptimeMillis() finally reach clock_gettime() on Android phone. 
    • elapsedRealtime() finally open "/dev/alarm", which is implemented in Android added alarm.c.

int64_t elapsedRealtime()

{
#if HAVE_ANDROID_OS
    static int s_fd = -1;
    if (s_fd == -1) {
        int fd = open("/dev/alarm", O_RDONLY);
        if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
            close(fd);
        }
    }
    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);
    }
#else
    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
    return (int64_t) nanoseconds_to_milliseconds(when);
#endif
}

 

 

原创粉丝点击