Merge "Disable kernel time zone offset-syncing behavior"

This commit is contained in:
Neil Fuller
2022-09-30 09:34:45 +00:00
committed by Android (Google) Code Review

View File

@@ -130,6 +130,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;
@@ -218,6 +219,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);
@@ -1887,10 +1901,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
@@ -2127,14 +2143,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.
@@ -2157,9 +2176,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
@@ -4290,6 +4311,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);
@@ -5036,10 +5066,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();
}
}