NetworkTimeUpdateServicepublic class NetworkTimeUpdateService extends Object Monitors the network time and updates the system time if it is out of sync
and there hasn't been any NITZ update from the carrier recently.
If looking up the network time fails for some reason, it tries a few times with a short
interval and then resets to checking on longer intervals.
If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't
available.
|
Fields Summary |
---|
private static final String | TAG | private static final boolean | DBG | private static final int | EVENT_AUTO_TIME_CHANGED | private static final int | EVENT_POLL_NETWORK_TIME | private static final int | EVENT_NETWORK_CHANGED | private static final String | ACTION_POLL | private static int | POLL_REQUEST | private static final long | NOT_SET | private long | mNitzTimeSetTime | private long | mNitzZoneSetTime | private android.content.Context | mContext | private android.util.TrustedTime | mTime | private android.os.Handler | mHandler | private android.app.AlarmManager | mAlarmManager | private android.app.PendingIntent | mPendingPollIntent | private SettingsObserver | mSettingsObserver | private long | mLastNtpFetchTime | private final long | mPollingIntervalMs | private final long | mPollingIntervalShorterMs | private final int | mTryAgainTimesMax | private final int | mTimeErrorThresholdMs | private int | mTryAgainCounter | private android.content.BroadcastReceiver | mNitzReceiverReceiver for Nitz time events | private android.content.BroadcastReceiver | mConnectivityReceiverReceiver for ConnectivityManager events |
Constructors Summary |
---|
public NetworkTimeUpdateService(android.content.Context context)
mContext = context;
mTime = NtpTrustedTime.getInstance(context);
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Intent pollIntent = new Intent(ACTION_POLL, null);
mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
mPollingIntervalMs = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpPollingInterval);
mPollingIntervalShorterMs = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpPollingIntervalShorter);
mTryAgainTimesMax = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpRetry);
mTimeErrorThresholdMs = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpThreshold);
|
Methods Summary |
---|
private boolean | isAutomaticTimeRequested()Checks if the user prefers to automatically set the time.
return Settings.Global.getInt(
mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0;
| private void | onPollNetworkTime(int event)
// If Automatic time is not set, don't bother.
if (!isAutomaticTimeRequested()) return;
final long refTime = SystemClock.elapsedRealtime();
// If NITZ time was received less than mPollingIntervalMs time ago,
// no need to sync to NTP.
if (mNitzTimeSetTime != NOT_SET && refTime - mNitzTimeSetTime < mPollingIntervalMs) {
resetAlarm(mPollingIntervalMs);
return;
}
final long currentTime = System.currentTimeMillis();
if (DBG) Log.d(TAG, "System time = " + currentTime);
// Get the NTP time
if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + mPollingIntervalMs
|| event == EVENT_AUTO_TIME_CHANGED) {
if (DBG) Log.d(TAG, "Before Ntp fetch");
// force refresh NTP cache when outdated
if (mTime.getCacheAge() >= mPollingIntervalMs) {
mTime.forceRefresh();
}
// only update when NTP time is fresh
if (mTime.getCacheAge() < mPollingIntervalMs) {
final long ntp = mTime.currentTimeMillis();
mTryAgainCounter = 0;
// If the clock is more than N seconds off or this is the first time it's been
// fetched since boot, set the current time.
if (Math.abs(ntp - currentTime) > mTimeErrorThresholdMs
|| mLastNtpFetchTime == NOT_SET) {
// Set the system time
if (DBG && mLastNtpFetchTime == NOT_SET
&& Math.abs(ntp - currentTime) <= mTimeErrorThresholdMs) {
Log.d(TAG, "For initial setup, rtc = " + currentTime);
}
if (DBG) Log.d(TAG, "Ntp time to be set = " + ntp);
// Make sure we don't overflow, since it's going to be converted to an int
if (ntp / 1000 < Integer.MAX_VALUE) {
SystemClock.setCurrentTimeMillis(ntp);
}
} else {
if (DBG) Log.d(TAG, "Ntp time is close enough = " + ntp);
}
mLastNtpFetchTime = SystemClock.elapsedRealtime();
} else {
// Try again shortly
mTryAgainCounter++;
if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
resetAlarm(mPollingIntervalShorterMs);
} else {
// Try much later
mTryAgainCounter = 0;
resetAlarm(mPollingIntervalMs);
}
return;
}
}
resetAlarm(mPollingIntervalMs);
| private void | registerForAlarms()
mContext.registerReceiver(
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
}
}, new IntentFilter(ACTION_POLL));
| private void | registerForConnectivityIntents()
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiver(mConnectivityReceiver, intentFilter);
| private void | registerForTelephonyIntents()
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
mContext.registerReceiver(mNitzReceiver, intentFilter);
| private void | resetAlarm(long interval)Cancel old alarm and starts a new one for the specified interval.
mAlarmManager.cancel(mPendingPollIntent);
long now = SystemClock.elapsedRealtime();
long next = now + interval;
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
| public void | systemRunning()Initialize the receivers and initiate the first NTP request
registerForTelephonyIntents();
registerForAlarms();
registerForConnectivityIntents();
HandlerThread thread = new HandlerThread(TAG);
thread.start();
mHandler = new MyHandler(thread.getLooper());
// Check the network time on the new thread
mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
mSettingsObserver.observe(mContext);
|
|