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

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23066012

Change-Id: I1fad1e9c8582e4694c073112da0461f8b9073179
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2023-05-08 19:02:01 +00:00
committed by Automerger Merge Worker
4 changed files with 103 additions and 39 deletions

View File

@@ -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);
} }
} }
} }

View File

@@ -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);
} }
} }

View File

@@ -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);
} }
} }

View File

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