自动时间检测

自动时间检测会从各种时间源接收时间建议,选择最佳选项,然后将 Android 中的系统时钟设置为与之匹配。以前的 Android 版本提供了两种设置日期和时间的方式:由每位用户手动设置,或通过自动时间检测设置(借由以下两个选项之一):

  • telephony:使用网络身份和时区 (NITZ) 电话信号。
  • network:使用网络时间协议 (NTP) 时间服务器。

每个选项都需要连接到外部网络,Android Automotive 中不一定始终会提供此类连接。例如,在某些国家/地区,某些汽车可能没有内置电话功能。因此,我们会将全球卫星导航系统 (GNSS) 时间作为系统时间源提供给您,以便在网络连接不可用时使用。

此即将发布的 Android 版本提供了另外两个用于自动检测和设置时间的选项:

  • gnss:使用全球卫星导航系统 (GNSS)。
  • external:使用 VHAL 属性或系统 API。

启用自动时间检测

如需启用自动时间检测功能,请务必依次选择设置 > 日期和时间 > 自动确定日期和时间

图 1. 选择“自动确定日期和时间”

配置时间源

如需指定自动时间检测功能中包含的时间源以及考虑这些时间源时的优先级,您必须修改设备的资源配置文件 core/res/res/values/config.xml

<!-- Specifies priority of automatic time sources. Suggestions from higher entries in the list
     take precedence over lower ones. See com.android.server.timedetector.TimeDetectorStrategy for
     available sources. -->
<string-array name="config_autoTimeSourcesPriority">
    <item>telephony</item>
    <item>network</item>
</string-array>

在这个示例中,自动时间检测考虑了 telephonynetworktelephony 时间建议优先于 network 时间建议。

一般来说,如果优先级较高的时间源建议无效或太旧,系统会忽略这些建议。此外,如果优先级最高的有效建议与设备当前的系统时钟时间仅相差几秒(默认值为两 [2] 秒),系统会视为两者互相匹配,不会更改时间。

时间下限

Android 12 提供了新的时间下限,可用于验证时间建议。在这项功能推出之前,自动时间检测不会验证建议的传入 UTC 时间。有了这项功能,系统会舍弃在时间下限之前经过的时间。

下限值由根据 build 时间戳得出的日期来确定。这基于以下原则:在系统映像构建之前无法发生有效时间。Android 不强制规定上限。

GNSS 时间建议

gnss 时间源是 Android 12 中的新增内容,由 GPS 信号提供。当 telephonynetwork 不可用时,这是可靠的时间源。此选项会添加到 SystemServer 内被动监听位置信息更新的新 GnssTimeUpdateService 中。收到有效的位置信息后,GnssTimeUpdateService 会向 TimeDetectorService 提供建议,然后后者确定是否应更新系统时钟。

默认情况下,gnss 时间源未在 AOSP 中启用,因此必须由合作伙伴启用:

<!-- Specifies priority of automatic time sources. Suggestions from higher entries in the list
    take precedence over lower ones.
    See com.android.server.timedetector.TimeDetectorStrategy for available sources. -->
<string-array name="config_autoTimeSourcesPriority">
    <item>telephony</item>
    <item>network</item>
    <item>gnss</item>
</string-array>

<!-- Enables the GnssTimeUpdate service. This is the global switch for enabling Gnss time based
    suggestions to TimeDetector service. See also config_autoTimeSourcesPriority. -->
<bool name="config_enableGnssTimeUpdateService">true</bool>

如需启用此功能,请执行以下操作:

  1. 更新 config_enableGnssTimeUpdateService。必须将 config_enableGnssTimeUpdateService 的值设置为 true
  2. 更新 config_autoTimeSourcesPriority。必须将 gnss 添加到 config_autoTimeSourcesPriority 的项列表中。gnss 在优先级列表中的位置决定了 GNSS 建议相对于来自其他时间源的值的优先级。

对电量的影响

GnssTimeUpdateService 被动监听位置信息更新,这意味着它绝不会主动开启 GPS 来消耗额外的电量。因此,启用 GNSS 时间源后所耗的电量可以忽略不计。这也意味着,除非系统中的其他应用或服务主动请求位置信息更新,否则 GnssTimeUpdateService 不会获得位置信息更新,也不会提供 GNSS 时间建议。

测试

兼容性测试套件 (CTS)

我们提供了一项 CTS 测试,用于验证 GNSS 提供的时间是否可用。有关详细信息,请参阅 LocationShellCommand.java 一文。

单元测试

请参阅以下文件中的基本单元测试:

atest frameworks/base/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java

手动测试

为了测试此功能,我们在 LocationShellCommand.java 中添加了新的命令。使用以下命令可添加测试提供程序,您可以使用这些提供程序来指定位置信息和关联的 GNSS 时间。GnssTimeUpdateService 会监听这些位置信息更新,并定期提供建议。

注意:这些命令的接口可能会因版本而异。

# Enable Master Location Switch in the foreground user (usually user 10 on automotive).
# If you just flashed, this can be done through Setup Wizard.
adb shell cmd location set-location-enabled true --user 10

# Add GPS test provider (this usually fails the first time and will throw a SecurityException
# with "android from <some-uid> not allowed to perform MOCK_LOCATION".)
adb shell cmd location providers add-test-provider gps

# Enable mock location permissions for previous UID
adb shell appops set <uid printed in previous error> android:mock_location allow

# Add GPS test provider (Should work with no errors.)
adb shell cmd location providers add-test-provider gps

# Enable GPS test provider
adb shell cmd location providers set-test-provider-enabled gps true

# Set location with time (time can't be earlier than the limit set by the lower bound.)
adb shell cmd location providers set-test-provider-location gps --location <LATITUDE>,<LONGITUDE> --time <TIME>

external 时间建议

external 时间建议是向 Android 提供自动时间建议的另一种方式。借助这个新选项,您可以向 Android 提供完全自定义的时间建议,这些建议可以源自各种实时 ECU,而这些 ECU 又可以结合使用实时时钟、GNSS、NITZ 或其他任何时间源。

Android 12 提供以下建议作为 external 时间建议:

  • VHAL 属性:系统提供了一个名为 EPOCH_TIME 的新 VHAL 属性。此属性表示自世界协调时间 (UTC) 1970 年 1 月 1 日以来经过的毫秒数。可以将其值传递给 Android TimeManager 来建议新的系统时间。下面的参考实现中提供了用于更新此属性的示例 VHAL 实现。
  • 系统 API:TimeManager 中提供了一个名为 suggestExternalTime() 的新方法,可为系统提供外部时间建议。如果系统已配置为将 external 时间建议考虑在内(在配置文件中使用 config_autoTimeSourcesPriority),则传递给此方法的时间戳将用于设置系统时间,前提是不存在优先级更高的建议。

您可以实现如下所述的外部时间解决方案:

  1. 更新资源配置文件 (core/res/res/values/config.xml),然后将值 external 添加到 config_autoTimeSourcesPriority
    <string-array name="config_autoTimeSourcesPriority>
            <item>external</item>
            <item>gnss</item>
    </string-array>
    

    这样做可以指示 Android 在设置系统时钟时,为 external 时间建议提供最高优先级。车辆上的硬件会将时间戳建议写入新的 EPOCH_TIME VHAL 属性中。

  2. 供应商提供的应用会读取此属性并调用 TimeManager.suggestExternal()。然后,Android 可以将提供的时间戳作为新的系统时钟值。