Loading src/java/com/android/internal/telephony/NitzStateMachine.java +41 −47 Original line number Diff line number Diff line Loading @@ -56,14 +56,21 @@ public class NitzStateMachine { private static final int NITZ_UPDATE_DIFF_DEFAULT = 2000; private final int mNitzUpdateDiff; private final GsmCdmaPhone mPhone; private final TelephonyManager mTelephonyManager; private final ContentResolver mCr; public DeviceState(Context context) { public DeviceState(GsmCdmaPhone phone) { mPhone = phone; Context context = phone.getContext(); mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); mCr = context.getContentResolver(); mNitzUpdateSpacing = SystemProperties .getInt("ro.nitz_update_spacing", NITZ_UPDATE_SPACING_DEFAULT); mNitzUpdateDiff = SystemProperties .getInt("ro.nitz_update_diff", NITZ_UPDATE_DIFF_DEFAULT); mNitzUpdateSpacing = SystemProperties.getInt("ro.nitz_update_spacing", NITZ_UPDATE_SPACING_DEFAULT); mNitzUpdateDiff = SystemProperties.getInt("ro.nitz_update_diff", NITZ_UPDATE_DIFF_DEFAULT); } /** Loading Loading @@ -113,6 +120,10 @@ public class NitzStateMachine { public long elapsedRealtime() { return SystemClock.elapsedRealtime(); } public String getNetworkCountryIsoForPhone() { return mTelephonyManager.getNetworkCountryIsoForPhone(mPhone.getPhoneId()); } } private static final String LOG_TAG = ServiceStateTracker.LOG_TAG; Loading Loading @@ -166,12 +177,10 @@ public class NitzStateMachine { /** Wake lock used while setting time of day. */ private PowerManager.WakeLock mWakeLock; private static final String WAKELOCK_TAG = "NitzStateMachine"; private final ContentResolver mCr; /** Boolean is true if setTimeFromNITZ was called */ private boolean mNitzUpdatedTime = false; private final Context mContext; private final GsmCdmaPhone mPhone; private final DeviceState mDeviceState; private final TimeServiceHelper mTimeServiceHelper; Loading @@ -179,22 +188,19 @@ public class NitzStateMachine { public NitzStateMachine(GsmCdmaPhone phone) { this(phone, TelephonyComponentFactory.getInstance().makeTimeServiceHelper(phone.getContext()), new DeviceState(phone.getContext())); new DeviceState(phone)); } @VisibleForTesting public NitzStateMachine(GsmCdmaPhone phone, TimeServiceHelper timeServiceHelper, DeviceState deviceState) { mPhone = phone; Context context = phone.getContext(); mContext = context; Context context = phone.getContext(); PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG); mCr = context.getContentResolver(); mDeviceState = deviceState; mTimeServiceHelper = timeServiceHelper; mTimeServiceHelper.setListener(new TimeServiceHelper.Listener() { Loading Loading @@ -342,7 +348,7 @@ public class NitzStateMachine { private void setTimeZoneFromNitz(NitzData newNitzData, long nitzReceiveTime) { try { String iso = getNetworkCountryIsoForPhone(); String iso = mDeviceState.getNetworkCountryIsoForPhone(); TimeZone zone; if (newNitzData.getEmulatorHostTimeZone() != null) { zone = newNitzData.getEmulatorHostTimeZone(); Loading Loading @@ -448,7 +454,7 @@ public class NitzStateMachine { long adjustedCurrentTimeMillis = newNitzData.getCurrentTimeInMillis(); adjustedCurrentTimeMillis += millisSinceNitzReceived; if (!mPhone.isPhoneTypeGsm() || mTimeServiceHelper.isTimeDetectionEnabled()) { if (mTimeServiceHelper.isTimeDetectionEnabled()) { String tmpLog = "NITZ: newNitaData=" + newNitzData + " nitzReceiveTime=" + nitzReceiveTime + " Setting time of day to " + adjustedCurrentTimeMillis Loading @@ -459,11 +465,6 @@ public class NitzStateMachine { Rlog.d(LOG_TAG, tmpLog); } mTimeLog.log(tmpLog); if (mPhone.isPhoneTypeGsm()) { setAndBroadcastNetworkSetTime(adjustedCurrentTimeMillis); Rlog.i(LOG_TAG, "NITZ: after Setting time of day"); } else { if (mTimeServiceHelper.isTimeDetectionEnabled()) { // Update system time automatically long gained = adjustedCurrentTimeMillis - System.currentTimeMillis(); long timeSinceLastUpdate = Loading @@ -489,8 +490,6 @@ public class NitzStateMachine { return; } } } } saveNitzTime(adjustedCurrentTimeMillis); } finally { mWakeLock.release(); Loading Loading @@ -553,7 +552,7 @@ public class NitzStateMachine { if (mSavedTimeZoneId != null) { setAndBroadcastNetworkSetTimeZone(mSavedTimeZoneId); } else { String iso = getNetworkCountryIsoForPhone(); String iso = mDeviceState.getNetworkCountryIsoForPhone(); if (!TextUtils.isEmpty(iso)) { updateTimeZoneByNetworkCountryCode(iso); } Loading Loading @@ -672,9 +671,4 @@ public class NitzStateMachine { return mNeedFixZoneAfterNitz; } // public so it can be used by tests for spying / setting up return values with Mockito. public String getNetworkCountryIsoForPhone() { return ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)) .getNetworkCountryIsoForPhone(mPhone.getPhoneId()); } } tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineTest.java +222 −40 Original line number Diff line number Diff line Loading @@ -18,9 +18,12 @@ package com.android.internal.telephony; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.spy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.icu.util.Calendar; Loading @@ -35,6 +38,9 @@ import org.mockito.Mock; public class NitzStateMachineTest extends TelephonyTest { private static final TimeZone US_TIME_ZONE = TimeZone.getTimeZone("America/Los_Angeles"); private static final String US_ISO_CODE = "us"; @Mock private NitzStateMachine.DeviceState mDeviceState; Loading @@ -52,15 +58,30 @@ public class NitzStateMachineTest extends TelephonyTest { when(mDeviceState.getNitzUpdateSpacingMillis()).thenReturn(1000 * 60 * 10); when(mDeviceState.elapsedRealtime()).thenReturn(123456789L); NitzStateMachine real = new NitzStateMachine(mPhone, mTimeServiceHelper, mDeviceState); mNitzStateMachine = spy(real); mNitzStateMachine = new NitzStateMachine(mPhone, mTimeServiceHelper, mDeviceState); logd("ServiceStateTrackerTest -Setup!"); } @After public void tearDown() throws Exception { mNitzStateMachine = null; // Confirm all mDeviceState side effects were verified. We don't care about retrievals of // device state. verify(mDeviceState, atLeast(0)).getIgnoreNitz(); verify(mDeviceState, atLeast(0)).getIgnoreNitzForTests(); verify(mDeviceState, atLeast(0)).getNitzUpdateDiffMillis(); verify(mDeviceState, atLeast(0)).getNitzUpdateSpacingMillis(); verify(mDeviceState, atLeast(0)).elapsedRealtime(); verify(mDeviceState, atLeast(0)).getNetworkCountryIsoForPhone(); verifyNoMoreInteractions(mDeviceState); // Confirm all mTimeServiceHelper side effects were verified. We don't care about current // auto time / time zone state retrievals / listening. verify(mTimeServiceHelper, atLeast(0)).setListener(any()); verify(mTimeServiceHelper, atLeast(0)).isTimeDetectionEnabled(); verify(mTimeServiceHelper, atLeast(0)).isTimeZoneDetectionEnabled(); verifyNoMoreInteractions(mTimeServiceHelper); super.tearDown(); } Loading @@ -71,44 +92,159 @@ public class NitzStateMachineTest extends TelephonyTest { when(mTimeServiceHelper.isTimeZoneDetectionEnabled()).thenReturn(true); // Simulate the country being known. when(mNitzStateMachine.getNetworkCountryIsoForPhone()).thenReturn("us"); when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn(US_ISO_CODE); mNitzStateMachine.setNetworkCountryIsoAvailable(true); // Create a simulated NITZ signal. TestNitzSignal usNitzSignal = createUsTestNitzSignal(); // Simulate the elapsedRealtime() value incrementing with the passage of time. incrementSimulatedDeviceClock(1000); // Simulate NITZ being received. long nitzReceivedRealtimeMillis = mDeviceState.elapsedRealtime(); TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles"); long nitzTimeMillis = createTime(timeZone, 2017, 1, 2, 12, 45, 25); NitzData nitzData = createValidNitzDataForTime(timeZone, nitzTimeMillis, false /* includeEmulatorTimeZone */); mNitzStateMachine.setTimeAndTimeZoneFromNitz( usNitzSignal.getNitzData(), usNitzSignal.getReceivedRealtimeMillis()); // Check resulting state and side effects. long expectedAdjustedCurrentTimeMillis = usNitzSignal.getAdjustedCurrentTimeMillis(mDeviceState.elapsedRealtime()); verifyTimeServiceTimeZoneWasSet(usNitzSignal.getTimeZoneId()); verifyTimeServiceTimeWasSet(expectedAdjustedCurrentTimeMillis); verifyNitzTimePropertyWasSet(expectedAdjustedCurrentTimeMillis); assertTrue(mNitzStateMachine.getNitzUpdatedTime()); assertEquals(usNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData()); assertEquals(usNitzSignal.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId()); } @Test public void test_setTimeAndTimeZoneFromNitz_countryKnown_autoTimeZoneDisabled() throws Exception { // Simulate device settings. when(mTimeServiceHelper.isTimeDetectionEnabled()).thenReturn(true); when(mTimeServiceHelper.isTimeZoneDetectionEnabled()).thenReturn(false); // Simulate the country being known. when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn(US_ISO_CODE); mNitzStateMachine.setNetworkCountryIsoAvailable(true); // Create a simulated NITZ signal. TestNitzSignal usNitzSignal = createUsTestNitzSignal(); // Simulate the elapsedRealtime() value incrementing with the passage of time. incrementSimulatedDeviceClock(1000); // Simulate NITZ being received. mNitzStateMachine.setTimeAndTimeZoneFromNitz( usNitzSignal.getNitzData(), usNitzSignal.getReceivedRealtimeMillis()); // Check resulting state and side effects. long expectedAdjustedCurrentTimeMillis = usNitzSignal.getAdjustedCurrentTimeMillis(mDeviceState.elapsedRealtime()); verifyTimeServiceTimeZoneWasNotSet(); verifyTimeServiceTimeWasSet(expectedAdjustedCurrentTimeMillis); verifyNitzTimePropertyWasSet(expectedAdjustedCurrentTimeMillis); assertTrue(mNitzStateMachine.getNitzUpdatedTime()); assertEquals(usNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData()); assertEquals(usNitzSignal.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId()); } @Test public void test_setTimeAndTimeZoneFromNitz_countryKnown_autoTimeDisabled() throws Exception { // Simulate device settings. when(mTimeServiceHelper.isTimeDetectionEnabled()).thenReturn(false); when(mTimeServiceHelper.isTimeZoneDetectionEnabled()).thenReturn(true); // Simulate the country being known. when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn(US_ISO_CODE); mNitzStateMachine.setNetworkCountryIsoAvailable(true); // Create a simulated NITZ signal. TestNitzSignal usNitzSignal = createUsTestNitzSignal(); // Simulate the elapsedRealtime() value incrementing with the passage of time. incrementSimulatedDeviceClock(1000); // Simulate NITZ being received. mNitzStateMachine.setTimeAndTimeZoneFromNitz( usNitzSignal.getNitzData(), usNitzSignal.getReceivedRealtimeMillis()); // Check resulting state and side effects. long expectedAdjustedCurrentTimeMillis = usNitzSignal.getAdjustedCurrentTimeMillis(mDeviceState.elapsedRealtime()); verifyTimeServiceTimeZoneWasSet(usNitzSignal.getTimeZoneId()); verifyTimeServiceTimeWasNotSet(); verifyNitzTimePropertyWasSet(expectedAdjustedCurrentTimeMillis); assertTrue(mNitzStateMachine.getNitzUpdatedTime()); assertEquals(usNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData()); assertEquals(usNitzSignal.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId()); } @Test public void test_setTimeAndTimeZoneFromNitz_countryKnown_autoTimeAndTimeZoneDisabled() throws Exception { // Simulate device settings. when(mTimeServiceHelper.isTimeDetectionEnabled()).thenReturn(false); when(mTimeServiceHelper.isTimeZoneDetectionEnabled()).thenReturn(false); // Simulate the country being known. when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn(US_ISO_CODE); mNitzStateMachine.setNetworkCountryIsoAvailable(true); // Create a simulated NITZ signal. TestNitzSignal usNitzSignal = createUsTestNitzSignal(); // Simulate the elapsedRealtime() value incrementing with the passage of time. incrementSimulatedDeviceClock(1000); mNitzStateMachine.setTimeAndTimeZoneFromNitz(nitzData, nitzReceivedRealtimeMillis); // Simulate NITZ being received. mNitzStateMachine.setTimeAndTimeZoneFromNitz( usNitzSignal.getNitzData(), usNitzSignal.getReceivedRealtimeMillis()); // Check resulting state and side effects. assertEquals(nitzData, mNitzStateMachine.getCachedNitzData()); verify(mTimeServiceHelper, times(1)).setDeviceTimeZone(timeZone.getID()); long expectedAdjustedCurrentTimeMillis = usNitzSignal.getAdjustedCurrentTimeMillis(mDeviceState.elapsedRealtime()); long timeServiceTimeMillis = verifyTimeServiceTimeWasSet(); assertEquals(nitzTimeMillis + (mDeviceState.elapsedRealtime() - nitzReceivedRealtimeMillis), timeServiceTimeMillis); assertEquals(timeServiceTimeMillis, verifyNitzTimePropertyWasSet()); verifyTimeServiceTimeZoneWasNotSet(); verifyTimeServiceTimeWasNotSet(); verifyNitzTimePropertyWasSet(expectedAdjustedCurrentTimeMillis); assertTrue(mNitzStateMachine.getNitzUpdatedTime()); assertEquals(timeZone.getID(), mNitzStateMachine.getSavedTimeZoneId()); assertEquals(usNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData()); assertEquals(usNitzSignal.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId()); } private void verifyTimeServiceTimeZoneWasNotSet() { verify(mTimeServiceHelper, times(0)).setDeviceTimeZone(any(String.class)); } private void verifyTimeServiceTimeZoneWasSet(String timeZoneId) { verify(mTimeServiceHelper, times(1)).setDeviceTimeZone(timeZoneId); } private void verifyTimeServiceTimeWasNotSet() { verify(mTimeServiceHelper, times(0)).setDeviceTime(anyLong()); } private long verifyTimeServiceTimeWasSet() { private void verifyTimeServiceTimeWasSet(long expectedTimeMillis) { ArgumentCaptor<Long> timeServiceTimeCaptor = ArgumentCaptor.forClass(Long.TYPE); verify(mTimeServiceHelper, times(1)).setDeviceTime(timeServiceTimeCaptor.capture()); return timeServiceTimeCaptor.getValue(); assertEquals(expectedTimeMillis, (long) timeServiceTimeCaptor.getValue()); } private long verifyNitzTimePropertyWasSet() { private void verifyNitzTimePropertyWasSet(long expectedTimeMillis) { ArgumentCaptor<Long> propertyCaptor = ArgumentCaptor.forClass(Long.TYPE); verify(mDeviceState, times(1)).setNitzTimeProperty(propertyCaptor.capture()); return propertyCaptor.getValue(); assertEquals(expectedTimeMillis, (long) propertyCaptor.getValue()); } private void incrementSimulatedDeviceClock(int incMillis) { Loading @@ -116,7 +252,61 @@ public class NitzStateMachineTest extends TelephonyTest { when(mDeviceState.elapsedRealtime()).thenReturn(currentElapsedRealtime + incMillis); } private NitzData createValidNitzDataForTime(TimeZone timeZone, long timeMillis, private static long createTime(TimeZone timeZone, int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute) { Calendar cal = new GregorianCalendar(timeZone); cal.clear(); cal.set(year, monthOfYear - 1, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute); return cal.getTimeInMillis(); } /** * Creates a TestNitzSignal for an arbitrary time with a US time zone. */ private TestNitzSignal createUsTestNitzSignal() { long receivedRealtimeMillis = mDeviceState.elapsedRealtime(); long nitzTimeMillis = createTime(US_TIME_ZONE, 2017, 1, 2, 12, 45, 25); return new TestNitzSignal(receivedRealtimeMillis, US_TIME_ZONE, nitzTimeMillis); } /** * A class to contain a simulated NITZ signal and test metadata. */ private static class TestNitzSignal { private final long mReceivedRealtimeMillis; private final TimeZone mTimeZone; private final NitzData mNitzData; TestNitzSignal(long receivedRealtimeMillis, TimeZone timeZone, long nitzTimeMillis) { mReceivedRealtimeMillis = receivedRealtimeMillis; mTimeZone = timeZone; mNitzData = createValidNitzDataForTime( timeZone, nitzTimeMillis, false /* includeEmulatorTimeZone */); } NitzData getNitzData() { return mNitzData; } long getReceivedRealtimeMillis() { return mReceivedRealtimeMillis; } long getCurrentTimeInMillis() { return mNitzData.getCurrentTimeInMillis(); } String getTimeZoneId() { return mTimeZone.getID(); } long getAdjustedCurrentTimeMillis(long currentElapsedRealtimeMillis) { long adjustmentMillis = currentElapsedRealtimeMillis - getReceivedRealtimeMillis(); return getCurrentTimeInMillis() + adjustmentMillis; } private static NitzData createValidNitzDataForTime(TimeZone timeZone, long timeMillis, boolean includeEmulatorTimeZone) { int[] offsets = new int[2]; timeZone.getOffset(timeMillis, false /* local */, offsets); Loading @@ -130,13 +320,5 @@ public class NitzStateMachineTest extends TelephonyTest { return NitzData.createForTests(zoneOffsetMillis, dstOffsetMillis, timeMillis, emulatorTimeZone); } private long createTime(TimeZone timeZone, int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute) { Calendar cal = new GregorianCalendar(timeZone); cal.clear(); cal.set(year, monthOfYear - 1, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute); return cal.getTimeInMillis(); } } Loading
src/java/com/android/internal/telephony/NitzStateMachine.java +41 −47 Original line number Diff line number Diff line Loading @@ -56,14 +56,21 @@ public class NitzStateMachine { private static final int NITZ_UPDATE_DIFF_DEFAULT = 2000; private final int mNitzUpdateDiff; private final GsmCdmaPhone mPhone; private final TelephonyManager mTelephonyManager; private final ContentResolver mCr; public DeviceState(Context context) { public DeviceState(GsmCdmaPhone phone) { mPhone = phone; Context context = phone.getContext(); mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); mCr = context.getContentResolver(); mNitzUpdateSpacing = SystemProperties .getInt("ro.nitz_update_spacing", NITZ_UPDATE_SPACING_DEFAULT); mNitzUpdateDiff = SystemProperties .getInt("ro.nitz_update_diff", NITZ_UPDATE_DIFF_DEFAULT); mNitzUpdateSpacing = SystemProperties.getInt("ro.nitz_update_spacing", NITZ_UPDATE_SPACING_DEFAULT); mNitzUpdateDiff = SystemProperties.getInt("ro.nitz_update_diff", NITZ_UPDATE_DIFF_DEFAULT); } /** Loading Loading @@ -113,6 +120,10 @@ public class NitzStateMachine { public long elapsedRealtime() { return SystemClock.elapsedRealtime(); } public String getNetworkCountryIsoForPhone() { return mTelephonyManager.getNetworkCountryIsoForPhone(mPhone.getPhoneId()); } } private static final String LOG_TAG = ServiceStateTracker.LOG_TAG; Loading Loading @@ -166,12 +177,10 @@ public class NitzStateMachine { /** Wake lock used while setting time of day. */ private PowerManager.WakeLock mWakeLock; private static final String WAKELOCK_TAG = "NitzStateMachine"; private final ContentResolver mCr; /** Boolean is true if setTimeFromNITZ was called */ private boolean mNitzUpdatedTime = false; private final Context mContext; private final GsmCdmaPhone mPhone; private final DeviceState mDeviceState; private final TimeServiceHelper mTimeServiceHelper; Loading @@ -179,22 +188,19 @@ public class NitzStateMachine { public NitzStateMachine(GsmCdmaPhone phone) { this(phone, TelephonyComponentFactory.getInstance().makeTimeServiceHelper(phone.getContext()), new DeviceState(phone.getContext())); new DeviceState(phone)); } @VisibleForTesting public NitzStateMachine(GsmCdmaPhone phone, TimeServiceHelper timeServiceHelper, DeviceState deviceState) { mPhone = phone; Context context = phone.getContext(); mContext = context; Context context = phone.getContext(); PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG); mCr = context.getContentResolver(); mDeviceState = deviceState; mTimeServiceHelper = timeServiceHelper; mTimeServiceHelper.setListener(new TimeServiceHelper.Listener() { Loading Loading @@ -342,7 +348,7 @@ public class NitzStateMachine { private void setTimeZoneFromNitz(NitzData newNitzData, long nitzReceiveTime) { try { String iso = getNetworkCountryIsoForPhone(); String iso = mDeviceState.getNetworkCountryIsoForPhone(); TimeZone zone; if (newNitzData.getEmulatorHostTimeZone() != null) { zone = newNitzData.getEmulatorHostTimeZone(); Loading Loading @@ -448,7 +454,7 @@ public class NitzStateMachine { long adjustedCurrentTimeMillis = newNitzData.getCurrentTimeInMillis(); adjustedCurrentTimeMillis += millisSinceNitzReceived; if (!mPhone.isPhoneTypeGsm() || mTimeServiceHelper.isTimeDetectionEnabled()) { if (mTimeServiceHelper.isTimeDetectionEnabled()) { String tmpLog = "NITZ: newNitaData=" + newNitzData + " nitzReceiveTime=" + nitzReceiveTime + " Setting time of day to " + adjustedCurrentTimeMillis Loading @@ -459,11 +465,6 @@ public class NitzStateMachine { Rlog.d(LOG_TAG, tmpLog); } mTimeLog.log(tmpLog); if (mPhone.isPhoneTypeGsm()) { setAndBroadcastNetworkSetTime(adjustedCurrentTimeMillis); Rlog.i(LOG_TAG, "NITZ: after Setting time of day"); } else { if (mTimeServiceHelper.isTimeDetectionEnabled()) { // Update system time automatically long gained = adjustedCurrentTimeMillis - System.currentTimeMillis(); long timeSinceLastUpdate = Loading @@ -489,8 +490,6 @@ public class NitzStateMachine { return; } } } } saveNitzTime(adjustedCurrentTimeMillis); } finally { mWakeLock.release(); Loading Loading @@ -553,7 +552,7 @@ public class NitzStateMachine { if (mSavedTimeZoneId != null) { setAndBroadcastNetworkSetTimeZone(mSavedTimeZoneId); } else { String iso = getNetworkCountryIsoForPhone(); String iso = mDeviceState.getNetworkCountryIsoForPhone(); if (!TextUtils.isEmpty(iso)) { updateTimeZoneByNetworkCountryCode(iso); } Loading Loading @@ -672,9 +671,4 @@ public class NitzStateMachine { return mNeedFixZoneAfterNitz; } // public so it can be used by tests for spying / setting up return values with Mockito. public String getNetworkCountryIsoForPhone() { return ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)) .getNetworkCountryIsoForPhone(mPhone.getPhoneId()); } }
tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineTest.java +222 −40 Original line number Diff line number Diff line Loading @@ -18,9 +18,12 @@ package com.android.internal.telephony; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.spy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.icu.util.Calendar; Loading @@ -35,6 +38,9 @@ import org.mockito.Mock; public class NitzStateMachineTest extends TelephonyTest { private static final TimeZone US_TIME_ZONE = TimeZone.getTimeZone("America/Los_Angeles"); private static final String US_ISO_CODE = "us"; @Mock private NitzStateMachine.DeviceState mDeviceState; Loading @@ -52,15 +58,30 @@ public class NitzStateMachineTest extends TelephonyTest { when(mDeviceState.getNitzUpdateSpacingMillis()).thenReturn(1000 * 60 * 10); when(mDeviceState.elapsedRealtime()).thenReturn(123456789L); NitzStateMachine real = new NitzStateMachine(mPhone, mTimeServiceHelper, mDeviceState); mNitzStateMachine = spy(real); mNitzStateMachine = new NitzStateMachine(mPhone, mTimeServiceHelper, mDeviceState); logd("ServiceStateTrackerTest -Setup!"); } @After public void tearDown() throws Exception { mNitzStateMachine = null; // Confirm all mDeviceState side effects were verified. We don't care about retrievals of // device state. verify(mDeviceState, atLeast(0)).getIgnoreNitz(); verify(mDeviceState, atLeast(0)).getIgnoreNitzForTests(); verify(mDeviceState, atLeast(0)).getNitzUpdateDiffMillis(); verify(mDeviceState, atLeast(0)).getNitzUpdateSpacingMillis(); verify(mDeviceState, atLeast(0)).elapsedRealtime(); verify(mDeviceState, atLeast(0)).getNetworkCountryIsoForPhone(); verifyNoMoreInteractions(mDeviceState); // Confirm all mTimeServiceHelper side effects were verified. We don't care about current // auto time / time zone state retrievals / listening. verify(mTimeServiceHelper, atLeast(0)).setListener(any()); verify(mTimeServiceHelper, atLeast(0)).isTimeDetectionEnabled(); verify(mTimeServiceHelper, atLeast(0)).isTimeZoneDetectionEnabled(); verifyNoMoreInteractions(mTimeServiceHelper); super.tearDown(); } Loading @@ -71,44 +92,159 @@ public class NitzStateMachineTest extends TelephonyTest { when(mTimeServiceHelper.isTimeZoneDetectionEnabled()).thenReturn(true); // Simulate the country being known. when(mNitzStateMachine.getNetworkCountryIsoForPhone()).thenReturn("us"); when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn(US_ISO_CODE); mNitzStateMachine.setNetworkCountryIsoAvailable(true); // Create a simulated NITZ signal. TestNitzSignal usNitzSignal = createUsTestNitzSignal(); // Simulate the elapsedRealtime() value incrementing with the passage of time. incrementSimulatedDeviceClock(1000); // Simulate NITZ being received. long nitzReceivedRealtimeMillis = mDeviceState.elapsedRealtime(); TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles"); long nitzTimeMillis = createTime(timeZone, 2017, 1, 2, 12, 45, 25); NitzData nitzData = createValidNitzDataForTime(timeZone, nitzTimeMillis, false /* includeEmulatorTimeZone */); mNitzStateMachine.setTimeAndTimeZoneFromNitz( usNitzSignal.getNitzData(), usNitzSignal.getReceivedRealtimeMillis()); // Check resulting state and side effects. long expectedAdjustedCurrentTimeMillis = usNitzSignal.getAdjustedCurrentTimeMillis(mDeviceState.elapsedRealtime()); verifyTimeServiceTimeZoneWasSet(usNitzSignal.getTimeZoneId()); verifyTimeServiceTimeWasSet(expectedAdjustedCurrentTimeMillis); verifyNitzTimePropertyWasSet(expectedAdjustedCurrentTimeMillis); assertTrue(mNitzStateMachine.getNitzUpdatedTime()); assertEquals(usNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData()); assertEquals(usNitzSignal.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId()); } @Test public void test_setTimeAndTimeZoneFromNitz_countryKnown_autoTimeZoneDisabled() throws Exception { // Simulate device settings. when(mTimeServiceHelper.isTimeDetectionEnabled()).thenReturn(true); when(mTimeServiceHelper.isTimeZoneDetectionEnabled()).thenReturn(false); // Simulate the country being known. when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn(US_ISO_CODE); mNitzStateMachine.setNetworkCountryIsoAvailable(true); // Create a simulated NITZ signal. TestNitzSignal usNitzSignal = createUsTestNitzSignal(); // Simulate the elapsedRealtime() value incrementing with the passage of time. incrementSimulatedDeviceClock(1000); // Simulate NITZ being received. mNitzStateMachine.setTimeAndTimeZoneFromNitz( usNitzSignal.getNitzData(), usNitzSignal.getReceivedRealtimeMillis()); // Check resulting state and side effects. long expectedAdjustedCurrentTimeMillis = usNitzSignal.getAdjustedCurrentTimeMillis(mDeviceState.elapsedRealtime()); verifyTimeServiceTimeZoneWasNotSet(); verifyTimeServiceTimeWasSet(expectedAdjustedCurrentTimeMillis); verifyNitzTimePropertyWasSet(expectedAdjustedCurrentTimeMillis); assertTrue(mNitzStateMachine.getNitzUpdatedTime()); assertEquals(usNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData()); assertEquals(usNitzSignal.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId()); } @Test public void test_setTimeAndTimeZoneFromNitz_countryKnown_autoTimeDisabled() throws Exception { // Simulate device settings. when(mTimeServiceHelper.isTimeDetectionEnabled()).thenReturn(false); when(mTimeServiceHelper.isTimeZoneDetectionEnabled()).thenReturn(true); // Simulate the country being known. when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn(US_ISO_CODE); mNitzStateMachine.setNetworkCountryIsoAvailable(true); // Create a simulated NITZ signal. TestNitzSignal usNitzSignal = createUsTestNitzSignal(); // Simulate the elapsedRealtime() value incrementing with the passage of time. incrementSimulatedDeviceClock(1000); // Simulate NITZ being received. mNitzStateMachine.setTimeAndTimeZoneFromNitz( usNitzSignal.getNitzData(), usNitzSignal.getReceivedRealtimeMillis()); // Check resulting state and side effects. long expectedAdjustedCurrentTimeMillis = usNitzSignal.getAdjustedCurrentTimeMillis(mDeviceState.elapsedRealtime()); verifyTimeServiceTimeZoneWasSet(usNitzSignal.getTimeZoneId()); verifyTimeServiceTimeWasNotSet(); verifyNitzTimePropertyWasSet(expectedAdjustedCurrentTimeMillis); assertTrue(mNitzStateMachine.getNitzUpdatedTime()); assertEquals(usNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData()); assertEquals(usNitzSignal.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId()); } @Test public void test_setTimeAndTimeZoneFromNitz_countryKnown_autoTimeAndTimeZoneDisabled() throws Exception { // Simulate device settings. when(mTimeServiceHelper.isTimeDetectionEnabled()).thenReturn(false); when(mTimeServiceHelper.isTimeZoneDetectionEnabled()).thenReturn(false); // Simulate the country being known. when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn(US_ISO_CODE); mNitzStateMachine.setNetworkCountryIsoAvailable(true); // Create a simulated NITZ signal. TestNitzSignal usNitzSignal = createUsTestNitzSignal(); // Simulate the elapsedRealtime() value incrementing with the passage of time. incrementSimulatedDeviceClock(1000); mNitzStateMachine.setTimeAndTimeZoneFromNitz(nitzData, nitzReceivedRealtimeMillis); // Simulate NITZ being received. mNitzStateMachine.setTimeAndTimeZoneFromNitz( usNitzSignal.getNitzData(), usNitzSignal.getReceivedRealtimeMillis()); // Check resulting state and side effects. assertEquals(nitzData, mNitzStateMachine.getCachedNitzData()); verify(mTimeServiceHelper, times(1)).setDeviceTimeZone(timeZone.getID()); long expectedAdjustedCurrentTimeMillis = usNitzSignal.getAdjustedCurrentTimeMillis(mDeviceState.elapsedRealtime()); long timeServiceTimeMillis = verifyTimeServiceTimeWasSet(); assertEquals(nitzTimeMillis + (mDeviceState.elapsedRealtime() - nitzReceivedRealtimeMillis), timeServiceTimeMillis); assertEquals(timeServiceTimeMillis, verifyNitzTimePropertyWasSet()); verifyTimeServiceTimeZoneWasNotSet(); verifyTimeServiceTimeWasNotSet(); verifyNitzTimePropertyWasSet(expectedAdjustedCurrentTimeMillis); assertTrue(mNitzStateMachine.getNitzUpdatedTime()); assertEquals(timeZone.getID(), mNitzStateMachine.getSavedTimeZoneId()); assertEquals(usNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData()); assertEquals(usNitzSignal.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId()); } private void verifyTimeServiceTimeZoneWasNotSet() { verify(mTimeServiceHelper, times(0)).setDeviceTimeZone(any(String.class)); } private void verifyTimeServiceTimeZoneWasSet(String timeZoneId) { verify(mTimeServiceHelper, times(1)).setDeviceTimeZone(timeZoneId); } private void verifyTimeServiceTimeWasNotSet() { verify(mTimeServiceHelper, times(0)).setDeviceTime(anyLong()); } private long verifyTimeServiceTimeWasSet() { private void verifyTimeServiceTimeWasSet(long expectedTimeMillis) { ArgumentCaptor<Long> timeServiceTimeCaptor = ArgumentCaptor.forClass(Long.TYPE); verify(mTimeServiceHelper, times(1)).setDeviceTime(timeServiceTimeCaptor.capture()); return timeServiceTimeCaptor.getValue(); assertEquals(expectedTimeMillis, (long) timeServiceTimeCaptor.getValue()); } private long verifyNitzTimePropertyWasSet() { private void verifyNitzTimePropertyWasSet(long expectedTimeMillis) { ArgumentCaptor<Long> propertyCaptor = ArgumentCaptor.forClass(Long.TYPE); verify(mDeviceState, times(1)).setNitzTimeProperty(propertyCaptor.capture()); return propertyCaptor.getValue(); assertEquals(expectedTimeMillis, (long) propertyCaptor.getValue()); } private void incrementSimulatedDeviceClock(int incMillis) { Loading @@ -116,7 +252,61 @@ public class NitzStateMachineTest extends TelephonyTest { when(mDeviceState.elapsedRealtime()).thenReturn(currentElapsedRealtime + incMillis); } private NitzData createValidNitzDataForTime(TimeZone timeZone, long timeMillis, private static long createTime(TimeZone timeZone, int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute) { Calendar cal = new GregorianCalendar(timeZone); cal.clear(); cal.set(year, monthOfYear - 1, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute); return cal.getTimeInMillis(); } /** * Creates a TestNitzSignal for an arbitrary time with a US time zone. */ private TestNitzSignal createUsTestNitzSignal() { long receivedRealtimeMillis = mDeviceState.elapsedRealtime(); long nitzTimeMillis = createTime(US_TIME_ZONE, 2017, 1, 2, 12, 45, 25); return new TestNitzSignal(receivedRealtimeMillis, US_TIME_ZONE, nitzTimeMillis); } /** * A class to contain a simulated NITZ signal and test metadata. */ private static class TestNitzSignal { private final long mReceivedRealtimeMillis; private final TimeZone mTimeZone; private final NitzData mNitzData; TestNitzSignal(long receivedRealtimeMillis, TimeZone timeZone, long nitzTimeMillis) { mReceivedRealtimeMillis = receivedRealtimeMillis; mTimeZone = timeZone; mNitzData = createValidNitzDataForTime( timeZone, nitzTimeMillis, false /* includeEmulatorTimeZone */); } NitzData getNitzData() { return mNitzData; } long getReceivedRealtimeMillis() { return mReceivedRealtimeMillis; } long getCurrentTimeInMillis() { return mNitzData.getCurrentTimeInMillis(); } String getTimeZoneId() { return mTimeZone.getID(); } long getAdjustedCurrentTimeMillis(long currentElapsedRealtimeMillis) { long adjustmentMillis = currentElapsedRealtimeMillis - getReceivedRealtimeMillis(); return getCurrentTimeInMillis() + adjustmentMillis; } private static NitzData createValidNitzDataForTime(TimeZone timeZone, long timeMillis, boolean includeEmulatorTimeZone) { int[] offsets = new int[2]; timeZone.getOffset(timeMillis, false /* local */, offsets); Loading @@ -130,13 +320,5 @@ public class NitzStateMachineTest extends TelephonyTest { return NitzData.createForTests(zoneOffsetMillis, dstOffsetMillis, timeMillis, emulatorTimeZone); } private long createTime(TimeZone timeZone, int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute) { Calendar cal = new GregorianCalendar(timeZone); cal.clear(); cal.set(year, monthOfYear - 1, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute); return cal.getTimeInMillis(); } }