summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorGreg Hackmann <ghackmann@google.com>2014-02-19 16:39:36 -0800
committerGreg Hackmann <ghackmann@google.com>2014-02-21 09:53:19 -0800
commit38bf51466881b726f42832743d8cca6ee67bb148 (patch)
treef2273799ae619f0f9b81ea0997009f2457d1cf54 /core/java
parent05cebdc2abd05b0dca351306cb039245d50c67ae (diff)
downloadframeworks_base-38bf51466881b726f42832743d8cca6ee67bb148.zip
frameworks_base-38bf51466881b726f42832743d8cca6ee67bb148.tar.gz
frameworks_base-38bf51466881b726f42832743d8cca6ee67bb148.tar.bz2
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 <ghackmann@google.com>
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/IAlarmManager.aidl2
-rw-r--r--core/java/android/os/SystemClock.java23
2 files changed, 23 insertions, 2 deletions
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;
* </ul>
*/
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.