چارچوب اندروید از منابع زمانی مختلفی برای همگامسازی زمان استفاده میکند. این صفحه بر روی منابع زمانی خودکار پروتکل زمان شبکه (NTP) و هویت شبکه و منطقه زمانی (NITZ) تمرکز دارد. به طور پیشفرض در اندروید ۱۲ یا بالاتر، چارچوب NTP را به عنوان منبع زمان نسبت به NITZ در اولویت قرار میدهد زیرا NTP دقیقتر و قابل اعتمادتر از NITZ است. در شرایطی که NTP در دسترس نباشد، چارچوب به NITZ روی میآورد. این یک تغییر اولویت پیشفرض از نسخههای قبلی پلتفرم است. به طور پیشفرض در اندروید ۱۱ و پایینتر، چارچوب NITZ را نسبت به NTP در اولویت قرار میدهد.
برای جزئیات بیشتر در مورد این تغییر، به وصلههای AOSP زیر مراجعه کنید: 1563678 ، 1513323 .
پیکربندی اولویت منبع زمان
برای پیکربندی اینکه کدام منبع زمانی به طور پیشفرض برای یک نسخه خاص اندروید اولویت دارد، کلید config_autoTimeSourcesPriority را در frameworks/base/core/res/res/values/config.xml در زمان ساخت پیکربندی کنید. پیشنهادهای زمانی از منبع زمانی که در لیست بالاتر است، نسبت به منابعی که در لیست پایینتر هستند، اولویت دارند.
منابع زمان اندروید که میتوانند پیکربندی شوند، در TimeDetectorStrategy.java یافت میشوند. منابع زیر به طور پیشفرض برای استفاده پیکربندی شدهاند:
- تلفن (NITZ)
- شبکه (NTP)
آزمایش
برای تأیید اینکه دستگاه از NITZ استفاده میکند وقتی NTP در دسترس نیست (وقتی داده تلفن همراه و Wi-Fi غیرفعال هستند)، موارد زیر را انجام دهید:
- مطمئن شوید که سیمکارت سالمی در دستگاه DUT وجود دارد.
- داده تلفن همراه و وایفای را خاموش کنید
- دستگاه را در حالت هواپیما قرار دهید تا مطمئن شوید که رادیوی سلولی خاموش است.
- تشخیص خودکار زمان را غیرفعال کنید
- در آینده ساعت را به صورت دستی روی مقدار زمانی نادرست تنظیم کنید
- دستگاه را دوباره راه اندازی کنید
- تشخیص خودکار زمان را روشن کنید
- دستگاه را از حالت هواپیما خارج کنید
این مراحل به محض دریافت سیگنال 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 تنظیم میشود.
در ادامه مثالی از خروجی آمده است که در آن دستگاه در صورت عدم دسترسی به 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}