From 38bf51466881b726f42832743d8cca6ee67bb148 Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Wed, 19 Feb 2014 16:39:36 -0800 Subject: Move time setting code from SystemClock to AlarmManagerService On devices using /dev/rtc instead of /dev/alarm, updating the time-of-day clock and RTC are separate syscalls. Hence the clock and RTC could be left in inconsistent states if two threads called SystemClock.setCurrentTimeMillis() simultaneously. By moving this code into AlarmManagerService, we can put a global lock around AlarmManagerService.setTime() and prevent the race condition. Note that access to SystemClock.setCurrentTimeMillis() is now gated by android.permission.SET_TIME, where before it was gated by filesystem permissions (i.e., could the process write to /dev/alarm or /dev/rtc). Change-Id: Ia34899a4cde983656305fd2ef466dfe908ed23c8 Signed-off-by: Greg Hackmann --- core/java/android/app/IAlarmManager.aidl | 2 +- core/java/android/os/SystemClock.java | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'core/java') diff --git a/core/java/android/app/IAlarmManager.aidl b/core/java/android/app/IAlarmManager.aidl index 8476609..ef9f26e 100644 --- a/core/java/android/app/IAlarmManager.aidl +++ b/core/java/android/app/IAlarmManager.aidl @@ -28,7 +28,7 @@ interface IAlarmManager { /** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */ void set(int type, long triggerAtTime, long windowLength, long interval, in PendingIntent operation, in WorkSource workSource); - void setTime(long millis); + boolean setTime(long millis); void setTimeZone(String zone); void remove(in PendingIntent operation); } diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java index 729c64b..672df6d 100644 --- a/core/java/android/os/SystemClock.java +++ b/core/java/android/os/SystemClock.java @@ -16,6 +16,9 @@ package android.os; +import android.app.IAlarmManager; +import android.content.Context; +import android.util.Slog; /** * Core timekeeping facilities. @@ -89,6 +92,8 @@ package android.os; * */ public final class SystemClock { + private static final String TAG = "SystemClock"; + /** * This class is uninstantiable. */ @@ -134,7 +139,23 @@ public final class SystemClock { * * @return if the clock was successfully set to the specified time. */ - native public static boolean setCurrentTimeMillis(long millis); + public static boolean setCurrentTimeMillis(long millis) { + IBinder b = ServiceManager.getService(Context.ALARM_SERVICE); + IAlarmManager mgr = IAlarmManager.Stub.asInterface(b); + if (mgr == null) { + return false; + } + + try { + return mgr.setTime(millis); + } catch (RemoteException e) { + Slog.e(TAG, "Unable to set RTC", e); + } catch (SecurityException e) { + Slog.e(TAG, "Unable to set RTC", e); + } + + return false; + } /** * Returns milliseconds since boot, not counting time spent in deep sleep. -- cgit v1.1