summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java68
1 files changed, 50 insertions, 18 deletions
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 8a823e22785c..c0f45d6fef1e 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -128,6 +128,7 @@ import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.Keep;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService;
@@ -216,6 +217,19 @@ public class AlarmManagerService extends SystemService {
private static final long TEMPORARY_QUOTA_DURATION = INTERVAL_DAY;
+ /*
+ * b/246256335: This compile-time constant controls whether Android attempts to sync the Kernel
+ * time zone offset via settimeofday(null, tz). For <= Android T behavior is the same as
+ * {@code true}, the state for future releases is the same as {@code false}.
+ * It is unlikely anything depends on this, but a compile-time constant has been used to limit
+ * the size of the revert if this proves to be invorrect. The guarded code and associated
+ * methods / native code can be removed after release testing has proved that removing the
+ * behavior doesn't break anything.
+ * TODO(b/246256335): After this change has soaked for a release, remove this constant and
+ * everything it affects.
+ */
+ private static final boolean KERNEL_TIME_ZONE_SYNC_ENABLED = false;
+
private final Intent mBackgroundIntent
= new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND);
@@ -1884,10 +1898,12 @@ public class AlarmManagerService extends SystemService {
mNextWakeup = mNextNonWakeup = 0;
- // We set the current offset in kernel because the kernel doesn't keep this after a
- // reboot. Keeping the kernel time zone in sync is "best effort" and can be wrong
- // for a period after daylight savings transitions.
- mInjector.syncKernelTimeZoneOffset();
+ if (KERNEL_TIME_ZONE_SYNC_ENABLED) {
+ // We set the current offset in kernel because the kernel doesn't keep this after a
+ // reboot. Keeping the kernel time zone in sync is "best effort" and can be wrong
+ // for a period after daylight savings transitions.
+ mInjector.syncKernelTimeZoneOffset();
+ }
// Ensure that we're booting with a halfway sensible current time. Use the
// most recent of Build.TIME, the root file system's timestamp, and the
@@ -2122,14 +2138,17 @@ public class AlarmManagerService extends SystemService {
final long currentTimeMillis = mInjector.getCurrentTimeMillis();
mInjector.setKernelTime(millis);
- // Changing the time may cross a DST transition; sync the kernel offset if needed.
- final TimeZone timeZone = TimeZone.getTimeZone(SystemTimeZone.getTimeZoneId());
- final int currentTzOffset = timeZone.getOffset(currentTimeMillis);
- final int newTzOffset = timeZone.getOffset(millis);
- if (currentTzOffset != newTzOffset) {
- Slog.i(TAG, "Timezone offset has changed, updating kernel timezone");
- mInjector.setKernelTimeZoneOffset(newTzOffset);
+ if (KERNEL_TIME_ZONE_SYNC_ENABLED) {
+ // Changing the time may cross a DST transition; sync the kernel offset if needed.
+ final TimeZone timeZone = TimeZone.getTimeZone(SystemTimeZone.getTimeZoneId());
+ final int currentTzOffset = timeZone.getOffset(currentTimeMillis);
+ final int newTzOffset = timeZone.getOffset(millis);
+ if (currentTzOffset != newTzOffset) {
+ Slog.i(TAG, "Timezone offset has changed, updating kernel timezone");
+ mInjector.setKernelTimeZoneOffset(newTzOffset);
+ }
}
+
// The native implementation of setKernelTime can return -1 even when the kernel
// time was set correctly, so assume setting kernel time was successful and always
// return true.
@@ -2152,9 +2171,11 @@ public class AlarmManagerService extends SystemService {
// newZone.getId(). It will be rejected if it is invalid.
timeZoneWasChanged = SystemTimeZone.setTimeZoneId(tzId, confidence);
- // Update the kernel timezone information
- int utcOffsetMillis = newZone.getOffset(mInjector.getCurrentTimeMillis());
- mInjector.setKernelTimeZoneOffset(utcOffsetMillis);
+ if (KERNEL_TIME_ZONE_SYNC_ENABLED) {
+ // Update the kernel timezone information
+ int utcOffsetMillis = newZone.getOffset(mInjector.getCurrentTimeMillis());
+ mInjector.setKernelTimeZoneOffset(utcOffsetMillis);
+ }
}
// Clear the default time zone in the system server process. This forces the next call
@@ -4285,6 +4306,15 @@ public class AlarmManagerService extends SystemService {
private static native int set(long nativeData, int type, long seconds, long nanoseconds);
private static native int waitForAlarm(long nativeData);
private static native int setKernelTime(long nativeData, long millis);
+
+ /*
+ * b/246256335: The @Keep ensures that the native definition is kept even when the optimizer can
+ * tell no calls will be made due to a compile-time constant. Allowing this definition to be
+ * optimized away breaks loadLibrary("alarm_jni") at boot time.
+ * TODO(b/246256335): Remove this native method and the associated native code when it is no
+ * longer needed.
+ */
+ @Keep
private static native int setKernelTimezone(long nativeData, int minuteswest);
private static native long getNextAlarm(long nativeData, int type);
@@ -5031,10 +5061,12 @@ public class AlarmManagerService extends SystemService {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
- // Since the kernel does not keep track of DST, we reset the TZ information at the
- // beginning of each day. This may miss a DST transition, but it will correct itself
- // within 24 hours.
- mInjector.syncKernelTimeZoneOffset();
+ if (KERNEL_TIME_ZONE_SYNC_ENABLED) {
+ // Since the kernel does not keep track of DST, we reset the TZ information at
+ // the beginning of each day. This may miss a DST transition, but it will
+ // correct itself within 24 hours.
+ mInjector.syncKernelTimeZoneOffset();
+ }
scheduleDateChangedEvent();
}
}