Priorytet źródła czasu

Struktura Androida wykorzystuje różne źródła czasu do synchronizacji czasu. Ta strona skupia się na automatycznych źródłach czasu Network Time Protocol (NTP) oraz Network Identity and Time Zone (NITZ). Domyślnie w systemie Android 12 lub nowszym platforma traktuje NTP jako źródło czasu przed NITZ, ponieważ NTP jest dokładniejszy i bardziej niezawodny niż NITZ. W sytuacjach, gdy protokół NTP nie jest dostępny, platforma opiera się na NITZ. Jest to odwrócenie domyślnego priorytetu z wcześniejszych wersji platformy. Domyślnie w systemie Android 11 i starszych wersjach platforma nadaje priorytet NITZ nad NTP.

Więcej szczegółów na temat tej zmiany można znaleźć w następujących poprawkach AOSP: 1563678 , 1513323 .

Konfiguracja priorytetu źródła czasu

Aby skonfigurować, które źródło czasu ma domyślnie priorytet dla określonej wersji Androida, skonfiguruj klucz config_autoTimeSourcesPriority w frameworks/base/core/res/res/values/config.xml w czasie kompilacji. Sugestie czasowe ze źródła czasu znajdującego się wyżej na liście mają pierwszeństwo przed źródłami znajdującymi się niżej na liście.

Źródła czasu Androida, które można skonfigurować, znajdują się w TimeDetectorStrategy.java . Domyślnie skonfigurowane są następujące źródła:

  • Telefonia (NITZ)
  • Sieć (NTP)

Testowanie

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

  1. Upewnij się, że w urządzeniu testowanym znajduje się działająca karta SIM
  2. Wyłącz mobilną transmisję danych i Wi-Fi
  3. Przełącz urządzenie w tryb samolotowy, aby upewnić się, że radio komórkowe jest wyłączone
  4. Wyłącz automatyczne wykrywanie czasu
  5. W przyszłości ręcznie ustaw zegar na nieprawidłową wartość czasu
  6. Uruchom ponownie urządzenie
  7. Włącz automatyczne wykrywanie czasu
  8. Wyłącz urządzenie z trybu samolotowego

Te kroki powodują zmianę zegara systemowego natychmiast po odebraniu sygnału NITZ. Aby sprawdzić, jak ustawiony jest czas urządzenia, uruchom następującą komendę:

adb shell dumpsys time_detector

Aby sprawdzić, czy zegar systemowy używa NITZ, potwierdź w wynikach polecenia następujące polecenie:

  • mEnvironment.isAutoTimeDetectionEnabled() ma wartość 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 za pomocą sugestii telefonicznej.
  • Sekcja Telephony suggestion history zawiera sugestie dotyczące czasu.
  • Sekcja Network suggestion history jest pusta.

Sugestie czasowe w sekcjach Telephony suggestion history i Network suggestion history są uważane za źródło prawdy dotyczące czasu. Jeśli urządzenie jest podłączone do Internetu i posiada kartę SIM, sugestie są generowane zarówno przy użyciu NTP (sieć), jak i NITZ (telefonia). W tym przypadku testowym tylko sekcja Telephony suggestion history zawiera sugestie, ponieważ protokół NTP jest wyłączony.

Sekcja Time change log rejestruje zmiany wprowadzone w zegarze systemowym urządzenia i zastosowane sugestie. 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. Ponadto, jeśli prawidłowa sugestia o najwyższym priorytecie odpowiada aktualnemu czasowi zegara systemowego urządzenia z dokładnością do kilku sekund, czas nie zostanie zmieniony. W tym przypadku testowym, o ile sugestie nie są przestarzałe, zegar systemowy jest ustawiany przy użyciu jednej z sugestii z Telephony suggestion history .

Poniżej znajduje się przykład wyjścia, w przypadku którego urządzenie ponownie korzysta z protokołu NITZ, gdy protokół NTP jest niedostępny.

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}

Dla porównania z wyjściem w scenariuszu testowym, poniżej znajduje się przykład typowego wyjścia, w którym urządzenie otrzymuje sugestie czasu zarówno ze źródeł czasu NTP, jak 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}