From a80891bebef9d536ab743f8aaf8254097e15f7dc Mon Sep 17 00:00:00 2001 From: Almaz Mingaleev Date: Mon, 30 Nov 2020 17:47:16 +0000 Subject: [PATCH] Make auto time source suggestions prioritisation configurable. Also get prefix is removed from Callback.getAutoOriginPriorities to make it consistent with the rest of the interface. Extra information added to TimeDetectorStrategyImpl dump. Bug: 172230856 Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/timedetector Change-Id: I2a67414d4f2b9d972507052c7c2c817d59be59ba Merged-In: I2a67414d4f2b9d972507052c7c2c817d59be59ba --- core/res/res/values/config.xml | 8 ++ core/res/res/values/symbols.xml | 1 + .../TimeDetectorStrategyCallbackImpl.java | 39 +++++++--- .../TimeDetectorStrategyImpl.java | 14 +++- .../TimeDetectorStrategyImplTest.java | 74 ++++++++++++------- 5 files changed, 100 insertions(+), 36 deletions(-) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 2b2bf8d8eea56..7fdbad0b76f2d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1532,6 +1532,14 @@ com.android.server.wallpaper.WallpaperManagerService + + + telephony + network + + false diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index c51dca17411e5..36e94e5ed1ab4 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2161,6 +2161,7 @@ + diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java index 5b6de0518999b..4f3f9dce8adbd 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java @@ -16,6 +16,8 @@ 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 android.annotation.NonNull; @@ -30,6 +32,9 @@ import android.os.SystemProperties; import android.provider.Settings; import android.util.Slog; +import com.android.internal.R; +import com.android.server.timedetector.TimeDetectorStrategy.Origin; + import java.time.Instant; import java.util.Objects; @@ -49,6 +54,13 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat private static final Instant TIME_LOWER_BOUND = Instant.ofEpochMilli( 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 * more the system clock will actually be updated. Used to prevent the system clock being set @@ -76,14 +88,7 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat SystemProperties.getInt("ro.sys.time_detector_update_diff", SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT); - // TODO(b/172230856): Obtain these values from configuration. - 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; + mOriginPriorities = getOriginPriorities(context); } @Override @@ -106,7 +111,7 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat } @Override - public int[] getAutoOriginPriorities() { + public int[] autoOriginPriorities() { return mOriginPriorities; } @@ -145,4 +150,20 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat 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; + } + } } diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java index 36a3ddd73d89e..b3c8c9022701a 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java @@ -18,6 +18,8 @@ package com.android.server.timedetector; import static com.android.server.timedetector.TimeDetectorStrategy.originToString; +import static java.util.stream.Collectors.joining; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AlarmManager; @@ -141,7 +143,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { * Returns the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants */ - @Origin int[] getAutoOriginPriorities(); + @Origin int[] autoOriginPriorities(); /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ void acquireWakeLock(); @@ -254,6 +256,14 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { ipw.println("mCallback.systemClockMillis()=" + mCallback.systemClockMillis()); ipw.println("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.increaseIndent(); // level 2 @@ -356,7 +366,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } // Try the different origins one at a time. - int[] originPriorities = mCallback.getAutoOriginPriorities(); + int[] originPriorities = mCallback.autoOriginPriorities(); for (int origin : originPriorities) { TimestampedValue newUtcTime = null; String cause = null; diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java index c23fb8028224e..21396fd0516e5 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java @@ -525,6 +525,7 @@ public class TimeDetectorStrategyImplTest { @Test public void testSuggestNetworkTime_autoTimeEnabled() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) + .pokeAutoOriginPriorities(ORIGIN_NETWORK) .pokeAutoTimeDetectionEnabled(true); NetworkTimeSuggestion timeSuggestion = @@ -541,6 +542,7 @@ public class TimeDetectorStrategyImplTest { @Test public void testSuggestNetworkTime_autoTimeDisabled() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) + .pokeAutoOriginPriorities(ORIGIN_NETWORK) .pokeAutoTimeDetectionEnabled(false); NetworkTimeSuggestion timeSuggestion = @@ -552,10 +554,26 @@ public class TimeDetectorStrategyImplTest { } @Test - public void testSuggestNetworkTime_telephonySuggestionsBeatNetworkSuggestions() { + public void networkTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) + .pokeAutoOriginPriorities(ORIGIN_NETWORK) .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. Instant networkTime1 = ARBITRARY_TEST_TIME; Instant networkTime2 = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); @@ -576,7 +594,7 @@ public class TimeDetectorStrategyImplTest { mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, null) .assertLatestNetworkSuggestion(networkTimeSuggestion1); assertEquals(networkTimeSuggestion1, mScript.peekLatestValidNetworkSuggestion()); - assertNull(mScript.peekBestTelephonySuggestion()); + assertNull("No telephony suggestions were made:", mScript.peekBestTelephonySuggestion()); // Simulate a little time passing. mScript.simulateTimePassing(smallTimeIncrementMillis) @@ -631,7 +649,9 @@ public class TimeDetectorStrategyImplTest { mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) .assertLatestNetworkSuggestion(networkTimeSuggestion2); 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. mScript.simulateAutoTimeDetectionToggle() @@ -646,27 +666,16 @@ public class TimeDetectorStrategyImplTest { mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) .assertLatestNetworkSuggestion(networkTimeSuggestion2); assertEquals(networkTimeSuggestion2, mScript.peekLatestValidNetworkSuggestion()); - assertNull(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); + assertNull( + "Telephony suggestion should still be expired:", + mScript.peekBestTelephonySuggestion()); } @Test public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_lowerPriorityComesFirst() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) - .pokeAutoTimeDetectionEnabled(true); + .pokeAutoTimeDetectionEnabled(true) + .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); Instant networkTime = ARBITRARY_TEST_TIME; Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); @@ -686,7 +695,8 @@ public class TimeDetectorStrategyImplTest { @Test public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_higherPriorityComesFirst() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) - .pokeAutoTimeDetectionEnabled(true); + .pokeAutoTimeDetectionEnabled(true) + .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); Instant networkTime = ARBITRARY_TEST_TIME; Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); @@ -706,7 +716,8 @@ public class TimeDetectorStrategyImplTest { @Test public void whenHighestPrioritySuggestionIsNotAvailable_fallbacksToNext() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) - .pokeAutoTimeDetectionEnabled(true); + .pokeAutoTimeDetectionEnabled(true) + .pokeAutoOriginPriorities(ORIGIN_TELEPHONY, ORIGIN_NETWORK); NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME); @@ -720,7 +731,7 @@ public class TimeDetectorStrategyImplTest { public void suggestionsFromSourceNotListedInPrioritiesList_areIgnored() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true) - .pokeAutoOriginPriorities(new int[]{ORIGIN_TELEPHONY}); + .pokeAutoOriginPriorities(ORIGIN_TELEPHONY); NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion( ARBITRARY_TEST_TIME); @@ -730,6 +741,19 @@ public class TimeDetectorStrategyImplTest { .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 * like the real thing should, it also asserts preconditions. @@ -761,7 +785,7 @@ public class TimeDetectorStrategyImplTest { } @Override - public int[] getAutoOriginPriorities() { + public int[] autoOriginPriorities() { return mAutoOriginPriorities; } @@ -886,8 +910,8 @@ public class TimeDetectorStrategyImplTest { return this; } - Script pokeAutoOriginPriorities(@Origin int[] autoOriginPriorites) { - mFakeCallback.pokeAutoOriginPriorities(autoOriginPriorites); + Script pokeAutoOriginPriorities(@Origin int... autoOriginPriorities) { + mFakeCallback.pokeAutoOriginPriorities(autoOriginPriorities); return this; }