מסגרת Android משתמשת במקורות זמן שונים לסנכרון הזמן. הדף הזה מתמקד במקורות הזמן האוטומטיים של Network Time Protocol (NTP) ו-Network Identity and Time Zone (NITZ). כברירת מחדל ב-Android 12 ואילך, המסגרת נותנת עדיפות ל-NTP כמקור הזמן על פני NITZ, כי NTP מדויק ומהימן יותר מ-NITZ. במצבים שבהם NTP לא זמין, המסגרת חוזרת ל-NITS. זוהי חזרה לאחור של סדר העדיפויות שמוגדר כברירת מחדל בגרסאות קודמות של הפלטפורמה. כברירת מחדל, ב-Android מגרסה 11 ומטה, המערכת נותנת עדיפות ל-Nitz על פני NTP.
פרטים נוספים על השינוי הזה זמינים בתיקוני ה-AOSP הבאים: 1563678, 1513323.
הגדרת העדיפות של מקור הזמן
כדי להגדיר איזה מקור זמן יקבל עדיפות כברירת מחדל בגרסה ספציפית של Android, מגדירים את המפתח config_autoTimeSourcesPriority
ב-frameworks/base/core/res/res/values/config.xml
בזמן ה-build. הצעות לזמנים ממקור הזמן שנמצא גבוה יותר ברשימה מקבלות קדימות על פני מקורות שנמצאים נמוך יותר ברשימה.
מקורות הזמן של Android שאפשר להגדיר נמצאים בקטע TimeDetectorStrategy.java
.
המקורות הבאים מוגדרים לשימוש כברירת מחדל:
- טלפוניה (NITZ)
- רשת (NTP)
בדיקה
כדי לוודא שהמכשיר משתמש ב-Nitz כש-NTP לא זמין (כשחבילת הגלישה וה-Wi-Fi מושבתים), מבצעים את הפעולות הבאות:
- מוודאים שיש כרטיס SIM תקין ב-DUT
- משביתים את חבילת הגלישה ואת ה-Wi-Fi
- מעבירים את המכשיר למצב טיסה כדי לוודא שהרדיו הסלולרי כבוי
- השבתת הזיהוי האוטומטי של השעה
- מגדירים את השעון באופן ידני לערך שגוי של שעה בעתיד
- הפעלת המכשיר מחדש
- הפעלת זיהוי הזמן האוטומטי
- הוצאת המכשיר ממצב טיסה
השלבים האלה מפעילים שינוי בשעון המערכת ברגע שמתקבל אות 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
נחשבות למקור המידע האמין לגבי הזמן. אם המכשיר מחובר לאינטרנט ויש בו כרטיס SIM, ההצעות נוצרות באמצעות 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}