Android フレームワークでは、時刻の同期にさまざまなタイムソースが使用されます。ここでは、NTP(ネットワーク タイム プロトコル)と NITZ(ネットワーク ID とタイムゾーン)の自動タイムソースについて説明します。Android 12 以降では、デフォルトでタイムソースとして NITZ よりも NTP が優先されます(NTP の方が NITZ よりも正確で信頼性が高いため)。NTP が使用できない状況では、NITZ にフォールバックされます。以前のバージョンのプラットフォームとは、デフォルトの優先度が逆になっています。Android 11 以前では、デフォルトで NTP より NITZ が優先されます。
この変更の詳細については、AOSP パッチの 1563678 と 1513323 をご覧ください。
タイムソースの優先度を設定する
特定のバージョンの Android でデフォルトで優先されるタイムソースを設定するには、ビルド時に frameworks/base/core/res/res/values/config.xml
の config_autoTimeSourcesPriority
キーを設定します。リスト内で上位にあるタイムソースからの提案は、下位にあるソースよりも優先されます。
設定可能な Android のタイムソースは TimeDetectorStrategy.java
に記載されています。デフォルトで以下のソースが使用されるように設定されています。
- テレフォニー(NITZ)
- ネットワーク(NTP)
テスト
NTP を利用できないとき(モバイルデータと Wi-Fi が無効になっているとき)に、デバイスで NITZ が使用されていることを確認するには、以下の手順に沿って行ってください。
- DUT に正常な SIM が挿入されていることを確認します。
- モバイルデータと 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(テレフォニー)の両方を使用して生成されます。このテストケースでは、NTP が無効になっているため、Telephony suggestion history
セクションのみに提案が含まれています。
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}