Prioridad de la fuente de tiempo

El framework de Android usa varias fuentes de tiempo para la sincronización de la hora. 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 fuente de hora sobre NITZ, ya que NTP es más preciso y confiable que NITZ. En situaciones en las que NTP no está disponible, el framework recurre a NITZ. Esta es una reversión de la prioridad predeterminada de las 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 tiempo que está más arriba en la lista tienen prioridad sobre las fuentes que se encuentran más abajo en la lista.

Las fuentes de hora de Android que se pueden configurar se encuentran en TimeDetectorStrategy.java. Las siguientes fuentes están configuradas para usarse 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 el 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 el Wi-Fi
  3. Pon el dispositivo en modo de avión para asegurarte de que la radio móvil esté desactivada.
  4. Cómo desactivar la detección automática de la hora
  5. Configurar el reloj manualmente con 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 NITZ. Para comprobar la configuración de 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() está true.
  • mEnvironment.autoOriginPriorities() contiene una lista de fuentes de tiempo con fuentes más altas en la lista que tienen prioridad sobre las fuentes que están más abajo.
  • En la sección Time change log, se muestra que el reloj del sistema se configura con una sugerencia de telefonía.
  • La sección Telephony suggestion history contiene sugerencias de horarios.
  • La sección Network suggestion history está vacía.

Las sugerencias de horarios en las secciones Telephony suggestion history y Network suggestion history se consideran la fuente de confianza para el tiempo. 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.

En la sección Time change log, se registran los cambios realizados en el reloj del sistema del dispositivo y la sugerencia usada. El reloj del sistema se configura en función del orden de las fuentes de tiempo que figuran en la lista de prioridades de la clave config_autoTimeSourcesPriority. Sin embargo, es posible que se ignoren las sugerencias de una fuente de mayor prioridad si la sugerencia es demasiado antigua o no es válida. 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 configurará con una de las sugerencias de Telephony suggestion history.

El siguiente es un ejemplo de una salida en la que el dispositivo recurre a usar 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}