সময় উৎস অগ্রাধিকার

অ্যান্ড্রয়েড ফ্রেমওয়ার্ক সময় সিঙ্ক্রোনাইজেশনের জন্য বিভিন্ন টাইম সোর্স ব্যবহার করে। এই পৃষ্ঠাটি নেটওয়ার্ক টাইম প্রোটোকল (NTP) এবং নেটওয়ার্ক আইডেন্টিটি অ্যান্ড টাইম জোন (NITZ) নামক স্বয়ংক্রিয় টাইম সোর্সগুলোর উপর আলোকপাত করে। অ্যান্ড্রয়েড ১২ বা তার পরবর্তী সংস্করণগুলোতে ডিফল্টভাবে, ফ্রেমওয়ার্ক NITZ-এর চেয়ে NTP-কে টাইম সোর্স হিসেবে অগ্রাধিকার দেয়, কারণ NTP, NITZ-এর চেয়ে বেশি নির্ভুল এবং নির্ভরযোগ্য। যেসব ক্ষেত্রে NTP উপলব্ধ থাকে না, তখন ফ্রেমওয়ার্ক NITZ ব্যবহার করে। এটি প্ল্যাটফর্মের পূর্ববর্তী সংস্করণগুলোর ডিফল্ট অগ্রাধিকারের একটি বিপরীত প্রক্রিয়া। অ্যান্ড্রয়েড ১১ এবং তার পূর্ববর্তী সংস্করণগুলোতে ডিফল্টভাবে, ফ্রেমওয়ার্ক NTP-এর চেয়ে NITZ-কে অগ্রাধিকার দেয়।

এই পরিবর্তন সম্পর্কে আরও বিস্তারিত জানতে, নিম্নলিখিত AOSP প্যাচগুলি দেখুন: 1563678 , 1513323

সময় উৎসের অগ্রাধিকার কনফিগার করুন

একটি নির্দিষ্ট অ্যান্ড্রয়েড সংস্করণের জন্য ডিফল্টরূপে কোন সময় উৎস অগ্রাধিকার পাবে তা কনফিগার করতে, বিল্ড করার সময় frameworks/base/core/res/res/values/config.xml ফাইলে config_autoTimeSourcesPriority কী-টি কনফিগার করুন। তালিকার উপরের দিকে থাকা সময় উৎস থেকে আসা সময়ের পরামর্শ, তালিকার নিচের দিকের উৎসগুলোর চেয়ে অগ্রাধিকার পায়।

কনফিগার করা যায় এমন অ্যান্ড্রয়েড টাইম সোর্সগুলো TimeDetectorStrategy.java ফাইলে পাওয়া যায়। ডিফল্টরূপে ব্যবহারের জন্য নিম্নলিখিত সোর্সগুলো কনফিগার করা থাকে:

  • টেলিফোনি (NITZ)
  • নেটওয়ার্ক (এনটিপি)

পরীক্ষা

যখন NTP উপলব্ধ থাকে না (যখন মোবাইল ডেটা এবং Wi-Fi নিষ্ক্রিয় থাকে), তখন ডিভাইসটি NITZ ব্যবহার করে কিনা তা যাচাই করতে নিম্নলিখিতগুলি করুন:

  1. ডিইউটি-তে একটি সচল সিম আছে কিনা তা নিশ্চিত করুন।
  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 থেকে যেকোনো একটি সাজেশন ব্যবহার করে সিস্টেম ক্লক সেট করা হয়।

নিম্নলিখিতটি এমন একটি আউটপুটের উদাহরণ যেখানে 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}