Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db42b61d authored by Neil Fuller's avatar Neil Fuller Committed by Android (Google) Code Review
Browse files

Merge "Fix behavior when primary fails initialization"

parents db3a0b49 443459b5
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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
@@ -108,6 +112,7 @@ class ControllerImpl extends LocationTimeZoneProviderController {
                    ControllerImpl.this::onProviderStateChange;
            mPrimaryProvider.initialize(providerListener);
            mSecondaryProvider.initialize(providerListener);
            mProvidersInitialized = true;

            alterProvidersStartedStateIfRequired(
                    null /* oldConfiguration */, mCurrentUserConfiguration);
@@ -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:
+83 −0
Original line number Diff line number Diff line
@@ -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,
@@ -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;

@@ -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