Merge "Enable telephony fallback triggered by providers"
This commit is contained in:
committed by
Android (Google) Code Review
commit
45ce9ddfab
@@ -19,6 +19,7 @@ package android.app.time;
|
||||
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_NOT_RUNNING;
|
||||
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED;
|
||||
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_RUNNING;
|
||||
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_UNKNOWN;
|
||||
import static android.app.time.DetectorStatusTypes.detectionAlgorithmStatusFromString;
|
||||
import static android.app.time.DetectorStatusTypes.detectionAlgorithmStatusToString;
|
||||
import static android.app.time.DetectorStatusTypes.requireValidDetectionAlgorithmStatus;
|
||||
@@ -319,6 +320,40 @@ public final class LocationTimeZoneAlgorithmStatus implements Parcelable {
|
||||
mSecondaryProviderStatus, mSecondaryProviderReportedStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the algorithm status could allow the time zone detector to enter
|
||||
* telephony fallback mode.
|
||||
*/
|
||||
public boolean couldEnableTelephonyFallback() {
|
||||
if (mStatus == DETECTION_ALGORITHM_STATUS_UNKNOWN
|
||||
|| mStatus == DETECTION_ALGORITHM_STATUS_NOT_RUNNING
|
||||
|| mStatus == DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED) {
|
||||
// This method is not expected to be called on objects with these statuses. Fallback
|
||||
// should not be enabled if it is.
|
||||
return false;
|
||||
}
|
||||
|
||||
// mStatus == DETECTOR_STATUS_RUNNING.
|
||||
|
||||
boolean primarySuggestsFallback = false;
|
||||
if (mPrimaryProviderStatus == PROVIDER_STATUS_NOT_PRESENT) {
|
||||
primarySuggestsFallback = true;
|
||||
} else if (mPrimaryProviderStatus == PROVIDER_STATUS_IS_UNCERTAIN
|
||||
&& mPrimaryProviderReportedStatus != null) {
|
||||
primarySuggestsFallback = mPrimaryProviderReportedStatus.couldEnableTelephonyFallback();
|
||||
}
|
||||
|
||||
boolean secondarySuggestsFallback = false;
|
||||
if (mSecondaryProviderStatus == PROVIDER_STATUS_NOT_PRESENT) {
|
||||
secondarySuggestsFallback = true;
|
||||
} else if (mSecondaryProviderStatus == PROVIDER_STATUS_IS_UNCERTAIN
|
||||
&& mSecondaryProviderReportedStatus != null) {
|
||||
secondarySuggestsFallback =
|
||||
mSecondaryProviderReportedStatus.couldEnableTelephonyFallback();
|
||||
}
|
||||
return primarySuggestsFallback && secondarySuggestsFallback;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
@NonNull
|
||||
|
||||
@@ -47,6 +47,7 @@ android_test {
|
||||
"androidx.test.ext.junit",
|
||||
"androidx.test.runner",
|
||||
"androidx.test.rules",
|
||||
"junit-params",
|
||||
"kotlin-test",
|
||||
"mockito-target-minus-junit4",
|
||||
"ub-uiautomator",
|
||||
|
||||
@@ -17,19 +17,26 @@
|
||||
package android.app.time;
|
||||
|
||||
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_NOT_RUNNING;
|
||||
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED;
|
||||
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_RUNNING;
|
||||
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_UNKNOWN;
|
||||
import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_IS_CERTAIN;
|
||||
import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_IS_UNCERTAIN;
|
||||
import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_NOT_PRESENT;
|
||||
import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_NOT_READY;
|
||||
import static android.app.time.ParcelableTestSupport.assertEqualsAndHashCode;
|
||||
import static android.app.time.ParcelableTestSupport.assertRoundTripParcelable;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_BLOCKED_BY_ENVIRONMENT;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_NOT_APPLICABLE;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_OK;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_NOT_APPLICABLE;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_OK;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.app.time.LocationTimeZoneAlgorithmStatus.ProviderStatus;
|
||||
import android.service.timezone.TimeZoneProviderStatus;
|
||||
@@ -207,4 +214,114 @@ public class LocationTimeZoneAlgorithmStatusTest {
|
||||
assertEquals(status,
|
||||
LocationTimeZoneAlgorithmStatus.parseCommandlineArg(status.toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCouldEnableTelephonyFallback_notRunning() {
|
||||
LocationTimeZoneAlgorithmStatus notRunning =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_NOT_RUNNING,
|
||||
PROVIDER_STATUS_NOT_READY, null, PROVIDER_STATUS_NOT_READY, null);
|
||||
assertFalse(notRunning.couldEnableTelephonyFallback());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCouldEnableTelephonyFallback_unknown() {
|
||||
// DETECTION_ALGORITHM_STATUS_UNKNOWN must never allow fallback
|
||||
LocationTimeZoneAlgorithmStatus unknown =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_UNKNOWN,
|
||||
PROVIDER_STATUS_NOT_READY, null, PROVIDER_STATUS_NOT_READY, null);
|
||||
assertFalse(unknown.couldEnableTelephonyFallback());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCouldEnableTelephonyFallback_notSupported() {
|
||||
// DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED must never allow fallback
|
||||
LocationTimeZoneAlgorithmStatus notSupported =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED,
|
||||
PROVIDER_STATUS_NOT_READY, null, PROVIDER_STATUS_NOT_READY, null);
|
||||
assertFalse(notSupported.couldEnableTelephonyFallback());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCouldEnableTelephonyFallback_running() {
|
||||
// DETECTION_ALGORITHM_STATUS_RUNNING may allow fallback
|
||||
|
||||
// Sample provider-reported statuses that do / do not enable fallback.
|
||||
TimeZoneProviderStatus enableTelephonyFallbackProviderStatus =
|
||||
new TimeZoneProviderStatus.Builder()
|
||||
.setLocationDetectionDependencyStatus(
|
||||
DEPENDENCY_STATUS_BLOCKED_BY_ENVIRONMENT)
|
||||
.setConnectivityDependencyStatus(DEPENDENCY_STATUS_NOT_APPLICABLE)
|
||||
.setTimeZoneResolutionOperationStatus(OPERATION_STATUS_NOT_APPLICABLE)
|
||||
.build();
|
||||
assertTrue(enableTelephonyFallbackProviderStatus.couldEnableTelephonyFallback());
|
||||
|
||||
TimeZoneProviderStatus notEnableTelephonyFallbackProviderStatus =
|
||||
new TimeZoneProviderStatus.Builder()
|
||||
.setLocationDetectionDependencyStatus(DEPENDENCY_STATUS_NOT_APPLICABLE)
|
||||
.setConnectivityDependencyStatus(DEPENDENCY_STATUS_NOT_APPLICABLE)
|
||||
.setTimeZoneResolutionOperationStatus(OPERATION_STATUS_NOT_APPLICABLE)
|
||||
.build();
|
||||
assertFalse(notEnableTelephonyFallbackProviderStatus.couldEnableTelephonyFallback());
|
||||
|
||||
// Provider not ready: Never enable fallback
|
||||
{
|
||||
LocationTimeZoneAlgorithmStatus status =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
|
||||
PROVIDER_STATUS_NOT_READY, null, PROVIDER_STATUS_NOT_READY, null);
|
||||
assertFalse(status.couldEnableTelephonyFallback());
|
||||
}
|
||||
|
||||
// Provider uncertain without reported status: Never enable fallback
|
||||
{
|
||||
LocationTimeZoneAlgorithmStatus status =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
|
||||
PROVIDER_STATUS_IS_UNCERTAIN, null, PROVIDER_STATUS_NOT_READY, null);
|
||||
assertFalse(status.couldEnableTelephonyFallback());
|
||||
}
|
||||
{
|
||||
LocationTimeZoneAlgorithmStatus status =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
|
||||
PROVIDER_STATUS_IS_UNCERTAIN, null, PROVIDER_STATUS_NOT_PRESENT, null);
|
||||
assertFalse(status.couldEnableTelephonyFallback());
|
||||
}
|
||||
|
||||
// Provider uncertain with reported status: Fallback is based on the status for present
|
||||
// providers that report their status. All present providers must have reported status and
|
||||
// agree that fallback is a good idea.
|
||||
{
|
||||
LocationTimeZoneAlgorithmStatus status =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
|
||||
PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus,
|
||||
PROVIDER_STATUS_NOT_READY, null);
|
||||
assertFalse(status.couldEnableTelephonyFallback());
|
||||
}
|
||||
{
|
||||
LocationTimeZoneAlgorithmStatus status =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
|
||||
PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus,
|
||||
PROVIDER_STATUS_NOT_PRESENT, null);
|
||||
assertTrue(status.couldEnableTelephonyFallback());
|
||||
}
|
||||
{
|
||||
LocationTimeZoneAlgorithmStatus status =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
|
||||
PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus,
|
||||
PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus);
|
||||
assertTrue(status.couldEnableTelephonyFallback());
|
||||
}
|
||||
{
|
||||
LocationTimeZoneAlgorithmStatus status =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
|
||||
PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus,
|
||||
PROVIDER_STATUS_IS_UNCERTAIN, notEnableTelephonyFallbackProviderStatus);
|
||||
assertFalse(status.couldEnableTelephonyFallback());
|
||||
}
|
||||
{
|
||||
LocationTimeZoneAlgorithmStatus status =
|
||||
new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
|
||||
PROVIDER_STATUS_NOT_PRESENT, null,
|
||||
PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus);
|
||||
assertTrue(status.couldEnableTelephonyFallback());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,31 @@
|
||||
|
||||
package android.service.timezone;
|
||||
|
||||
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_BLOCKED_BY_ENVIRONMENT;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_BLOCKED_BY_SETTINGS;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_OK;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_UNKNOWN;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_FAILED;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_OK;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_UNKNOWN;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.service.timezone.TimeZoneProviderStatus.DependencyStatus;
|
||||
import android.service.timezone.TimeZoneProviderStatus.OperationStatus;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import junitparams.JUnitParamsRunner;
|
||||
import junitparams.Parameters;
|
||||
|
||||
/** Non-SDK tests. See CTS for SDK API tests. */
|
||||
@RunWith(JUnitParamsRunner.class)
|
||||
public class TimeZoneProviderStatusTest {
|
||||
|
||||
@Test
|
||||
@@ -37,4 +53,51 @@ public class TimeZoneProviderStatusTest {
|
||||
|
||||
assertEquals(status, TimeZoneProviderStatus.parseProviderStatus(status.toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Parameters(method = "couldEnableTelephonyFallbackParams")
|
||||
public void couldEnableTelephonyFallback(@DependencyStatus int locationDetectionStatus,
|
||||
@DependencyStatus int connectivityStatus, @OperationStatus int tzResolutionStatus) {
|
||||
TimeZoneProviderStatus providerStatus =
|
||||
new TimeZoneProviderStatus.Builder()
|
||||
.setLocationDetectionDependencyStatus(locationDetectionStatus)
|
||||
.setConnectivityDependencyStatus(connectivityStatus)
|
||||
.setTimeZoneResolutionOperationStatus(tzResolutionStatus)
|
||||
.build();
|
||||
boolean locationDetectionStatusCouldEnableFallback =
|
||||
(locationDetectionStatus == DEPENDENCY_STATUS_BLOCKED_BY_ENVIRONMENT
|
||||
|| locationDetectionStatus == DEPENDENCY_STATUS_BLOCKED_BY_SETTINGS);
|
||||
boolean connectivityStatusCouldEnableFallback =
|
||||
(connectivityStatus == DEPENDENCY_STATUS_BLOCKED_BY_ENVIRONMENT
|
||||
|| connectivityStatus == DEPENDENCY_STATUS_BLOCKED_BY_SETTINGS);
|
||||
boolean tzResolutionStatusCouldEnableFallback = false;
|
||||
|
||||
assertEquals(locationDetectionStatusCouldEnableFallback
|
||||
|| connectivityStatusCouldEnableFallback
|
||||
|| tzResolutionStatusCouldEnableFallback,
|
||||
providerStatus.couldEnableTelephonyFallback());
|
||||
}
|
||||
|
||||
public static Integer[][] couldEnableTelephonyFallbackParams() {
|
||||
List<Integer[]> params = new ArrayList<>();
|
||||
@DependencyStatus int[] dependencyStatuses =
|
||||
IntStream.rangeClosed(
|
||||
DEPENDENCY_STATUS_UNKNOWN, DEPENDENCY_STATUS_BLOCKED_BY_SETTINGS).toArray();
|
||||
@OperationStatus int[] operationStatuses =
|
||||
IntStream.rangeClosed(OPERATION_STATUS_UNKNOWN, OPERATION_STATUS_FAILED).toArray();
|
||||
|
||||
// Cartesian product: dependencyStatus x dependencyStatus x operationStatus
|
||||
for (@DependencyStatus int locationDetectionStatus : dependencyStatuses) {
|
||||
for (@DependencyStatus int connectivityStatus : dependencyStatuses) {
|
||||
for (@OperationStatus int tzResolutionStatus : operationStatuses) {
|
||||
params.add(new Integer[] {
|
||||
locationDetectionStatus,
|
||||
connectivityStatus,
|
||||
tzResolutionStatus
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return params.toArray(new Integer[0][0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
|
||||
deviceActivityMonitor.addListener(new DeviceActivityMonitor.Listener() {
|
||||
@Override
|
||||
public void onFlightComplete() {
|
||||
timeZoneDetectorStrategy.enableTelephonyTimeZoneFallback();
|
||||
timeZoneDetectorStrategy.enableTelephonyTimeZoneFallback("onFlightComplete()");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -402,9 +402,9 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
|
||||
* Sends a signal to enable telephony fallback. Provided for command-line access for use
|
||||
* during tests. This is not exposed as a binder API.
|
||||
*/
|
||||
void enableTelephonyFallback() {
|
||||
void enableTelephonyFallback(@NonNull String reason) {
|
||||
enforceManageTimeZoneDetectorPermission();
|
||||
mTimeZoneDetectorStrategy.enableTelephonyTimeZoneFallback();
|
||||
mTimeZoneDetectorStrategy.enableTelephonyTimeZoneFallback(reason);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -189,7 +189,7 @@ class TimeZoneDetectorShellCommand extends ShellCommand {
|
||||
}
|
||||
|
||||
private int runEnableTelephonyFallback() {
|
||||
mInterface.enableTelephonyFallback();
|
||||
mInterface.enableTelephonyFallback("Command line");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,13 +35,13 @@ import android.util.IndentingPrintWriter;
|
||||
* <p>Devices can have zero, one or two automatic time zone detection algorithms available at any
|
||||
* point in time.
|
||||
*
|
||||
* <p>The two automatic detection algorithms supported are "telephony" and "geolocation". Algorithm
|
||||
* <p>The two automatic detection algorithms supported are "telephony" and "location". Algorithm
|
||||
* availability and use depends on several factors:
|
||||
* <ul>
|
||||
* <li>Telephony is only available on devices with a telephony stack.
|
||||
* <li>Geolocation is also optional and configured at image creation time. When enabled on a
|
||||
* device, its availability depends on the current user's settings, so switching between users can
|
||||
* change the automatic algorithm used by the device.</li>
|
||||
* <li>Location is also optional and configured at image creation time. When enabled on a device,
|
||||
* its availability depends on the current user's settings, so switching between users can change
|
||||
* the automatic detection algorithm used by the device.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>If there are no automatic time zone detections algorithms available then the user can usually
|
||||
@@ -56,14 +56,14 @@ import android.util.IndentingPrintWriter;
|
||||
* slotIndexes must have an empty suggestion submitted in order to "withdraw" their previous
|
||||
* suggestion otherwise it will remain in use.
|
||||
*
|
||||
* <p>Geolocation detection is dependent on the current user and their settings. The device retains
|
||||
* at most one geolocation suggestion. Generally, use of a device's location is dependent on the
|
||||
* user's "location toggle", but even when that is enabled the user may choose to enable / disable
|
||||
* the use of geolocation for device time zone detection. If the current user changes to one that
|
||||
* does not have geolocation detection enabled, or the user turns off geolocation detection, then
|
||||
* the strategy discards the latest geolocation suggestion. Devices that lose a location fix must
|
||||
* have an empty suggestion submitted in order to "withdraw" their previous suggestion otherwise it
|
||||
* will remain in use.
|
||||
* <p>Location-based detection is dependent on the current user and their settings. The device
|
||||
* retains at most one geolocation suggestion. Generally, use of a device's location is dependent on
|
||||
* the user's "location toggle", but even when that is enabled the user may choose to enable /
|
||||
* disable the use of location for device time zone detection. If the current user changes to one
|
||||
* that does not have location-based detection enabled, or the user turns off the location-based
|
||||
* detection, then the strategy will be sent an event that clears the latest suggestion. Devices
|
||||
* that lose their location fix must have an empty suggestion submitted in order to "withdraw" their
|
||||
* previous suggestion otherwise it will remain in use.
|
||||
*
|
||||
* <p>The strategy uses only one algorithm at a time and does not attempt consensus even when
|
||||
* more than one is available on a device. This "use only one" behavior is deliberate as different
|
||||
@@ -72,25 +72,27 @@ import android.util.IndentingPrintWriter;
|
||||
* users enter areas without the necessary signals. Ultimately, with no perfect algorithm available,
|
||||
* the user is left to choose which algorithm works best for their circumstances.
|
||||
*
|
||||
* <p>When geolocation detection is supported and enabled, in certain circumstances, such as during
|
||||
* international travel, it makes sense to prioritize speed of detection via telephony (when
|
||||
* available) Vs waiting for the geolocation algorithm to reach certainty. Geolocation detection can
|
||||
* sometimes be slow to get a location fix and can require network connectivity (which cannot be
|
||||
* assumed when users are travelling) for server-assisted location detection or time zone lookup.
|
||||
* Therefore, as a restricted form of prioritization between geolocation and telephony algorithms,
|
||||
* the strategy provides "telephony fallback" behavior, which can be set to "supported" via device
|
||||
* config. Fallback mode is toggled on at runtime via {@link #enableTelephonyTimeZoneFallback()} in
|
||||
* response to signals outside of the scope of this class. Telephony fallback allows the use of
|
||||
* telephony suggestions to help with faster detection but only until geolocation detection
|
||||
* provides a concrete, "certain" suggestion. After geolocation has made the first certain
|
||||
* suggestion, telephony fallback is disabled until the next call to {@link
|
||||
* #enableTelephonyTimeZoneFallback()}.
|
||||
* <p>When the location detection algorithm is supported and enabled, in certain circumstances, such
|
||||
* as during international travel, it makes sense to prioritize speed of detection via telephony
|
||||
* (when available) Vs waiting for the location-based detection algorithm to reach certainty.
|
||||
* Location-based detection can sometimes be slow to get a location fix and can require network
|
||||
* connectivity (which cannot be assumed when users are travelling) for server-assisted location
|
||||
* detection or time zone lookup. Therefore, as a restricted form of prioritization between location
|
||||
* and telephony algorithms, the strategy provides "telephony fallback mode" behavior, which can be
|
||||
* set to "supported" via device config. Fallback mode is entered at runtime in response to signals
|
||||
* from outside of the strategy, e.g. from a call to {@link
|
||||
* #enableTelephonyTimeZoneFallback(String)}, or from information in the latest {@link
|
||||
* LocationAlgorithmEvent}. For telephony fallback mode to actually use a telephony suggestion, the
|
||||
* location algorithm <em>must</em> report it is uncertain. Telephony fallback allows the use of
|
||||
* telephony suggestions to help with faster detection but only until the location algorithm
|
||||
* provides a concrete, "certain" suggestion. After the location algorithm has made a certain
|
||||
* suggestion, telephony fallback mode is disabled.
|
||||
*
|
||||
* <p>Threading:
|
||||
*
|
||||
* <p>Implementations of this class must be thread-safe as calls calls like {@link
|
||||
* #generateMetricsState()} and {@link #dump(IndentingPrintWriter, String[])} may be called on
|
||||
* differents thread concurrently with other operations.
|
||||
* different threads concurrently with other operations.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -181,11 +183,11 @@ public interface TimeZoneDetectorStrategy extends Dumpable {
|
||||
void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion suggestion);
|
||||
|
||||
/**
|
||||
* Tells the strategy that it can fall back to telephony detection while geolocation detection
|
||||
* remains uncertain. {@link #handleLocationAlgorithmEvent(LocationAlgorithmEvent)} can
|
||||
* disable it again. See {@link TimeZoneDetectorStrategy} for details.
|
||||
* Tells the strategy that it can fall back to telephony detection while the location detection
|
||||
* algorithm remains uncertain. {@link #handleLocationAlgorithmEvent(LocationAlgorithmEvent)}
|
||||
* can disable it again. See {@link TimeZoneDetectorStrategy} for details.
|
||||
*/
|
||||
void enableTelephonyTimeZoneFallback();
|
||||
void enableTelephonyTimeZoneFallback(@NonNull String reason);
|
||||
|
||||
/** Generates a state snapshot for metrics. */
|
||||
@NonNull
|
||||
@@ -194,6 +196,6 @@ public interface TimeZoneDetectorStrategy extends Dumpable {
|
||||
/** Returns {@code true} if the device supports telephony time zone detection. */
|
||||
boolean isTelephonyTimeZoneDetectionSupported();
|
||||
|
||||
/** Returns {@code true} if the device supports geolocation time zone detection. */
|
||||
/** Returns {@code true} if the device supports location-based time zone detection. */
|
||||
boolean isGeoTimeZoneDetectionSupported();
|
||||
}
|
||||
|
||||
@@ -63,12 +63,8 @@ import java.util.Objects;
|
||||
public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrategy {
|
||||
|
||||
/**
|
||||
* Used by {@link TimeZoneDetectorStrategyImpl} to interact with device configuration / settings
|
||||
* / system properties. It can be faked for testing.
|
||||
*
|
||||
* <p>Note: Because the settings / system properties-derived values can currently be modified
|
||||
* independently and from different threads (and processes!), their use is prone to race
|
||||
* conditions.
|
||||
* Used by {@link TimeZoneDetectorStrategyImpl} to interact with device state besides that
|
||||
* available from {@link #mServiceConfigAccessor}. It can be faked for testing.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public interface Environment {
|
||||
@@ -234,7 +230,7 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
* allows).
|
||||
*
|
||||
* <p>This field is only actually used when telephony time zone fallback is supported, but the
|
||||
* value is maintained even when it isn't supported as it can be turned on at any time via
|
||||
* value is maintained even when it isn't supported as support can be turned on at any time via
|
||||
* server flags. The elapsed realtime when the mode last changed is used to help ordering
|
||||
* between fallback mode switches and suggestions.
|
||||
*
|
||||
@@ -421,10 +417,15 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
notifyStateChangeListenersAsynchronously();
|
||||
}
|
||||
|
||||
// Update the mTelephonyTimeZoneFallbackEnabled state if needed: a certain suggestion
|
||||
// will usually disable telephony fallback mode if it is currently enabled.
|
||||
// TODO(b/236624675)Some provider status codes can be used to enable telephony fallback.
|
||||
disableTelephonyFallbackIfNeeded();
|
||||
// Manage telephony fallback state.
|
||||
if (event.getAlgorithmStatus().couldEnableTelephonyFallback()) {
|
||||
// An event may trigger entry into telephony fallback mode if the status
|
||||
// indicates the location algorithm cannot work and is likely to stay not working.
|
||||
enableTelephonyTimeZoneFallback("handleLocationAlgorithmEvent(), event=" + event);
|
||||
} else {
|
||||
// A certain suggestion will exit telephony fallback mode.
|
||||
disableTelephonyFallbackIfNeeded();
|
||||
}
|
||||
|
||||
// Now perform auto time zone detection. The new event may be used to modify the time zone
|
||||
// setting.
|
||||
@@ -497,38 +498,41 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void enableTelephonyTimeZoneFallback() {
|
||||
// Only do any work if fallback is currently not enabled.
|
||||
public synchronized void enableTelephonyTimeZoneFallback(@NonNull String reason) {
|
||||
// Only do any work to enter fallback mode if fallback is currently not already enabled.
|
||||
if (!mTelephonyTimeZoneFallbackEnabled.getValue()) {
|
||||
ConfigurationInternal currentUserConfig = mCurrentConfigurationInternal;
|
||||
final boolean fallbackEnabled = true;
|
||||
mTelephonyTimeZoneFallbackEnabled = new TimestampedValue<>(
|
||||
mEnvironment.elapsedRealtimeMillis(), fallbackEnabled);
|
||||
|
||||
String logMsg = "enableTelephonyTimeZoneFallbackMode: "
|
||||
+ " currentUserConfig=" + currentUserConfig
|
||||
+ ", mTelephonyTimeZoneFallbackEnabled="
|
||||
+ mTelephonyTimeZoneFallbackEnabled;
|
||||
String logMsg = "enableTelephonyTimeZoneFallback: "
|
||||
+ " reason=" + reason
|
||||
+ ", currentUserConfig=" + currentUserConfig
|
||||
+ ", mTelephonyTimeZoneFallbackEnabled=" + mTelephonyTimeZoneFallbackEnabled;
|
||||
logTimeZoneDebugInfo(logMsg);
|
||||
|
||||
// mTelephonyTimeZoneFallbackEnabled and mLatestLocationAlgorithmEvent interact.
|
||||
// If the latest event contains a "certain" geolocation suggestion, then the telephony
|
||||
// fallback value needs to be considered after changing it.
|
||||
// If the latest location algorithm event contains a "certain" geolocation suggestion,
|
||||
// then the telephony fallback mode needs to be (re)considered after changing it.
|
||||
//
|
||||
// With the way that the mTelephonyTimeZoneFallbackEnabled time is currently chosen
|
||||
// above, and the fact that geolocation suggestions should never have a time in the
|
||||
// future, the following call will be a no-op, and telephony fallback will remain
|
||||
// enabled. This comment / call is left as a reminder that it is possible for there to
|
||||
// be a current, "certain" geolocation suggestion when this signal arrives and it is
|
||||
// intentional that fallback stays enabled in this case. The choice to do this
|
||||
// is mostly for symmetry WRT the case where fallback is enabled and an old "certain"
|
||||
// geolocation is received; that would also leave telephony fallback enabled.
|
||||
// This choice means that telephony fallback will remain enabled until a new "certain"
|
||||
// geolocation suggestion is received. If, instead, the next geolocation is "uncertain",
|
||||
// then telephony fallback will occur.
|
||||
// future, the following call will usually be a no-op, and telephony fallback mode will
|
||||
// remain enabled. This comment / call is left as a reminder that it is possible in some
|
||||
// cases for there to be a current, "certain" geolocation suggestion when an attempt is
|
||||
// made to enable telephony fallback mode and it is intentional that fallback mode stays
|
||||
// enabled in this case. The choice to do this is mostly for symmetry WRT the case where
|
||||
// fallback is enabled and then an old "certain" geolocation suggestion is received;
|
||||
// that would also leave telephony fallback mode enabled.
|
||||
//
|
||||
// This choice means that telephony fallback mode remains enabled if there is an
|
||||
// existing "certain" suggestion until a new "certain" geolocation suggestion is
|
||||
// received. If, instead, the next geolocation suggestion is "uncertain", then telephony
|
||||
// fallback, i.e. the use of a telephony suggestion, will actually occur.
|
||||
disableTelephonyFallbackIfNeeded();
|
||||
|
||||
if (currentUserConfig.isTelephonyFallbackSupported()) {
|
||||
String reason = "enableTelephonyTimeZoneFallbackMode";
|
||||
doAutoTimeZoneDetection(currentUserConfig, reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ public class FakeTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableTelephonyTimeZoneFallback() {
|
||||
public void enableTelephonyTimeZoneFallback(String reason) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYP
|
||||
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS;
|
||||
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
|
||||
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_BLOCKED_BY_SETTINGS;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_UNKNOWN;
|
||||
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_UNKNOWN;
|
||||
|
||||
import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_HIGH;
|
||||
import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_LOW;
|
||||
@@ -65,6 +68,7 @@ import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
|
||||
import android.app.timezonedetector.TelephonyTimeZoneSuggestion.MatchType;
|
||||
import android.app.timezonedetector.TelephonyTimeZoneSuggestion.Quality;
|
||||
import android.os.HandlerThread;
|
||||
import android.service.timezone.TimeZoneProviderStatus;
|
||||
|
||||
import com.android.server.SystemTimeZone.TimeZoneConfidence;
|
||||
import com.android.server.timezonedetector.TimeZoneDetectorStrategyImpl.QualifiedTelephonyTimeZoneSuggestion;
|
||||
@@ -1148,7 +1152,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTelephonyFallback() {
|
||||
public void testTelephonyFallback_enableTelephonyTimeZoneFallbackCalled() {
|
||||
ConfigurationInternal config = new ConfigurationInternal.Builder(
|
||||
CONFIG_AUTO_ENABLED_GEO_ENABLED)
|
||||
.setTelephonyFallbackSupported(true)
|
||||
@@ -1178,19 +1182,21 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
// Receiving an "uncertain" geolocation suggestion should have no effect.
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent locationAlgorithmEvent = createUncertainLocationAlgorithmEvent();
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
script.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.verifyTelephonyFallbackIsEnabled(true);
|
||||
}
|
||||
|
||||
// Receiving a "certain" geolocation suggestion should disable telephony fallback mode.
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent locationAlgorithmEvent =
|
||||
createCertainLocationAlgorithmEvent("Europe/London");
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
script.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
.verifyTimeZoneChangedAndReset(locationAlgorithmEvent)
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
}
|
||||
@@ -1214,17 +1220,19 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
// Geolocation suggestions should continue to be used as normal (previous telephony
|
||||
// suggestions are not used, even when the geolocation suggestion is uncertain).
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent certainLocationAlgorithmEvent =
|
||||
createCertainLocationAlgorithmEvent("Europe/Rome");
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(certainLocationAlgorithmEvent)
|
||||
script.simulateLocationAlgorithmEvent(certainLocationAlgorithmEvent)
|
||||
.verifyTimeZoneChangedAndReset(certainLocationAlgorithmEvent)
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent uncertainLocationAlgorithmEvent =
|
||||
createUncertainLocationAlgorithmEvent();
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(uncertainLocationAlgorithmEvent)
|
||||
script.simulateLocationAlgorithmEvent(uncertainLocationAlgorithmEvent)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
|
||||
@@ -1246,19 +1254,21 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
// Make the geolocation algorithm uncertain.
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent locationAlgorithmEvent = createUncertainLocationAlgorithmEvent();
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
script.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
.verifyTimeZoneChangedAndReset(lastTelephonySuggestion)
|
||||
.verifyTelephonyFallbackIsEnabled(true);
|
||||
}
|
||||
|
||||
// Make the geolocation algorithm certain, disabling telephony fallback.
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent locationAlgorithmEvent =
|
||||
createCertainLocationAlgorithmEvent("Europe/Lisbon");
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
script.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
.verifyTimeZoneChangedAndReset(locationAlgorithmEvent)
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
|
||||
@@ -1267,9 +1277,10 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
// Demonstrate what happens when geolocation is uncertain when telephony fallback is
|
||||
// enabled.
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent locationAlgorithmEvent = createUncertainLocationAlgorithmEvent();
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
script.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.verifyTelephonyFallbackIsEnabled(false)
|
||||
.simulateEnableTelephonyFallback()
|
||||
@@ -1278,6 +1289,132 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTelephonyFallback_locationAlgorithmEventSuggestsFallback() {
|
||||
ConfigurationInternal config = new ConfigurationInternal.Builder(
|
||||
CONFIG_AUTO_ENABLED_GEO_ENABLED)
|
||||
.setTelephonyFallbackSupported(true)
|
||||
.build();
|
||||
|
||||
Script script = new Script()
|
||||
.initializeClock(ARBITRARY_ELAPSED_REALTIME_MILLIS)
|
||||
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID, TIME_ZONE_CONFIDENCE_LOW)
|
||||
.simulateConfigurationInternalChange(config)
|
||||
.resetConfigurationTracking();
|
||||
|
||||
// Confirm initial state is as expected.
|
||||
script.verifyTelephonyFallbackIsEnabled(true)
|
||||
.verifyTimeZoneNotChanged();
|
||||
|
||||
// Although geolocation detection is enabled, telephony fallback should be used initially
|
||||
// and until a suitable "certain" geolocation suggestion is received.
|
||||
{
|
||||
TelephonyTimeZoneSuggestion telephonySuggestion = createTelephonySuggestion(
|
||||
SLOT_INDEX1, MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE,
|
||||
"Europe/Paris");
|
||||
script.simulateIncrementClock()
|
||||
.simulateTelephonyTimeZoneSuggestion(telephonySuggestion)
|
||||
.verifyTimeZoneChangedAndReset(telephonySuggestion)
|
||||
.verifyTelephonyFallbackIsEnabled(true);
|
||||
}
|
||||
|
||||
// Receiving an "uncertain" geolocation suggestion without a status should have no effect.
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent locationAlgorithmEvent = createUncertainLocationAlgorithmEvent();
|
||||
script.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.verifyTelephonyFallbackIsEnabled(true);
|
||||
}
|
||||
|
||||
// Receiving a "certain" geolocation suggestion should disable telephony fallback mode.
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent locationAlgorithmEvent =
|
||||
createCertainLocationAlgorithmEvent("Europe/London");
|
||||
script.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
.verifyTimeZoneChangedAndReset(locationAlgorithmEvent)
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
}
|
||||
|
||||
// Used to record the last telephony suggestion received, which will be used when fallback
|
||||
// takes place.
|
||||
TelephonyTimeZoneSuggestion lastTelephonySuggestion;
|
||||
|
||||
// Telephony suggestions should now be ignored and geolocation detection is "in control".
|
||||
{
|
||||
TelephonyTimeZoneSuggestion telephonySuggestion = createTelephonySuggestion(
|
||||
SLOT_INDEX1, MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE,
|
||||
"Europe/Berlin");
|
||||
script.simulateIncrementClock()
|
||||
.simulateTelephonyTimeZoneSuggestion(telephonySuggestion)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
lastTelephonySuggestion = telephonySuggestion;
|
||||
}
|
||||
|
||||
// Geolocation suggestions should continue to be used as normal (previous telephony
|
||||
// suggestions are not used, even when the geolocation suggestion is uncertain).
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent certainLocationAlgorithmEvent =
|
||||
createCertainLocationAlgorithmEvent("Europe/Rome");
|
||||
script.simulateLocationAlgorithmEvent(certainLocationAlgorithmEvent)
|
||||
.verifyTimeZoneChangedAndReset(certainLocationAlgorithmEvent)
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent uncertainLocationAlgorithmEvent =
|
||||
createUncertainLocationAlgorithmEvent();
|
||||
script.simulateLocationAlgorithmEvent(uncertainLocationAlgorithmEvent)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent certainLocationAlgorithmEvent2 =
|
||||
createCertainLocationAlgorithmEvent("Europe/Rome");
|
||||
script.simulateLocationAlgorithmEvent(certainLocationAlgorithmEvent2)
|
||||
// No change needed, device will already be set to Europe/Rome.
|
||||
.verifyTimeZoneNotChanged()
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
}
|
||||
|
||||
// Enable telephony fallback via a LocationAlgorithmEvent containing an "uncertain"
|
||||
// suggestion.
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
TimeZoneProviderStatus primaryProviderReportedStatus =
|
||||
new TimeZoneProviderStatus.Builder()
|
||||
.setLocationDetectionDependencyStatus(
|
||||
DEPENDENCY_STATUS_BLOCKED_BY_SETTINGS)
|
||||
.setConnectivityDependencyStatus(DEPENDENCY_STATUS_UNKNOWN)
|
||||
.setTimeZoneResolutionOperationStatus(OPERATION_STATUS_UNKNOWN)
|
||||
.build();
|
||||
LocationAlgorithmEvent uncertainEventBlockedBySettings =
|
||||
createUncertainLocationAlgorithmEvent(primaryProviderReportedStatus);
|
||||
script.simulateLocationAlgorithmEvent(uncertainEventBlockedBySettings)
|
||||
.verifyTimeZoneChangedAndReset(lastTelephonySuggestion)
|
||||
.verifyTelephonyFallbackIsEnabled(true);
|
||||
}
|
||||
|
||||
// Make the geolocation algorithm certain, disabling telephony fallback.
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent locationAlgorithmEvent =
|
||||
createCertainLocationAlgorithmEvent("Europe/Lisbon");
|
||||
script.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
.verifyTimeZoneChangedAndReset(locationAlgorithmEvent)
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTelephonyFallback_noTelephonySuggestionToFallBackTo() {
|
||||
ConfigurationInternal config = new ConfigurationInternal.Builder(
|
||||
@@ -1297,9 +1434,10 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
// Receiving an "uncertain" geolocation suggestion should have no effect.
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent locationAlgorithmEvent = createUncertainLocationAlgorithmEvent();
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
script.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.verifyTelephonyFallbackIsEnabled(true);
|
||||
}
|
||||
@@ -1307,9 +1445,10 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
// Make an uncertain geolocation suggestion, there is no telephony suggestion to fall back
|
||||
// to
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent locationAlgorithmEvent = createUncertainLocationAlgorithmEvent();
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
script.simulateLocationAlgorithmEvent(locationAlgorithmEvent)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.verifyTelephonyFallbackIsEnabled(true);
|
||||
}
|
||||
@@ -1319,16 +1458,18 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
// Geolocation suggestions should continue to be used as normal (previous telephony
|
||||
// suggestions are not used, even when the geolocation suggestion is uncertain).
|
||||
{
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent certainEvent =
|
||||
createCertainLocationAlgorithmEvent("Europe/Rome");
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(certainEvent)
|
||||
script.simulateLocationAlgorithmEvent(certainEvent)
|
||||
.verifyTimeZoneChangedAndReset(certainEvent)
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
|
||||
// Increment the clock before creating the event: the clock's value is used by the event
|
||||
script.simulateIncrementClock();
|
||||
LocationAlgorithmEvent uncertainEvent = createUncertainLocationAlgorithmEvent();
|
||||
script.simulateIncrementClock()
|
||||
.simulateLocationAlgorithmEvent(uncertainEvent)
|
||||
script.simulateLocationAlgorithmEvent(uncertainEvent)
|
||||
.verifyTimeZoneNotChanged()
|
||||
.verifyTelephonyFallbackIsEnabled(false);
|
||||
|
||||
@@ -1549,9 +1690,16 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
}
|
||||
|
||||
private LocationAlgorithmEvent createUncertainLocationAlgorithmEvent() {
|
||||
TimeZoneProviderStatus primaryProviderReportedStatus = null;
|
||||
return createUncertainLocationAlgorithmEvent(primaryProviderReportedStatus);
|
||||
}
|
||||
|
||||
private LocationAlgorithmEvent createUncertainLocationAlgorithmEvent(
|
||||
TimeZoneProviderStatus primaryProviderReportedStatus) {
|
||||
GeolocationTimeZoneSuggestion suggestion = createUncertainGeolocationSuggestion();
|
||||
LocationTimeZoneAlgorithmStatus algorithmStatus = new LocationTimeZoneAlgorithmStatus(
|
||||
DETECTION_ALGORITHM_STATUS_RUNNING, PROVIDER_STATUS_IS_UNCERTAIN, null,
|
||||
DETECTION_ALGORITHM_STATUS_RUNNING,
|
||||
PROVIDER_STATUS_IS_UNCERTAIN, primaryProviderReportedStatus,
|
||||
PROVIDER_STATUS_NOT_PRESENT, null);
|
||||
LocationAlgorithmEvent event = new LocationAlgorithmEvent(algorithmStatus, suggestion);
|
||||
event.addDebugInfo("Test uncertain event");
|
||||
@@ -1744,11 +1892,12 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates the time zone detection strategty receiving a signal that allows it to do
|
||||
* Simulates the time zone detection strategy receiving a signal that allows it to do
|
||||
* telephony fallback.
|
||||
*/
|
||||
Script simulateEnableTelephonyFallback() {
|
||||
mTimeZoneDetectorStrategy.enableTelephonyTimeZoneFallback();
|
||||
mTimeZoneDetectorStrategy.enableTelephonyTimeZoneFallback(
|
||||
"simulateEnableTelephonyFallback()");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user