اولویت منبع زمان

چارچوب Android از منابع زمانی مختلفی برای همگام‌سازی زمان استفاده می‌کند. این صفحه بر «پروتکل زمان شبکه» (NTP) و منابع زمان خودکار «منطقه زمانی و هویت شبکه» (NITZ) تمرکز دارد. به‌طور پیش‌فرض در Android 12 یا بالاتر، چارچوب NTP را به‌عنوان منبع زمان بر NITZ اولویت می‌دهد زیرا NTP دقیق‌تر و قابل‌اعتمادتر از NITZ است. در شرایطی که NTP دردسترس نباشد، چارچوب به NITZ برمی‌گردد. این تغییر اولویت پیش‌فرض از نسخه‌های قبلی پلاتفرم است. به‌طور پیش‌فرض در Android 11 و نسخه‌های پایین‌تر، چارچوب NITZ را بر NTP اولویت می‌دهد.

برای جزئیات بیشتر درباره این تغییر، تکه‌کدهای AOSP زیر را ببینید: 1563678، 1513323.

پیکربندی اولویت منبع زمان

برای پیکربندی اینکه کدام منبع زمان به‌طور پیش‌فرض برای نسخه خاصی از Android اولویت داشته باشد، کلید config_autoTimeSourcesPriority را در frameworks/base/core/res/res/values/config.xml در زمان ساخت پیکربندی کنید. پیشنهادهای زمان از منبع زمانی که در فهرست بالاتر است بر منابعی که در فهرست پایین‌تر هستند اولویت دارد.

منابع زمانی Android که می‌توانند پیکربندی شوند در TimeDetectorStrategy.java قرار دارند. منابع زیر به‌طور پیش‌فرض برای استفاده پیکربندی شده‌اند:

  • مکالمه از راه دور (NITZ)
  • شبکه (NTP)

آزمایش

برای تأیید اینکه دستگاه وقتی NTP دردسترس نیست از NITZ استفاده می‌کند (وقتی داده تلفن همراه و Wi-Fi غیرفعال است)، این کارها را انجام دهید:

  1. مطمئن شوید سیم‌کارت فعال در دستگاه تحت آزمایش وجود دارد
  2. خاموش کردن داده تلفن همراه و Wi-Fi
  3. دستگاه را در حالت هواپیما قرار دهید تا مطمئن شوید رادیو سلولی خاموش است
  4. خاموش کردن تشخیص خودکار زمان
  5. ساعت را به‌صورت دستی روی مقدار زمان نادرستی در آینده تنظیم کنید
  6. بازراه‌اندازی دستگاه
  7. روشن کردن تشخیص خودکار زمان
  8. دستگاه را از حالت هواپیما خارج کنید

این مراحل به‌محض دریافت سیگنال NITZ، تغییری در ساعت سیستم ایجاد می‌کند. برای بررسی نحوه تنظیم زمان دستگاه، فرمان زیر را اجرا کنید:

adb shell dumpsys time_detector

برای تأیید اینکه ساعت سیستم از NITZ استفاده می‌کند، موارد زیر را در خروجی فرمان تأیید کنید:

  • mEnvironment.isAutoTimeDetectionEnabled() true است.
  • ‫mEnvironment.autoOriginPriorities() حاوی فهرستی از منابع زمانی است که منابع بالاتر در فهرست بر منابع پایین‌تر در فهرست اولویت دارند.
  • بخش Time change log نشان می‌دهد که ساعت سیستم بااستفاده از پیشنهاد تلفنی تنظیم شده است.
  • بخش Telephony suggestion history حاوی پیشنهادهای زمان است.
  • بخش Network suggestion history خالی است.

پیشنهادهای زمان در بخش‌های Telephony suggestion history و Network suggestion history به‌عنوان منبع موثق برای زمان درنظر گرفته می‌شوند. اگر دستگاه به اینترنت متصل باشد و سیم‌کارت داشته باشد، پیشنهادها بااستفاده از هر دو پروتکل NTP (شبکه) و NITZ (تلفن) تولید می‌شوند. در این مورد آزمایشی، فقط بخش Telephony suggestion history حاوی پیشنهادها است زیرا «صفحه برگه جدید» غیرفعال است.

بخش Time change log تغییرات ایجادشده در ساعت سیستم دستگاه و پیشنهاد استفاده‌شده را ثبت می‌کند. ساعت سیستم براساس ترتیب منابع زمان در فهرست اولویت در کلید config_autoTimeSourcesPriority تنظیم می‌شود. بااین‌حال، اگر پیشنهاد خیلی قدیمی یا نامعتبر باشد، ممکن است پیشنهادهای منبع با اولویت بالاتر نادیده گرفته شوند. همچنین، اگر پیشنهاد معتبر با بالاترین اولویت با زمان ساعت سیستم فعلی دستگاه تا چند ثانیه مطابقت داشته باشد، زمان تغییر نخواهد کرد. در این مورد آزمایشی، تا زمانی که پیشنهادها قدیمی نباشند، ساعت سیستم بااستفاده از یکی از پیشنهادهای Telephony suggestion history تنظیم می‌شود.

در زیر نمونه‌ای از خروجی‌ای آورده شده است که در آن دستگاه درصورت دردسترس نبودن NTP، به استفاده از NITZ برمی‌گردد.

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}

برای مرجع به‌عنوان مقایسه با خروجی در سناریو آزمایش، در زیر نمونه‌ای از خروجی معمولی ارائه شده است که در آن دستگاه پیشنهادهای زمان را از هر دو منبع زمانی NTP و 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}