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

Commit c4acf226 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Hook up binderDied callback to cancel session when service dies" into udc-dev am: c48c4fc2

parents 6f17fc20 c48c4fc2
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -132,7 +132,8 @@ public final class ProviderClearSession extends ProviderSession<ClearCredentialS
    protected void invokeSession() {
    protected void invokeSession() {
        if (mRemoteCredentialService != null) {
        if (mRemoteCredentialService != null) {
            startCandidateMetrics();
            startCandidateMetrics();
            mRemoteCredentialService.onClearCredentialState(mProviderRequest, this);
            mRemoteCredentialService.setCallback(this);
            mRemoteCredentialService.onClearCredentialState(mProviderRequest);
        }
        }
    }
    }
}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -248,7 +248,8 @@ public final class ProviderCreateSession extends ProviderSession<
    protected void invokeSession() {
    protected void invokeSession() {
        if (mRemoteCredentialService != null) {
        if (mRemoteCredentialService != null) {
            startCandidateMetrics();
            startCandidateMetrics();
            mRemoteCredentialService.onBeginCreateCredential(mProviderRequest, this);
            mRemoteCredentialService.setCallback(this);
            mRemoteCredentialService.onBeginCreateCredential(mProviderRequest);
        }
        }
    }
    }


+2 −1
Original line number Original line Diff line number Diff line
@@ -309,7 +309,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
    protected void invokeSession() {
    protected void invokeSession() {
        if (mRemoteCredentialService != null) {
        if (mRemoteCredentialService != null) {
            startCandidateMetrics();
            startCandidateMetrics();
            mRemoteCredentialService.onBeginGetCredential(mProviderRequest, this);
            mRemoteCredentialService.setCallback(this);
            mRemoteCredentialService.onBeginGetCredential(mProviderRequest);
        }
        }
    }
    }


+97 −36
Original line number Original line Diff line number Diff line
@@ -48,6 +48,7 @@ import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReference;


/**
/**
@@ -66,6 +67,10 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr


    private final ComponentName mComponentName;
    private final ComponentName mComponentName;


    private AtomicBoolean mOngoingRequest = new AtomicBoolean(false);

    @Nullable private ProviderCallbacks mCallback;

    /**
    /**
     * Callbacks to be invoked when the provider remote service responds with a
     * Callbacks to be invoked when the provider remote service responds with a
     * success or failure.
     * success or failure.
@@ -94,12 +99,35 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
        mComponentName = componentName;
        mComponentName = componentName;
    }
    }


    public void setCallback(ProviderCallbacks callback) {
        mCallback = callback;
    }

    /** Unbinds automatically after this amount of time. */
    /** Unbinds automatically after this amount of time. */
    @Override
    @Override
    protected long getAutoDisconnectTimeoutMs() {
    protected long getAutoDisconnectTimeoutMs() {
        return TIMEOUT_IDLE_SERVICE_CONNECTION_MILLIS;
        return TIMEOUT_IDLE_SERVICE_CONNECTION_MILLIS;
    }
    }


    @Override
    public void onBindingDied(ComponentName name) {
        super.onBindingDied(name);

        Slog.w(TAG, "binding died for: " + name);
    }

    @Override
    public void binderDied() {
        super.binderDied();
        Slog.w(TAG, "binderDied");

        if (mCallback != null) {
            mOngoingRequest.set(false);
            mCallback.onProviderServiceDied(this);
        }

    }

    /** Return the componentName of the service to be connected. */
    /** Return the componentName of the service to be connected. */
    @NonNull
    @NonNull
    public ComponentName getComponentName() {
    public ComponentName getComponentName() {
@@ -116,11 +144,14 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
     * provider service.
     * provider service.
     *
     *
     * @param request  the request to be sent to the provider
     * @param request  the request to be sent to the provider
     * @param callback the callback to be used to send back the provider response to the
     *                 {@link ProviderGetSession} class that maintains provider state
     */
     */
    public void onBeginGetCredential(@NonNull BeginGetCredentialRequest request,
    public void onBeginGetCredential(@NonNull BeginGetCredentialRequest request) {
            ProviderCallbacks<BeginGetCredentialResponse> callback) {
        if (mCallback == null) {
            Slog.w(TAG, "Callback is not set");
            return;
        }
        mOngoingRequest.set(true);

        AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
        AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
        AtomicReference<CompletableFuture<BeginGetCredentialResponse>> futureRef =
        AtomicReference<CompletableFuture<BeginGetCredentialResponse>> futureRef =
                new AtomicReference<>();
                new AtomicReference<>();
@@ -154,7 +185,9 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
                                    dispatchCancellationSignal(cancellation);
                                    dispatchCancellationSignal(cancellation);
                                } else {
                                } else {
                                    cancellationSink.set(cancellation);
                                    cancellationSink.set(cancellation);
                                    callback.onProviderCancellable(cancellation);
                                    if (mCallback != null) {
                                        mCallback.onProviderCancellable(cancellation);
                                    }
                                }
                                }
                            }
                            }
                        });
                        });
@@ -166,7 +199,7 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
        futureRef.set(connectThenExecute);
        futureRef.set(connectThenExecute);


        connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
        connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
                handleExecutionResponse(result, error, cancellationSink, callback)));
                handleExecutionResponse(result, error, cancellationSink)));
    }
    }


    /**
    /**
@@ -174,11 +207,14 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
     * provider service.
     * provider service.
     *
     *
     * @param request  the request to be sent to the provider
     * @param request  the request to be sent to the provider
     * @param callback the callback to be used to send back the provider response to the
     *                 {@link ProviderCreateSession} class that maintains provider state
     */
     */
    public void onBeginCreateCredential(@NonNull BeginCreateCredentialRequest request,
    public void onBeginCreateCredential(@NonNull BeginCreateCredentialRequest request) {
            ProviderCallbacks<BeginCreateCredentialResponse> callback) {
        if (mCallback == null) {
            Slog.w(TAG, "Callback is not set");
            return;
        }
        mOngoingRequest.set(true);

        AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
        AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
        AtomicReference<CompletableFuture<BeginCreateCredentialResponse>> futureRef =
        AtomicReference<CompletableFuture<BeginCreateCredentialResponse>> futureRef =
                new AtomicReference<>();
                new AtomicReference<>();
@@ -212,7 +248,9 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
                                            dispatchCancellationSignal(cancellation);
                                            dispatchCancellationSignal(cancellation);
                                        } else {
                                        } else {
                                            cancellationSink.set(cancellation);
                                            cancellationSink.set(cancellation);
                                            callback.onProviderCancellable(cancellation);
                                            if (mCallback != null) {
                                                mCallback.onProviderCancellable(cancellation);
                                            }
                                        }
                                        }
                                    }
                                    }
                                });
                                });
@@ -224,7 +262,7 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
        futureRef.set(connectThenExecute);
        futureRef.set(connectThenExecute);


        connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
        connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
                handleExecutionResponse(result, error, cancellationSink, callback)));
                handleExecutionResponse(result, error, cancellationSink)));
    }
    }


    /**
    /**
@@ -232,11 +270,14 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
     * provider service.
     * provider service.
     *
     *
     * @param request  the request to be sent to the provider
     * @param request  the request to be sent to the provider
     * @param callback the callback to be used to send back the provider response to the
     *                 {@link ProviderClearSession} class that maintains provider state
     */
     */
    public void onClearCredentialState(@NonNull ClearCredentialStateRequest request,
    public void onClearCredentialState(@NonNull ClearCredentialStateRequest request) {
            ProviderCallbacks<Void> callback) {
        if (mCallback == null) {
            Slog.w(TAG, "Callback is not set");
            return;
        }
        mOngoingRequest.set(true);

        AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
        AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
        AtomicReference<CompletableFuture<Void>> futureRef = new AtomicReference<>();
        AtomicReference<CompletableFuture<Void>> futureRef = new AtomicReference<>();


@@ -269,7 +310,9 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
                                            dispatchCancellationSignal(cancellation);
                                            dispatchCancellationSignal(cancellation);
                                        } else {
                                        } else {
                                            cancellationSink.set(cancellation);
                                            cancellationSink.set(cancellation);
                                            callback.onProviderCancellable(cancellation);
                                            if (mCallback != null) {
                                                mCallback.onProviderCancellable(cancellation);
                                            }
                                        }
                                        }
                                    }
                                    }
                                });
                                });
@@ -281,43 +324,61 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
        futureRef.set(connectThenExecute);
        futureRef.set(connectThenExecute);


        connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
        connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
                handleExecutionResponse(result, error, cancellationSink, callback)));
                handleExecutionResponse(result, error, cancellationSink)));
    }
    }


    private <T> void handleExecutionResponse(T result,
    private <T> void handleExecutionResponse(T result,
            Throwable error,
            Throwable error,
            AtomicReference<ICancellationSignal> cancellationSink,
            AtomicReference<ICancellationSignal> cancellationSink) {
            ProviderCallbacks<T> callback) {
        if (error == null) {
        if (error == null) {
            callback.onProviderResponseSuccess(result);
            if (mCallback != null) {
                mCallback.onProviderResponseSuccess(result);
            }
        } else {
        } else {
            if (error instanceof TimeoutException) {
            if (error instanceof TimeoutException) {
                Slog.i(TAG, "Remote provider response timed tuo for: " + mComponentName);
                Slog.i(TAG, "Remote provider response timed tuo for: " + mComponentName);
                if (!mOngoingRequest.get()) {
                    return;
                }
                dispatchCancellationSignal(cancellationSink.get());
                dispatchCancellationSignal(cancellationSink.get());
                callback.onProviderResponseFailure(
                if (mCallback != null) {
                        CredentialProviderErrors.ERROR_TIMEOUT,
                    mOngoingRequest.set(false);
                        null);
                    mCallback.onProviderResponseFailure(
                            CredentialProviderErrors.ERROR_TIMEOUT, null);
                }
            } else if (error instanceof CancellationException) {
            } else if (error instanceof CancellationException) {
                Slog.i(TAG, "Cancellation exception for remote provider: " + mComponentName);
                Slog.i(TAG, "Cancellation exception for remote provider: " + mComponentName);
                if (!mOngoingRequest.get()) {
                    return;
                }
                dispatchCancellationSignal(cancellationSink.get());
                dispatchCancellationSignal(cancellationSink.get());
                callback.onProviderResponseFailure(
                if (mCallback != null) {
                    mOngoingRequest.set(false);
                    mCallback.onProviderResponseFailure(
                            CredentialProviderErrors.ERROR_TASK_CANCELED,
                            CredentialProviderErrors.ERROR_TASK_CANCELED,
                            null);
                            null);
                }
            } else if (error instanceof GetCredentialException) {
            } else if (error instanceof GetCredentialException) {
                callback.onProviderResponseFailure(
                if (mCallback != null) {
                    mCallback.onProviderResponseFailure(
                            CredentialProviderErrors.ERROR_PROVIDER_FAILURE,
                            CredentialProviderErrors.ERROR_PROVIDER_FAILURE,
                            (GetCredentialException) error);
                            (GetCredentialException) error);
                }
            } else if (error instanceof CreateCredentialException) {
            } else if (error instanceof CreateCredentialException) {
                callback.onProviderResponseFailure(
                if (mCallback != null) {
                    mCallback.onProviderResponseFailure(
                            CredentialProviderErrors.ERROR_PROVIDER_FAILURE,
                            CredentialProviderErrors.ERROR_PROVIDER_FAILURE,
                            (CreateCredentialException) error);
                            (CreateCredentialException) error);
                }
            } else {
            } else {
                callback.onProviderResponseFailure(
                if (mCallback != null) {
                    mCallback.onProviderResponseFailure(
                            CredentialProviderErrors.ERROR_UNKNOWN,
                            CredentialProviderErrors.ERROR_UNKNOWN,
                            (Exception) error);
                            (Exception) error);
                }
                }
            }
            }
        }
        }
    }


    private void dispatchCancellationSignal(@Nullable ICancellationSignal signal) {
    private void dispatchCancellationSignal(@Nullable ICancellationSignal signal) {
        if (signal == null) {
        if (signal == null) {