frameworks/base/core/java/android/app/AlarmManager.java
/**
* Set the system default time zone.
* Requires the permission android.permission.SET_TIME_ZONE.
*
* @param timeZone in the format understood by {@link java.util.TimeZone}
*/
public void setTimeZone(String timeZone) {
try {
mService.setTimeZone(timeZone);
} catch (RemoteException ex) {
}
}
frameworks/base/services/java/com/android/server/AlarmManagerService.java
private static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
It's constructor method is :
public AlarmManagerService(Context context) {
mContext = context;
mDescriptor = init();
// We have to set current TimeZone info to kernel
// because kernel doesn't keep this after reboot
String tz = SystemProperties.get(TIMEZONE_PROPERTY);
if (tz != null) {
setTimeZone(tz);
}
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mTimeTickSender = PendingIntent.getBroadcastAsUser(context, 0,
new Intent(Intent.ACTION_TIME_TICK).addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY), 0,
UserHandle.ALL);
Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
mDateChangeSender = PendingIntent.getBroadcastAsUser(context, 0, intent,
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, UserHandle.ALL);
// now that we have initied the driver schedule the alarm
mClockReceiver= new ClockReceiver();
mClockReceiver.scheduleTimeTickEvent();
mClockReceiver.scheduleDateChangedEvent();
mUninstallReceiver = new UninstallReceiver();
if (mDescriptor != -1) {
mWaitThread.start();
} else {
Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler.");
}
try{
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream("/system/etc/alarm_blacklist.txt")));
String line ="";
AppBlacklistItem backitem= null;
while ((line = br.readLine()) != null){
if (localLOGV) Log.d(TAG, "black alarm" +line);
String nametype[] = line.split(":");
backitem = new AppBlacklistItem(nametype[0], nametype[1]);
mAppBlacklist.add(backitem);
}
br.close();
}catch(java.io.FileNotFoundException ex){
}catch(java.io.IOException ex){
}
}
public void setTimeZone(String tz) {
mContext.enforceCallingOrSelfPermission(
"android.permission.SET_TIME_ZONE",
"setTimeZone");
long oldId = Binder.clearCallingIdentity();
try {
if (TextUtils.isEmpty(tz)) return;
TimeZone zone = TimeZone.getTimeZone(tz);
// Prevent reentrant calls from stepping on each other when writing
// the time zone property
boolean timeZoneWasChanged = false;
synchronized (this) {
String current = SystemProperties.get(TIMEZONE_PROPERTY);
if (current == null || !current.equals(zone.getID())) {
if (localLOGV) {
Slog.v(TAG, "timezone changed: " + current + ", new=" + zone.getID());
}
timeZoneWasChanged = true;
SystemProperties.set(TIMEZONE_PROPERTY, zone.getID());
}
// Update the kernel timezone information
// Kernel tracks time offsets as 'minutes west of GMT'
int gmtOffset = zone.getOffset(System.currentTimeMillis());
setKernelTimezone(mDescriptor, -(gmtOffset / 60000));
}
TimeZone.setDefault(null);
if (timeZoneWasChanged) {
Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra("time-zone", zone.getID());
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}
} finally {
Binder.restoreCallingIdentity(oldId);
}
}
By setKernelTimezone in setTimeZone(String tz) method ,then invoke JNI to write kernel RTC .
frameworks/base/services/jni/com_android_server_AlarmManagerService.cpp:
static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv* env, jobject obj, jint fd, jint minswest)
{
struct timezone tz;
tz.tz_minuteswest = minswest;
tz.tz_dsttime = 0;
int result = settimeofday(NULL, &tz);
if (result < 0) {
ALOGE("Unable to set kernel timezone to %d: %s\n", minswest, strerror(errno));
return -1;
} else {
ALOGD("Kernel timezone updated to %d minutes west of GMT\n", minswest);
}
return 0;
}
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"init", "()I", (void*)android_server_AlarmManagerService_init},
{"close", "(I)V", (void*)android_server_AlarmManagerService_close},
{"set", "(IIJJ)V", (void*)android_server_AlarmManagerService_set},
{"waitForAlarm", "(I)I", (void*)android_server_AlarmManagerService_waitForAlarm},
{"setKernelTimezone", "(II)I", (void*)android_server_AlarmManagerService_setKernelTimezone},
};