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

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

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

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

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

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

  • تلفن (NITZ)
  • شبکه (NTP)

آزمایش کردن

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

  1. مطمئن شوید که یک سیم کارت در DUT کار می کند
  2. داده تلفن همراه و وای فای را خاموش کنید
  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 حاوی پیشنهادات است زیرا NTP غیرفعال است.

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

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

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}