summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/location/timezone/ControllerImpl.java153
-rw-r--r--services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java31
-rw-r--r--services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java451
4 files changed, 577 insertions, 62 deletions
diff --git a/services/core/java/com/android/server/location/timezone/ControllerImpl.java b/services/core/java/com/android/server/location/timezone/ControllerImpl.java
index 99414c4cdf91..d48263722d38 100644
--- a/services/core/java/com/android/server/location/timezone/ControllerImpl.java
+++ b/services/core/java/com/android/server/location/timezone/ControllerImpl.java
@@ -44,16 +44,22 @@ import java.util.List;
import java.util.Objects;
/**
- * A real implementation of {@link LocationTimeZoneProviderController} that supports a single
- * {@link LocationTimeZoneProvider}.
+ * A real implementation of {@link LocationTimeZoneProviderController} that supports a primary and a
+ * secondary {@link LocationTimeZoneProvider}.
*
- * TODO(b/152744911): This implementation currently only supports a single ("primary") provider.
- * Support for a secondary provider will be added in a later commit.
+ * <p>The primary is used until it fails or becomes uncertain. The secondary will then be enabled.
+ * The controller will immediately make suggestions based on "certain" {@link
+ * LocationTimeZoneEvent}s, i.e. events that demonstrate the provider is certain what the time zone
+ * is. The controller will not make immediate suggestions based on "uncertain" events, giving
+ * providers time to change their mind. This also gives the secondary provider time to initialize
+ * when the primary becomes uncertain.
*/
class ControllerImpl extends LocationTimeZoneProviderController {
@NonNull private final LocationTimeZoneProvider mPrimaryProvider;
+ @NonNull private final LocationTimeZoneProvider mSecondaryProvider;
+
@GuardedBy("mSharedLock")
// Non-null after initialize()
private ConfigurationInternal mCurrentUserConfiguration;
@@ -67,7 +73,9 @@ class ControllerImpl extends LocationTimeZoneProviderController {
private Callback mCallback;
/**
- * Used for scheduling uncertainty timeouts, i.e after the provider has reported uncertainty.
+ * Used for scheduling uncertainty timeouts, i.e after a provider has reported uncertainty.
+ * This timeout is not provider-specific: it is started when the controller becomes uncertain
+ * due to events it has received from one or other provider.
*/
@NonNull private final SingleRunnableQueue mUncertaintyTimeoutQueue;
@@ -77,10 +85,12 @@ class ControllerImpl extends LocationTimeZoneProviderController {
private GeolocationTimeZoneSuggestion mLastSuggestion;
ControllerImpl(@NonNull ThreadingDomain threadingDomain,
- @NonNull LocationTimeZoneProvider primaryProvider) {
+ @NonNull LocationTimeZoneProvider primaryProvider,
+ @NonNull LocationTimeZoneProvider secondaryProvider) {
super(threadingDomain);
mUncertaintyTimeoutQueue = threadingDomain.createSingleRunnableQueue();
mPrimaryProvider = Objects.requireNonNull(primaryProvider);
+ mSecondaryProvider = Objects.requireNonNull(secondaryProvider);
}
@Override
@@ -96,8 +106,9 @@ class ControllerImpl extends LocationTimeZoneProviderController {
LocationTimeZoneProvider.ProviderListener providerListener =
ControllerImpl.this::onProviderStateChange;
mPrimaryProvider.initialize(providerListener);
+ mSecondaryProvider.initialize(providerListener);
- alterProviderEnabledStateIfRequired(
+ alterProvidersEnabledStateIfRequired(
null /* oldConfiguration */, mCurrentUserConfiguration);
}
}
@@ -115,15 +126,15 @@ class ControllerImpl extends LocationTimeZoneProviderController {
if (!newConfig.equals(oldConfig)) {
if (newConfig.getUserId() != oldConfig.getUserId()) {
- // If the user changed, disable the provider if needed. It may be re-enabled for
- // the new user below if their settings allow.
+ // If the user changed, disable the providers if needed. They may be re-enabled
+ // for the new user immediately afterwards if their settings allow.
debugLog("User changed. old=" + oldConfig.getUserId()
- + ", new=" + newConfig.getUserId() + ": Disabling provider");
- disableProvider();
+ + ", new=" + newConfig.getUserId() + ": Disabling providers");
+ disableProviders();
- alterProviderEnabledStateIfRequired(null /* oldConfiguration */, newConfig);
+ alterProvidersEnabledStateIfRequired(null /* oldConfiguration */, newConfig);
} else {
- alterProviderEnabledStateIfRequired(oldConfig, newConfig);
+ alterProvidersEnabledStateIfRequired(oldConfig, newConfig);
}
}
}
@@ -140,10 +151,11 @@ class ControllerImpl extends LocationTimeZoneProviderController {
}
@GuardedBy("mSharedLock")
- private void disableProvider() {
+ private void disableProviders() {
disableProviderIfEnabled(mPrimaryProvider);
+ disableProviderIfEnabled(mSecondaryProvider);
- // By definition, if the provider is disabled, the controller is uncertain.
+ // By definition, if both providers are disabled, the controller is uncertain.
cancelUncertaintyTimeout();
}
@@ -181,7 +193,7 @@ class ControllerImpl extends LocationTimeZoneProviderController {
}
/**
- * Sets the provider into the correct enabled/disabled state for the {@code newConfiguration}
+ * Sets the providers into the correct enabled/disabled state for the {@code newConfiguration}
* and, if there is a provider state change, makes any suggestions required to inform the
* downstream time zone detection code.
*
@@ -190,7 +202,7 @@ class ControllerImpl extends LocationTimeZoneProviderController {
* or when a new configuration has been received.
*/
@GuardedBy("mSharedLock")
- private void alterProviderEnabledStateIfRequired(
+ private void alterProvidersEnabledStateIfRequired(
@Nullable ConfigurationInternal oldConfiguration,
@NonNull ConfigurationInternal newConfiguration) {
@@ -203,21 +215,40 @@ class ControllerImpl extends LocationTimeZoneProviderController {
return;
}
+ // The check above ensures that the logic below only executes if providers are going from
+ // {enabled *} -> {disabled}, or {disabled} -> {enabled initializing}. If this changes in
+ // future and there could be {enabled *} -> {enabled *} cases, or cases where the provider
+ // can't be assumed to go straight to the {enabled initializing} state, then the logic below
+ // would need to cover extra conditions, for example:
+ // 1) If the primary is in {enabled uncertain}, the secondary should be enabled.
+ // 2) If (1), and the secondary instantly enters the {perm failed} state, the uncertainty
+ // timeout started when the primary entered {enabled uncertain} should be cancelled.
+
if (newGeoDetectionEnabled) {
// Try to enable the primary provider.
tryEnableProvider(mPrimaryProvider, newConfiguration);
+ // The secondary should only ever be enabled if the primary now isn't enabled (i.e. it
+ // couldn't become {enabled initializing} because it is {perm failed}).
ProviderState newPrimaryState = mPrimaryProvider.getCurrentState();
if (!newPrimaryState.isEnabled()) {
- // If the provider is perm failed then the controller is immediately considered
- // uncertain.
- GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion(
- "Provider is failed:"
- + " primary=" + mPrimaryProvider.getCurrentState());
- makeSuggestion(suggestion);
+ // If the primary provider is {perm failed} then the controller must try to enable
+ // the secondary.
+ tryEnableProvider(mSecondaryProvider, newConfiguration);
+
+ ProviderState newSecondaryState = mSecondaryProvider.getCurrentState();
+ if (!newSecondaryState.isEnabled()) {
+ // If both providers are {perm failed} then the controller immediately
+ // becomes uncertain.
+ GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion(
+ "Providers are failed:"
+ + " primary=" + mPrimaryProvider.getCurrentState()
+ + " secondary=" + mPrimaryProvider.getCurrentState());
+ makeSuggestion(suggestion);
+ }
}
} else {
- disableProvider();
+ disableProviders();
// There can be an uncertainty timeout set if the controller most recently received
// an uncertain event. This is a no-op if there isn't a timeout set.
@@ -300,35 +331,63 @@ class ControllerImpl extends LocationTimeZoneProviderController {
}
private void assertProviderKnown(@NonNull LocationTimeZoneProvider provider) {
- if (provider != mPrimaryProvider) {
+ if (provider != mPrimaryProvider && provider != mSecondaryProvider) {
throw new IllegalArgumentException("Unknown provider: " + provider);
}
}
/**
- * Called when the provider has reported that it has failed permanently.
+ * Called when a provider has reported that it has failed permanently.
*/
@GuardedBy("mSharedLock")
private void handleProviderFailedStateChange(@NonNull ProviderState providerState) {
LocationTimeZoneProvider failedProvider = providerState.provider;
+ ProviderState primaryCurrentState = mPrimaryProvider.getCurrentState();
+ ProviderState secondaryCurrentState = mSecondaryProvider.getCurrentState();
+
+ // If a provider has failed, the other may need to be enabled.
+ if (failedProvider == mPrimaryProvider) {
+ if (secondaryCurrentState.stateEnum != PROVIDER_STATE_PERM_FAILED) {
+ // The primary must have failed. Try to enable the secondary. This does nothing if
+ // the provider is already enabled, and will leave the provider in
+ // {enabled initializing} if the provider is disabled.
+ tryEnableProvider(mSecondaryProvider, mCurrentUserConfiguration);
+ }
+ } else if (failedProvider == mSecondaryProvider) {
+ // No-op: The secondary will only be active if the primary is uncertain or is failed.
+ // So, there the primary should not need to be enabled when the secondary fails.
+ if (primaryCurrentState.stateEnum != PROVIDER_STATE_ENABLED_UNCERTAIN
+ && primaryCurrentState.stateEnum != PROVIDER_STATE_PERM_FAILED) {
+ warnLog("Secondary provider unexpected reported a failure:"
+ + " failed provider=" + failedProvider.getName()
+ + ", primary provider=" + mPrimaryProvider
+ + ", secondary provider=" + mSecondaryProvider);
+ }
+ }
- // If the provider is newly perm failed then the controller is uncertain by
- // definition.
- cancelUncertaintyTimeout();
+ // If both providers are now failed, the controller needs to tell the next component in the
+ // time zone detection process.
+ if (primaryCurrentState.stateEnum == PROVIDER_STATE_PERM_FAILED
+ && secondaryCurrentState.stateEnum == PROVIDER_STATE_PERM_FAILED) {
- // If the provider is now failed, then we must send a suggestion informing the time
- // zone detector that there are no further updates coming in future.
+ // If both providers are newly failed then the controller is uncertain by definition
+ // and it will never recover so it can send a suggestion immediately.
+ cancelUncertaintyTimeout();
- GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion(
- "The provider is permanently failed:"
- + " provider=" + failedProvider);
- makeSuggestion(suggestion);
+ // If both providers are now failed, then a suggestion must be sent informing the time
+ // zone detector that there are no further updates coming in future.
+ GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion(
+ "Both providers are permanently failed:"
+ + " primary=" + primaryCurrentState.provider
+ + ", secondary=" + secondaryCurrentState.provider);
+ makeSuggestion(suggestion);
+ }
}
/**
* Called when a provider has changed state but just moved from one enabled state to another
* enabled state, usually as a result of a new {@link LocationTimeZoneEvent} being received.
- * However, there are rare cases where the event can be null.
+ * However, there are rare cases where the event can also be null.
*/
@GuardedBy("mSharedLock")
private void handleProviderEnabledStateChange(@NonNull ProviderState providerState) {
@@ -395,6 +454,10 @@ class ControllerImpl extends LocationTimeZoneProviderController {
// By definition, the controller is now certain.
cancelUncertaintyTimeout();
+ if (provider == mPrimaryProvider) {
+ disableProviderIfEnabled(mSecondaryProvider);
+ }
+
GeolocationTimeZoneSuggestion suggestion =
new GeolocationTimeZoneSuggestion(timeZoneIds);
suggestion.addDebugInfo(reason);
@@ -421,6 +484,11 @@ class ControllerImpl extends LocationTimeZoneProviderController {
mPrimaryProvider.dump(ipw, args);
ipw.decreaseIndent(); // level 2
+ ipw.println("Secondary Provider:");
+ ipw.increaseIndent(); // level 2
+ mSecondaryProvider.dump(ipw, args);
+ ipw.decreaseIndent(); // level 2
+
ipw.decreaseIndent(); // level 1
}
}
@@ -470,6 +538,14 @@ class ControllerImpl extends LocationTimeZoneProviderController {
mUncertaintyTimeoutQueue.runDelayed(() -> onProviderUncertaintyTimeout(provider),
delay.toMillis());
}
+
+ if (provider == mPrimaryProvider) {
+ // (Try to) enable the secondary. It could already be enabled, or enabling might not
+ // succeed if the provider has previously reported it is perm failed. The uncertainty
+ // timeout (set above) is used to ensure that an uncertain suggestion will be made if
+ // the secondary cannot generate a success event in time.
+ tryEnableProvider(mSecondaryProvider, mCurrentUserConfiguration);
+ }
}
private void onProviderUncertaintyTimeout(@NonNull LocationTimeZoneProvider provider) {
@@ -478,7 +554,8 @@ class ControllerImpl extends LocationTimeZoneProviderController {
synchronized (mSharedLock) {
GeolocationTimeZoneSuggestion suggestion = createUncertainSuggestion(
"Uncertainty timeout triggered for " + provider.getName() + ":"
- + " primary=" + mPrimaryProvider);
+ + " primary=" + mPrimaryProvider
+ + ", secondary=" + mSecondaryProvider);
makeSuggestion(suggestion);
}
}
@@ -498,6 +575,8 @@ class ControllerImpl extends LocationTimeZoneProviderController {
LocationTimeZoneProvider targetProvider;
if (Objects.equals(mPrimaryProvider.getName(), targetProviderName)) {
targetProvider = mPrimaryProvider;
+ } else if (Objects.equals(mSecondaryProvider.getName(), targetProviderName)) {
+ targetProvider = mSecondaryProvider;
} else {
warnLog("Unable to process simulated binder provider event,"
+ " unknown providerName in event=" + event);
diff --git a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
index 97d3b826f3ff..a8589d43116d 100644
--- a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
+++ b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
@@ -44,8 +44,8 @@ import java.util.Objects;
* are made to the {@link TimeZoneDetectorInternal}, and the {@link LocationTimeZoneProvider}s that
* offer {@link android.location.timezone.LocationTimeZoneEvent}s.
*
- * TODO(b/152744911): This implementation currently only supports a primary provider. Support for a
- * secondary provider must be added in a later commit.
+ * <p>For details of the time zone suggestion behavior, see {@link
+ * LocationTimeZoneProviderController}.
*
* <p>Implementation details:
*
@@ -109,6 +109,7 @@ public class LocationTimeZoneManagerService extends Binder {
static final String TAG = "LocationTZDetector";
static final String PRIMARY_PROVIDER_NAME = "primary";
+ static final String SECONDARY_PROVIDER_NAME = "secondary";
private static final String SIMULATION_MODE_SYSTEM_PROPERTY_PREFIX =
"persist.sys.location_tz_simulation_mode.";
@@ -117,6 +118,8 @@ public class LocationTimeZoneManagerService extends Binder {
private static final String PRIMARY_LOCATION_TIME_ZONE_SERVICE_ACTION =
"com.android.location.timezone.service.v1.PrimaryLocationTimeZoneProvider";
+ private static final String SECONDARY_LOCATION_TIME_ZONE_SERVICE_ACTION =
+ "com.android.location.timezone.service.v1.SecondaryLocationTimeZoneProvider";
@NonNull private final Context mContext;
@@ -160,8 +163,9 @@ public class LocationTimeZoneManagerService extends Binder {
// Called on an arbitrary thread during initialization.
synchronized (mSharedLock) {
LocationTimeZoneProvider primary = createPrimaryProvider();
+ LocationTimeZoneProvider secondary = createSecondaryProvider();
mLocationTimeZoneDetectorController =
- new ControllerImpl(mThreadingDomain, primary);
+ new ControllerImpl(mThreadingDomain, primary, secondary);
ControllerCallbackImpl callback = new ControllerCallbackImpl(mThreadingDomain);
ControllerEnvironmentImpl environment = new ControllerEnvironmentImpl(
mThreadingDomain, mLocationTimeZoneDetectorController);
@@ -189,6 +193,27 @@ public class LocationTimeZoneManagerService extends Binder {
return createLocationTimeZoneProvider(PRIMARY_PROVIDER_NAME, proxy);
}
+ private LocationTimeZoneProvider createSecondaryProvider() {
+ LocationTimeZoneProviderProxy proxy;
+ if (isInSimulationMode(SECONDARY_PROVIDER_NAME)) {
+ proxy = new SimulatedLocationTimeZoneProviderProxy(mContext, mThreadingDomain);
+ } else {
+ // TODO Uncomment this code in a later commit.
+ throw new UnsupportedOperationException("Not implemented");
+ /*
+ proxy = RealLocationTimeZoneProviderProxy.createAndRegister(
+ mContext,
+ mThreadingDomain,
+ SECONDARY_LOCATION_TIME_ZONE_SERVICE_ACTION,
+ com.android.internal.R.bool.config_enableSecondaryLocationTimeZoneOverlay,
+ com.android.internal.R.string
+ .config_secondaryLocationTimeZoneProviderPackageName
+ );
+ */
+ }
+ return createLocationTimeZoneProvider(SECONDARY_PROVIDER_NAME, proxy);
+ }
+
private boolean isInSimulationMode(String providerName) {
return SystemProperties.getBoolean(
SIMULATION_MODE_SYSTEM_PROPERTY_PREFIX + providerName, false);
diff --git a/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java b/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java
index ef2e349fceaa..f1d37237872b 100644
--- a/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java
+++ b/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java
@@ -21,6 +21,7 @@ import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_SUCCESS
import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN;
import static com.android.server.location.timezone.LocationTimeZoneManagerService.PRIMARY_PROVIDER_NAME;
+import static com.android.server.location.timezone.LocationTimeZoneManagerService.SECONDARY_PROVIDER_NAME;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -42,7 +43,8 @@ import java.util.Objects;
*/
final class SimulatedBinderProviderEvent {
- private static final List<String> VALID_PROVIDER_NAMES = Arrays.asList(PRIMARY_PROVIDER_NAME);
+ private static final List<String> VALID_PROVIDER_NAMES =
+ Arrays.asList(PRIMARY_PROVIDER_NAME, SECONDARY_PROVIDER_NAME);
static final int INJECTED_EVENT_TYPE_ON_BIND = 1;
static final int INJECTED_EVENT_TYPE_ON_UNBIND = 2;
diff --git a/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java b/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java
index 9ee9259a23c2..292b7c6bf5ad 100644
--- a/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java
@@ -77,6 +77,7 @@ public class ControllerImplTest {
private TestThreadingDomain mTestThreadingDomain;
private TestCallback mTestCallback;
private TestLocationTimeZoneProvider mTestPrimaryLocationTimeZoneProvider;
+ private TestLocationTimeZoneProvider mTestSecondaryLocationTimeZoneProvider;
@Before
public void setUp() {
@@ -87,26 +88,30 @@ public class ControllerImplTest {
mTestCallback = new TestCallback(mTestThreadingDomain);
mTestPrimaryLocationTimeZoneProvider =
new TestLocationTimeZoneProvider(mTestThreadingDomain, "primary");
+ mTestSecondaryLocationTimeZoneProvider =
+ new TestLocationTimeZoneProvider(mTestThreadingDomain, "secondary");
}
@Test
public void initialState_enabled() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
Duration expectedInitTimeout = testEnvironment.getProviderInitializationTimeout()
.plus(testEnvironment.getProviderInitializationTimeoutFuzz());
- // Initialize. After initialization the provider must be initialized and should be
+ // Initialize. After initialization the providers must be initialized and one should be
// enabled.
controllerImpl.initialize(testEnvironment, mTestCallback);
mTestPrimaryLocationTimeZoneProvider.assertInitialized();
+ mTestSecondaryLocationTimeZoneProvider.assertInitialized();
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
mTestPrimaryLocationTimeZoneProvider.assertInitializationTimeoutSet(expectedInitTimeout);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
}
@@ -114,17 +119,19 @@ public class ControllerImplTest {
@Test
public void initialState_disabled() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_DISABLED);
- // Initialize. After initialization the provider must be initialized but should not be
+ // Initialize. After initialization the providers must be initialized but neither should be
// enabled.
controllerImpl.initialize(testEnvironment, mTestCallback);
mTestPrimaryLocationTimeZoneProvider.assertInitialized();
+ mTestSecondaryLocationTimeZoneProvider.assertInitialized();
mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
}
@@ -132,7 +139,7 @@ public class ControllerImplTest {
@Test
public void enabled_uncertaintySuggestionSentIfNoEventReceived() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
@@ -141,6 +148,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -148,9 +156,24 @@ public class ControllerImplTest {
mTestThreadingDomain.executeNext();
// The primary should have reported uncertainty, which should trigger the controller to
- // start the uncertainty timeout.
+ // start the uncertainty timeout and enable the secondary.
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+
+ // Simulate time passing with no provider event being received from either the primary or
+ // secondary.
+ mTestThreadingDomain.executeNext();
+
+ // Now both initialization timeouts should have triggered. The uncertainty timeout should
+ // still not be triggered.
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
mTestCallback.assertNoSuggestionMade();
assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
@@ -160,6 +183,8 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
mTestCallback.assertUncertainSuggestionMadeAndCommit();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
}
@@ -167,7 +192,7 @@ public class ControllerImplTest {
@Test
public void enabled_eventReceivedBeforeInitializationTimeout() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
@@ -176,6 +201,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -186,6 +212,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertSuggestionMadeAndCommit(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds());
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -194,7 +221,7 @@ public class ControllerImplTest {
@Test
public void enabled_eventReceivedFromPrimaryAfterInitializationTimeout() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
@@ -203,6 +230,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -211,16 +239,59 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
mTestCallback.assertNoSuggestionMade();
assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
// Simulate a location event being received from the primary provider. This should cause a
- // suggestion to be made.
+ // suggestion to be made and the secondary to be shut down.
mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestCallback.assertSuggestionMadeAndCommit(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds());
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+ }
+
+ @Test
+ public void enabled_eventReceivedFromSecondaryAfterInitializationTimeout() {
+ ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
+ TestEnvironment testEnvironment = new TestEnvironment(
+ mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
+
+ // Initialize and check initial state.
+ controllerImpl.initialize(testEnvironment, mTestCallback);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate time passing with no provider event being received from the primary.
+ mTestThreadingDomain.executeNext();
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+
+ // Simulate a location event being received from the secondary provider. This should cause a
+ // suggestion to be made.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
mTestCallback.assertSuggestionMadeAndCommit(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds());
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -229,7 +300,7 @@ public class ControllerImplTest {
@Test
public void enabled_repeatedPrimaryCertainty() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
@@ -238,6 +309,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -248,6 +320,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertSuggestionMadeAndCommit(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds());
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -258,6 +331,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -267,6 +341,70 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestCallback.assertSuggestionMadeAndCommit(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds());
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+ }
+
+ @Test
+ public void enabled_repeatedSecondaryCertainty() {
+ ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
+ TestEnvironment testEnvironment = new TestEnvironment(
+ mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
+
+ // Initialize and check initial state.
+ controllerImpl.initialize(testEnvironment, mTestCallback);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate time passing with no provider event being received from the primary.
+ mTestThreadingDomain.executeNext();
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+
+ // Simulate a location event being received from the secondary provider. This should cause a
+ // suggestion to be made.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertSuggestionMadeAndCommit(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds());
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // A second, identical event should not cause another suggestion.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // And a third, different event should cause another suggestion.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
mTestCallback.assertSuggestionMadeAndCommit(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds());
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -275,7 +413,7 @@ public class ControllerImplTest {
@Test
public void enabled_uncertaintyTriggersASuggestionAfterUncertaintyTimeout() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
@@ -284,6 +422,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -294,18 +433,48 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertSuggestionMadeAndCommit(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds());
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
// Simulate an uncertain event being received from the primary provider. This should not
// cause a suggestion to be made straight away, but the uncertainty timeout should be
- // started.
+ // started and the secondary should be enabled.
mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+
+ // Simulate a location event being received from the secondary provider. This should cause a
+ // suggestion to be made, cancel the uncertainty timeout and ensure the secondary is
+ // considered initialized.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertSuggestionMadeAndCommit(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds());
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate an uncertain event being received from the secondary provider. This should not
+ // cause a suggestion to be made straight away, but the uncertainty timeout should be
+ // started. Both providers are now enabled, with no initialization timeout set.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
mTestCallback.assertNoSuggestionMade();
assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
@@ -315,6 +484,8 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
mTestCallback.assertUncertainSuggestionMadeAndCommit();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
}
@@ -322,7 +493,7 @@ public class ControllerImplTest {
@Test
public void enabled_briefUncertaintyTriggersNoSuggestion() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
@@ -331,6 +502,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -341,27 +513,32 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertSuggestionMadeAndCommit(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds());
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
// Uncertainty should not cause a suggestion to be made straight away, but the uncertainty
- // timeout should be started.
+ // timeout should be started and the secondary should be enabled.
mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
mTestCallback.assertNoSuggestionMade();
assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
// And a success event from the primary provider should cause the controller to make another
- // suggestion, the uncertainty timeout should be cancelled.
+ // suggestion, the uncertainty timeout should be cancelled and the secondary should be
+ // disabled again.
mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertSuggestionMadeAndCommit(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds());
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -370,7 +547,7 @@ public class ControllerImplTest {
@Test
public void configChanges_enableAndDisableWithNoPreviousSuggestion() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_DISABLED);
@@ -378,6 +555,7 @@ public class ControllerImplTest {
controllerImpl.initialize(testEnvironment, mTestCallback);
mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -386,6 +564,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -393,6 +572,7 @@ public class ControllerImplTest {
testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED);
mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
}
@@ -400,7 +580,7 @@ public class ControllerImplTest {
@Test
public void configChanges_enableAndDisableWithPreviousSuggestion() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_DISABLED);
@@ -408,6 +588,7 @@ public class ControllerImplTest {
controllerImpl.initialize(testEnvironment, mTestCallback);
mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -416,6 +597,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -425,6 +607,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertSuggestionMadeAndCommit(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds());
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -436,6 +619,7 @@ public class ControllerImplTest {
testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED);
mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertUncertainSuggestionMadeAndCommit();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
}
@@ -443,7 +627,7 @@ public class ControllerImplTest {
@Test
public void configChanges_userSwitch_enabledToEnabled() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
@@ -452,6 +636,7 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -463,6 +648,7 @@ public class ControllerImplTest {
// and also clear the scheduled uncertainty suggestion.
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertSuggestionMadeAndCommit(
USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1.getTimeZoneIds());
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -477,13 +663,74 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateChangesAndCommit(expectedStateTransitions);
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfig(
PROVIDER_STATE_ENABLED_INITIALIZING, USER2_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
}
@Test
+ public void primaryPermFailure_secondaryEventsReceived() {
+ ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
+ TestEnvironment testEnvironment = new TestEnvironment(
+ mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
+
+ // Initialize and check initial state.
+ controllerImpl.initialize(testEnvironment, mTestCallback);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate a failure location event being received from the primary provider. This should
+ // cause the secondary to be enabled.
+ mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate uncertainty from the secondary.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+
+ // And a success event from the secondary provider should cause the controller to make
+ // another suggestion, the uncertainty timeout should be cancelled.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
+
+ mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertSuggestionMadeAndCommit(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds());
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate uncertainty from the secondary.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+ }
+
+ @Test
public void primaryPermFailure_disableAndEnable() {
ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
- mTestPrimaryLocationTimeZoneProvider);
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
TestEnvironment testEnvironment = new TestEnvironment(
mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
@@ -492,22 +739,26 @@ public class ControllerImplTest {
mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
// Simulate a failure location event being received from the primary provider. This should
- // cause an uncertain suggestion to be made.
+ // cause the secondary to be enabled.
mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
- mTestCallback.assertUncertainSuggestionMadeAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
// Now signal a config change so that geo detection is disabled.
testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED);
mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
mTestCallback.assertNoSuggestionMade();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
@@ -515,6 +766,164 @@ public class ControllerImplTest {
testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_ENABLED);
mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+ }
+
+ @Test
+ public void secondaryPermFailure_primaryEventsReceived() {
+ ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
+ TestEnvironment testEnvironment = new TestEnvironment(
+ mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
+
+ // Initialize and check initial state.
+ controllerImpl.initialize(testEnvironment, mTestCallback);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate an uncertain event from the primary. This will enable the secondary, which will
+ // give this test the opportunity to simulate its failure. Then it will be possible to
+ // demonstrate controller behavior with only the primary working.
+ mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+
+ // Simulate failure event from the secondary. This should just affect the secondary's state.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+
+ // And a success event from the primary provider should cause the controller to make
+ // a suggestion, the uncertainty timeout should be cancelled.
+ mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_CERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestCallback.assertSuggestionMadeAndCommit(
+ USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT2.getTimeZoneIds());
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate uncertainty from the primary. The secondary cannot be enabled.
+ mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+ }
+
+ @Test
+ public void secondaryPermFailure_disableAndEnable() {
+ ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
+ TestEnvironment testEnvironment = new TestEnvironment(
+ mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
+
+ // Initialize and check initial state.
+ controllerImpl.initialize(testEnvironment, mTestCallback);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate an uncertain event from the primary. This will enable the secondary, which will
+ // give this test the opportunity to simulate its failure. Then it will be possible to
+ // demonstrate controller behavior with only the primary working.
+ mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_UNCERTAIN_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+
+ // Simulate failure event from the secondary. This should just affect the secondary's state.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_UNCERTAIN, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertUncertaintyTimeoutSet(testEnvironment, controllerImpl);
+
+ // Now signal a config change so that geo detection is disabled.
+ testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_DISABLED);
+
+ mTestPrimaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Now signal a config change so that geo detection is enabled. Only the primary can be
+ // enabled.
+ testEnvironment.simulateConfigChange(USER1_CONFIG_GEO_DETECTION_ENABLED);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+ }
+
+ @Test
+ public void bothPermFailure_disableAndEnable() {
+ ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain,
+ mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider);
+ TestEnvironment testEnvironment = new TestEnvironment(
+ mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED);
+
+ // Initialize and check initial state.
+ controllerImpl.initialize(testEnvironment, mTestCallback);
+
+ mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestSecondaryLocationTimeZoneProvider.assertIsDisabledAndCommit();
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate a failure event from the primary. This will enable the secondary.
+ mTestPrimaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit(
+ PROVIDER_STATE_ENABLED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED);
+ mTestCallback.assertNoSuggestionMade();
+ assertFalse(controllerImpl.isUncertaintyTimeoutSet());
+
+ // Simulate failure event from the secondary.
+ mTestSecondaryLocationTimeZoneProvider.simulateLocationTimeZoneEvent(
+ USER1_PERM_FAILURE_LOCATION_TIME_ZONE_EVENT);
+
+ mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
+ mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit();
mTestCallback.assertUncertainSuggestionMadeAndCommit();
assertFalse(controllerImpl.isUncertaintyTimeoutSet());
}