أولوية مصدر الوقت

يستخدم إطار عمل 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 (عند تعطيل بيانات الهاتف المحمول وWi-Fi)، قم بما يلي:

  1. تأكد من وجود بطاقة SIM عاملة في DUT
  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 مصدر الحقيقة للوقت. إذا كان الجهاز متصلاً بالإنترنت ويحتوي على بطاقة 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}