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:
- Upewnij się, że w urządzeniu testowanym znajduje się działająca karta SIM
- Wyłącz mobilną transmisję danych i Wi-Fi
- Przełącz urządzenie w tryb samolotowy, aby upewnić się, że radio komórkowe jest wyłączone
- Wyłącz automatyczne wykrywanie czasu
- W przyszłości ręcznie ustaw zegar na nieprawidłową wartość czasu
- Uruchom ponownie urządzenie
- Włącz automatyczne wykrywanie czasu
- 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}