Prioridad de la fuente de tiempo

El framework de Android usa varias fuentes de tiempo para la sincronización. En esta página, se describen las fuentes de hora automáticas del protocolo NTP y de identidad de red y zona horaria (NITZ). De forma predeterminada, en Android 12 o versiones posteriores, el framework prioriza NTP como la fuente de tiempo sobre NITZ porque NTP es más precisa y confiable que NITZ. En situaciones en las que NTP no está disponible, el framework recurre a NITZ. Esta es una inversión de la prioridad predeterminada de versiones anteriores de la plataforma. De forma predeterminada, en Android 11 y versiones anteriores, el framework prioriza NITZ sobre NTP.

Para obtener más detalles sobre este cambio, consulta los siguientes parches de AOSP: 1563678 y 1513323.

Configura la prioridad de la fuente de tiempo

Para configurar qué fuente de tiempo tiene prioridad de forma predeterminada para una versión específica de Android, configura la clave config_autoTimeSourcesPriority en frameworks/base/core/res/res/values/config.xml durante el tiempo de compilación. Las sugerencias de hora de la fuente de hora que está más arriba en la lista tienen prioridad sobre las fuentes que están más abajo en la lista.

Las fuentes de tiempo de Android que se pueden configurar se encuentran en TimeDetectorStrategy.java. Las siguientes fuentes se configuran para su uso de forma predeterminada:

  • Telefonía (NITZ)
  • Red (NTP)

Prueba

Para verificar que el dispositivo use NITZ cuando NTP no esté disponible (cuando los datos móviles y Wi-Fi estén inhabilitados), haz lo siguiente:

  1. Asegúrate de que haya una SIM que funcione en el DUT.
  2. Cómo desactivar los datos móviles y la conexión Wi-Fi
  3. Pon el dispositivo en modo de avión para asegurarte de que la radio celular esté desactivada.
  4. Cómo desactivar la detección automática de la hora
  5. Configura el reloj manualmente en un valor de hora incorrecto en el futuro
  6. Reinicia el dispositivo
  7. Cómo activar la detección automática de la hora
  8. Desactiva el modo de avión en el dispositivo

Estos pasos activan un cambio en el reloj del sistema en cuanto se recibe una señal de NITZ. Para verificar cómo se configura la hora del dispositivo, ejecuta el siguiente comando:

adb shell dumpsys time_detector

Para verificar que el reloj del sistema use NITZ, confirma lo siguiente en el resultado del comando:

  • mEnvironment.isAutoTimeDetectionEnabled(): true.
  • mEnvironment.autoOriginPriorities() contiene una lista de fuentes de tiempo con fuentes más altas en la lista que tienen prioridad sobre las fuentes más bajas en la lista.
  • La sección Time change log muestra que el reloj del sistema se configura con una sugerencia de telefonía.
  • La sección Telephony suggestion history contiene sugerencias de tiempo.
  • La sección Network suggestion history está vacía.

Las sugerencias de hora en las secciones Telephony suggestion history y Network suggestion history se consideran la fuente de confianza para la hora. Si el dispositivo está conectado a Internet y tiene una tarjeta SIM, se generan sugerencias con NTP (red) y NITZ (telefonía). En este caso de prueba, solo la sección Telephony suggestion history contiene sugerencias porque NTP está inhabilitado.

La sección Time change log registra los cambios realizados en el reloj del sistema del dispositivo y la sugerencia que se usó. El reloj del sistema se establece según el orden de las fuentes de tiempo en la lista de prioridades de la clave config_autoTimeSourcesPriority. Sin embargo, es posible que se ignoren las sugerencias de una fuente de prioridad más alta si son demasiado antiguas o no son válidas. Además, si la sugerencia válida de prioridad más alta coincide con la hora del reloj del sistema actual del dispositivo en un par de segundos, la hora no se cambiará. En este caso de prueba, siempre que las sugerencias no estén desactualizadas, el reloj del sistema se configura con una de las sugerencias de Telephony suggestion history.

El siguiente es un ejemplo de un resultado en el que el dispositivo recurre al uso de NITZ cuando NTP no está disponible.

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}

A modo de referencia para comparar el resultado en la situación de prueba, el siguiente es un ejemplo de un resultado típico en el que el dispositivo recibe sugerencias de hora de las fuentes de tiempo NTP y 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}