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);
        }
    }
相关推荐
BoomHe4 小时前
Android Framework 文件应用移植到 AndroidStudio
android
传奇开心果编程5 小时前
【Jetpack Compose基础语法学与练】第8课 rememberSaveable,页面旋转/系统重建保留状态
android·学习·ui·kotlin·android jetpack
>Andre<5 小时前
UFS5.0标准中文全译·卷一:范围、术语与架构
android·linux·嵌入式硬件
事圆则缓6 小时前
Java 8 Lambda、Stream、Optional 与 Android 边界:从回调语法到运行时兼容
android·java
mmsx6 小时前
Android 地图十万要素不卡顿:空间网格 + 渐进式加载的移动端实践
android·大数据·opengl
Godikov8 小时前
Android 工业终端保活实战:前台服务 + 开机自启 + 更新自启的三重保障
android
字节暗面8 小时前
SO加固强度怎么量化?腾讯ACE与FairGuard静态分析实测
android·逆向
终端安全笔记10 小时前
描述文件、企业证书、MDM 不是三个名字,是三层
android·ios·智能手机
字节暗面10 小时前
一次游戏安全SO静态分析记录:腾讯ACE与FairGuard加固强度对比
android·逆向工程·游戏加固
传奇开心果编程10 小时前
【Jetpack Compose基础语法学与练】第9课 SideEffect副作用 + LaunchedEffect,处理异步任务和生命周期
android·学习·ui·kotlin·android jetpack