A estrutura do Android usa várias fontes de tempo para sincronização. Esta página se concentra no Network Time Protocol (NTP) e nas fontes de horário automáticas de identidade de rede e fuso horário (NITZ). Por padrão, no Android 12 ou versões mais recentes, o framework prioriza o NTP como fonte de horário em vez do NITZ porque o NTP é mais preciso e confiável do que o NITZ. Em situações em que o NTP não está disponível, a estrutura recorre ao NITZ. Essa é uma inversão da prioridade padrão das versões anteriores da plataforma. Por padrão, no Android 11 e em versões anteriores, o framework prioriza o NITZ em vez do NTP.
Para mais detalhes sobre essa mudança, consulte os seguintes patches do AOSP: 1563678, 1513323.
Configurar a prioridade da fonte de tempo
Para configurar qual fonte de tempo tem prioridade por padrão em uma versão específica do Android, configure a chave
config_autoTimeSourcesPriority
em frameworks/base/core/res/res/values/config.xml
no momento da build. As sugestões de horário da fonte de tempo que está mais acima na lista têm precedência sobre as fontes que estão mais abaixo.
As fontes de tempo do Android que podem ser configuradas estão em
TimeDetectorStrategy.java
.
As seguintes fontes são configuradas para uso por padrão:
- Telefonia (NITZ)
- Rede (NTP)
Teste
Para verificar se o dispositivo usa NITZ quando o NTP 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
- Desativar dados móveis e Wi-Fi
- Coloque o dispositivo no modo avião para garantir que o rádio celular esteja desativado.
- Desativar a detecção automática de horário
- Defina manualmente um valor de hora incorreto no futuro.
- Reiniciar o dispositivo
- Ativar a detecção automática de hora
- Tire o dispositivo do modo avião.
Essas etapas acionam uma mudança no relógio do sistema assim que um sinal NITZ é recebido. Para verificar como a hora do dispositivo está definida, execute o seguinte comando:
adb shell dumpsys time_detector
Para verificar se o relógio do sistema usa NITZ, confirme o seguinte na saída do comando:
- A
mEnvironment.isAutoTimeDetectionEnabled()
estátrue
. mEnvironment.autoOriginPriorities()
contém uma lista de fontes de tempo, com as fontes mais altas na lista tendo precedência sobre as fontes mais baixas.- 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ário. - 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 de verdade para o horário. 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, apenas a seção Telephony suggestion history
contém sugestões porque a NTP está desativada.
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 tempo na lista de prioridade da chave config_autoTimeSourcesPriority
. No entanto, sugestões de uma fonte de prioridade mais alta podem ser ignoradas se forem muito antigas ou inválidas.
Além disso, se a sugestão válida de maior prioridade corresponder ao horário atual do relógio do sistema do dispositivo em até alguns segundos, o horário não será alterado.
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 a seguir um exemplo de saída em que o dispositivo volta a usar NITZ quando o NTP não está disponí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 e comparação com a saída no cenário de teste, confira a seguir um exemplo de saída típica em que o dispositivo recebe sugestões de horário das 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}