0. 前言
最近修改客户问题的时候发现系统默认时间和ntp网络时间之间出现了一次时间的跳变,虽然不是什么大问题,但是可以跟进了解一下。
1. 问题分析
如图,系统时间从8:00跳变到0:00
通过分析代码,frameworks\base\services\java\com\android\server\SystemServer.java
// The earliest supported time. We pick one day into 1970, to
// give any timezone code room without going into negative time.
private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
private void run() {
try {
android.os.Process.setThreadPriority(-19);
traceBeginAndSlog("InitBeforeStartServices");
// If a device's clock is before 1970 (before 0), a lot of
// APIs crash dealing with negative numbers, notably
// java.io.File#setLastModified, so instead we fake it and
// hope that time from cell towers or NTP fixes it shortly.
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//
// Default the timezone property to GMT if not set.
//
String timezoneProperty = SystemProperties.get("persist.sys.timezone");
if (timezoneProperty == null || timezoneProperty.isEmpty()) {
Slog.w(TAG, "Timezone not set; setting to GMT.");
SystemProperties.set("persist.sys.timezone", "GMT");
}
......
}
此处判断的是否早于1970年,若早于1970年则设为1970年1月1日8:00,此处符合log预期,那就要继续追踪log查看系统时间被修改的位置。
此时跟踪系统修改时间的函数setCurrentTimeMillis
,加打印排查发现没有修改系统时间的地方,此时追踪setCurrentTimeMillis
函数流程,发现会调用setKernelTime
追查此函数发现一处可疑的地方,但是log中无打印,因此通过关键字抓打印
此时看到关键元凶AlarmManager,追查源码:
frameworks\base\services\core\java\com\android\server\AlarmManagerService.java
@Override
public void onStart() {
mNativeData = init();
mNextWakeup = mNextNonWakeup = 0;
// We have to set current TimeZone info to kernel
// because kernel doesn't keep this after reboot
setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY));
// Also sure that we're booting with a halfway sensible current time
if (mNativeData != 0) {
final long systemBuildTime = Environment.getRootDirectory().lastModified();
if (System.currentTimeMillis() < systemBuildTime) {
Slog.i(TAG, "Current time only " + System.currentTimeMillis()
+ ", advancing to build time " + systemBuildTime);
setKernelTime(mNativeData, systemBuildTime);
}
}
此处对比当前系统时间和system 文件夹时间,发现系统时间早于文件夹时间,将系统时间设置为文件夹时间。
drwxr-xr-x 14 root root 4096 2009-01-01 00:00 system
-rw-r–r-- 1 root root 5272 2009-01-01 00:00 ueventd.rc
drwxr-xr-x 13 root root 4096 2009-01-01 00:00 vendor
OK,至此真相大白,因为不影响功能,暂时也没有修改