Priorytet źródła czasu

Do synchronizacji czasu framework Androida używa różnych źródeł czasu. Ta strona skupia się na automatycznych źródłach czasu, takich jak Network Time Protocol (NTP) i Network Identity and Time Zone (NITZ). Domyślnie w Androidzie 12 lub nowszym framework preferuje NTP jako źródło czasu zamiast NITZ, ponieważ NTP jest dokładniejszy i bardziej niezawodny niż NITZ. W sytuacjach, gdy serwer NTP jest niedostępny, framework korzysta z serwera NITZ. Jest to odwrócenie domyślnego priorytetu z wcześniejszych wersji platformy. Domyślnie w Androidzie 11 i starszych framework daje priorytet NITZ nad NTP.

Więcej informacji o tej zmianie znajdziesz w tych poprawkach AOSP: 1563678, 1513323.

Konfigurowanie priorytetu źródła czasu

Aby skonfigurować, które źródło czasu ma mieć domyślnie pierwszeństwo w przypadku konkretnej wersji Androida, skonfiguruj klucz config_autoTimeSourcesPriority w pliku frameworks/base/core/res/res/values/config.xml na etapie kompilacji. Propozycje dotyczące czasu ze źródła, które znajduje się wyżej na liście, mają pierwszeństwo przed propozycjami ze źródeł znajdujących się niżej na liście.

Źródła czasu Androida, które można skonfigurować, znajdziesz w sekcji TimeDetectorStrategy.java. Domyślnie używane są te źródła:

  • Połączenia telefoniczne (NITZ)
  • Sieć (NTP)

Testowanie

Aby sprawdzić, czy urządzenie korzysta z NITZ, gdy serwer NTP jest niedostępny (gdy mobilna transmisja danych i Wi-Fi są wyłączone), wykonaj te czynności:

  1. Upewnij się, że w badanym urządzeniu jest karta SIM, która działa prawidłowo.
  2. Wyłączanie mobilnej transmisji danych i Wi-Fi
  3. Włącz na urządzeniu tryb samolotowy, aby mieć pewność, że radio komórkowe jest wyłączone.
  4. Wyłączanie automatycznego wykrywania czasu
  5. Ręczne ustawienie zegara na nieprawidłową wartość czasu w przyszłości
  6. Uruchom ponownie urządzenie.
  7. Włączanie automatycznego wykrywania czasu
  8. Wyłącz tryb samolotowy na urządzeniu.

Te kroki powodują zmianę zegara systemowego, gdy tylko zostanie odebrany sygnał NITZ. Aby sprawdzić, jak ustawiony jest czas na urządzeniu, uruchom to polecenie:

adb shell dumpsys time_detector

Aby sprawdzić, czy zegar systemowy używa NITZ, sprawdź w wyjściu polecenia:

  • mEnvironment.isAutoTimeDetectionEnabled(): true.
  • mEnvironment.autoOriginPriorities() zawiera listę źródeł czasu, przy czym źródła znajdujące się wyżej na liście mają pierwszeństwo przed źródłami znajdującymi się niżej na liście.
  • Sekcja Time change log pokazuje, że zegar systemowy jest ustawiany przy użyciu sugestii dotyczącej telefonii.
  • Sekcja Telephony suggestion history zawiera propozycje czasu.
  • Sekcja Network suggestion history jest pusta.

Propozycje dotyczące czasu w sekcjach Telephony suggestion historyNetwork suggestion history są uważane za źródło danych podstawowych dotyczące czasu. Jeśli urządzenie jest połączone z internetem i ma kartę SIM, sugestie są generowane za pomocą protokołu NTP (Network Time Protocol) i NitZ (Network Time Protocol). W tym przypadku tylko sekcja Telephony suggestion history zawiera sugestie, ponieważ NTP jest wyłączone.

Sekcja Time change log zawiera informacje o zmianach wprowadzonych w systemowym zegarku urządzenia oraz o użytej sugestii. Zegar systemowy jest ustawiany na podstawie kolejności źródeł czasu na liście priorytetów w kluczu config_autoTimeSourcesPriority. Jednak sugestie ze źródła o wyższym priorytecie mogą zostać zignorowane, jeśli są zbyt stare lub nieprawidłowe. Jeśli ponadto propozycja z najwyższym priorytetem zgadza się z aktualnym czasem zegara systemowego urządzenia z dokładnością do kilku sekund, czas nie zostanie zmieniony. W tym teście, o ile sugestie nie są nieaktualne, zegar systemowy jest ustawiany za pomocą jednej z sugestii z funkcji Telephony suggestion history.

Poniżej znajduje się przykład danych wyjściowych, w których urządzenie używa NITZ, gdy NTP jest niedostępne.

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}

Poniżej znajdziesz przykład typowego wyniku, w którym urządzenie otrzymuje propozycje czasu z źródeł czasu NTP i 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}