diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index e728a2c55765e5e3d224968e20175b7f26d10075..d0a1b027ec48ed206a13dd128d00cc687d21d1fa 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -183,6 +183,9 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.zone.ZoneOffsetTransition; +import java.time.zone.ZoneRules; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -194,6 +197,7 @@ import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; import java.util.function.Predicate; /** @@ -234,8 +238,12 @@ public class AlarmManagerService extends SystemService { private static final long TEMPORARY_QUOTA_DURATION = INTERVAL_DAY; - // System property read on some device configurations to initialize time properly. + // System properties read on some device configurations to initialize time properly and + // perform DST transitions at the bootloader level. private static final String TIMEOFFSET_PROPERTY = "persist.sys.time.offset"; + private static final String DST_TRANSITION_PROPERTY = "persist.sys.time.dst_transition"; + private static final String DST_OFFSET_PROPERTY = "persist.sys.time.dst_offset"; + private final Intent mBackgroundIntent = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND); @@ -2200,6 +2208,19 @@ public class AlarmManagerService extends SystemService { final int gmtOffset = newZone.getOffset(mInjector.getCurrentTimeMillis()); SystemProperties.set(TIMEOFFSET_PROPERTY, String.valueOf(gmtOffset)); + + final ZoneRules rules = newZone.toZoneId().getRules(); + final ZoneOffsetTransition transition = rules.nextTransition(Instant.now()); + if (null != transition) { + // Get the offset between the time after the DST transition and before. + final long transitionOffset = TimeUnit.SECONDS.toMillis(( + transition.getOffsetAfter().getTotalSeconds() + - transition.getOffsetBefore().getTotalSeconds())); + // Time when the next DST transition is programmed. + final long nextTransition = TimeUnit.SECONDS.toMillis(transition.toEpochSecond()); + SystemProperties.set(DST_TRANSITION_PROPERTY, String.valueOf(nextTransition)); + SystemProperties.set(DST_OFFSET_PROPERTY, String.valueOf(transitionOffset)); + } } // Clear the default time zone in the system server process. This forces the next call