Loading services/core/java/com/android/server/location/timezone/ControllerImpl.java +15 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,10 @@ class ControllerImpl extends LocationTimeZoneProviderController { // Non-null after initialize() private Callback mCallback; /** Indicates both providers have completed initialization. */ @GuardedBy("mSharedLock") private boolean mProvidersInitialized; /** * 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 Loading Loading @@ -108,6 +112,7 @@ class ControllerImpl extends LocationTimeZoneProviderController { ControllerImpl.this::onProviderStateChange; mPrimaryProvider.initialize(providerListener); mSecondaryProvider.initialize(providerListener); mProvidersInitialized = true; alterProvidersStartedStateIfRequired( null /* oldConfiguration */, mCurrentUserConfiguration); Loading Loading @@ -322,6 +327,16 @@ class ControllerImpl extends LocationTimeZoneProviderController { assertProviderKnown(provider); synchronized (mSharedLock) { // Ignore provider state changes during initialization. e.g. if the primary provider // moves to PROVIDER_STATE_PERM_FAILED during initialization, the secondary will not // be ready to take over yet. if (!mProvidersInitialized) { warnLog("onProviderStateChange: Ignoring provider state change because both" + " providers have not yet completed initialization." + " providerState=" + providerState); return; } switch (providerState.stateEnum) { case PROVIDER_STATE_STARTED_INITIALIZING: case PROVIDER_STATE_STOPPED: Loading services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java +83 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,81 @@ public class ControllerImplTest { new TestLocationTimeZoneProvider(mTestThreadingDomain, "secondary"); } @Test public void initializationFailure_primary() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); Duration expectedInitTimeout = testEnvironment.getProviderInitializationTimeout() .plus(testEnvironment.getProviderInitializationTimeoutFuzz()); mTestPrimaryLocationTimeZoneProvider.setFailDuringInitialization(true); // Initialize. After initialization the providers must be initialized and one should be // started. controllerImpl.initialize(testEnvironment, mTestCallback); mTestPrimaryLocationTimeZoneProvider.assertInitialized(); mTestSecondaryLocationTimeZoneProvider.assertInitialized(); mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestSecondaryLocationTimeZoneProvider.assertInitializationTimeoutSet(expectedInitTimeout); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @Test public void initializationFailure_secondary() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); Duration expectedInitTimeout = testEnvironment.getProviderInitializationTimeout() .plus(testEnvironment.getProviderInitializationTimeoutFuzz()); mTestSecondaryLocationTimeZoneProvider.setFailDuringInitialization(true); // Initialize. After initialization the providers must be initialized and one should be // started. controllerImpl.initialize(testEnvironment, mTestCallback); mTestPrimaryLocationTimeZoneProvider.assertInitialized(); mTestSecondaryLocationTimeZoneProvider.assertInitialized(); mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestPrimaryLocationTimeZoneProvider.assertInitializationTimeoutSet(expectedInitTimeout); mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @Test public void initializationFailure_both() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestPrimaryLocationTimeZoneProvider.setFailDuringInitialization(true); mTestSecondaryLocationTimeZoneProvider.setFailDuringInitialization(true); // Initialize. After initialization the providers must be initialized and one should be // started. controllerImpl.initialize(testEnvironment, mTestCallback); mTestPrimaryLocationTimeZoneProvider.assertInitialized(); mTestSecondaryLocationTimeZoneProvider.assertInitialized(); mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); mTestCallback.assertUncertainSuggestionMadeAndCommit(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @Test public void initialState_started() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, Loading Loading @@ -1097,6 +1172,7 @@ public class ControllerImplTest { /** Used to track historic provider states for tests. */ private final TestState<ProviderState> mTestProviderState = new TestState<>(); private boolean mFailDuringInitialization; private boolean mInitialized; private boolean mDestroyed; Loading @@ -1107,9 +1183,16 @@ public class ControllerImplTest { super(threadingDomain, providerName); } public void setFailDuringInitialization(boolean failInitialization) { mFailDuringInitialization = failInitialization; } @Override void onInitialize() { mInitialized = true; if (mFailDuringInitialization) { throw new RuntimeException("Simulated initialization failure"); } } @Override Loading Loading
services/core/java/com/android/server/location/timezone/ControllerImpl.java +15 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,10 @@ class ControllerImpl extends LocationTimeZoneProviderController { // Non-null after initialize() private Callback mCallback; /** Indicates both providers have completed initialization. */ @GuardedBy("mSharedLock") private boolean mProvidersInitialized; /** * 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 Loading Loading @@ -108,6 +112,7 @@ class ControllerImpl extends LocationTimeZoneProviderController { ControllerImpl.this::onProviderStateChange; mPrimaryProvider.initialize(providerListener); mSecondaryProvider.initialize(providerListener); mProvidersInitialized = true; alterProvidersStartedStateIfRequired( null /* oldConfiguration */, mCurrentUserConfiguration); Loading Loading @@ -322,6 +327,16 @@ class ControllerImpl extends LocationTimeZoneProviderController { assertProviderKnown(provider); synchronized (mSharedLock) { // Ignore provider state changes during initialization. e.g. if the primary provider // moves to PROVIDER_STATE_PERM_FAILED during initialization, the secondary will not // be ready to take over yet. if (!mProvidersInitialized) { warnLog("onProviderStateChange: Ignoring provider state change because both" + " providers have not yet completed initialization." + " providerState=" + providerState); return; } switch (providerState.stateEnum) { case PROVIDER_STATE_STARTED_INITIALIZING: case PROVIDER_STATE_STOPPED: Loading
services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java +83 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,81 @@ public class ControllerImplTest { new TestLocationTimeZoneProvider(mTestThreadingDomain, "secondary"); } @Test public void initializationFailure_primary() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); Duration expectedInitTimeout = testEnvironment.getProviderInitializationTimeout() .plus(testEnvironment.getProviderInitializationTimeoutFuzz()); mTestPrimaryLocationTimeZoneProvider.setFailDuringInitialization(true); // Initialize. After initialization the providers must be initialized and one should be // started. controllerImpl.initialize(testEnvironment, mTestCallback); mTestPrimaryLocationTimeZoneProvider.assertInitialized(); mTestSecondaryLocationTimeZoneProvider.assertInitialized(); mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); mTestSecondaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestSecondaryLocationTimeZoneProvider.assertInitializationTimeoutSet(expectedInitTimeout); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @Test public void initializationFailure_secondary() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); Duration expectedInitTimeout = testEnvironment.getProviderInitializationTimeout() .plus(testEnvironment.getProviderInitializationTimeoutFuzz()); mTestSecondaryLocationTimeZoneProvider.setFailDuringInitialization(true); // Initialize. After initialization the providers must be initialized and one should be // started. controllerImpl.initialize(testEnvironment, mTestCallback); mTestPrimaryLocationTimeZoneProvider.assertInitialized(); mTestSecondaryLocationTimeZoneProvider.assertInitialized(); mTestPrimaryLocationTimeZoneProvider.assertStateEnumAndConfigAndCommit( PROVIDER_STATE_STARTED_INITIALIZING, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestPrimaryLocationTimeZoneProvider.assertInitializationTimeoutSet(expectedInitTimeout); mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); mTestCallback.assertNoSuggestionMade(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @Test public void initializationFailure_both() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, mTestPrimaryLocationTimeZoneProvider, mTestSecondaryLocationTimeZoneProvider); TestEnvironment testEnvironment = new TestEnvironment( mTestThreadingDomain, controllerImpl, USER1_CONFIG_GEO_DETECTION_ENABLED); mTestPrimaryLocationTimeZoneProvider.setFailDuringInitialization(true); mTestSecondaryLocationTimeZoneProvider.setFailDuringInitialization(true); // Initialize. After initialization the providers must be initialized and one should be // started. controllerImpl.initialize(testEnvironment, mTestCallback); mTestPrimaryLocationTimeZoneProvider.assertInitialized(); mTestSecondaryLocationTimeZoneProvider.assertInitialized(); mTestPrimaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); mTestSecondaryLocationTimeZoneProvider.assertIsPermFailedAndCommit(); mTestCallback.assertUncertainSuggestionMadeAndCommit(); assertFalse(controllerImpl.isUncertaintyTimeoutSet()); } @Test public void initialState_started() { ControllerImpl controllerImpl = new ControllerImpl(mTestThreadingDomain, Loading Loading @@ -1097,6 +1172,7 @@ public class ControllerImplTest { /** Used to track historic provider states for tests. */ private final TestState<ProviderState> mTestProviderState = new TestState<>(); private boolean mFailDuringInitialization; private boolean mInitialized; private boolean mDestroyed; Loading @@ -1107,9 +1183,16 @@ public class ControllerImplTest { super(threadingDomain, providerName); } public void setFailDuringInitialization(boolean failInitialization) { mFailDuringInitialization = failInitialization; } @Override void onInitialize() { mInitialized = true; if (mFailDuringInitialization) { throw new RuntimeException("Simulated initialization failure"); } } @Override Loading