O framework do Android usa várias fontes de tempo para sincronização. O foco desta página são as origens de tempo automáticas Network Time Protocol (NTP) e Network Identity and Time Zone (NITZ). Por padrão, no Android 12 ou versões mais recentes, o framework prioriza o NTP como a fonte de tempo em vez do NITZ, porque ele é mais preciso e confiável do que o NITZ. Em situações em que o NTP não está disponível, a estrutura usa NITZ. Isso é uma inversão da prioridade padrão em relação às versões anteriores da plataforma. Por padrão, no Android 11 e versões anteriores, o framework prioriza o NITZ em vez de NTP.
Para mais detalhes sobre essa mudança, consulte os seguintes patches do AOSP: 1563678, 1513323 (links em inglês).
Configurar a prioridade da fonte de horário
Para configurar qual origem de tempo tem prioridade por padrão para uma versão
específica do Android, configure a chave
config_autoTimeSourcesPriority
em frameworks/base/core/res/res/values/config.xml
durante o build. As sugestões de horário da fonte com o valor mais alto na lista têm precedência sobre as fontes com valores mais baixos na lista.
As origens de horário do Android que podem ser configuradas são encontradas em
TimeDetectorStrategy.java
.
As origens a seguir estão configuradas para uso por padrão:
- Telefonia (NITZ)
- Rede (NTP)
Testes
Para verificar se o dispositivo usa o NITZ quando ele não está disponível (quando os dados móveis e o Wi-Fi estão desativados), faça o seguinte:
- Verifique se há um chip funcionando no DUT
- Desative os dados móveis e o Wi-Fi
- Coloque o dispositivo no modo avião para verificar se o rádio celular está desligado
- Desativar a detecção automática de tempo
- Definir o relógio manualmente para um valor de hora incorreto no futuro
- Reinicialize o dispositivo.
- Ativar a detecção automática de tempo
- Tire o dispositivo do modo avião
Estas etapas acionam uma mudança no relógio do sistema assim que um sinal NITZ é recebido. Para conferir como o horário do dispositivo está definido, execute o comando abaixo:
adb shell dumpsys time_detector
Para verificar se o relógio do sistema usa o NITZ, confirme o seguinte na resposta ao comando:
- A
mEnvironment.isAutoTimeDetectionEnabled()
estátrue
. mEnvironment.autoOriginPriorities()
contém uma lista de fontes de horário em que as fontes mais altas na lista têm precedência sobre as fontes mais baixas na lista.- A seção
Time change log
mostra que o relógio do sistema está definido usando uma sugestão de telefonia. - A seção
Telephony suggestion history
contém sugestões de horários. - A seção
Network suggestion history
está vazia.
As sugestões de horário nas seções Telephony suggestion history
e
Network suggestion history
são consideradas a fonte da verdade para o
tempo. Se o dispositivo estiver conectado à Internet e tiver um chip, as sugestões
serão geradas usando NTP (rede) e NITZ (telefonia). Neste caso de teste,
somente a seção Telephony suggestion history
contém sugestões porque
o NTP está desativado.
A seção Time change log
registra as mudanças feitas no relógio
do sistema do dispositivo e a sugestão usada. O relógio do sistema é definido com base na
ordem das fontes de horário na lista de prioridades na
chave config_autoTimeSourcesPriority
. No entanto, as sugestões de uma
fonte de prioridade mais alta poderão ser ignoradas se a sugestão for muito antiga ou inválida.
Além disso, se a sugestão válida de maior prioridade corresponder ao horário do relógio
do sistema atual do dispositivo em alguns segundos, o horário não vai ser mudado.
Nesse caso de teste, desde que as sugestões não estejam desatualizadas, o relógio do sistema
será definido usando uma das sugestões do Telephony suggestion history
.
Confira abaixo um exemplo de saída em que o dispositivo volta a usar o NITZ quando o NTP está indisponível.
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}
Para referência como uma comparação com a saída no cenário de teste, veja a seguir um exemplo de saída típica em que o dispositivo recebe sugestões de horário de fontes de horário NTP e 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}