Приоритет источника времени

Фреймворк Android использует различные источники времени для синхронизации времени. На этой странице рассказывается о протоколе NTP и автоматических источниках времени NITZ. В Android 12 и более поздних версий по умолчанию NTP имеет приоритет над NITZ, поскольку NTP точнее и надежнее. Если NTP недоступен, фреймворк использует NITZ. Это изменение приоритета по умолчанию по сравнению с более ранними версиями платформы. По умолчанию в Android 11 и более ранних версиях фреймворк отдает приоритет NITZ перед NTP.

Подробнее об этом изменении можно узнать из следующих исправлений AOSP: 1563678, 1513323.

Как настроить приоритет источников времени

Чтобы настроить, какой источник времени будет приоритетным по умолчанию для определенной версии Android, задайте ключ config_autoTimeSourcesPriority в файле frameworks/base/core/res/res/values/config.xml во время сборки. Предложения от источника, который находится выше в списке, имеют приоритет над предложениями от источников, которые находятся ниже.

Источники времени Android, которые можно настроить, находятся в файле TimeDetectorStrategy.java. По умолчанию настроены следующие источники:

  • Телефонная связь (NITZ)
  • Сеть (NTP)

Тестирование

Чтобы проверить, использует ли устройство NITZ, когда NTP недоступен (мобильный интернет и Wi-Fi отключены), выполните следующие действия:

  1. Убедитесь, что в тестируемом устройстве установлена рабочая SIM-карта.
  2. Отключите мобильный интернет и Wi-Fi
  3. Переведите устройство в режим полета, чтобы отключить радиомодуль.
  4. Как отключить автоматическое определение времени
  5. Вручную установите на часах неправильное время в будущем.
  6. Перезагрузите устройство
  7. Включите автоматическое определение времени
  8. Выключите режим полета на устройстве.

После этого системные часы будут изменены, как только будет получен сигнал NITZ. Чтобы проверить, как настроено время на устройстве, выполните следующую команду:

adb shell dumpsys time_detector

Чтобы убедиться, что системные часы используют NITZ, проверьте следующее в выходных данных команды:

  • mEnvironment.isAutoTimeDetectionEnabled(): true.
  • mEnvironment.autoOriginPriorities() содержит список источников времени, причем источники, расположенные выше в списке, имеют приоритет над источниками, расположенными ниже.
  • В разделе Time change log указано, что системные часы настроены на основе данных, полученных от оператора связи.
  • Раздел Telephony suggestion history содержит предложения времени.
  • Раздел Network suggestion history пуст.

Предложения времени в разделах Telephony suggestion history и Network suggestion history считаются источником достоверной информации о времени. Если устройство подключено к интернету и в нем есть SIM-карта, предложения генерируются с использованием как NTP (сеть), так и NITZ (телефония). В этом отчете о тестировании рекомендации будут показываться только в разделе Telephony suggestion history, поскольку NTP отключен.

В разделе Time change log регистрируются изменения, внесенные в системные часы устройства, и использованные подсказки. Системные часы настраиваются на основе порядка источников времени в списке приоритетов в ключе config_autoTimeSourcesPriority. Однако подсказки из источника с более высоким приоритетом могут игнорироваться, если они слишком старые или недействительные. Кроме того, если действительное предложение с самым высоким приоритетом отличается от текущего времени системных часов устройства на несколько секунд, время не будет изменено. В этом отчете о тестировании, если подсказки не устарели, системные часы устанавливаются на основе одной из подсказок из Telephony suggestion history.

Ниже приведен пример выходных данных, в которых устройство переходит на использование NITZ, когда NTP недоступен.

TimeDetectorStrategy:
  mLastAutoSystemClockTimeSet=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}
  mEnvironment.isAutoTimeDetectionEnabled()=true
  mEnvironment.elapsedRealtimeMillis()=73059
  mEnvironment.systemClockMillis()=1614186767818
  mEnvironment.systemClockUpdateThresholdMillis()=2000
  mEnvironment.autoTimeLowerBound()=2021-02-24T15:44:15Z(1614181455000)
  mEnvironment.autoOriginPriorities()=[network,telephony]
  Time change log:
    66261 / 2021-02-24T17:12:41.020Z - Set system clock using time=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000} cause=Found good telephony suggestion., bestTelephonySuggestion=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}, detectionReason=New telephony time suggested. timeSuggestion=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]} elapsedRealtimeMillis=66259 newSystemClockMillis=1614186761019
  Telephony suggestion history:
    key idx: 0=0
    val idx: 0=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}
      Historic values=[
        0@PT1M6.258S: TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}
      ]
  Network suggestion history:
    {Empty}
  Gnss suggestion history:
    {Empty}
  External suggestion history:
    {Empty}

Ниже приведен пример типичного результата, который можно сравнить с результатами тестирования. В этом примере устройство получает предложения времени от источников NTP и NITZ.

TimeDetectorStrategy:
  mLastAutoSystemClockTimeSet=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}
  mEnvironment.isAutoTimeDetectionEnabled()=true
  mEnvironment.elapsedRealtimeMillis()=302926
  mEnvironment.systemClockMillis()=1614186997685
  mEnvironment.systemClockUpdateThresholdMillis()=2000
  mEnvironment.autoTimeLowerBound()=2021-02-24T15:44:15Z(1614181455000)
  mEnvironment.autoOriginPriorities()=[network,telephony]
  Time change log:
    66261 / 2021-02-24T17:12:41.020Z - Set system clock using time=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000} cause=Found good telephony suggestion., bestTelephonySuggestion=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}, detectionReason=New telephony time suggested. timeSuggestion=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]} elapsedRealtimeMillis=66259 newSystemClockMillis=1614186761019
  Telephony suggestion history:
    key idx: 0=0
    val idx: 0=TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}
      Historic values=[
        0@PT1M6.258S: TelephonyTimeSuggestion{mSlotIndex='0', mUtcTime=TimestampedValue{mReferenceTimeMillis=66240, mValue=1614186761000}, mDebugInfo=[Sending new time suggestion nitzSignal=TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}}, reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=66240, mValue=NitzData{mOriginalString=21/02/24,17:12:41+00,00, mZoneOffset=0, mDstOffset=0, mCurrentTimeMillis=1614186761000, mEmulatorHostTimeZone=null}})]}
      ]
  Network suggestion history:
    0@PT4M4.04S: NetworkTimeSuggestion{mUtcTime=TimestampedValue{mReferenceTimeMillis=244038, mValue=1614186939242}, mDebugInfo=[Origin: NetworkTimeUpdateService. event=3]}
  Gnss suggestion history:
    {Empty}
  External suggestion history:
    {Empty}