Merge "Change TimeZoneDetectorStrategyImpl to allow geo"
This commit is contained in:
@@ -91,11 +91,13 @@ public final class TimeZoneCapabilities implements Parcelable {
|
||||
|
||||
private final @UserIdInt int mUserId;
|
||||
private final @CapabilityState int mConfigureAutoDetectionEnabled;
|
||||
private final @CapabilityState int mConfigureGeoDetectionEnabled;
|
||||
private final @CapabilityState int mSuggestManualTimeZone;
|
||||
|
||||
private TimeZoneCapabilities(@NonNull Builder builder) {
|
||||
this.mUserId = builder.mUserId;
|
||||
this.mConfigureAutoDetectionEnabled = builder.mConfigureAutoDetectionEnabled;
|
||||
this.mConfigureGeoDetectionEnabled = builder.mConfigureGeoDetectionEnabled;
|
||||
this.mSuggestManualTimeZone = builder.mSuggestManualTimeZone;
|
||||
}
|
||||
|
||||
@@ -103,6 +105,7 @@ public final class TimeZoneCapabilities implements Parcelable {
|
||||
private static TimeZoneCapabilities createFromParcel(Parcel in) {
|
||||
return new TimeZoneCapabilities.Builder(in.readInt())
|
||||
.setConfigureAutoDetectionEnabled(in.readInt())
|
||||
.setConfigureGeoDetectionEnabled(in.readInt())
|
||||
.setSuggestManualTimeZone(in.readInt())
|
||||
.build();
|
||||
}
|
||||
@@ -111,6 +114,7 @@ public final class TimeZoneCapabilities implements Parcelable {
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mUserId);
|
||||
dest.writeInt(mConfigureAutoDetectionEnabled);
|
||||
dest.writeInt(mConfigureGeoDetectionEnabled);
|
||||
dest.writeInt(mSuggestManualTimeZone);
|
||||
}
|
||||
|
||||
@@ -120,8 +124,8 @@ public final class TimeZoneCapabilities implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user's capability state for controlling automatic time zone detection via
|
||||
* {@link TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)} and {@link
|
||||
* Returns the user's capability state for controlling whether automatic time zone detection is
|
||||
* enabled via {@link TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)} and {@link
|
||||
* TimeZoneConfiguration#isAutoDetectionEnabled()}.
|
||||
*/
|
||||
@CapabilityState
|
||||
@@ -129,6 +133,16 @@ public final class TimeZoneCapabilities implements Parcelable {
|
||||
return mConfigureAutoDetectionEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user's capability state for controlling whether geolocation can be used to detect
|
||||
* time zone via {@link TimeZoneDetector#updateConfiguration(TimeZoneConfiguration)} and {@link
|
||||
* TimeZoneConfiguration#isGeoDetectionEnabled()}.
|
||||
*/
|
||||
@CapabilityState
|
||||
public int getConfigureGeoDetectionEnabled() {
|
||||
return mConfigureGeoDetectionEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user's capability state for manually setting the time zone on a device via
|
||||
* {@link TimeZoneDetector#suggestManualTimeZone(ManualTimeZoneSuggestion)}.
|
||||
@@ -157,12 +171,16 @@ public final class TimeZoneCapabilities implements Parcelable {
|
||||
TimeZoneCapabilities that = (TimeZoneCapabilities) o;
|
||||
return mUserId == that.mUserId
|
||||
&& mConfigureAutoDetectionEnabled == that.mConfigureAutoDetectionEnabled
|
||||
&& mConfigureGeoDetectionEnabled == that.mConfigureGeoDetectionEnabled
|
||||
&& mSuggestManualTimeZone == that.mSuggestManualTimeZone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mUserId, mConfigureAutoDetectionEnabled, mSuggestManualTimeZone);
|
||||
return Objects.hash(mUserId,
|
||||
mConfigureAutoDetectionEnabled,
|
||||
mConfigureGeoDetectionEnabled,
|
||||
mSuggestManualTimeZone);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -170,6 +188,7 @@ public final class TimeZoneCapabilities implements Parcelable {
|
||||
return "TimeZoneDetectorCapabilities{"
|
||||
+ "mUserId=" + mUserId
|
||||
+ ", mConfigureAutomaticDetectionEnabled=" + mConfigureAutoDetectionEnabled
|
||||
+ ", mConfigureGeoDetectionEnabled=" + mConfigureGeoDetectionEnabled
|
||||
+ ", mSuggestManualTimeZone=" + mSuggestManualTimeZone
|
||||
+ '}';
|
||||
}
|
||||
@@ -179,6 +198,7 @@ public final class TimeZoneCapabilities implements Parcelable {
|
||||
|
||||
private final @UserIdInt int mUserId;
|
||||
private @CapabilityState int mConfigureAutoDetectionEnabled;
|
||||
private @CapabilityState int mConfigureGeoDetectionEnabled;
|
||||
private @CapabilityState int mSuggestManualTimeZone;
|
||||
|
||||
/**
|
||||
@@ -194,6 +214,12 @@ public final class TimeZoneCapabilities implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the state for the geolocation time zone detection enabled config. */
|
||||
public Builder setConfigureGeoDetectionEnabled(@CapabilityState int value) {
|
||||
this.mConfigureGeoDetectionEnabled = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the state for the suggestManualTimeZone action. */
|
||||
public Builder setSuggestManualTimeZone(@CapabilityState int value) {
|
||||
this.mSuggestManualTimeZone = value;
|
||||
@@ -204,6 +230,7 @@ public final class TimeZoneCapabilities implements Parcelable {
|
||||
@NonNull
|
||||
public TimeZoneCapabilities build() {
|
||||
verifyCapabilitySet(mConfigureAutoDetectionEnabled, "configureAutoDetectionEnabled");
|
||||
verifyCapabilitySet(mConfigureGeoDetectionEnabled, "configureGeoDetectionEnabled");
|
||||
verifyCapabilitySet(mSuggestManualTimeZone, "suggestManualTimeZone");
|
||||
return new TimeZoneCapabilities(this);
|
||||
}
|
||||
|
||||
@@ -67,6 +67,10 @@ public final class TimeZoneConfiguration implements Parcelable {
|
||||
@Property
|
||||
public static final String PROPERTY_AUTO_DETECTION_ENABLED = "autoDetectionEnabled";
|
||||
|
||||
/** See {@link TimeZoneConfiguration#isGeoDetectionEnabled()} for details. */
|
||||
@Property
|
||||
public static final String PROPERTY_GEO_DETECTION_ENABLED = "geoDetectionEnabled";
|
||||
|
||||
private final Bundle mBundle;
|
||||
|
||||
private TimeZoneConfiguration(Builder builder) {
|
||||
@@ -86,7 +90,8 @@ public final class TimeZoneConfiguration implements Parcelable {
|
||||
|
||||
/** Returns {@code true} if all known properties are set. */
|
||||
public boolean isComplete() {
|
||||
return hasProperty(PROPERTY_AUTO_DETECTION_ENABLED);
|
||||
return hasProperty(PROPERTY_AUTO_DETECTION_ENABLED)
|
||||
&& hasProperty(PROPERTY_GEO_DETECTION_ENABLED);
|
||||
}
|
||||
|
||||
/** Returns true if the specified property is set. */
|
||||
@@ -108,6 +113,28 @@ public final class TimeZoneConfiguration implements Parcelable {
|
||||
return mBundle.getBoolean(PROPERTY_AUTO_DETECTION_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the {@link #PROPERTY_GEO_DETECTION_ENABLED} property. This
|
||||
* controls whether a device can use location to determine time zone. Only used when
|
||||
* {@link #isAutoDetectionEnabled()} is true.
|
||||
*
|
||||
* @throws IllegalStateException if the field has not been set
|
||||
*/
|
||||
public boolean isGeoDetectionEnabled() {
|
||||
if (!mBundle.containsKey(PROPERTY_GEO_DETECTION_ENABLED)) {
|
||||
throw new IllegalStateException(PROPERTY_GEO_DETECTION_ENABLED + " is not set");
|
||||
}
|
||||
return mBundle.getBoolean(PROPERTY_GEO_DETECTION_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to merge this with another. The argument configuration properties have
|
||||
* precedence.
|
||||
*/
|
||||
public TimeZoneConfiguration with(TimeZoneConfiguration other) {
|
||||
return new Builder(this).mergeProperties(other).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
@@ -174,6 +201,12 @@ public final class TimeZoneConfiguration implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the desired state of the geolocation time zone detection enabled property. */
|
||||
public Builder setGeoDetectionEnabled(boolean enabled) {
|
||||
this.mBundle.putBoolean(PROPERTY_GEO_DETECTION_ENABLED, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Returns the {@link TimeZoneConfiguration}. */
|
||||
@NonNull
|
||||
public TimeZoneConfiguration build() {
|
||||
|
||||
@@ -33,9 +33,11 @@ public class TimeZoneCapabilitiesTest {
|
||||
public void testEquals() {
|
||||
TimeZoneCapabilities.Builder builder1 = new TimeZoneCapabilities.Builder(ARBITRARY_USER_ID)
|
||||
.setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
|
||||
.setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
|
||||
.setSuggestManualTimeZone(CAPABILITY_POSSESSED);
|
||||
TimeZoneCapabilities.Builder builder2 = new TimeZoneCapabilities.Builder(ARBITRARY_USER_ID)
|
||||
.setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
|
||||
.setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
|
||||
.setSuggestManualTimeZone(CAPABILITY_POSSESSED);
|
||||
{
|
||||
TimeZoneCapabilities one = builder1.build();
|
||||
@@ -57,6 +59,20 @@ public class TimeZoneCapabilitiesTest {
|
||||
assertEquals(one, two);
|
||||
}
|
||||
|
||||
builder2.setConfigureGeoDetectionEnabled(CAPABILITY_NOT_ALLOWED);
|
||||
{
|
||||
TimeZoneCapabilities one = builder1.build();
|
||||
TimeZoneCapabilities two = builder2.build();
|
||||
assertNotEquals(one, two);
|
||||
}
|
||||
|
||||
builder1.setConfigureGeoDetectionEnabled(CAPABILITY_NOT_ALLOWED);
|
||||
{
|
||||
TimeZoneCapabilities one = builder1.build();
|
||||
TimeZoneCapabilities two = builder2.build();
|
||||
assertEquals(one, two);
|
||||
}
|
||||
|
||||
builder2.setSuggestManualTimeZone(CAPABILITY_NOT_ALLOWED);
|
||||
{
|
||||
TimeZoneCapabilities one = builder1.build();
|
||||
@@ -76,12 +92,16 @@ public class TimeZoneCapabilitiesTest {
|
||||
public void testParcelable() {
|
||||
TimeZoneCapabilities.Builder builder = new TimeZoneCapabilities.Builder(ARBITRARY_USER_ID)
|
||||
.setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
|
||||
.setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
|
||||
.setSuggestManualTimeZone(CAPABILITY_POSSESSED);
|
||||
assertRoundTripParcelable(builder.build());
|
||||
|
||||
builder.setConfigureAutoDetectionEnabled(CAPABILITY_NOT_ALLOWED);
|
||||
assertRoundTripParcelable(builder.build());
|
||||
|
||||
builder.setConfigureGeoDetectionEnabled(CAPABILITY_NOT_ALLOWED);
|
||||
assertRoundTripParcelable(builder.build());
|
||||
|
||||
builder.setSuggestManualTimeZone(CAPABILITY_NOT_ALLOWED);
|
||||
assertRoundTripParcelable(builder.build());
|
||||
}
|
||||
|
||||
@@ -29,8 +29,9 @@ public class TimeZoneConfigurationTest {
|
||||
|
||||
@Test
|
||||
public void testBuilder_copyConstructor() {
|
||||
TimeZoneConfiguration.Builder builder1 =
|
||||
new TimeZoneConfiguration.Builder().setAutoDetectionEnabled(true);
|
||||
TimeZoneConfiguration.Builder builder1 = new TimeZoneConfiguration.Builder()
|
||||
.setAutoDetectionEnabled(true)
|
||||
.setGeoDetectionEnabled(true);
|
||||
TimeZoneConfiguration configuration1 = builder1.build();
|
||||
|
||||
TimeZoneConfiguration configuration2 =
|
||||
@@ -41,16 +42,15 @@ public class TimeZoneConfigurationTest {
|
||||
|
||||
@Test
|
||||
public void testIsComplete() {
|
||||
TimeZoneConfiguration incompleteConfiguration =
|
||||
new TimeZoneConfiguration.Builder()
|
||||
.build();
|
||||
assertFalse(incompleteConfiguration.isComplete());
|
||||
TimeZoneConfiguration.Builder builder =
|
||||
new TimeZoneConfiguration.Builder();
|
||||
assertFalse(builder.build().isComplete());
|
||||
|
||||
TimeZoneConfiguration completeConfiguration =
|
||||
new TimeZoneConfiguration.Builder()
|
||||
.setAutoDetectionEnabled(true)
|
||||
.build();
|
||||
assertTrue(completeConfiguration.isComplete());
|
||||
builder.setAutoDetectionEnabled(true);
|
||||
assertFalse(builder.build().isComplete());
|
||||
|
||||
builder.setGeoDetectionEnabled(true);
|
||||
assertTrue(builder.build().isComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -122,6 +122,27 @@ public class TimeZoneConfigurationTest {
|
||||
TimeZoneConfiguration two = builder2.build();
|
||||
assertEquals(one, two);
|
||||
}
|
||||
|
||||
builder1.setGeoDetectionEnabled(true);
|
||||
{
|
||||
TimeZoneConfiguration one = builder1.build();
|
||||
TimeZoneConfiguration two = builder2.build();
|
||||
assertNotEquals(one, two);
|
||||
}
|
||||
|
||||
builder2.setGeoDetectionEnabled(false);
|
||||
{
|
||||
TimeZoneConfiguration one = builder1.build();
|
||||
TimeZoneConfiguration two = builder2.build();
|
||||
assertNotEquals(one, two);
|
||||
}
|
||||
|
||||
builder1.setGeoDetectionEnabled(false);
|
||||
{
|
||||
TimeZoneConfiguration one = builder1.build();
|
||||
TimeZoneConfiguration two = builder2.build();
|
||||
assertEquals(one, two);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -135,5 +156,11 @@ public class TimeZoneConfigurationTest {
|
||||
|
||||
builder.setAutoDetectionEnabled(false);
|
||||
assertRoundTripParcelable(builder.build());
|
||||
|
||||
builder.setGeoDetectionEnabled(false);
|
||||
assertRoundTripParcelable(builder.build());
|
||||
|
||||
builder.setGeoDetectionEnabled(true);
|
||||
assertRoundTripParcelable(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,10 @@ public final class TimeZoneDetectorCallbackImpl implements TimeZoneDetectorStrat
|
||||
builder.setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED);
|
||||
}
|
||||
|
||||
// TODO(b/149014708) Replace this with real logic when the settings storage is fully
|
||||
// implemented.
|
||||
builder.setConfigureGeoDetectionEnabled(CAPABILITY_NOT_SUPPORTED);
|
||||
|
||||
// The ability to make manual time zone suggestions can also be restricted by policy. With
|
||||
// the current logic above, this could lead to a situation where a device hardware does not
|
||||
// support auto detection, the device has been forced into "auto" mode by an admin and the
|
||||
@@ -90,6 +94,7 @@ public final class TimeZoneDetectorCallbackImpl implements TimeZoneDetectorStrat
|
||||
public TimeZoneConfiguration getConfiguration(@UserIdInt int userId) {
|
||||
return new TimeZoneConfiguration.Builder()
|
||||
.setAutoDetectionEnabled(isAutoDetectionEnabled())
|
||||
.setGeoDetectionEnabled(isGeoDetectionEnabled())
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -105,8 +110,11 @@ public final class TimeZoneDetectorCallbackImpl implements TimeZoneDetectorStrat
|
||||
// detection: if we wrote it down then we'd set the default explicitly. That might influence
|
||||
// what happens on later releases that do support auto detection on the same hardware.
|
||||
if (isAutoDetectionSupported()) {
|
||||
final int value = configuration.isAutoDetectionEnabled() ? 1 : 0;
|
||||
Settings.Global.putInt(mCr, Settings.Global.AUTO_TIME_ZONE, value);
|
||||
final int autoEnabledValue = configuration.isAutoDetectionEnabled() ? 1 : 0;
|
||||
Settings.Global.putInt(mCr, Settings.Global.AUTO_TIME_ZONE, autoEnabledValue);
|
||||
|
||||
final boolean geoTzDetectionEnabledValue = configuration.isGeoDetectionEnabled();
|
||||
// TODO(b/149014708) Write this down to user-scoped settings once implemented.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +133,14 @@ public final class TimeZoneDetectorCallbackImpl implements TimeZoneDetectorStrat
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeoDetectionEnabled() {
|
||||
// TODO(b/149014708) Read this from user-scoped settings once implemented. The user's
|
||||
// location toggle will act as an override for this setting, i.e. so that the setting will
|
||||
// return false if the location toggle is disabled.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeviceTimeZoneInitialized() {
|
||||
// timezone.equals("GMT") will be true and only true if the time zone was
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
|
||||
* The internal (in-process) system server API for the {@link
|
||||
* com.android.server.timezonedetector.TimeZoneDetectorService}.
|
||||
*
|
||||
* <p>The methods on this class can be called from any thread.
|
||||
* @hide
|
||||
*/
|
||||
public interface TimeZoneDetectorInternal extends Dumpable.Container {
|
||||
@@ -29,7 +30,7 @@ public interface TimeZoneDetectorInternal extends Dumpable.Container {
|
||||
/**
|
||||
* Suggests the current time zone, determined using geolocation, to the detector. The
|
||||
* detector may ignore the signal based on system settings, whether better information is
|
||||
* available, and so on.
|
||||
* available, and so on. This method may be implemented asynchronously.
|
||||
*/
|
||||
void suggestGeolocationTimeZone(@NonNull GeolocationTimeZoneSuggestion timeZoneSuggestion);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ public final class TimeZoneDetectorInternalImpl implements TimeZoneDetectorInter
|
||||
@NonNull GeolocationTimeZoneSuggestion timeZoneSuggestion) {
|
||||
Objects.requireNonNull(timeZoneSuggestion);
|
||||
|
||||
// All strategy calls must take place on the mHandler thread.
|
||||
mHandler.post(
|
||||
() -> mTimeZoneDetectorStrategy.suggestGeolocationTimeZone(timeZoneSuggestion));
|
||||
}
|
||||
|
||||
@@ -130,6 +130,10 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
|
||||
service.handleAutoTimeZoneConfigChanged();
|
||||
}
|
||||
});
|
||||
// TODO(b/149014708) Listen for changes to geolocation time zone detection enabled config.
|
||||
// This should also include listening to the current user and the current user's location
|
||||
// toggle since the config is user-scoped and the location toggle overrides the geolocation
|
||||
// time zone enabled setting.
|
||||
return service;
|
||||
}
|
||||
|
||||
@@ -280,7 +284,7 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
|
||||
|
||||
void handleConfigurationChanged() {
|
||||
// Note: we could trigger an async time zone detection operation here via a call to
|
||||
// handleAutoTimeZoneDetectionChanged(), but that is triggered in response to the underlying
|
||||
// handleAutoTimeZoneConfigChanged(), but that is triggered in response to the underlying
|
||||
// setting value changing so it is currently unnecessary. If we get to a point where all
|
||||
// configuration changes are guaranteed to happen in response to an updateConfiguration()
|
||||
// call, then we can remove that path and call it here instead.
|
||||
@@ -288,7 +292,6 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
|
||||
// Configuration has changed, but each user may have a different view of the configuration.
|
||||
// It's possible that this will cause unnecessary notifications but that shouldn't be a
|
||||
// problem.
|
||||
|
||||
synchronized (mConfigurationListeners) {
|
||||
final int userCount = mConfigurationListeners.size();
|
||||
for (int userIndex = 0; userIndex < userCount; userIndex++) {
|
||||
|
||||
@@ -30,9 +30,9 @@ import android.util.IndentingPrintWriter;
|
||||
* <p>The strategy uses suggestions to decide whether to modify the device's time zone setting
|
||||
* and what to set it to.
|
||||
*
|
||||
* <p>Most calls will be handled by a single thread but that is not true for all calls. For example
|
||||
* {@link #dump(IndentingPrintWriter, String[])}) may be called on a different thread so
|
||||
* implementations mustvhandle thread safety.
|
||||
* <p>Most calls will be handled by a single thread, but that is not true for all calls. For example
|
||||
* {@link #dump(IndentingPrintWriter, String[])}) may be called on a different thread concurrently
|
||||
* with other operations so implementations must still handle thread safety.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_S
|
||||
import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE;
|
||||
import static android.app.timezonedetector.TimeZoneCapabilities.CAPABILITY_POSSESSED;
|
||||
import static android.app.timezonedetector.TimeZoneConfiguration.PROPERTY_AUTO_DETECTION_ENABLED;
|
||||
import static android.app.timezonedetector.TimeZoneConfiguration.PROPERTY_GEO_DETECTION_ENABLED;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -97,6 +98,12 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
*/
|
||||
boolean isAutoDetectionEnabled();
|
||||
|
||||
/**
|
||||
* Returns whether geolocation can be used for time zone detection when {@link
|
||||
* #isAutoDetectionEnabled()} returns {@code true}.
|
||||
*/
|
||||
boolean isGeoDetectionEnabled();
|
||||
|
||||
/**
|
||||
* Returns true if the device has had an explicit time zone set.
|
||||
*/
|
||||
@@ -200,7 +207,15 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
private ArrayMapWithHistory<Integer, QualifiedTelephonyTimeZoneSuggestion>
|
||||
mSuggestionBySlotIndex = new ArrayMapWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
|
||||
mTelephonySuggestionsBySlotIndex =
|
||||
new ArrayMapWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
|
||||
|
||||
/**
|
||||
* The latest geolocation suggestion received.
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
private ReferenceWithHistory<GeolocationTimeZoneSuggestion> mLatestGeoLocationSuggestion =
|
||||
new ReferenceWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
|
||||
|
||||
@GuardedBy("this")
|
||||
private final List<Dumpable> mDumpables = new ArrayList<>();
|
||||
@@ -284,17 +299,26 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
|
||||
private static boolean containsAutoTimeDetectionProperties(
|
||||
@NonNull TimeZoneConfiguration configuration) {
|
||||
return configuration.hasProperty(PROPERTY_AUTO_DETECTION_ENABLED);
|
||||
return configuration.hasProperty(PROPERTY_AUTO_DETECTION_ENABLED)
|
||||
|| configuration.hasProperty(PROPERTY_GEO_DETECTION_ENABLED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void suggestGeolocationTimeZone(
|
||||
@NonNull GeolocationTimeZoneSuggestion suggestion) {
|
||||
Objects.requireNonNull(suggestion);
|
||||
if (DBG) {
|
||||
Slog.d(LOG_TAG, "Geolocation suggestion received. newSuggestion=" + suggestion);
|
||||
}
|
||||
|
||||
// TODO Implement this.
|
||||
throw new UnsupportedOperationException(
|
||||
"Geo-location time zone detection is not currently implemented");
|
||||
Objects.requireNonNull(suggestion);
|
||||
mLatestGeoLocationSuggestion.set(suggestion);
|
||||
|
||||
// Now perform auto time zone detection. The new suggestion may be used to modify the time
|
||||
// zone setting.
|
||||
if (mCallback.isGeoDetectionEnabled()) {
|
||||
String reason = "New geolocation time zone suggested. suggestion=" + suggestion;
|
||||
doAutoTimeZoneDetection(reason);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -332,12 +356,14 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
new QualifiedTelephonyTimeZoneSuggestion(suggestion, score);
|
||||
|
||||
// Store the suggestion against the correct slotIndex.
|
||||
mSuggestionBySlotIndex.put(suggestion.getSlotIndex(), scoredSuggestion);
|
||||
mTelephonySuggestionsBySlotIndex.put(suggestion.getSlotIndex(), scoredSuggestion);
|
||||
|
||||
// Now perform auto time zone detection. The new suggestion may be used to modify the time
|
||||
// zone setting.
|
||||
String reason = "New telephony time suggested. suggestion=" + suggestion;
|
||||
doAutoTimeZoneDetection(reason);
|
||||
if (!mCallback.isGeoDetectionEnabled()) {
|
||||
String reason = "New telephony time zone suggested. suggestion=" + suggestion;
|
||||
doAutoTimeZoneDetection(reason);
|
||||
}
|
||||
}
|
||||
|
||||
private static int scoreTelephonySuggestion(@NonNull TelephonyTimeZoneSuggestion suggestion) {
|
||||
@@ -363,9 +389,7 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the best available time zone suggestion from all slotIndexes. If it is high-enough
|
||||
* quality and automatic time zone detection is enabled then it will be set on the device. The
|
||||
* outcome can be that this strategy becomes / remains un-opinionated and nothing is set.
|
||||
* Performs automatic time zone detection.
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
private void doAutoTimeZoneDetection(@NonNull String detectionReason) {
|
||||
@@ -374,6 +398,62 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the right suggestions based on the current configuration. This check is potentially
|
||||
// race-prone until this value is set via a call to TimeZoneDetectorStrategy.
|
||||
if (mCallback.isGeoDetectionEnabled()) {
|
||||
doGeolocationTimeZoneDetection(detectionReason);
|
||||
} else {
|
||||
doTelephonyTimeZoneDetection(detectionReason);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the time zone using the latest available geolocation time zone suggestion, if one is
|
||||
* available. The outcome can be that this strategy becomes / remains un-opinionated and nothing
|
||||
* is set.
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
private void doGeolocationTimeZoneDetection(@NonNull String detectionReason) {
|
||||
GeolocationTimeZoneSuggestion latestGeolocationSuggestion =
|
||||
mLatestGeoLocationSuggestion.get();
|
||||
if (latestGeolocationSuggestion == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> zoneIds = latestGeolocationSuggestion.getZoneIds();
|
||||
if (zoneIds == null || zoneIds.isEmpty()) {
|
||||
// This means the client has become uncertain about the time zone or it is certain there
|
||||
// is no known zone. In either case we must leave the existing time zone setting as it
|
||||
// is.
|
||||
return;
|
||||
}
|
||||
|
||||
// GeolocationTimeZoneSuggestion has no measure of quality. We assume all suggestions are
|
||||
// reliable.
|
||||
String zoneId;
|
||||
|
||||
// Introduce bias towards the device's current zone when there are multiple zone suggested.
|
||||
String deviceTimeZone = mCallback.getDeviceTimeZone();
|
||||
if (zoneIds.contains(deviceTimeZone)) {
|
||||
if (DBG) {
|
||||
Slog.d(LOG_TAG,
|
||||
"Geo tz suggestion contains current device time zone. Applying bias.");
|
||||
}
|
||||
zoneId = deviceTimeZone;
|
||||
} else {
|
||||
zoneId = zoneIds.get(0);
|
||||
}
|
||||
setDeviceTimeZoneIfRequired(zoneId, detectionReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the time zone using the latest available telephony time zone suggestions.
|
||||
* Finds the best available time zone suggestion from all slotIndexes. If it is high-enough
|
||||
* quality and automatic time zone detection is enabled then it will be set on the device. The
|
||||
* outcome can be that this strategy becomes / remains un-opinionated and nothing is set.
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
private void doTelephonyTimeZoneDetection(@NonNull String detectionReason) {
|
||||
QualifiedTelephonyTimeZoneSuggestion bestTelephonySuggestion =
|
||||
findBestTelephonySuggestion();
|
||||
|
||||
@@ -468,9 +548,9 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
// slotIndex and find the best. Note that we deliberately do not look at age: the caller can
|
||||
// rate-limit so age is not a strong indicator of confidence. Instead, the callers are
|
||||
// expected to withdraw suggestions they no longer have confidence in.
|
||||
for (int i = 0; i < mSuggestionBySlotIndex.size(); i++) {
|
||||
for (int i = 0; i < mTelephonySuggestionsBySlotIndex.size(); i++) {
|
||||
QualifiedTelephonyTimeZoneSuggestion candidateSuggestion =
|
||||
mSuggestionBySlotIndex.valueAt(i);
|
||||
mTelephonySuggestionsBySlotIndex.valueAt(i);
|
||||
if (candidateSuggestion == null) {
|
||||
// Unexpected
|
||||
continue;
|
||||
@@ -505,14 +585,10 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
@Override
|
||||
public synchronized void handleAutoTimeZoneConfigChanged() {
|
||||
if (DBG) {
|
||||
Slog.d(LOG_TAG, "handleTimeZoneDetectionChange() called");
|
||||
}
|
||||
if (mCallback.isAutoDetectionEnabled()) {
|
||||
// When the user enabled time zone detection, run the time zone detection and change the
|
||||
// device time zone if possible.
|
||||
String reason = "Auto time zone detection setting enabled.";
|
||||
doAutoTimeZoneDetection(reason);
|
||||
Slog.d(LOG_TAG, "handleAutoTimeZoneConfigChanged()");
|
||||
}
|
||||
|
||||
doAutoTimeZoneDetection("handleAutoTimeZoneConfigChanged()");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -532,15 +608,21 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
ipw.println("mCallback.isDeviceTimeZoneInitialized()="
|
||||
+ mCallback.isDeviceTimeZoneInitialized());
|
||||
ipw.println("mCallback.getDeviceTimeZone()=" + mCallback.getDeviceTimeZone());
|
||||
ipw.println("mCallback.isGeoDetectionEnabled()=" + mCallback.isGeoDetectionEnabled());
|
||||
|
||||
ipw.println("Time zone change log:");
|
||||
ipw.increaseIndent(); // level 2
|
||||
mTimeZoneChangesLog.dump(ipw);
|
||||
ipw.decreaseIndent(); // level 2
|
||||
|
||||
ipw.println("Geolocation suggestion history:");
|
||||
ipw.increaseIndent(); // level 2
|
||||
mLatestGeoLocationSuggestion.dump(ipw);
|
||||
ipw.decreaseIndent(); // level 2
|
||||
|
||||
ipw.println("Telephony suggestion history:");
|
||||
ipw.increaseIndent(); // level 2
|
||||
mSuggestionBySlotIndex.dump(ipw);
|
||||
mTelephonySuggestionsBySlotIndex.dump(ipw);
|
||||
ipw.decreaseIndent(); // level 2
|
||||
ipw.decreaseIndent(); // level 1
|
||||
|
||||
@@ -555,7 +637,15 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
@VisibleForTesting
|
||||
public synchronized QualifiedTelephonyTimeZoneSuggestion getLatestTelephonySuggestion(
|
||||
int slotIndex) {
|
||||
return mSuggestionBySlotIndex.get(slotIndex);
|
||||
return mTelephonySuggestionsBySlotIndex.get(slotIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* A method used to inspect strategy state during tests. Not intended for general use.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public GeolocationTimeZoneSuggestion getLatestGeolocationSuggestion() {
|
||||
return mLatestGeoLocationSuggestion.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,9 @@ import android.app.timezonedetector.TimeZoneCapabilities;
|
||||
import android.app.timezonedetector.TimeZoneConfiguration;
|
||||
import android.util.IndentingPrintWriter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class FakeTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
|
||||
|
||||
private StrategyListener mListener;
|
||||
@@ -41,6 +44,7 @@ class FakeTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
|
||||
private TelephonyTimeZoneSuggestion mLastTelephonySuggestion;
|
||||
private boolean mHandleAutoTimeZoneConfigChangedCalled;
|
||||
private boolean mDumpCalled;
|
||||
private final List<Dumpable> mDumpables = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void setStrategyListener(@NonNull StrategyListener listener) {
|
||||
@@ -105,7 +109,7 @@ class FakeTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
|
||||
|
||||
@Override
|
||||
public void addDumpable(Dumpable dumpable) {
|
||||
// Stubbed
|
||||
mDumpables.add(dumpable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -149,4 +153,8 @@ class FakeTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
|
||||
void verifyDumpCalled() {
|
||||
assertTrue(mDumpCalled);
|
||||
}
|
||||
|
||||
void verifyHasDumpable(Dumpable expected) {
|
||||
assertTrue(mDumpables.contains(expected));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,16 @@ public class TimeZoneDetectorInternalImplTest {
|
||||
mFakeTimeZoneDetectorStrategy.verifySuggestGeolocationTimeZoneCalled(timeZoneSuggestion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddDumpable() throws Exception {
|
||||
Dumpable stubbedDumpable = mock(Dumpable.class);
|
||||
|
||||
mTimeZoneDetectorInternal.addDumpable(stubbedDumpable);
|
||||
mTestHandler.assertTotalMessagesEnqueued(0);
|
||||
|
||||
mFakeTimeZoneDetectorStrategy.verifyHasDumpable(stubbedDumpable);
|
||||
}
|
||||
|
||||
private static GeolocationTimeZoneSuggestion createGeolocationTimeZoneSuggestion() {
|
||||
return new GeolocationTimeZoneSuggestion(ARBITRARY_ZONE_IDS);
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TimeZoneDetectorServiceTest {
|
||||
@@ -252,6 +253,39 @@ public class TimeZoneDetectorServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = SecurityException.class)
|
||||
public void testSuggestGeolocationTimeZone_withoutPermission() {
|
||||
doThrow(new SecurityException("Mock"))
|
||||
.when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
|
||||
GeolocationTimeZoneSuggestion timeZoneSuggestion = createGeolocationTimeZoneSuggestion();
|
||||
|
||||
try {
|
||||
mTimeZoneDetectorService.suggestGeolocationTimeZone(timeZoneSuggestion);
|
||||
fail();
|
||||
} finally {
|
||||
verify(mMockContext).enforceCallingOrSelfPermission(
|
||||
eq(android.Manifest.permission.SET_TIME_ZONE),
|
||||
anyString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuggestGeolocationTimeZone() throws Exception {
|
||||
doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
|
||||
|
||||
GeolocationTimeZoneSuggestion timeZoneSuggestion = createGeolocationTimeZoneSuggestion();
|
||||
|
||||
mTimeZoneDetectorService.suggestGeolocationTimeZone(timeZoneSuggestion);
|
||||
mTestHandler.assertTotalMessagesEnqueued(1);
|
||||
|
||||
verify(mMockContext).enforceCallingOrSelfPermission(
|
||||
eq(android.Manifest.permission.SET_TIME_ZONE),
|
||||
anyString());
|
||||
|
||||
mTestHandler.waitForMessagesToBeProcessed();
|
||||
mFakeTimeZoneDetectorStrategy.verifySuggestGeolocationTimeZoneCalled(timeZoneSuggestion);
|
||||
}
|
||||
|
||||
@Test(expected = SecurityException.class)
|
||||
public void testSuggestManualTimeZone_withoutPermission() {
|
||||
doThrow(new SecurityException("Mock"))
|
||||
@@ -346,7 +380,7 @@ public class TimeZoneDetectorServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoTimeZoneDetectionChanged() throws Exception {
|
||||
public void testHandleAutoTimeZoneConfigChanged() throws Exception {
|
||||
mTimeZoneDetectorService.handleAutoTimeZoneConfigChanged();
|
||||
mTestHandler.assertTotalMessagesEnqueued(1);
|
||||
mTestHandler.waitForMessagesToBeProcessed();
|
||||
@@ -370,10 +404,15 @@ public class TimeZoneDetectorServiceTest {
|
||||
private static TimeZoneCapabilities createTimeZoneCapabilities() {
|
||||
return new TimeZoneCapabilities.Builder(ARBITRARY_USER_ID)
|
||||
.setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
|
||||
.setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
|
||||
.setSuggestManualTimeZone(CAPABILITY_POSSESSED)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static GeolocationTimeZoneSuggestion createGeolocationTimeZoneSuggestion() {
|
||||
return new GeolocationTimeZoneSuggestion(Arrays.asList("TestZoneId"));
|
||||
}
|
||||
|
||||
private static ManualTimeZoneSuggestion createManualTimeZoneSuggestion() {
|
||||
return new ManualTimeZoneSuggestion("TestZoneId");
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.timezonedetector.ManualTimeZoneSuggestion;
|
||||
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
|
||||
@@ -56,10 +57,10 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@@ -93,16 +94,26 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
TELEPHONY_SCORE_HIGHEST),
|
||||
};
|
||||
|
||||
private static final TimeZoneConfiguration CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED =
|
||||
private static final TimeZoneConfiguration CONFIG_AUTO_ENABLED =
|
||||
new TimeZoneConfiguration.Builder()
|
||||
.setAutoDetectionEnabled(true)
|
||||
.build();
|
||||
|
||||
private static final TimeZoneConfiguration CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED =
|
||||
private static final TimeZoneConfiguration CONFIG_AUTO_DISABLED =
|
||||
new TimeZoneConfiguration.Builder()
|
||||
.setAutoDetectionEnabled(false)
|
||||
.build();
|
||||
|
||||
private static final TimeZoneConfiguration CONFIG_GEO_DETECTION_DISABLED =
|
||||
new TimeZoneConfiguration.Builder()
|
||||
.setGeoDetectionEnabled(false)
|
||||
.build();
|
||||
|
||||
private static final TimeZoneConfiguration CONFIG_GEO_DETECTION_ENABLED =
|
||||
new TimeZoneConfiguration.Builder()
|
||||
.setGeoDetectionEnabled(true)
|
||||
.build();
|
||||
|
||||
private TimeZoneDetectorStrategyImpl mTimeZoneDetectorStrategy;
|
||||
private FakeCallback mFakeCallback;
|
||||
private MockStrategyListener mMockStrategyListener;
|
||||
@@ -120,7 +131,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
public void testGetCapabilities() {
|
||||
new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
TimeZoneCapabilities expectedCapabilities = mFakeCallback.getCapabilities(USER_ID);
|
||||
assertEquals(expectedCapabilities, mTimeZoneDetectorStrategy.getCapabilities(USER_ID));
|
||||
}
|
||||
@@ -129,7 +140,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
public void testGetConfiguration() {
|
||||
new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
TimeZoneConfiguration expectedConfiguration = mFakeCallback.getConfiguration(USER_ID);
|
||||
assertTrue(expectedConfiguration.isComplete());
|
||||
assertEquals(expectedConfiguration, mTimeZoneDetectorStrategy.getConfiguration(USER_ID));
|
||||
@@ -140,20 +151,22 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
Script script = new Script();
|
||||
|
||||
script.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
{
|
||||
// Check the fake test infra is doing what is expected.
|
||||
TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
|
||||
assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureAutoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureGeoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_NOT_APPLICABLE, capabilities.getSuggestManualTimeZone());
|
||||
}
|
||||
|
||||
script.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED);
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
{
|
||||
// Check the fake test infra is doing what is expected.
|
||||
TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
|
||||
assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureAutoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureGeoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_POSSESSED, capabilities.getSuggestManualTimeZone());
|
||||
}
|
||||
}
|
||||
@@ -163,20 +176,22 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
Script script = new Script();
|
||||
|
||||
script.initializeUser(USER_ID, UserCase.RESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
{
|
||||
// Check the fake test infra is doing what is expected.
|
||||
TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
|
||||
assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureGeoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSuggestManualTimeZone());
|
||||
}
|
||||
|
||||
script.initializeUser(USER_ID, UserCase.RESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED);
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
{
|
||||
// Check the fake test infra is doing what is expected.
|
||||
TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
|
||||
assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureGeoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSuggestManualTimeZone());
|
||||
}
|
||||
}
|
||||
@@ -186,20 +201,22 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
Script script = new Script();
|
||||
|
||||
script.initializeUser(USER_ID, UserCase.AUTO_DETECT_NOT_SUPPORTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
{
|
||||
// Check the fake test infra is doing what is expected.
|
||||
TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
|
||||
assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureAutoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_POSSESSED, capabilities.getSuggestManualTimeZone());
|
||||
}
|
||||
|
||||
script.initializeUser(USER_ID, UserCase.AUTO_DETECT_NOT_SUPPORTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED);
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
{
|
||||
// Check the fake test infra is doing what is expected.
|
||||
TimeZoneCapabilities capabilities = mFakeCallback.getCapabilities(USER_ID);
|
||||
assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureAutoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabled());
|
||||
assertEquals(CAPABILITY_POSSESSED, capabilities.getSuggestManualTimeZone());
|
||||
}
|
||||
}
|
||||
@@ -208,42 +225,61 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
public void testUpdateConfiguration_unrestricted() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
|
||||
// Set the configuration with auto detection enabled.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */);
|
||||
|
||||
// Nothing should have happened: it was initialized in this state.
|
||||
script.verifyConfigurationNotChanged();
|
||||
|
||||
// Update the configuration with auto detection disabled.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED);
|
||||
script.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */);
|
||||
|
||||
// The settings should have been changed and the StrategyListener onChange() called.
|
||||
script.verifyConfigurationChangedAndReset(
|
||||
USER_ID, CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED);
|
||||
script.verifyConfigurationChangedAndReset(USER_ID,
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
|
||||
// Update the configuration with auto detection enabled.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */);
|
||||
|
||||
// The settings should have been changed and the StrategyListener onChange() called.
|
||||
script.verifyConfigurationChangedAndReset(USER_ID, CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
script.verifyConfigurationChangedAndReset(USER_ID,
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
|
||||
// Update the configuration to enable geolocation time zone detection.
|
||||
script.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_GEO_DETECTION_ENABLED, true /* expectedResult */);
|
||||
|
||||
// The settings should have been changed and the StrategyListener onChange() called.
|
||||
script.verifyConfigurationChangedAndReset(USER_ID,
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateConfiguration_restricted() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.RESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
|
||||
// Try to update the configuration with auto detection disabled.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED);
|
||||
script.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_DISABLED, false /* expectedResult */);
|
||||
|
||||
// The settings should not have been changed: user shouldn't have the capabilities.
|
||||
script.verifyConfigurationNotChanged();
|
||||
|
||||
// Update the configuration with auto detection enabled.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
script.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_ENABLED, false /* expectedResult */);
|
||||
|
||||
// The settings should not have been changed: user shouldn't have the capabilities.
|
||||
script.verifyConfigurationNotChanged();
|
||||
|
||||
// Update the configuration to enable geolocation time zone detection.
|
||||
script.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_GEO_DETECTION_ENABLED, false /* expectedResult */);
|
||||
|
||||
// The settings should not have been changed: user shouldn't have the capabilities.
|
||||
script.verifyConfigurationNotChanged();
|
||||
@@ -253,16 +289,18 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
public void testUpdateConfiguration_autoDetectNotSupported() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.AUTO_DETECT_NOT_SUPPORTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
|
||||
// Try to update the configuration with auto detection disabled.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED);
|
||||
script.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_DISABLED, false /* expectedResult */);
|
||||
|
||||
// The settings should not have been changed: user shouldn't have the capabilities.
|
||||
script.verifyConfigurationNotChanged();
|
||||
|
||||
// Update the configuration with auto detection enabled.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
script.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_ENABLED, false /* expectedResult */);
|
||||
|
||||
// The settings should not have been changed: user shouldn't have the capabilities.
|
||||
script.verifyConfigurationNotChanged();
|
||||
@@ -276,7 +314,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
createEmptySlotIndex2Suggestion();
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED)
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
script.simulateTelephonyTimeZoneSuggestion(slotIndex1TimeZoneSuggestion)
|
||||
@@ -308,6 +346,10 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
|
||||
}
|
||||
|
||||
/**
|
||||
* Telephony suggestions have quality metadata. Ordinarily, low scoring suggestions are not
|
||||
* used, but this is not true if the device's time zone setting is uninitialized.
|
||||
*/
|
||||
@Test
|
||||
public void testTelephonySuggestionsWhenTimeZoneUninitialized() {
|
||||
assertTrue(TELEPHONY_SCORE_LOW < TELEPHONY_SCORE_USAGE_THRESHOLD);
|
||||
@@ -319,7 +361,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
|
||||
// A low quality suggestions will not be taken: The device time zone setting is left
|
||||
// uninitialized.
|
||||
@@ -376,16 +418,16 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
/**
|
||||
* Confirms that toggling the auto time zone detection setting has the expected behavior when
|
||||
* the strategy is "opinionated".
|
||||
* the strategy is "opinionated" when using telephony auto detection.
|
||||
*/
|
||||
@Test
|
||||
public void testTogglingAutoTimeZoneDetection() {
|
||||
public void testTogglingAutoDetection_autoTelephony() {
|
||||
Script script = new Script();
|
||||
|
||||
for (TelephonyTestCase testCase : TELEPHONY_TEST_CASES) {
|
||||
// Start with the device in a known state.
|
||||
script.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED)
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
TelephonyTimeZoneSuggestion suggestion =
|
||||
@@ -405,7 +447,8 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
|
||||
|
||||
// Toggling the time zone setting on should cause the device setting to be set.
|
||||
script.simulateAutoTimeZoneDetectionEnabled(USER_ID, true);
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED,
|
||||
true /* expectedResult */);
|
||||
|
||||
// When time zone detection is already enabled the suggestion (if it scores highly
|
||||
// enough) should be set immediately.
|
||||
@@ -422,7 +465,8 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
|
||||
|
||||
// Toggling the time zone setting should off should do nothing.
|
||||
script.simulateAutoTimeZoneDetectionEnabled(USER_ID, false)
|
||||
script.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneNotChanged();
|
||||
|
||||
// Assert internal service state.
|
||||
@@ -437,7 +481,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
public void testTelephonySuggestionsSingleSlotId() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED)
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
for (TelephonyTestCase testCase : TELEPHONY_TEST_CASES) {
|
||||
@@ -451,8 +495,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
*/
|
||||
|
||||
// Each test case will have the same or lower score than the last.
|
||||
ArrayList<TelephonyTestCase> descendingCasesByScore =
|
||||
new ArrayList<>(Arrays.asList(TELEPHONY_TEST_CASES));
|
||||
List<TelephonyTestCase> descendingCasesByScore = list(TELEPHONY_TEST_CASES);
|
||||
Collections.reverse(descendingCasesByScore);
|
||||
|
||||
for (TelephonyTestCase testCase : descendingCasesByScore) {
|
||||
@@ -504,7 +547,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED)
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID)
|
||||
// Initialize the latest suggestions as empty so we don't need to worry about nulls
|
||||
// below for the first loop.
|
||||
@@ -583,15 +626,15 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link TimeZoneDetectorStrategyImpl.Callback} is left to detect whether changing
|
||||
* the time zone is actually necessary. This test proves that the service doesn't assume it
|
||||
* knows the current setting.
|
||||
* The {@link TimeZoneDetectorStrategyImpl.Callback} is left to detect whether changing the time
|
||||
* zone is actually necessary. This test proves that the strategy doesn't assume it knows the
|
||||
* current settings.
|
||||
*/
|
||||
@Test
|
||||
public void testTelephonySuggestionTimeZoneDetectorStrategyDoesNotAssumeCurrentSetting() {
|
||||
public void testTelephonySuggestionStrategyDoesNotAssumeCurrentSetting_autoTelephony() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED);
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED));
|
||||
|
||||
TelephonyTestCase testCase = newTelephonyTestCase(
|
||||
MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE, TELEPHONY_SCORE_HIGH);
|
||||
@@ -609,26 +652,40 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
// Toggling time zone detection should set the device time zone only if the current setting
|
||||
// value is different from the most recent telephony suggestion.
|
||||
script.simulateAutoTimeZoneDetectionEnabled(USER_ID, false)
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.simulateAutoTimeZoneDetectionEnabled(USER_ID, true)
|
||||
.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneNotChanged();
|
||||
|
||||
// Simulate a user turning auto detection off, a new suggestion being made while auto
|
||||
// detection is off, and the user turning it on again.
|
||||
script.simulateAutoTimeZoneDetectionEnabled(USER_ID, false)
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
|
||||
.simulateTelephonyTimeZoneSuggestion(newYorkSuggestion)
|
||||
.verifyTimeZoneNotChanged();
|
||||
// Latest suggestion should be used.
|
||||
script.simulateAutoTimeZoneDetectionEnabled(USER_ID, true)
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneChangedAndReset(newYorkSuggestion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualSuggestion_unrestricted_simulateAutoTimeZoneEnabled() {
|
||||
public void testManualSuggestion_autoDetectionEnabled_autoTelephony() {
|
||||
checkManualSuggestion_autoDetectionEnabled(false /* geoDetectionEnabled */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualSuggestion_autoDetectionEnabled_autoGeo() {
|
||||
checkManualSuggestion_autoDetectionEnabled(true /* geoDetectionEnabled */);
|
||||
}
|
||||
|
||||
private void checkManualSuggestion_autoDetectionEnabled(boolean geoDetectionEnabled) {
|
||||
TimeZoneConfiguration geoTzEnabledConfig =
|
||||
new TimeZoneConfiguration.Builder()
|
||||
.setGeoDetectionEnabled(geoDetectionEnabled)
|
||||
.build();
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED)
|
||||
CONFIG_AUTO_ENABLED.with(geoTzEnabledConfig))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
// Auto time zone detection is enabled so the manual suggestion should be ignored.
|
||||
@@ -641,7 +698,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
public void testManualSuggestion_restricted_simulateAutoTimeZoneEnabled() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.RESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED)
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
// Auto time zone detection is enabled so the manual suggestion should be ignored.
|
||||
@@ -654,7 +711,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
public void testManualSuggestion_autoDetectNotSupported_simulateAutoTimeZoneEnabled() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.AUTO_DETECT_NOT_SUPPORTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_ENABLED)
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
// Auto time zone detection is enabled so the manual suggestion should be ignored.
|
||||
@@ -668,7 +725,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
public void testManualSuggestion_unrestricted_autoTimeZoneDetectionDisabled() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED)
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
// Auto time zone detection is disabled so the manual suggestion should be used.
|
||||
@@ -682,7 +739,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
public void testManualSuggestion_restricted_autoTimeZoneDetectionDisabled() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.RESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED)
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
// Restricted users do not have the capability.
|
||||
@@ -696,7 +753,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
public void testManualSuggestion_autoDetectNotSupported_autoTimeZoneDetectionDisabled() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.AUTO_DETECT_NOT_SUPPORTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED)
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
// Unrestricted users have the capability.
|
||||
@@ -706,11 +763,262 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
.verifyTimeZoneChangedAndReset(manualSuggestion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoSuggestion_uncertain() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
GeolocationTimeZoneSuggestion uncertainSuggestion = createUncertainGeoLocationSuggestion();
|
||||
|
||||
script.simulateGeolocationTimeZoneSuggestion(uncertainSuggestion)
|
||||
.verifyTimeZoneNotChanged();
|
||||
|
||||
// Assert internal service state.
|
||||
assertEquals(uncertainSuggestion,
|
||||
mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoSuggestion_noZones() {
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
GeolocationTimeZoneSuggestion noZonesSuggestion = createGeoLocationSuggestion(list());
|
||||
|
||||
script.simulateGeolocationTimeZoneSuggestion(noZonesSuggestion)
|
||||
.verifyTimeZoneNotChanged();
|
||||
|
||||
// Assert internal service state.
|
||||
assertEquals(noZonesSuggestion, mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeoSuggestion_oneZone() {
|
||||
GeolocationTimeZoneSuggestion suggestion =
|
||||
createGeoLocationSuggestion(list("Europe/London"));
|
||||
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
script.simulateGeolocationTimeZoneSuggestion(suggestion)
|
||||
.verifyTimeZoneChangedAndReset("Europe/London");
|
||||
|
||||
// Assert internal service state.
|
||||
assertEquals(suggestion, mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
|
||||
}
|
||||
|
||||
/**
|
||||
* In the current implementation, the first zone ID is always used unless the device is set to
|
||||
* one of the other options. This is "stickiness" - the device favors the zone it is currently
|
||||
* set to until that unambiguously can't be correct.
|
||||
*/
|
||||
@Test
|
||||
public void testGeoSuggestion_multiZone() {
|
||||
GeolocationTimeZoneSuggestion londonOnlySuggestion =
|
||||
createGeoLocationSuggestion(list("Europe/London"));
|
||||
GeolocationTimeZoneSuggestion londonOrParisSuggestion =
|
||||
createGeoLocationSuggestion(list("Europe/Paris", "Europe/London"));
|
||||
GeolocationTimeZoneSuggestion parisOnlySuggestion =
|
||||
createGeoLocationSuggestion(list("Europe/Paris"));
|
||||
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
script.simulateGeolocationTimeZoneSuggestion(londonOnlySuggestion)
|
||||
.verifyTimeZoneChangedAndReset("Europe/London");
|
||||
assertEquals(londonOnlySuggestion,
|
||||
mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
|
||||
|
||||
// Confirm bias towards the current device zone when there's multiple zones to choose from.
|
||||
script.simulateGeolocationTimeZoneSuggestion(londonOrParisSuggestion)
|
||||
.verifyTimeZoneNotChanged();
|
||||
assertEquals(londonOrParisSuggestion,
|
||||
mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
|
||||
|
||||
script.simulateGeolocationTimeZoneSuggestion(parisOnlySuggestion)
|
||||
.verifyTimeZoneChangedAndReset("Europe/Paris");
|
||||
assertEquals(parisOnlySuggestion,
|
||||
mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
|
||||
|
||||
// Now the suggestion that previously left the device on Europe/London will leave the device
|
||||
// on Europe/Paris.
|
||||
script.simulateGeolocationTimeZoneSuggestion(londonOrParisSuggestion)
|
||||
.verifyTimeZoneNotChanged();
|
||||
assertEquals(londonOrParisSuggestion,
|
||||
mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that toggling the auto time zone detection enabled setting has the expected behavior
|
||||
* when the strategy is "opinionated" and "un-opinionated" when in geolocation detection is
|
||||
* enabled.
|
||||
*/
|
||||
@Test
|
||||
public void testTogglingAutoDetectionEnabled_autoGeo() {
|
||||
GeolocationTimeZoneSuggestion geolocationSuggestion =
|
||||
createGeoLocationSuggestion(list("Europe/London"));
|
||||
GeolocationTimeZoneSuggestion uncertainGeolocationSuggestion =
|
||||
createUncertainGeoLocationSuggestion();
|
||||
ManualTimeZoneSuggestion manualSuggestion = createManualSuggestion("Europe/Paris");
|
||||
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_ENABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
script.simulateGeolocationTimeZoneSuggestion(geolocationSuggestion);
|
||||
|
||||
// When time zone detection is not enabled, the time zone suggestion will not be set.
|
||||
script.verifyTimeZoneNotChanged();
|
||||
|
||||
// Assert internal service state.
|
||||
assertEquals(geolocationSuggestion,
|
||||
mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
|
||||
|
||||
// Toggling the time zone setting on should cause the device setting to be set.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneChangedAndReset("Europe/London");
|
||||
|
||||
// Toggling the time zone setting should off should do nothing because the device is now
|
||||
// set to that time zone.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneNotChanged();
|
||||
|
||||
// Now toggle auto time zone setting, and confirm it is opinionated.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
|
||||
.simulateManualTimeZoneSuggestion(
|
||||
USER_ID, manualSuggestion, true /* expectedResult */)
|
||||
.verifyTimeZoneChangedAndReset(manualSuggestion)
|
||||
.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneChangedAndReset("Europe/London");
|
||||
|
||||
// Now withdraw the geolocation suggestion, and assert the strategy is no longer
|
||||
// opinionated.
|
||||
/* expectedResult */
|
||||
script.simulateGeolocationTimeZoneSuggestion(uncertainGeolocationSuggestion)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.simulateManualTimeZoneSuggestion(
|
||||
USER_ID, manualSuggestion, true /* expectedResult */)
|
||||
.verifyTimeZoneChangedAndReset(manualSuggestion)
|
||||
.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneNotChanged();
|
||||
|
||||
// Assert internal service state.
|
||||
assertEquals(uncertainGeolocationSuggestion,
|
||||
mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that changing the geolocation time zone detection enabled setting has the expected
|
||||
* behavior, i.e. immediately recompute the detected time zone using different signals.
|
||||
*/
|
||||
@Test
|
||||
public void testChangingGeoDetectionEnabled() {
|
||||
GeolocationTimeZoneSuggestion geolocationSuggestion =
|
||||
createGeoLocationSuggestion(list("Europe/London"));
|
||||
TelephonyTimeZoneSuggestion telephonySuggestion = createTelephonySuggestion(
|
||||
SLOT_INDEX1, MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE,
|
||||
"Europe/Paris");
|
||||
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
// Add suggestions. Nothing should happen as time zone detection is disabled.
|
||||
script.simulateGeolocationTimeZoneSuggestion(geolocationSuggestion)
|
||||
.verifyTimeZoneNotChanged();
|
||||
script.simulateTelephonyTimeZoneSuggestion(telephonySuggestion)
|
||||
.verifyTimeZoneNotChanged();
|
||||
|
||||
// Assert internal service state.
|
||||
assertEquals(geolocationSuggestion,
|
||||
mTimeZoneDetectorStrategy.getLatestGeolocationSuggestion());
|
||||
assertEquals(telephonySuggestion,
|
||||
mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1).suggestion);
|
||||
|
||||
// Toggling the time zone detection enabled setting on should cause the device setting to be
|
||||
// set from the telephony signal, as we've started with geolocation time zone detection
|
||||
// disabled.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneChangedAndReset(telephonySuggestion);
|
||||
|
||||
// Changing the detection to enable geo detection should cause the device tz setting to
|
||||
// change to the geo suggestion.
|
||||
script.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_GEO_DETECTION_ENABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneChangedAndReset(geolocationSuggestion.getZoneIds().get(0));
|
||||
|
||||
// Changing the detection to disable geo detection should cause the device tz setting to
|
||||
// change to the telephony suggestion.
|
||||
script.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_GEO_DETECTION_DISABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneChangedAndReset(telephonySuggestion);
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link TimeZoneDetectorStrategyImpl.Callback} is left to detect whether changing the time
|
||||
* zone is actually necessary. This test proves that the strategy doesn't assume it knows the
|
||||
* current setting.
|
||||
*/
|
||||
@Test
|
||||
public void testTimeZoneDetectorStrategyDoesNotAssumeCurrentSetting_autoGeo() {
|
||||
GeolocationTimeZoneSuggestion losAngelesSuggestion =
|
||||
createGeoLocationSuggestion(list("America/Los_Angeles"));
|
||||
GeolocationTimeZoneSuggestion newYorkSuggestion =
|
||||
createGeoLocationSuggestion(list("America/New_York"));
|
||||
|
||||
Script script = new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_ENABLED.with(CONFIG_GEO_DETECTION_ENABLED));
|
||||
|
||||
// Initialization.
|
||||
script.simulateGeolocationTimeZoneSuggestion(losAngelesSuggestion)
|
||||
.verifyTimeZoneChangedAndReset("America/Los_Angeles");
|
||||
// Suggest it again - it should not be set because it is already set.
|
||||
script.simulateGeolocationTimeZoneSuggestion(losAngelesSuggestion)
|
||||
.verifyTimeZoneNotChanged();
|
||||
|
||||
// Toggling time zone detection should set the device time zone only if the current setting
|
||||
// value is different from the most recent telephony suggestion.
|
||||
/* expectedResult */
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.simulateUpdateConfiguration(
|
||||
USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneNotChanged();
|
||||
|
||||
// Simulate a user turning auto detection off, a new suggestion being made while auto
|
||||
// detection is off, and the user turning it on again.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_DISABLED, true /* expectedResult */)
|
||||
.simulateGeolocationTimeZoneSuggestion(newYorkSuggestion)
|
||||
.verifyTimeZoneNotChanged();
|
||||
// Latest suggestion should be used.
|
||||
script.simulateUpdateConfiguration(USER_ID, CONFIG_AUTO_ENABLED, true /* expectedResult */)
|
||||
.verifyTimeZoneChangedAndReset("America/New_York");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddDumpable() {
|
||||
new Script()
|
||||
.initializeUser(USER_ID, UserCase.UNRESTRICTED,
|
||||
CONFIG_AUTO_TIME_ZONE_DETECTION_DISABLED)
|
||||
CONFIG_AUTO_DISABLED.with(CONFIG_GEO_DETECTION_DISABLED))
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
|
||||
|
||||
AtomicBoolean dumpCalled = new AtomicBoolean(false);
|
||||
@@ -733,6 +1041,15 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
return new ManualTimeZoneSuggestion(zoneId);
|
||||
}
|
||||
|
||||
private static TelephonyTimeZoneSuggestion createTelephonySuggestion(
|
||||
int slotIndex, @MatchType int matchType, @Quality int quality, String zoneId) {
|
||||
return new TelephonyTimeZoneSuggestion.Builder(slotIndex)
|
||||
.setMatchType(matchType)
|
||||
.setQuality(quality)
|
||||
.setZoneId(zoneId)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static TelephonyTimeZoneSuggestion createEmptySlotIndex1Suggestion() {
|
||||
return new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX1).build();
|
||||
}
|
||||
@@ -741,6 +1058,17 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
return new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX2).build();
|
||||
}
|
||||
|
||||
private static GeolocationTimeZoneSuggestion createUncertainGeoLocationSuggestion() {
|
||||
return createGeoLocationSuggestion(null);
|
||||
}
|
||||
|
||||
private static GeolocationTimeZoneSuggestion createGeoLocationSuggestion(
|
||||
@Nullable List<String> zoneIds) {
|
||||
GeolocationTimeZoneSuggestion suggestion = new GeolocationTimeZoneSuggestion(zoneIds);
|
||||
suggestion.addDebugInfo("Test suggestion");
|
||||
return suggestion;
|
||||
}
|
||||
|
||||
static class FakeCallback implements TimeZoneDetectorStrategyImpl.Callback {
|
||||
|
||||
private TimeZoneCapabilities mCapabilities;
|
||||
@@ -757,7 +1085,8 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
TimeZoneConfiguration configuration) {
|
||||
assertEquals(userId, capabilities.getUserId());
|
||||
mCapabilities = capabilities;
|
||||
assertTrue(configuration.isComplete());
|
||||
assertTrue("Configuration must be complete when initializing, config=" + configuration,
|
||||
configuration.isComplete());
|
||||
mConfiguration.init(new UserConfiguration(userId, configuration));
|
||||
}
|
||||
|
||||
@@ -790,11 +1119,8 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
mConfiguration.set(new UserConfiguration(userId, newConfig));
|
||||
|
||||
if (!newConfig.equals(oldConfig)) {
|
||||
if (oldConfig.isAutoDetectionEnabled() != newConfig.isAutoDetectionEnabled()) {
|
||||
// Simulate what happens when the auto detection enabled configuration is
|
||||
// changed.
|
||||
mStrategy.handleAutoTimeZoneConfigChanged();
|
||||
}
|
||||
// Simulate what happens when the auto detection configuration is changed.
|
||||
mStrategy.handleAutoTimeZoneConfigChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -803,6 +1129,11 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
return mConfiguration.getLatest().configuration.isAutoDetectionEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeoDetectionEnabled() {
|
||||
return mConfiguration.getLatest().configuration.isGeoDetectionEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeviceTimeZoneInitialized() {
|
||||
return mTimeZoneId.getLatest() != null;
|
||||
@@ -942,32 +1273,33 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
* supplied configuration.
|
||||
*/
|
||||
private static TimeZoneCapabilities createCapabilities(
|
||||
int userId, UserCase userRole, TimeZoneConfiguration configuration) {
|
||||
switch (userRole) {
|
||||
int userId, UserCase userCase, TimeZoneConfiguration configuration) {
|
||||
switch (userCase) {
|
||||
case UNRESTRICTED: {
|
||||
int suggestManualTimeZoneCapability = configuration.isAutoDetectionEnabled()
|
||||
? CAPABILITY_NOT_APPLICABLE : CAPABILITY_POSSESSED;
|
||||
return new TimeZoneCapabilities.Builder(userId)
|
||||
.setConfigureAutoDetectionEnabled(CAPABILITY_POSSESSED)
|
||||
.setConfigureGeoDetectionEnabled(CAPABILITY_POSSESSED)
|
||||
.setSuggestManualTimeZone(suggestManualTimeZoneCapability)
|
||||
.build();
|
||||
}
|
||||
case RESTRICTED: {
|
||||
return new TimeZoneCapabilities.Builder(userId)
|
||||
.setConfigureAutoDetectionEnabled(CAPABILITY_NOT_ALLOWED)
|
||||
.setConfigureGeoDetectionEnabled(CAPABILITY_NOT_ALLOWED)
|
||||
.setSuggestManualTimeZone(CAPABILITY_NOT_ALLOWED)
|
||||
.build();
|
||||
|
||||
}
|
||||
case AUTO_DETECT_NOT_SUPPORTED: {
|
||||
return new TimeZoneCapabilities.Builder(userId)
|
||||
.setConfigureAutoDetectionEnabled(CAPABILITY_NOT_SUPPORTED)
|
||||
.setConfigureGeoDetectionEnabled(CAPABILITY_NOT_SUPPORTED)
|
||||
.setSuggestManualTimeZone(CAPABILITY_POSSESSED)
|
||||
.build();
|
||||
|
||||
}
|
||||
default:
|
||||
throw new AssertionError(userRole + " not recognized");
|
||||
throw new AssertionError(userCase + " not recognized");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -978,8 +1310,8 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
private class Script {
|
||||
|
||||
Script initializeUser(
|
||||
@UserIdInt int userId, UserCase userRole, TimeZoneConfiguration configuration) {
|
||||
TimeZoneCapabilities capabilities = createCapabilities(userId, userRole, configuration);
|
||||
@UserIdInt int userId, UserCase userCase, TimeZoneConfiguration configuration) {
|
||||
TimeZoneCapabilities capabilities = createCapabilities(userId, userCase, configuration);
|
||||
mFakeCallback.initializeUser(userId, capabilities, configuration);
|
||||
return this;
|
||||
}
|
||||
@@ -989,27 +1321,24 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
return this;
|
||||
}
|
||||
|
||||
Script simulateAutoTimeZoneDetectionEnabled(@UserIdInt int userId, boolean enabled) {
|
||||
TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
|
||||
.setAutoDetectionEnabled(enabled)
|
||||
.build();
|
||||
return simulateUpdateConfiguration(userId, configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates the time zone detection strategy receiving an updated configuration.
|
||||
* Simulates the time zone detection strategy receiving an updated configuration and checks
|
||||
* the return value.
|
||||
*/
|
||||
Script simulateUpdateConfiguration(
|
||||
@UserIdInt int userId, TimeZoneConfiguration configuration) {
|
||||
mTimeZoneDetectorStrategy.updateConfiguration(userId, configuration);
|
||||
@UserIdInt int userId, TimeZoneConfiguration configuration,
|
||||
boolean expectedResult) {
|
||||
assertEquals(expectedResult,
|
||||
mTimeZoneDetectorStrategy.updateConfiguration(userId, configuration));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates the time zone detection strategy receiving a telephony-originated suggestion.
|
||||
* Simulates the time zone detection strategy receiving a geolocation-originated
|
||||
* suggestion.
|
||||
*/
|
||||
Script simulateTelephonyTimeZoneSuggestion(TelephonyTimeZoneSuggestion timeZoneSuggestion) {
|
||||
mTimeZoneDetectorStrategy.suggestTelephonyTimeZone(timeZoneSuggestion);
|
||||
Script simulateGeolocationTimeZoneSuggestion(GeolocationTimeZoneSuggestion suggestion) {
|
||||
mTimeZoneDetectorStrategy.suggestGeolocationTimeZone(suggestion);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1024,13 +1353,26 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates the time zone detection strategy receiving a telephony-originated suggestion.
|
||||
*/
|
||||
Script simulateTelephonyTimeZoneSuggestion(TelephonyTimeZoneSuggestion timeZoneSuggestion) {
|
||||
mTimeZoneDetectorStrategy.suggestTelephonyTimeZone(timeZoneSuggestion);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the device's time zone has not been set by previous actions since the test
|
||||
* state was last reset.
|
||||
*/
|
||||
Script verifyTimeZoneNotChanged() {
|
||||
mFakeCallback.assertTimeZoneNotChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
Script verifyTimeZoneChangedAndReset(TelephonyTimeZoneSuggestion suggestion) {
|
||||
mFakeCallback.assertTimeZoneChangedTo(suggestion.getZoneId());
|
||||
/** Verifies the device's time zone has been set and clears change tracking history. */
|
||||
Script verifyTimeZoneChangedAndReset(String zoneId) {
|
||||
mFakeCallback.assertTimeZoneChangedTo(zoneId);
|
||||
mFakeCallback.commitAllChanges();
|
||||
return this;
|
||||
}
|
||||
@@ -1041,6 +1383,12 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
return this;
|
||||
}
|
||||
|
||||
Script verifyTimeZoneChangedAndReset(TelephonyTimeZoneSuggestion suggestion) {
|
||||
mFakeCallback.assertTimeZoneChangedTo(suggestion.getZoneId());
|
||||
mFakeCallback.commitAllChanges();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the configuration has been changed to the expected value.
|
||||
*/
|
||||
@@ -1120,4 +1468,8 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
mOnConfigurationChangedCalled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> List<T> list(T... values) {
|
||||
return Arrays.asList(values);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user