Merge "Make auto time source suggestions prioritisation configurable."
This commit is contained in:
@@ -1532,6 +1532,14 @@
|
||||
<!-- Class name of WallpaperManagerService. -->
|
||||
<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
|
||||
zone update mechanism. -->
|
||||
<bool name="config_enableUpdateableTimeZoneRules">false</bool>
|
||||
|
||||
@@ -2161,6 +2161,7 @@
|
||||
<java-symbol type="string" name="config_defaultNetworkScorerPackageName" />
|
||||
<java-symbol type="string" name="config_persistentDataPackageName" />
|
||||
<java-symbol type="string" name="config_deviceConfiguratorPackageName" />
|
||||
<java-symbol type="array" name="config_autoTimeSourcesPriority" />
|
||||
|
||||
<java-symbol type="layout" name="resolver_list" />
|
||||
<java-symbol type="id" name="resolver_list" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Long> newUtcTime = null;
|
||||
String cause = null;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user