diff --git a/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java b/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java index f054c5756e20a..59df6ff3582e8 100644 --- a/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java +++ b/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java @@ -67,7 +67,7 @@ class BinderLocationTimeZoneProvider extends LocationTimeZoneProvider { @Override public void onProviderUnbound() { - handleProviderLost("onProviderUnbound()"); + handleTemporaryFailure("onProviderUnbound()"); } }); } @@ -77,50 +77,6 @@ class BinderLocationTimeZoneProvider extends LocationTimeZoneProvider { mProxy.destroy(); } - private void handleProviderLost(String reason) { - mThreadingDomain.assertCurrentThread(); - - synchronized (mSharedLock) { - ProviderState currentState = mCurrentState.get(); - switch (currentState.stateEnum) { - case PROVIDER_STATE_STARTED_INITIALIZING: - case PROVIDER_STATE_STARTED_UNCERTAIN: - case PROVIDER_STATE_STARTED_CERTAIN: { - // Losing a remote provider is treated as becoming uncertain. - String msg = "handleProviderLost reason=" + reason - + ", mProviderName=" + mProviderName - + ", currentState=" + currentState; - debugLog(msg); - // This is an unusual PROVIDER_STATE_STARTED_UNCERTAIN state because - // event == null - ProviderState newState = currentState.newState( - PROVIDER_STATE_STARTED_UNCERTAIN, null, - currentState.currentUserConfiguration, msg); - setCurrentState(newState, true); - break; - } - case PROVIDER_STATE_STOPPED: { - debugLog("handleProviderLost reason=" + reason - + ", mProviderName=" + mProviderName - + ", currentState=" + currentState - + ": No state change required, provider is stopped."); - break; - } - case PROVIDER_STATE_PERM_FAILED: - case PROVIDER_STATE_DESTROYED: { - debugLog("handleProviderLost reason=" + reason - + ", mProviderName=" + mProviderName - + ", currentState=" + currentState - + ": No state change required, provider is terminated."); - break; - } - default: { - throw new IllegalStateException("Unknown currentState=" + currentState); - } - } - } - } - private void handleOnProviderBound() { mThreadingDomain.assertCurrentThread(); diff --git a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java index e116a8742208d..c2add2d85d260 100644 --- a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java +++ b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java @@ -592,9 +592,7 @@ abstract class LocationTimeZoneProvider implements Dumpable { PROVIDER_STATE_STOPPED, null, null, "stopUpdates() called"); setCurrentState(newState, false); - if (mInitializationTimeoutQueue.hasQueued()) { - mInitializationTimeoutQueue.cancel(); - } + cancelInitializationTimeoutIfSet(); onStopUpdates(); } @@ -656,9 +654,7 @@ abstract class LocationTimeZoneProvider implements Dumpable { ProviderState newState = currentState.newState( PROVIDER_STATE_PERM_FAILED, null, null, msg); setCurrentState(newState, true); - if (mInitializationTimeoutQueue.hasQueued()) { - mInitializationTimeoutQueue.cancel(); - } + cancelInitializationTimeoutIfSet(); return; } case EVENT_TYPE_SUGGESTION: @@ -691,9 +687,7 @@ abstract class LocationTimeZoneProvider implements Dumpable { ProviderState newState = currentState.newState( PROVIDER_STATE_PERM_FAILED, null, null, msg); setCurrentState(newState, true); - if (mInitializationTimeoutQueue.hasQueued()) { - mInitializationTimeoutQueue.cancel(); - } + cancelInitializationTimeoutIfSet(); return; } @@ -709,9 +703,7 @@ abstract class LocationTimeZoneProvider implements Dumpable { timeZoneProviderEvent, currentState.currentUserConfiguration, "handleTimeZoneProviderEvent() when started"); setCurrentState(newState, true); - if (mInitializationTimeoutQueue.hasQueued()) { - mInitializationTimeoutQueue.cancel(); - } + cancelInitializationTimeoutIfSet(); return; } default: { @@ -727,6 +719,52 @@ abstract class LocationTimeZoneProvider implements Dumpable { } } + /** For subclasses to invoke when needing to report a temporary failure. */ + final void handleTemporaryFailure(String reason) { + mThreadingDomain.assertCurrentThread(); + + synchronized (mSharedLock) { + ProviderState currentState = mCurrentState.get(); + switch (currentState.stateEnum) { + case PROVIDER_STATE_STARTED_INITIALIZING: + case PROVIDER_STATE_STARTED_UNCERTAIN: + case PROVIDER_STATE_STARTED_CERTAIN: { + // A temporary failure is treated as becoming uncertain. + String msg = "handleProviderLost reason=" + reason + + ", mProviderName=" + mProviderName + + ", currentState=" + currentState; + debugLog(msg); + // This is an unusual PROVIDER_STATE_STARTED_UNCERTAIN state because + // event == null + ProviderState newState = currentState.newState( + PROVIDER_STATE_STARTED_UNCERTAIN, null, + currentState.currentUserConfiguration, msg); + setCurrentState(newState, true); + cancelInitializationTimeoutIfSet(); + break; + } + case PROVIDER_STATE_STOPPED: { + debugLog("handleProviderLost reason=" + reason + + ", mProviderName=" + mProviderName + + ", currentState=" + currentState + + ": No state change required, provider is stopped."); + break; + } + case PROVIDER_STATE_PERM_FAILED: + case PROVIDER_STATE_DESTROYED: { + debugLog("handleProviderLost reason=" + reason + + ", mProviderName=" + mProviderName + + ", currentState=" + currentState + + ": No state change required, provider is terminated."); + break; + } + default: { + throw new IllegalStateException("Unknown currentState=" + currentState); + } + } + } + } + @GuardedBy("mSharedLock") private void assertIsStarted() { ProviderState currentState = mCurrentState.get(); @@ -751,6 +789,13 @@ abstract class LocationTimeZoneProvider implements Dumpable { } } + @GuardedBy("mSharedLock") + private void cancelInitializationTimeoutIfSet() { + if (mInitializationTimeoutQueue.hasQueued()) { + mInitializationTimeoutQueue.cancel(); + } + } + @VisibleForTesting Duration getInitializationTimeoutDelay() { synchronized (mSharedLock) {