Loading src/java/com/android/internal/telephony/NewNitzStateMachine.java +56 −99 Original line number Diff line number Diff line Loading @@ -43,9 +43,8 @@ public final class NewNitzStateMachine implements NitzStateMachine { // Time detection state. /** * The last NITZ-sourced time considered. If auto time detection was off at the time this may * not have been used to set the device time, but it can be used if auto time detection is * re-enabled. * The last NITZ-sourced time considered sent to the time detector service. Used to rate-limit * calls to the time detector. */ private TimestampedValue<Long> mSavedNitzTime; Loading Loading @@ -112,13 +111,6 @@ public final class NewNitzStateMachine implements NitzStateMachine { mTimeZoneLookupHelper = timeZoneLookupHelper; mTimeServiceHelper = timeServiceHelper; mTimeServiceHelper.setListener(new NewTimeServiceHelper.Listener() { @Override public void onTimeDetectionChange(boolean enabled) { if (enabled) { handleAutoTimeEnabled(); } } @Override public void onTimeZoneDetectionChange(boolean enabled) { if (enabled) { Loading Loading @@ -314,18 +306,17 @@ public final class NewNitzStateMachine implements NitzStateMachine { boolean ignoreNitz = mDeviceState.getIgnoreNitz(); if (ignoreNitz) { if (DBG) { Rlog.d(LOG_TAG, "updateTimeFromNitz: Not setting clock because gsm.ignore-nitz is set"); Rlog.d(LOG_TAG, "updateTimeFromNitz: Not suggesting system clock because" + " gsm.ignore-nitz is set"); } return; } // Validate the nitzTimeSignal to reject obviously bogus elapsedRealtime values. try { // Acquire the wake lock as we are reading the elapsed realtime clock and system // clock. // Acquire the wake lock as we are reading the elapsed realtime clock below. mWakeLock.acquire(); // Validate the nitzTimeSignal to reject obviously bogus elapsedRealtime values. long elapsedRealtime = mTimeServiceHelper.elapsedRealtime(); long millisSinceNitzReceived = elapsedRealtime - nitzSignal.getReferenceTimeMillis(); Loading @@ -337,57 +328,61 @@ public final class NewNitzStateMachine implements NitzStateMachine { } return; } } finally { mWakeLock.release(); } // Adjust the NITZ time by the delay since it was received to get the time now. long adjustedCurrentTimeMillis = nitzSignal.getValue().getCurrentTimeInMillis() + millisSinceNitzReceived; long gained = adjustedCurrentTimeMillis - mTimeServiceHelper.currentTimeMillis(); if (mTimeServiceHelper.isTimeDetectionEnabled()) { String logMsg = "updateTimeFromNitz:" + " nitzSignal=" + nitzSignal + " adjustedCurrentTimeMillis=" + adjustedCurrentTimeMillis + " millisSinceNitzReceived= " + millisSinceNitzReceived + " gained=" + gained; TimestampedValue<Long> newNitzTime = new TimestampedValue<>( nitzSignal.getReferenceTimeMillis(), nitzSignal.getValue().getCurrentTimeInMillis()); if (mSavedNitzTime == null) { logMsg += ": First update received."; setAndBroadcastNetworkSetTime(logMsg, adjustedCurrentTimeMillis); } else { long elapsedRealtimeSinceLastSaved = mTimeServiceHelper.elapsedRealtime() - mSavedNitzTime.getReferenceTimeMillis(); // Perform rate limiting: a NITZ signal received too close to a previous // one will be disregarded unless there is a significant difference between the // UTC times they represent. if (mSavedNitzTime != null) { int nitzUpdateSpacing = mDeviceState.getNitzUpdateSpacingMillis(); int nitzUpdateDiff = mDeviceState.getNitzUpdateDiffMillis(); if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing || Math.abs(gained) > nitzUpdateDiff) { // Either it has been a while since we received an update, or the gain // is sufficiently large that we want to act on it. logMsg += ": New update received."; setAndBroadcastNetworkSetTime(logMsg, adjustedCurrentTimeMillis); } else { // Calculate the elapsed time between the new signal and the last signal. long elapsedRealtimeSinceLastSaved = newNitzTime.getReferenceTimeMillis() - mSavedNitzTime.getReferenceTimeMillis(); // Calculate the UTC difference between the time the two signals hold. long utcTimeDifferenceMillis = newNitzTime.getValue() - mSavedNitzTime.getValue(); // Ideally the difference between elapsedRealtimeSinceLastSaved and // utcTimeDifferenceMillis would be zero. long millisGained = utcTimeDifferenceMillis - elapsedRealtimeSinceLastSaved; if (elapsedRealtimeSinceLastSaved <= nitzUpdateSpacing && Math.abs(millisGained) <= nitzUpdateDiff) { if (DBG) { Rlog.d(LOG_TAG, logMsg + ": Update throttled."); Rlog.d(LOG_TAG, "updateTimeFromNitz: not setting time. NITZ signal is" + " too similar to previous value received " + " mSavedNitzTime=" + mSavedNitzTime + ", nitzSignal=" + nitzSignal + ", nitzUpdateSpacing=" + nitzUpdateSpacing + ", nitzUpdateDiff=" + nitzUpdateDiff); } // Return early. This means that we don't reset the // mSavedNitzTime for next time and that we may act on more // NITZ time signals overall but should end up with a system clock that // tracks NITZ more closely than if we saved throttled values (which // would reset mSavedNitzTime.elapsedRealtime used to calculate time // since the last NITZ signal was received). return; } } } // Save the last NITZ time signal used so we can return to it later // if auto-time detection is toggled. mSavedNitzTime = new TimestampedValue<>( nitzSignal.getReferenceTimeMillis(), nitzSignal.getValue().getCurrentTimeInMillis()); } finally { mWakeLock.release(); String logMsg = "updateTimeFromNitz: suggesting system clock update" + " nitzSignal=" + nitzSignal + ", newNitzTime=" + newNitzTime + ", mSavedNitzTime= " + mSavedNitzTime; if (DBG) { Rlog.d(LOG_TAG, logMsg); } mTimeLog.log(logMsg); mTimeServiceHelper.suggestDeviceTime(newNitzTime); TelephonyMetrics.getInstance().writeNITZEvent( mPhone.getPhoneId(), newNitzTime.getValue()); // Save the last NITZ time signal that was suggested to enable rate limiting. mSavedNitzTime = newNitzTime; } catch (RuntimeException ex) { Rlog.e(LOG_TAG, "updateTimeFromNitz: Processing NITZ data" + " nitzSignal=" + nitzSignal Loading @@ -407,44 +402,6 @@ public final class NewNitzStateMachine implements NitzStateMachine { } } private void setAndBroadcastNetworkSetTime(String msg, long time) { if (!mWakeLock.isHeld()) { Rlog.w(LOG_TAG, "setAndBroadcastNetworkSetTime: Wake lock not held while setting device" + " time (msg=" + msg + ")"); } msg = "setAndBroadcastNetworkSetTime: [Setting time to time=" + time + "]:" + msg; if (DBG) { Rlog.d(LOG_TAG, msg); } mTimeLog.log(msg); mTimeServiceHelper.setDeviceTime(time); TelephonyMetrics.getInstance().writeNITZEvent(mPhone.getPhoneId(), time); } private void handleAutoTimeEnabled() { if (DBG) { Rlog.d(LOG_TAG, "handleAutoTimeEnabled: Reverting to NITZ Time:" + " mSavedNitzTime=" + mSavedNitzTime); } if (mSavedNitzTime != null) { try { // Acquire the wakelock as we're reading the elapsed realtime clock here. mWakeLock.acquire(); long elapsedRealtime = mTimeServiceHelper.elapsedRealtime(); String msg = "mSavedNitzTime: Reverting to NITZ time" + " elapsedRealtime=" + elapsedRealtime + " mSavedNitzTime=" + mSavedNitzTime; long adjustedCurrentTimeMillis = mSavedNitzTime.getValue() + (elapsedRealtime - mSavedNitzTime.getReferenceTimeMillis()); setAndBroadcastNetworkSetTime(msg, adjustedCurrentTimeMillis); } finally { mWakeLock.release(); } } } private void handleAutoTimeZoneEnabled() { String tmpLog = "handleAutoTimeZoneEnabled: Reverting to NITZ TimeZone:" + " mSavedTimeZoneId=" + mSavedTimeZoneId; Loading src/java/com/android/internal/telephony/NewTimeServiceHelper.java +10 −32 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.internal.telephony; import android.app.AlarmManager; import android.app.timedetector.TimeDetector; import android.app.timedetector.TimeSignal; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; Loading @@ -26,6 +28,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.util.TimestampedValue; /** * An interface to various time / time zone detection behaviors that should be centralized into a Loading @@ -38,11 +41,6 @@ public class NewTimeServiceHelper { * Callback interface for automatic detection enable/disable changes. */ public interface Listener { /** * Automatic time detection has been enabled or disabled. */ void onTimeDetectionChange(boolean enabled); /** * Automatic time zone detection has been enabled or disabled. */ Loading @@ -53,6 +51,7 @@ public class NewTimeServiceHelper { private final Context mContext; private final ContentResolver mCr; private final TimeDetector mTimeDetector; private Listener mListener; Loading @@ -60,6 +59,7 @@ public class NewTimeServiceHelper { public NewTimeServiceHelper(Context context) { mContext = context; mCr = context.getContentResolver(); mTimeDetector = context.getSystemService(TimeDetector.class); } /** Loading @@ -74,13 +74,6 @@ public class NewTimeServiceHelper { throw new IllegalStateException("listener already set"); } this.mListener = listener; mCr.registerContentObserver( Settings.Global.getUriFor(Settings.Global.AUTO_TIME), true, new ContentObserver(new Handler()) { public void onChange(boolean selfChange) { listener.onTimeDetectionChange(isTimeDetectionEnabled()); } }); mCr.registerContentObserver( Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE), true, new ContentObserver(new Handler()) { Loading Loading @@ -112,17 +105,6 @@ public class NewTimeServiceHelper { } /** * Returns true if automatic time detection is enabled in settings. */ public boolean isTimeDetectionEnabled() { try { return Settings.Global.getInt(mCr, Settings.Global.AUTO_TIME) > 0; } catch (Settings.SettingNotFoundException snfe) { return true; } } /** * Returns true if automatic time zone detection is enabled in settings. */ Loading @@ -145,17 +127,13 @@ public class NewTimeServiceHelper { } /** * Set the time and Send out a sticky broadcast so the system can determine * if the time was set by the carrier. * Suggest the time to the {@link TimeDetector}. * * @param time time set by network * @param signalTimeMillis the signal time as received from the network */ public void setDeviceTime(long time) { SystemClock.setCurrentTimeMillis(time); Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra("time", time); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); public void suggestDeviceTime(TimestampedValue<Long> signalTimeMillis) { TimeSignal timeSignal = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, signalTimeMillis); mTimeDetector.suggestTime(timeSignal); } /** Loading tests/telephonytests/src/com/android/internal/telephony/NewNitzStateMachineTest.java +54 −194 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/java/com/android/internal/telephony/NewNitzStateMachine.java +56 −99 Original line number Diff line number Diff line Loading @@ -43,9 +43,8 @@ public final class NewNitzStateMachine implements NitzStateMachine { // Time detection state. /** * The last NITZ-sourced time considered. If auto time detection was off at the time this may * not have been used to set the device time, but it can be used if auto time detection is * re-enabled. * The last NITZ-sourced time considered sent to the time detector service. Used to rate-limit * calls to the time detector. */ private TimestampedValue<Long> mSavedNitzTime; Loading Loading @@ -112,13 +111,6 @@ public final class NewNitzStateMachine implements NitzStateMachine { mTimeZoneLookupHelper = timeZoneLookupHelper; mTimeServiceHelper = timeServiceHelper; mTimeServiceHelper.setListener(new NewTimeServiceHelper.Listener() { @Override public void onTimeDetectionChange(boolean enabled) { if (enabled) { handleAutoTimeEnabled(); } } @Override public void onTimeZoneDetectionChange(boolean enabled) { if (enabled) { Loading Loading @@ -314,18 +306,17 @@ public final class NewNitzStateMachine implements NitzStateMachine { boolean ignoreNitz = mDeviceState.getIgnoreNitz(); if (ignoreNitz) { if (DBG) { Rlog.d(LOG_TAG, "updateTimeFromNitz: Not setting clock because gsm.ignore-nitz is set"); Rlog.d(LOG_TAG, "updateTimeFromNitz: Not suggesting system clock because" + " gsm.ignore-nitz is set"); } return; } // Validate the nitzTimeSignal to reject obviously bogus elapsedRealtime values. try { // Acquire the wake lock as we are reading the elapsed realtime clock and system // clock. // Acquire the wake lock as we are reading the elapsed realtime clock below. mWakeLock.acquire(); // Validate the nitzTimeSignal to reject obviously bogus elapsedRealtime values. long elapsedRealtime = mTimeServiceHelper.elapsedRealtime(); long millisSinceNitzReceived = elapsedRealtime - nitzSignal.getReferenceTimeMillis(); Loading @@ -337,57 +328,61 @@ public final class NewNitzStateMachine implements NitzStateMachine { } return; } } finally { mWakeLock.release(); } // Adjust the NITZ time by the delay since it was received to get the time now. long adjustedCurrentTimeMillis = nitzSignal.getValue().getCurrentTimeInMillis() + millisSinceNitzReceived; long gained = adjustedCurrentTimeMillis - mTimeServiceHelper.currentTimeMillis(); if (mTimeServiceHelper.isTimeDetectionEnabled()) { String logMsg = "updateTimeFromNitz:" + " nitzSignal=" + nitzSignal + " adjustedCurrentTimeMillis=" + adjustedCurrentTimeMillis + " millisSinceNitzReceived= " + millisSinceNitzReceived + " gained=" + gained; TimestampedValue<Long> newNitzTime = new TimestampedValue<>( nitzSignal.getReferenceTimeMillis(), nitzSignal.getValue().getCurrentTimeInMillis()); if (mSavedNitzTime == null) { logMsg += ": First update received."; setAndBroadcastNetworkSetTime(logMsg, adjustedCurrentTimeMillis); } else { long elapsedRealtimeSinceLastSaved = mTimeServiceHelper.elapsedRealtime() - mSavedNitzTime.getReferenceTimeMillis(); // Perform rate limiting: a NITZ signal received too close to a previous // one will be disregarded unless there is a significant difference between the // UTC times they represent. if (mSavedNitzTime != null) { int nitzUpdateSpacing = mDeviceState.getNitzUpdateSpacingMillis(); int nitzUpdateDiff = mDeviceState.getNitzUpdateDiffMillis(); if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing || Math.abs(gained) > nitzUpdateDiff) { // Either it has been a while since we received an update, or the gain // is sufficiently large that we want to act on it. logMsg += ": New update received."; setAndBroadcastNetworkSetTime(logMsg, adjustedCurrentTimeMillis); } else { // Calculate the elapsed time between the new signal and the last signal. long elapsedRealtimeSinceLastSaved = newNitzTime.getReferenceTimeMillis() - mSavedNitzTime.getReferenceTimeMillis(); // Calculate the UTC difference between the time the two signals hold. long utcTimeDifferenceMillis = newNitzTime.getValue() - mSavedNitzTime.getValue(); // Ideally the difference between elapsedRealtimeSinceLastSaved and // utcTimeDifferenceMillis would be zero. long millisGained = utcTimeDifferenceMillis - elapsedRealtimeSinceLastSaved; if (elapsedRealtimeSinceLastSaved <= nitzUpdateSpacing && Math.abs(millisGained) <= nitzUpdateDiff) { if (DBG) { Rlog.d(LOG_TAG, logMsg + ": Update throttled."); Rlog.d(LOG_TAG, "updateTimeFromNitz: not setting time. NITZ signal is" + " too similar to previous value received " + " mSavedNitzTime=" + mSavedNitzTime + ", nitzSignal=" + nitzSignal + ", nitzUpdateSpacing=" + nitzUpdateSpacing + ", nitzUpdateDiff=" + nitzUpdateDiff); } // Return early. This means that we don't reset the // mSavedNitzTime for next time and that we may act on more // NITZ time signals overall but should end up with a system clock that // tracks NITZ more closely than if we saved throttled values (which // would reset mSavedNitzTime.elapsedRealtime used to calculate time // since the last NITZ signal was received). return; } } } // Save the last NITZ time signal used so we can return to it later // if auto-time detection is toggled. mSavedNitzTime = new TimestampedValue<>( nitzSignal.getReferenceTimeMillis(), nitzSignal.getValue().getCurrentTimeInMillis()); } finally { mWakeLock.release(); String logMsg = "updateTimeFromNitz: suggesting system clock update" + " nitzSignal=" + nitzSignal + ", newNitzTime=" + newNitzTime + ", mSavedNitzTime= " + mSavedNitzTime; if (DBG) { Rlog.d(LOG_TAG, logMsg); } mTimeLog.log(logMsg); mTimeServiceHelper.suggestDeviceTime(newNitzTime); TelephonyMetrics.getInstance().writeNITZEvent( mPhone.getPhoneId(), newNitzTime.getValue()); // Save the last NITZ time signal that was suggested to enable rate limiting. mSavedNitzTime = newNitzTime; } catch (RuntimeException ex) { Rlog.e(LOG_TAG, "updateTimeFromNitz: Processing NITZ data" + " nitzSignal=" + nitzSignal Loading @@ -407,44 +402,6 @@ public final class NewNitzStateMachine implements NitzStateMachine { } } private void setAndBroadcastNetworkSetTime(String msg, long time) { if (!mWakeLock.isHeld()) { Rlog.w(LOG_TAG, "setAndBroadcastNetworkSetTime: Wake lock not held while setting device" + " time (msg=" + msg + ")"); } msg = "setAndBroadcastNetworkSetTime: [Setting time to time=" + time + "]:" + msg; if (DBG) { Rlog.d(LOG_TAG, msg); } mTimeLog.log(msg); mTimeServiceHelper.setDeviceTime(time); TelephonyMetrics.getInstance().writeNITZEvent(mPhone.getPhoneId(), time); } private void handleAutoTimeEnabled() { if (DBG) { Rlog.d(LOG_TAG, "handleAutoTimeEnabled: Reverting to NITZ Time:" + " mSavedNitzTime=" + mSavedNitzTime); } if (mSavedNitzTime != null) { try { // Acquire the wakelock as we're reading the elapsed realtime clock here. mWakeLock.acquire(); long elapsedRealtime = mTimeServiceHelper.elapsedRealtime(); String msg = "mSavedNitzTime: Reverting to NITZ time" + " elapsedRealtime=" + elapsedRealtime + " mSavedNitzTime=" + mSavedNitzTime; long adjustedCurrentTimeMillis = mSavedNitzTime.getValue() + (elapsedRealtime - mSavedNitzTime.getReferenceTimeMillis()); setAndBroadcastNetworkSetTime(msg, adjustedCurrentTimeMillis); } finally { mWakeLock.release(); } } } private void handleAutoTimeZoneEnabled() { String tmpLog = "handleAutoTimeZoneEnabled: Reverting to NITZ TimeZone:" + " mSavedTimeZoneId=" + mSavedTimeZoneId; Loading
src/java/com/android/internal/telephony/NewTimeServiceHelper.java +10 −32 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.internal.telephony; import android.app.AlarmManager; import android.app.timedetector.TimeDetector; import android.app.timedetector.TimeSignal; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; Loading @@ -26,6 +28,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.util.TimestampedValue; /** * An interface to various time / time zone detection behaviors that should be centralized into a Loading @@ -38,11 +41,6 @@ public class NewTimeServiceHelper { * Callback interface for automatic detection enable/disable changes. */ public interface Listener { /** * Automatic time detection has been enabled or disabled. */ void onTimeDetectionChange(boolean enabled); /** * Automatic time zone detection has been enabled or disabled. */ Loading @@ -53,6 +51,7 @@ public class NewTimeServiceHelper { private final Context mContext; private final ContentResolver mCr; private final TimeDetector mTimeDetector; private Listener mListener; Loading @@ -60,6 +59,7 @@ public class NewTimeServiceHelper { public NewTimeServiceHelper(Context context) { mContext = context; mCr = context.getContentResolver(); mTimeDetector = context.getSystemService(TimeDetector.class); } /** Loading @@ -74,13 +74,6 @@ public class NewTimeServiceHelper { throw new IllegalStateException("listener already set"); } this.mListener = listener; mCr.registerContentObserver( Settings.Global.getUriFor(Settings.Global.AUTO_TIME), true, new ContentObserver(new Handler()) { public void onChange(boolean selfChange) { listener.onTimeDetectionChange(isTimeDetectionEnabled()); } }); mCr.registerContentObserver( Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE), true, new ContentObserver(new Handler()) { Loading Loading @@ -112,17 +105,6 @@ public class NewTimeServiceHelper { } /** * Returns true if automatic time detection is enabled in settings. */ public boolean isTimeDetectionEnabled() { try { return Settings.Global.getInt(mCr, Settings.Global.AUTO_TIME) > 0; } catch (Settings.SettingNotFoundException snfe) { return true; } } /** * Returns true if automatic time zone detection is enabled in settings. */ Loading @@ -145,17 +127,13 @@ public class NewTimeServiceHelper { } /** * Set the time and Send out a sticky broadcast so the system can determine * if the time was set by the carrier. * Suggest the time to the {@link TimeDetector}. * * @param time time set by network * @param signalTimeMillis the signal time as received from the network */ public void setDeviceTime(long time) { SystemClock.setCurrentTimeMillis(time); Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra("time", time); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); public void suggestDeviceTime(TimestampedValue<Long> signalTimeMillis) { TimeSignal timeSignal = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, signalTimeMillis); mTimeDetector.suggestTime(timeSignal); } /** Loading
tests/telephonytests/src/com/android/internal/telephony/NewNitzStateMachineTest.java +54 −194 File changed.Preview size limit exceeded, changes collapsed. Show changes