Android 10&15 Framework 允许设置系统时间早于编译时间

文章目录

Android系统时间⌚相关文章
Android 10&15 Framework 允许设置系统时间早于编译时间
Android10设置未来时间后自动更新时间失败
Android10实现根据定位自动更新时区

一、背景说明

Android系统默认不允许系统时间设置早于系统固件编译时间,毕竟时间是始终向前的,通常不会设置某个过去的无效时间。但在项目测试环节提出了此问题:

当设置系统时间为早于编译时间的时刻时,设备重启时间复位为固件编译时间。

二、根因分析

先以Android10展开分析,从现象分析可知:

1.设置系统时间后是重启 设备才复位,因此是开机过程某处重置了系统时间

2.时间被复位为固件编译时间

分析开机log可看到相关log:

复制代码
AlarmManager Current time only xxx , advancing to build time xxx

从而可知开机时时间被复位成固件编译时间,响应log代码位于:

frameworks/base/services/core/java/com/android/server/AlarmManagerService.java

复制代码
    @Override
    public void onStart() {
        mInjector.init();
        synchronized (mLock) {
           ...
            // 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
            // value of the ro.build.date.utc system property (which is in seconds).
            final long systemBuildTime =  Long.max(
                    1000L * SystemProperties.getLong("ro.build.date.utc", -1L),
                    Long.max(Environment.getRootDirectory().lastModified(), Build.TIME));
            if (mInjector.getCurrentTimeMillis() < systemBuildTime) {
                Slog.i(TAG, "Current time only " + mInjector.getCurrentTimeMillis()
                        + ", advancing to build time " + systemBuildTime);
                mInjector.setKernelTime(systemBuildTime);
            }

此外我们知道固件编译保存在ro.build.date.utc属性中,全局搜索代码,也较容易定位到上述代码。

由此可知,开机AlarmManager服务启动时,从ro.builddate.utc属性中固件编译时间,并于当前系统时间比较,若当前系统时间早于编译时间,则以固件编译时间为系统时间。

三、解决方案

Android10

frameworks/base/services/core/java/com/android/server/AlarmManagerService.java

复制代码
    @Override
    public void onStart() {
        mInjector.init();
        synchronized (mLock) {
           ...
            // 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
            // value of the ro.build.date.utc system property (which is in seconds).
            //Patch Start
            /*
            final long systemBuildTime =  Long.max(
                    1000L * SystemProperties.getLong("ro.build.date.utc", -1L),
                    Long.max(Environment.getRootDirectory().lastModified(), Build.TIME));
            if (mInjector.getCurrentTimeMillis() < systemBuildTime) {
                Slog.i(TAG, "Current time only " + mInjector.getCurrentTimeMillis()
                        + ", advancing to build time " + systemBuildTime);
                mInjector.setKernelTime(systemBuildTime);
            }
            */
            //Patch End

Android15 流程有些变化,在initializeTimeIfRequired()初始化合适的系统时间

frameworks/base/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java

复制代码
    @Override
    public void onStart() {
        mInjector.init();
        mHandler = new AlarmHandler();
        ...
        synchronized (mLock) {
            ...

            // Ensure that we're booting with a halfway sensible current time.
            //Patch Start
            //mInjector.initializeTimeIfRequired();
            //Patch End
            ...
            }
            ...
    }

frameworks/base/services/core/java/com/android/server/SystemClockTime.java

复制代码
    /**
     * Sets the system clock time to a reasonable lower bound. Used during boot-up to ensure the
     * device has a time that is better than a default like 1970-01-01.
     */
    public static void initializeIfRequired() {
        // Use the most recent of Build.TIME, the root file system's timestamp, and the
        // value of the ro.build.date.utc system property (which is in seconds).
        final long systemBuildTime = Long.max(
                1000L * SystemProperties.getLong("ro.build.date.utc", -1L),
                Long.max(Environment.getRootDirectory().lastModified(), Build.TIME));
        long currentTimeMillis = getCurrentTimeMillis();
        if (currentTimeMillis < systemBuildTime) {
            String logMsg = "Current time only " + currentTimeMillis
                    + ", advancing to build time " + systemBuildTime;
            Slog.i(TAG, logMsg);
            
            setTimeAndConfidence(systemBuildTime, TIME_CONFIDENCE_LOW, logMsg);
        }
    }
相关推荐
2501_944525544 分钟前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
不急不躁1233 小时前
Android16 GTS GtsPermissionTestcases 测试,跳过权限检查
android
符哥20085 小时前
关于用Android Compose开发成不成熟的分析
android·android jetpack
蜗牛、Z5 小时前
Android 蓝牙/Wi-Fi通信协议之:蓝牙扫描ScanCallback详解
android
黄昏晓x5 小时前
Linux----进程控制
android·linux·运维
我是阿亮啊6 小时前
android中事件分发机制
android·事件分发·事件分发机制
心前阳光7 小时前
Unity 模拟父子关系
android·unity·游戏引擎
2501_915106327 小时前
当 Perfdog 开始收费之后,我重新整理了一替代方案
android·ios·小程序·https·uni-app·iphone·webview
多多*7 小时前
2月3日面试题整理 字节跳动后端开发相关
android·java·开发语言·网络·jvm·adb·c#
习惯就好zz8 小时前
[Android/Linux] 实战记录:利用 Kconfig 精确控制 i.MX8MM 特定 DTB 的编译生成
android·linux·dts·dtb·lunch·多卡板配置