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

Commit 627920cb authored by Neil Fuller's avatar Neil Fuller
Browse files

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
parent ad4d5d36
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -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) {
+5 −1
Original line number Diff line number Diff line
@@ -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);
        }
    }
}
+18 −13
Original line number Diff line number Diff line
@@ -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);

            // 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();
+1 −1
Original line number Diff line number Diff line
@@ -79,9 +79,9 @@ abstract class LocationTimeZoneProviderProxy implements Dumpable {
                throw new IllegalStateException("listener already set");
            }
            this.mListener = listener;
        }
            onInitialize();
        }
    }

    /**
     * Initializes the proxy. This is called after {@link #mListener} is set.
+0 −6
Original line number Diff line number Diff line
@@ -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) {
Loading