Loading core/res/res/values/config.xml +8 −0 Original line number Original line Diff line number Diff line Loading @@ -1532,6 +1532,14 @@ <!-- Class name of WallpaperManagerService. --> <!-- Class name of WallpaperManagerService. --> <string name="config_wallpaperManagerServiceName" translatable="false">com.android.server.wallpaper.WallpaperManagerService</string> <string name="config_wallpaperManagerServiceName" translatable="false">com.android.server.wallpaper.WallpaperManagerService</string> <!-- Specifies priority of automatic time sources. Suggestions from higher entries in the list take precedence over lower ones. See com.android.server.timedetector.TimeDetectorStrategy for available sources. --> <string-array name="config_autoTimeSourcesPriority"> <item>telephony</item> <item>network</item> </string-array> <!-- Enables the TimeZoneRuleManager service. This is the global switch for the updateable time <!-- Enables the TimeZoneRuleManager service. This is the global switch for the updateable time zone update mechanism. --> zone update mechanism. --> <bool name="config_enableUpdateableTimeZoneRules">false</bool> <bool name="config_enableUpdateableTimeZoneRules">false</bool> Loading core/res/res/values/symbols.xml +1 −0 Original line number Original line Diff line number Diff line Loading @@ -2161,6 +2161,7 @@ <java-symbol type="string" name="config_defaultNetworkScorerPackageName" /> <java-symbol type="string" name="config_defaultNetworkScorerPackageName" /> <java-symbol type="string" name="config_persistentDataPackageName" /> <java-symbol type="string" name="config_persistentDataPackageName" /> <java-symbol type="string" name="config_deviceConfiguratorPackageName" /> <java-symbol type="string" name="config_deviceConfiguratorPackageName" /> <java-symbol type="array" name="config_autoTimeSourcesPriority" /> <java-symbol type="layout" name="resolver_list" /> <java-symbol type="layout" name="resolver_list" /> <java-symbol type="id" name="resolver_list" /> <java-symbol type="id" name="resolver_list" /> Loading services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java +30 −9 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.timedetector; package com.android.server.timedetector; import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK; import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPHONY; import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin; import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin; import android.annotation.NonNull; import android.annotation.NonNull; Loading @@ -30,6 +32,9 @@ import android.os.SystemProperties; import android.provider.Settings; import android.provider.Settings; import android.util.Slog; import android.util.Slog; import com.android.internal.R; import com.android.server.timedetector.TimeDetectorStrategy.Origin; import java.time.Instant; import java.time.Instant; import java.util.Objects; import java.util.Objects; Loading @@ -49,6 +54,13 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat private static final Instant TIME_LOWER_BOUND = Instant.ofEpochMilli( private static final Instant TIME_LOWER_BOUND = Instant.ofEpochMilli( Long.max(Environment.getRootDirectory().lastModified(), Build.TIME)); Long.max(Environment.getRootDirectory().lastModified(), Build.TIME)); /** * By default telephony and network only suggestions are accepted and telephony takes * precedence over network. */ private static final @Origin int[] DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES = { ORIGIN_TELEPHONY, ORIGIN_NETWORK }; /** /** * If a newly calculated system clock time and the current system clock time differs by this or * If a newly calculated system clock time and the current system clock time differs by this or * more the system clock will actually be updated. Used to prevent the system clock being set * more the system clock will actually be updated. Used to prevent the system clock being set Loading Loading @@ -76,14 +88,7 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat SystemProperties.getInt("ro.sys.time_detector_update_diff", SystemProperties.getInt("ro.sys.time_detector_update_diff", SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT); SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT); // TODO(b/172230856): Obtain these values from configuration. mOriginPriorities = getOriginPriorities(context); String[] originStrings = { "telephony", "network" }; int[] origins = new int[originStrings.length]; for (int i = 0; i < originStrings.length; i++) { int origin = stringToOrigin(originStrings[i]); origins[i] = origin; } mOriginPriorities = origins; } } @Override @Override Loading @@ -106,7 +111,7 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat } } @Override @Override public int[] getAutoOriginPriorities() { public int[] autoOriginPriorities() { return mOriginPriorities; return mOriginPriorities; } } Loading Loading @@ -145,4 +150,20 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat Slog.wtf(TAG, "WakeLock " + mWakeLock + " not held"); Slog.wtf(TAG, "WakeLock " + mWakeLock + " not held"); } } } } private static int[] getOriginPriorities(@NonNull Context context) { String[] originStrings = context.getResources().getStringArray(R.array.config_autoTimeSourcesPriority); if (originStrings.length == 0) { return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES; } else { int[] origins = new int[originStrings.length]; for (int i = 0; i < originStrings.length; i++) { int origin = stringToOrigin(originStrings[i]); origins[i] = origin; } return origins; } } } } services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +12 −2 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.server.timedetector; import static com.android.server.timedetector.TimeDetectorStrategy.originToString; import static com.android.server.timedetector.TimeDetectorStrategy.originToString; import static java.util.stream.Collectors.joining; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.AlarmManager; import android.app.AlarmManager; Loading Loading @@ -141,7 +143,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { * Returns the order to look at time suggestions when automatically detecting time. * Returns the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants * See {@code #ORIGIN_} constants */ */ @Origin int[] getAutoOriginPriorities(); @Origin int[] autoOriginPriorities(); /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ void acquireWakeLock(); void acquireWakeLock(); Loading Loading @@ -254,6 +256,14 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { ipw.println("mCallback.systemClockMillis()=" + mCallback.systemClockMillis()); ipw.println("mCallback.systemClockMillis()=" + mCallback.systemClockMillis()); ipw.println("mCallback.systemClockUpdateThresholdMillis()=" ipw.println("mCallback.systemClockUpdateThresholdMillis()=" + mCallback.systemClockUpdateThresholdMillis()); + mCallback.systemClockUpdateThresholdMillis()); ipw.printf("mCallback.autoTimeLowerBound()=%s(%s)\n", mCallback.autoTimeLowerBound(), mCallback.autoTimeLowerBound().toEpochMilli()); String priorities = Arrays.stream(mCallback.autoOriginPriorities()) .mapToObj(TimeDetectorStrategy::originToString) .collect(joining(",", "[", "]")); ipw.println("mCallback.autoOriginPriorities()=" + priorities); ipw.println("Time change log:"); ipw.println("Time change log:"); ipw.increaseIndent(); // level 2 ipw.increaseIndent(); // level 2 Loading Loading @@ -356,7 +366,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } } // Try the different origins one at a time. // Try the different origins one at a time. int[] originPriorities = mCallback.getAutoOriginPriorities(); int[] originPriorities = mCallback.autoOriginPriorities(); for (int origin : originPriorities) { for (int origin : originPriorities) { TimestampedValue<Long> newUtcTime = null; TimestampedValue<Long> newUtcTime = null; String cause = null; String cause = null; Loading services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java +49 −25 Original line number Original line Diff line number Diff line Loading @@ -525,6 +525,7 @@ public class TimeDetectorStrategyImplTest { @Test @Test public void testSuggestNetworkTime_autoTimeEnabled() { public void testSuggestNetworkTime_autoTimeEnabled() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoOriginPriorities(ORIGIN_NETWORK) .pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true); NetworkTimeSuggestion timeSuggestion = NetworkTimeSuggestion timeSuggestion = Loading @@ -541,6 +542,7 @@ public class TimeDetectorStrategyImplTest { @Test @Test public void testSuggestNetworkTime_autoTimeDisabled() { public void testSuggestNetworkTime_autoTimeDisabled() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoOriginPriorities(ORIGIN_NETWORK) .pokeAutoTimeDetectionEnabled(false); .pokeAutoTimeDetectionEnabled(false); NetworkTimeSuggestion timeSuggestion = NetworkTimeSuggestion timeSuggestion = Loading @@ -552,10 +554,26 @@ public class TimeDetectorStrategyImplTest { } } @Test @Test public void testSuggestNetworkTime_telephonySuggestionsBeatNetworkSuggestions() { public void networkTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoOriginPriorities(ORIGIN_NETWORK) .pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true); Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1)); NetworkTimeSuggestion timeSuggestion = mScript .generateNetworkTimeSuggestion(suggestedTime); mScript.simulateNetworkTimeSuggestion(timeSuggestion) .verifySystemClockWasNotSetAndResetCallTracking() .assertLatestNetworkSuggestion(null); } @Test public void highPrioritySuggestionsShouldBeatLowerPrioritySuggestions() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true) .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); // Three obviously different times that could not be mistaken for each other. // Three obviously different times that could not be mistaken for each other. Instant networkTime1 = ARBITRARY_TEST_TIME; Instant networkTime1 = ARBITRARY_TEST_TIME; Instant networkTime2 = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Instant networkTime2 = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Loading @@ -576,7 +594,7 @@ public class TimeDetectorStrategyImplTest { mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, null) mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, null) .assertLatestNetworkSuggestion(networkTimeSuggestion1); .assertLatestNetworkSuggestion(networkTimeSuggestion1); assertEquals(networkTimeSuggestion1, mScript.peekLatestValidNetworkSuggestion()); assertEquals(networkTimeSuggestion1, mScript.peekLatestValidNetworkSuggestion()); assertNull(mScript.peekBestTelephonySuggestion()); assertNull("No telephony suggestions were made:", mScript.peekBestTelephonySuggestion()); // Simulate a little time passing. // Simulate a little time passing. mScript.simulateTimePassing(smallTimeIncrementMillis) mScript.simulateTimePassing(smallTimeIncrementMillis) Loading Loading @@ -631,7 +649,9 @@ public class TimeDetectorStrategyImplTest { mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) .assertLatestNetworkSuggestion(networkTimeSuggestion2); .assertLatestNetworkSuggestion(networkTimeSuggestion2); assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion()); assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion()); assertNull(mScript.peekBestTelephonySuggestion()); assertNull( "Telephony suggestion should be expired:", mScript.peekBestTelephonySuggestion()); // Toggle auto-time off and on to force the detection logic to run. // Toggle auto-time off and on to force the detection logic to run. mScript.simulateAutoTimeDetectionToggle() mScript.simulateAutoTimeDetectionToggle() Loading @@ -646,27 +666,16 @@ public class TimeDetectorStrategyImplTest { mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) .assertLatestNetworkSuggestion(networkTimeSuggestion2); .assertLatestNetworkSuggestion(networkTimeSuggestion2); assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion()); assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion()); assertNull(mScript.peekBestTelephonySuggestion()); assertNull( } "Telephony suggestion should still be expired:", mScript.peekBestTelephonySuggestion()); @Test public void networkTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true); Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1)); NetworkTimeSuggestion timeSuggestion = mScript .generateNetworkTimeSuggestion(suggestedTime); mScript.simulateNetworkTimeSuggestion(timeSuggestion) .verifySystemClockWasNotSetAndResetCallTracking() .assertLatestNetworkSuggestion(null); } } @Test @Test public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_lowerPriorityComesFirst() { public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_lowerPriorityComesFirst() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true) .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); Instant networkTime = ARBITRARY_TEST_TIME; Instant networkTime = ARBITRARY_TEST_TIME; Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Loading @@ -686,7 +695,8 @@ public class TimeDetectorStrategyImplTest { @Test @Test public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_higherPriorityComesFirst() { public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_higherPriorityComesFirst() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true) .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); Instant networkTime = ARBITRARY_TEST_TIME; Instant networkTime = ARBITRARY_TEST_TIME; Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Loading @@ -706,7 +716,8 @@ public class TimeDetectorStrategyImplTest { @Test @Test public void whenHighestPrioritySuggestionIsNotAvailable_fallbacksToNext() { public void whenHighestPrioritySuggestionIsNotAvailable_fallbacksToNext() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true) .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); NetworkTimeSuggestion timeSuggestion = NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME); mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME); Loading @@ -720,7 +731,7 @@ public class TimeDetectorStrategyImplTest { public void suggestionsFromSourceNotListedInPrioritiesList_areIgnored() { public void suggestionsFromSourceNotListedInPrioritiesList_areIgnored() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true) .pokeAutoTimeDetectionEnabled(true) .pokeAutoOriginPriorities(new int[]{ORIGIN_TELEPHONY}); .pokeAutoOriginPriorities(ORIGIN_TELEPHONY); NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion( NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion( ARBITRARY_TEST_TIME); ARBITRARY_TEST_TIME); Loading @@ -730,6 +741,19 @@ public class TimeDetectorStrategyImplTest { .verifySystemClockWasNotSetAndResetCallTracking(); .verifySystemClockWasNotSetAndResetCallTracking(); } } @Test public void autoOriginPrioritiesList_doesNotAffectManualSuggestion() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(false) .pokeAutoOriginPriorities(ORIGIN_TELEPHONY); ManualTimeSuggestion timeSuggestion = mScript.generateManualTimeSuggestion(ARBITRARY_TEST_TIME); mScript.simulateManualTimeSuggestion(timeSuggestion, true /* expectedResult */) .verifySystemClockWasSetAndResetCallTracking(ARBITRARY_TEST_TIME.toEpochMilli()); } /** /** * A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving * A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving * like the real thing should, it also asserts preconditions. * like the real thing should, it also asserts preconditions. Loading Loading @@ -761,7 +785,7 @@ public class TimeDetectorStrategyImplTest { } } @Override @Override public int[] getAutoOriginPriorities() { public int[] autoOriginPriorities() { return mAutoOriginPriorities; return mAutoOriginPriorities; } } Loading Loading @@ -886,8 +910,8 @@ public class TimeDetectorStrategyImplTest { return this; return this; } } Script pokeAutoOriginPriorities(@Origin int[] autoOriginPriorites) { Script pokeAutoOriginPriorities(@Origin int... autoOriginPriorities) { mFakeCallback.pokeAutoOriginPriorities(autoOriginPriorites); mFakeCallback.pokeAutoOriginPriorities(autoOriginPriorities); return this; return this; } } Loading Loading
core/res/res/values/config.xml +8 −0 Original line number Original line Diff line number Diff line Loading @@ -1532,6 +1532,14 @@ <!-- Class name of WallpaperManagerService. --> <!-- Class name of WallpaperManagerService. --> <string name="config_wallpaperManagerServiceName" translatable="false">com.android.server.wallpaper.WallpaperManagerService</string> <string name="config_wallpaperManagerServiceName" translatable="false">com.android.server.wallpaper.WallpaperManagerService</string> <!-- Specifies priority of automatic time sources. Suggestions from higher entries in the list take precedence over lower ones. See com.android.server.timedetector.TimeDetectorStrategy for available sources. --> <string-array name="config_autoTimeSourcesPriority"> <item>telephony</item> <item>network</item> </string-array> <!-- Enables the TimeZoneRuleManager service. This is the global switch for the updateable time <!-- Enables the TimeZoneRuleManager service. This is the global switch for the updateable time zone update mechanism. --> zone update mechanism. --> <bool name="config_enableUpdateableTimeZoneRules">false</bool> <bool name="config_enableUpdateableTimeZoneRules">false</bool> Loading
core/res/res/values/symbols.xml +1 −0 Original line number Original line Diff line number Diff line Loading @@ -2161,6 +2161,7 @@ <java-symbol type="string" name="config_defaultNetworkScorerPackageName" /> <java-symbol type="string" name="config_defaultNetworkScorerPackageName" /> <java-symbol type="string" name="config_persistentDataPackageName" /> <java-symbol type="string" name="config_persistentDataPackageName" /> <java-symbol type="string" name="config_deviceConfiguratorPackageName" /> <java-symbol type="string" name="config_deviceConfiguratorPackageName" /> <java-symbol type="array" name="config_autoTimeSourcesPriority" /> <java-symbol type="layout" name="resolver_list" /> <java-symbol type="layout" name="resolver_list" /> <java-symbol type="id" name="resolver_list" /> <java-symbol type="id" name="resolver_list" /> Loading
services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java +30 −9 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.timedetector; package com.android.server.timedetector; import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK; import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPHONY; import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin; import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin; import android.annotation.NonNull; import android.annotation.NonNull; Loading @@ -30,6 +32,9 @@ import android.os.SystemProperties; import android.provider.Settings; import android.provider.Settings; import android.util.Slog; import android.util.Slog; import com.android.internal.R; import com.android.server.timedetector.TimeDetectorStrategy.Origin; import java.time.Instant; import java.time.Instant; import java.util.Objects; import java.util.Objects; Loading @@ -49,6 +54,13 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat private static final Instant TIME_LOWER_BOUND = Instant.ofEpochMilli( private static final Instant TIME_LOWER_BOUND = Instant.ofEpochMilli( Long.max(Environment.getRootDirectory().lastModified(), Build.TIME)); Long.max(Environment.getRootDirectory().lastModified(), Build.TIME)); /** * By default telephony and network only suggestions are accepted and telephony takes * precedence over network. */ private static final @Origin int[] DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES = { ORIGIN_TELEPHONY, ORIGIN_NETWORK }; /** /** * If a newly calculated system clock time and the current system clock time differs by this or * If a newly calculated system clock time and the current system clock time differs by this or * more the system clock will actually be updated. Used to prevent the system clock being set * more the system clock will actually be updated. Used to prevent the system clock being set Loading Loading @@ -76,14 +88,7 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat SystemProperties.getInt("ro.sys.time_detector_update_diff", SystemProperties.getInt("ro.sys.time_detector_update_diff", SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT); SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT); // TODO(b/172230856): Obtain these values from configuration. mOriginPriorities = getOriginPriorities(context); String[] originStrings = { "telephony", "network" }; int[] origins = new int[originStrings.length]; for (int i = 0; i < originStrings.length; i++) { int origin = stringToOrigin(originStrings[i]); origins[i] = origin; } mOriginPriorities = origins; } } @Override @Override Loading @@ -106,7 +111,7 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat } } @Override @Override public int[] getAutoOriginPriorities() { public int[] autoOriginPriorities() { return mOriginPriorities; return mOriginPriorities; } } Loading Loading @@ -145,4 +150,20 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat Slog.wtf(TAG, "WakeLock " + mWakeLock + " not held"); Slog.wtf(TAG, "WakeLock " + mWakeLock + " not held"); } } } } private static int[] getOriginPriorities(@NonNull Context context) { String[] originStrings = context.getResources().getStringArray(R.array.config_autoTimeSourcesPriority); if (originStrings.length == 0) { return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES; } else { int[] origins = new int[originStrings.length]; for (int i = 0; i < originStrings.length; i++) { int origin = stringToOrigin(originStrings[i]); origins[i] = origin; } return origins; } } } }
services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +12 −2 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.server.timedetector; import static com.android.server.timedetector.TimeDetectorStrategy.originToString; import static com.android.server.timedetector.TimeDetectorStrategy.originToString; import static java.util.stream.Collectors.joining; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.AlarmManager; import android.app.AlarmManager; Loading Loading @@ -141,7 +143,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { * Returns the order to look at time suggestions when automatically detecting time. * Returns the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants * See {@code #ORIGIN_} constants */ */ @Origin int[] getAutoOriginPriorities(); @Origin int[] autoOriginPriorities(); /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ void acquireWakeLock(); void acquireWakeLock(); Loading Loading @@ -254,6 +256,14 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { ipw.println("mCallback.systemClockMillis()=" + mCallback.systemClockMillis()); ipw.println("mCallback.systemClockMillis()=" + mCallback.systemClockMillis()); ipw.println("mCallback.systemClockUpdateThresholdMillis()=" ipw.println("mCallback.systemClockUpdateThresholdMillis()=" + mCallback.systemClockUpdateThresholdMillis()); + mCallback.systemClockUpdateThresholdMillis()); ipw.printf("mCallback.autoTimeLowerBound()=%s(%s)\n", mCallback.autoTimeLowerBound(), mCallback.autoTimeLowerBound().toEpochMilli()); String priorities = Arrays.stream(mCallback.autoOriginPriorities()) .mapToObj(TimeDetectorStrategy::originToString) .collect(joining(",", "[", "]")); ipw.println("mCallback.autoOriginPriorities()=" + priorities); ipw.println("Time change log:"); ipw.println("Time change log:"); ipw.increaseIndent(); // level 2 ipw.increaseIndent(); // level 2 Loading Loading @@ -356,7 +366,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } } // Try the different origins one at a time. // Try the different origins one at a time. int[] originPriorities = mCallback.getAutoOriginPriorities(); int[] originPriorities = mCallback.autoOriginPriorities(); for (int origin : originPriorities) { for (int origin : originPriorities) { TimestampedValue<Long> newUtcTime = null; TimestampedValue<Long> newUtcTime = null; String cause = null; String cause = null; Loading
services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java +49 −25 Original line number Original line Diff line number Diff line Loading @@ -525,6 +525,7 @@ public class TimeDetectorStrategyImplTest { @Test @Test public void testSuggestNetworkTime_autoTimeEnabled() { public void testSuggestNetworkTime_autoTimeEnabled() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoOriginPriorities(ORIGIN_NETWORK) .pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true); NetworkTimeSuggestion timeSuggestion = NetworkTimeSuggestion timeSuggestion = Loading @@ -541,6 +542,7 @@ public class TimeDetectorStrategyImplTest { @Test @Test public void testSuggestNetworkTime_autoTimeDisabled() { public void testSuggestNetworkTime_autoTimeDisabled() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoOriginPriorities(ORIGIN_NETWORK) .pokeAutoTimeDetectionEnabled(false); .pokeAutoTimeDetectionEnabled(false); NetworkTimeSuggestion timeSuggestion = NetworkTimeSuggestion timeSuggestion = Loading @@ -552,10 +554,26 @@ public class TimeDetectorStrategyImplTest { } } @Test @Test public void testSuggestNetworkTime_telephonySuggestionsBeatNetworkSuggestions() { public void networkTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoOriginPriorities(ORIGIN_NETWORK) .pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true); Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1)); NetworkTimeSuggestion timeSuggestion = mScript .generateNetworkTimeSuggestion(suggestedTime); mScript.simulateNetworkTimeSuggestion(timeSuggestion) .verifySystemClockWasNotSetAndResetCallTracking() .assertLatestNetworkSuggestion(null); } @Test public void highPrioritySuggestionsShouldBeatLowerPrioritySuggestions() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true) .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); // Three obviously different times that could not be mistaken for each other. // Three obviously different times that could not be mistaken for each other. Instant networkTime1 = ARBITRARY_TEST_TIME; Instant networkTime1 = ARBITRARY_TEST_TIME; Instant networkTime2 = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Instant networkTime2 = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Loading @@ -576,7 +594,7 @@ public class TimeDetectorStrategyImplTest { mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, null) mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, null) .assertLatestNetworkSuggestion(networkTimeSuggestion1); .assertLatestNetworkSuggestion(networkTimeSuggestion1); assertEquals(networkTimeSuggestion1, mScript.peekLatestValidNetworkSuggestion()); assertEquals(networkTimeSuggestion1, mScript.peekLatestValidNetworkSuggestion()); assertNull(mScript.peekBestTelephonySuggestion()); assertNull("No telephony suggestions were made:", mScript.peekBestTelephonySuggestion()); // Simulate a little time passing. // Simulate a little time passing. mScript.simulateTimePassing(smallTimeIncrementMillis) mScript.simulateTimePassing(smallTimeIncrementMillis) Loading Loading @@ -631,7 +649,9 @@ public class TimeDetectorStrategyImplTest { mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) .assertLatestNetworkSuggestion(networkTimeSuggestion2); .assertLatestNetworkSuggestion(networkTimeSuggestion2); assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion()); assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion()); assertNull(mScript.peekBestTelephonySuggestion()); assertNull( "Telephony suggestion should be expired:", mScript.peekBestTelephonySuggestion()); // Toggle auto-time off and on to force the detection logic to run. // Toggle auto-time off and on to force the detection logic to run. mScript.simulateAutoTimeDetectionToggle() mScript.simulateAutoTimeDetectionToggle() Loading @@ -646,27 +666,16 @@ public class TimeDetectorStrategyImplTest { mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) .assertLatestNetworkSuggestion(networkTimeSuggestion2); .assertLatestNetworkSuggestion(networkTimeSuggestion2); assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion()); assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion()); assertNull(mScript.peekBestTelephonySuggestion()); assertNull( } "Telephony suggestion should still be expired:", mScript.peekBestTelephonySuggestion()); @Test public void networkTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true); Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1)); NetworkTimeSuggestion timeSuggestion = mScript .generateNetworkTimeSuggestion(suggestedTime); mScript.simulateNetworkTimeSuggestion(timeSuggestion) .verifySystemClockWasNotSetAndResetCallTracking() .assertLatestNetworkSuggestion(null); } } @Test @Test public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_lowerPriorityComesFirst() { public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_lowerPriorityComesFirst() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true) .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); Instant networkTime = ARBITRARY_TEST_TIME; Instant networkTime = ARBITRARY_TEST_TIME; Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Loading @@ -686,7 +695,8 @@ public class TimeDetectorStrategyImplTest { @Test @Test public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_higherPriorityComesFirst() { public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_higherPriorityComesFirst() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true) .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); Instant networkTime = ARBITRARY_TEST_TIME; Instant networkTime = ARBITRARY_TEST_TIME; Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); Loading @@ -706,7 +716,8 @@ public class TimeDetectorStrategyImplTest { @Test @Test public void whenHighestPrioritySuggestionIsNotAvailable_fallbacksToNext() { public void whenHighestPrioritySuggestionIsNotAvailable_fallbacksToNext() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true) .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); NetworkTimeSuggestion timeSuggestion = NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME); mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME); Loading @@ -720,7 +731,7 @@ public class TimeDetectorStrategyImplTest { public void suggestionsFromSourceNotListedInPrioritiesList_areIgnored() { public void suggestionsFromSourceNotListedInPrioritiesList_areIgnored() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true) .pokeAutoTimeDetectionEnabled(true) .pokeAutoOriginPriorities(new int[]{ORIGIN_TELEPHONY}); .pokeAutoOriginPriorities(ORIGIN_TELEPHONY); NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion( NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion( ARBITRARY_TEST_TIME); ARBITRARY_TEST_TIME); Loading @@ -730,6 +741,19 @@ public class TimeDetectorStrategyImplTest { .verifySystemClockWasNotSetAndResetCallTracking(); .verifySystemClockWasNotSetAndResetCallTracking(); } } @Test public void autoOriginPrioritiesList_doesNotAffectManualSuggestion() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(false) .pokeAutoOriginPriorities(ORIGIN_TELEPHONY); ManualTimeSuggestion timeSuggestion = mScript.generateManualTimeSuggestion(ARBITRARY_TEST_TIME); mScript.simulateManualTimeSuggestion(timeSuggestion, true /* expectedResult */) .verifySystemClockWasSetAndResetCallTracking(ARBITRARY_TEST_TIME.toEpochMilli()); } /** /** * A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving * A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving * like the real thing should, it also asserts preconditions. * like the real thing should, it also asserts preconditions. Loading Loading @@ -761,7 +785,7 @@ public class TimeDetectorStrategyImplTest { } } @Override @Override public int[] getAutoOriginPriorities() { public int[] autoOriginPriorities() { return mAutoOriginPriorities; return mAutoOriginPriorities; } } Loading Loading @@ -886,8 +910,8 @@ public class TimeDetectorStrategyImplTest { return this; return this; } } Script pokeAutoOriginPriorities(@Origin int[] autoOriginPriorites) { Script pokeAutoOriginPriorities(@Origin int... autoOriginPriorities) { mFakeCallback.pokeAutoOriginPriorities(autoOriginPriorites); mFakeCallback.pokeAutoOriginPriorities(autoOriginPriorities); return this; return this; } } Loading