Handle provider initialization failure

Handle provider initialization failure gracefully. Now the provider is
declared "permanently failed" and the thrown exception does not pop out
the top of the stack causing a system server crash.

Test: Withdrew a required permission for the only registered provider,
verified device failed to boot to UI before, and now it does.

Bug: 176812518
Change-Id: I541f5f300b7841c1342e0255fd2ba586d6429706
This commit is contained in:
Neil Fuller
2020-12-24 16:40:37 +00:00
parent ad4d5d365d
commit 627920cbcb
6 changed files with 23 additions and 30 deletions

View File

@@ -161,11 +161,6 @@ class BinderLocationTimeZoneProvider extends LocationTimeZoneProvider {
mProxy.setRequest(request);
}
@Override
void logWarn(String msg) {
Slog.w(TAG, msg);
}
@Override
public void dump(@NonNull IndentingPrintWriter ipw, @Nullable String[] args) {
synchronized (mSharedLock) {

View File

@@ -285,8 +285,12 @@ public class LocationTimeZoneManagerService extends Binder {
}
static void warnLog(String msg) {
warnLog(msg, null);
}
static void warnLog(String msg, @Nullable Throwable t) {
if (Log.isLoggable(TAG, Log.WARN)) {
Slog.w(TAG, msg);
Slog.w(TAG, msg, t);
}
}
}

View File

@@ -17,6 +17,7 @@
package com.android.server.location.timezone;
import static com.android.server.location.timezone.LocationTimeZoneManagerService.debugLog;
import static com.android.server.location.timezone.LocationTimeZoneManagerService.warnLog;
import static com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_PERM_FAILED;
import static com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STARTED_CERTAIN;
import static com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STARTED_INITIALIZING;
@@ -345,12 +346,21 @@ abstract class LocationTimeZoneProvider implements Dumpable {
}
mProviderListener = Objects.requireNonNull(providerListener);
ProviderState currentState = ProviderState.createStartingState(this);
ProviderState newState = currentState.newState(
currentState = currentState.newState(
PROVIDER_STATE_STOPPED, null, null,
"initialize() called");
setCurrentState(newState, false);
setCurrentState(currentState, false);
onInitialize();
// Guard against uncaught exceptions due to initialization problems.
try {
onInitialize();
} catch (RuntimeException e) {
warnLog("Unable to initialize the provider", e);
currentState = currentState
.newState(PROVIDER_STATE_PERM_FAILED, null, null,
"Provider failed to initialize");
setCurrentState(currentState, true);
}
}
}
@@ -498,7 +508,7 @@ abstract class LocationTimeZoneProvider implements Dumpable {
case PROVIDER_STATE_PERM_FAILED: {
// After entering perm failed, there is nothing to do. The remote peer is
// supposed to stop sending events after it has reported perm failure.
logWarn("handleTimeZoneProviderEvent: Event=" + timeZoneProviderEvent
warnLog("handleTimeZoneProviderEvent: Event=" + timeZoneProviderEvent
+ " received for provider=" + this + " when in failed state");
return;
}
@@ -509,7 +519,7 @@ abstract class LocationTimeZoneProvider implements Dumpable {
+ " Failure event=" + timeZoneProviderEvent
+ " received for stopped provider=" + this
+ ", entering permanently failed state";
logWarn(msg);
warnLog(msg);
ProviderState newState = currentState.newState(
PROVIDER_STATE_PERM_FAILED, null, null, msg);
setCurrentState(newState, true);
@@ -522,7 +532,7 @@ abstract class LocationTimeZoneProvider implements Dumpable {
case EVENT_TYPE_UNCERTAIN: {
// Any geolocation-related events received for a stopped provider are
// ignored: they should not happen.
logWarn("handleTimeZoneProviderEvent:"
warnLog("handleTimeZoneProviderEvent:"
+ " event=" + timeZoneProviderEvent
+ " received for stopped provider=" + this
+ ", ignoring");
@@ -544,7 +554,7 @@ abstract class LocationTimeZoneProvider implements Dumpable {
+ " Failure event=" + timeZoneProviderEvent
+ " received for provider=" + this
+ ", entering permanently failed state";
logWarn(msg);
warnLog(msg);
ProviderState newState = currentState.newState(
PROVIDER_STATE_PERM_FAILED, null, null, msg);
setCurrentState(newState, true);
@@ -584,11 +594,6 @@ abstract class LocationTimeZoneProvider implements Dumpable {
}
}
/**
* Implemented by subclasses.
*/
abstract void logWarn(String msg);
@GuardedBy("mSharedLock")
private void assertIsStarted() {
ProviderState currentState = mCurrentState.get();

View File

@@ -79,8 +79,8 @@ abstract class LocationTimeZoneProviderProxy implements Dumpable {
throw new IllegalStateException("listener already set");
}
this.mListener = listener;
onInitialize();
}
onInitialize();
}
/**

View File

@@ -21,7 +21,6 @@ import static com.android.server.location.timezone.LocationTimeZoneProvider.Prov
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.IndentingPrintWriter;
import android.util.Slog;
import java.time.Duration;
@@ -73,11 +72,6 @@ class NullLocationTimeZoneProvider extends LocationTimeZoneProvider {
// Ignored - this implementation is always permanently failed.
}
@Override
void logWarn(String msg) {
Slog.w(TAG, msg);
}
@Override
public void dump(@NonNull IndentingPrintWriter ipw, @Nullable String[] args) {
synchronized (mSharedLock) {

View File

@@ -1052,11 +1052,6 @@ public class ControllerImplTest {
// Nothing needed for tests.
}
@Override
void logWarn(String msg) {
System.out.println(msg);
}
@Override
public void dump(IndentingPrintWriter pw, String[] args) {
// Nothing needed for tests.