Prioritas sumber waktu

Framework Android menggunakan berbagai sumber waktu untuk sinkronisasi waktu. Halaman ini berfokus pada Network Time Protocol (NTP) dan sumber waktu otomatis Network Identity and Time Zone (NITZ). Secara default di Android 12 atau yang lebih tinggi, framework membuat NTP sebagai sumber waktu yang lebih diprioritaskan daripada NITZ karena NTP lebih akurat dan andal daripada NITZ. Dalam situasi ketika NTP tidak tersedia, framework akan melakukan fallback ke NITZ. Hal ini merupakan pembalikan prioritas default dari versi platform sebelumnya. Secara default di Android 11 dan yang lebih rendah, framework memprioritaskan NITZ daripada NTP.

Untuk mengetahui detail selengkapnya tentang perubahan ini, lihat patch AOSP berikut: 1563678, 1513323.

Mengonfigurasi prioritas sumber waktu

Untuk mengonfigurasi sumber waktu mana yang diprioritaskan secara default untuk versi Android tertentu, konfigurasikan kunci config_autoTimeSourcesPriority di frameworks/base/core/res/res/values/config.xml pada waktu build. Saran waktu dari sumber waktu yang lebih tinggi dalam daftar akan diutamakan daripada sumber yang lebih rendah dalam daftar.

Sumber waktu Android yang dapat dikonfigurasi dapat ditemukan di TimeDetectorStrategy.java. Sumber berikut dikonfigurasi untuk digunakan secara default:

  • Telepon (NITZ)
  • Jaringan (NTP)

Pengujian

Untuk memverifikasi bahwa perangkat menggunakan NITZ saat NTP tidak tersedia (saat data seluler dan Wi-Fi dinonaktifkan), lakukan hal berikut:

  1. Pastikan ada SIM yang berfungsi di DUT
  2. Nonaktifkan data seluler dan Wi-Fi
  3. Aktifkan mode pesawat pada perangkat untuk memastikan radio seluler dinonaktifkan
  4. Menonaktifkan deteksi waktu otomatis
  5. Menyetel jam secara manual ke nilai waktu yang salah pada masa mendatang
  6. Mulai ulang perangkat
  7. Mengaktifkan deteksi waktu otomatis
  8. Keluar dari mode pesawat

Langkah-langkah ini memicu perubahan pada jam sistem segera setelah sinyal NITZ diterima. Untuk memeriksa cara waktu perangkat disetel, jalankan perintah berikut:

adb shell dumpsys time_detector

Untuk memverifikasi bahwa clock sistem menggunakan NITZ, konfirmasi hal berikut dalam output perintah:

  • mEnvironment.isAutoTimeDetectionEnabled() true.
  • mEnvironment.autoOriginPriorities() berisi daftar sumber waktu dengan sumber yang lebih tinggi dalam daftar lebih diutamakan daripada sumber yang lebih rendah dalam daftar.
  • Bagian Time change log menunjukkan bahwa clock sistem disetel menggunakan saran telepon.
  • Bagian Telephony suggestion history berisi saran waktu.
  • Bagian Network suggestion history kosong.

Saran waktu di bagian Telephony suggestion history dan Network suggestion history dianggap sebagai sumber kebenaran untuk waktu. Jika perangkat terhubung ke internet dan memiliki kartu SIM, saran dibuat menggunakan NTP (jaringan) dan NITZ (telefoni). Dalam kasus pengujian ini, hanya bagian Telephony suggestion history yang berisi saran karena NTP dinonaktifkan.

Bagian Time change log mencatat perubahan yang dilakukan pada jam sistem perangkat dan saran yang digunakan. Waktu sistem ditetapkan berdasarkan urutan sumber waktu dalam daftar prioritas di kunci config_autoTimeSourcesPriority. Namun, saran dari sumber dengan prioritas lebih tinggi mungkin diabaikan jika saran tersebut sudah terlalu lama atau tidak valid. Selain itu, jika saran valid dengan prioritas tertinggi cocok dengan waktu jam sistem perangkat saat ini dalam beberapa detik, waktu tidak akan diubah. Dalam kasus pengujian ini, selama saran tidak kedaluwarsa, jam sistem disetel menggunakan salah satu saran dari Telephony suggestion history.

Berikut adalah contoh output saat perangkat kembali menggunakan NITZ jika NTP tidak tersedia.

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}

Sebagai referensi untuk perbandingan dengan output dalam skenario pengujian, berikut adalah contoh output umum saat perangkat menerima saran waktu dari sumber waktu NTP dan 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}