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}, };