Merge "Guard setting of remote entry with a permission" into udc-dev
This commit is contained in:
@@ -40549,7 +40549,7 @@ package android.service.credentials {
|
||||
method @NonNull public android.service.credentials.BeginCreateCredentialResponse.Builder addCreateEntry(@NonNull android.service.credentials.CreateEntry);
|
||||
method @NonNull public android.service.credentials.BeginCreateCredentialResponse build();
|
||||
method @NonNull public android.service.credentials.BeginCreateCredentialResponse.Builder setCreateEntries(@NonNull java.util.List<android.service.credentials.CreateEntry>);
|
||||
method @NonNull public android.service.credentials.BeginCreateCredentialResponse.Builder setRemoteCreateEntry(@Nullable android.service.credentials.RemoteEntry);
|
||||
method @NonNull @RequiresPermission("android.permission.PROVIDE_REMOTE_CREDENTIALS") public android.service.credentials.BeginCreateCredentialResponse.Builder setRemoteCreateEntry(@Nullable android.service.credentials.RemoteEntry);
|
||||
}
|
||||
|
||||
public class BeginGetCredentialOption implements android.os.Parcelable {
|
||||
@@ -40598,7 +40598,7 @@ package android.service.credentials {
|
||||
method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder setActions(@NonNull java.util.List<android.service.credentials.Action>);
|
||||
method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder setAuthenticationActions(@NonNull java.util.List<android.service.credentials.Action>);
|
||||
method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder setCredentialEntries(@NonNull java.util.List<android.service.credentials.CredentialEntry>);
|
||||
method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder setRemoteCredentialEntry(@Nullable android.service.credentials.RemoteEntry);
|
||||
method @NonNull @RequiresPermission("android.permission.PROVIDE_REMOTE_CREDENTIALS") public android.service.credentials.BeginGetCredentialResponse.Builder setRemoteCredentialEntry(@Nullable android.service.credentials.RemoteEntry);
|
||||
}
|
||||
|
||||
public final class CallingAppInfo implements android.os.Parcelable {
|
||||
|
||||
@@ -254,7 +254,7 @@ package android {
|
||||
field public static final String PERFORM_SIM_ACTIVATION = "android.permission.PERFORM_SIM_ACTIVATION";
|
||||
field public static final String POWER_SAVER = "android.permission.POWER_SAVER";
|
||||
field public static final String PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE = "android.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE";
|
||||
field public static final String PROVIDE_HYBRID_CREDENTIAL_SERVICE = "android.permission.PROVIDE_HYBRID_CREDENTIAL_SERVICE";
|
||||
field public static final String PROVIDE_REMOTE_CREDENTIALS = "android.permission.PROVIDE_REMOTE_CREDENTIALS";
|
||||
field public static final String PROVIDE_RESOLVER_RANKER_SERVICE = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
|
||||
field public static final String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
|
||||
field public static final String PROVISION_DEMO_DEVICE = "android.permission.PROVISION_DEMO_DEVICE";
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
@@ -137,7 +139,17 @@ public final class BeginCreateCredentialResponse implements Parcelable {
|
||||
* result should be set to {@link android.app.Activity#RESULT_OK} and an extra with the
|
||||
* {@link CredentialProviderService#EXTRA_CREATE_CREDENTIAL_RESPONSE} key should be populated
|
||||
* with a {@link android.credentials.CreateCredentialResponse} object.
|
||||
*
|
||||
* <p> Note that as a provider service you will only be able to set a remote entry if :
|
||||
* - Provider service possesses the
|
||||
* {@link Manifest.permission.PROVIDE_REMOTE_CREDENTIALS} permission.
|
||||
* - Provider service is configured as the provider that can provide remote entries.
|
||||
*
|
||||
* If the above conditions are not met, setting back {@link BeginCreateCredentialResponse}
|
||||
* on the callback from {@link CredentialProviderService#onBeginCreateCredential}
|
||||
* will throw a {@link SecurityException}.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.PROVIDE_REMOTE_CREDENTIALS)
|
||||
public @NonNull Builder setRemoteCreateEntry(@Nullable RemoteEntry remoteCreateEntry) {
|
||||
mRemoteCreateEntry = remoteCreateEntry;
|
||||
return this;
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
@@ -154,7 +156,17 @@ public final class BeginGetCredentialResponse implements Parcelable {
|
||||
* result should be set to {@link android.app.Activity#RESULT_OK} and an extra with the
|
||||
* {@link CredentialProviderService#EXTRA_GET_CREDENTIAL_RESPONSE} key should be populated
|
||||
* with a {@link android.credentials.Credential} object.
|
||||
*
|
||||
* <p> Note that as a provider service you will only be able to set a remote entry if :
|
||||
* - Provider service possesses the
|
||||
* {@link Manifest.permission.PROVIDE_REMOTE_CREDENTIALS} permission.
|
||||
* - Provider service is configured as the provider that can provide remote entries.
|
||||
*
|
||||
* If the above conditions are not met, setting back {@link BeginGetCredentialResponse}
|
||||
* on the callback from {@link CredentialProviderService#onBeginGetCredential} will
|
||||
* throw a {@link SecurityException}.
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.PROVIDE_REMOTE_CREDENTIALS)
|
||||
public @NonNull Builder setRemoteCredentialEntry(@Nullable RemoteEntry
|
||||
remoteCredentialEntry) {
|
||||
mRemoteCredentialEntry = remoteCredentialEntry;
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.service.credentials;
|
||||
|
||||
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.CallSuper;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SdkConstant;
|
||||
@@ -218,6 +219,11 @@ public abstract class CredentialProviderService extends Service {
|
||||
GetCredentialException>() {
|
||||
@Override
|
||||
public void onResult(BeginGetCredentialResponse result) {
|
||||
// If provider service does not possess the HYBRID permission, this
|
||||
// check will throw an exception in the provider process.
|
||||
if (result.getRemoteCredentialEntry() != null) {
|
||||
enforceRemoteEntryPermission();
|
||||
}
|
||||
try {
|
||||
callback.onSuccess(result);
|
||||
} catch (RemoteException e) {
|
||||
@@ -236,6 +242,15 @@ public abstract class CredentialProviderService extends Service {
|
||||
));
|
||||
return transport;
|
||||
}
|
||||
private void enforceRemoteEntryPermission() {
|
||||
String permission =
|
||||
Manifest.permission.PROVIDE_REMOTE_CREDENTIALS;
|
||||
getApplicationContext().enforceCallingOrSelfPermission(
|
||||
permission,
|
||||
String.format("Provider must have %s, in order to set a "
|
||||
+ "remote entry", permission)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICancellationSignal onBeginCreateCredential(BeginCreateCredentialRequest request,
|
||||
@@ -253,6 +268,11 @@ public abstract class CredentialProviderService extends Service {
|
||||
BeginCreateCredentialResponse, CreateCredentialException>() {
|
||||
@Override
|
||||
public void onResult(BeginCreateCredentialResponse result) {
|
||||
// If provider service does not possess the HYBRID permission, this
|
||||
// check will throw an exception in the provider process.
|
||||
if (result.getRemoteCreateEntry() != null) {
|
||||
enforceRemoteEntryPermission();
|
||||
}
|
||||
try {
|
||||
callback.onSuccess(result);
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -4482,8 +4482,8 @@
|
||||
<!-- Allows an application to be able to store and retrieve credentials from a remote
|
||||
device.
|
||||
@hide @SystemApi -->
|
||||
<permission android:name="android.permission.PROVIDE_HYBRID_CREDENTIAL_SERVICE"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
<permission android:name="android.permission.PROVIDE_REMOTE_CREDENTIALS"
|
||||
android:protectionLevel="signature|privileged|role" />
|
||||
|
||||
<!-- ========================================= -->
|
||||
<!-- Permissions for special development tools -->
|
||||
|
||||
@@ -137,7 +137,8 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
remoteCredentialService);
|
||||
mCompleteRequest = completeCreateRequest;
|
||||
setStatus(Status.PENDING);
|
||||
mProviderResponseDataHandler = new ProviderResponseDataHandler(hybridService);
|
||||
mProviderResponseDataHandler = new ProviderResponseDataHandler(
|
||||
ComponentName.unflattenFromString(hybridService));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -297,21 +298,23 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
}
|
||||
|
||||
private class ProviderResponseDataHandler {
|
||||
private final ComponentName mExpectedRemoteEntryProviderService;
|
||||
@Nullable private final ComponentName mExpectedRemoteEntryProviderService;
|
||||
|
||||
@NonNull
|
||||
private final Map<String, Pair<CreateEntry, Entry>> mUiCreateEntries = new HashMap<>();
|
||||
|
||||
@Nullable private Pair<String, Pair<RemoteEntry, Entry>> mUiRemoteEntry = null;
|
||||
|
||||
ProviderResponseDataHandler(String hybridService) {
|
||||
mExpectedRemoteEntryProviderService = ComponentName.unflattenFromString(hybridService);
|
||||
ProviderResponseDataHandler(@Nullable ComponentName expectedRemoteEntryProviderService) {
|
||||
mExpectedRemoteEntryProviderService = expectedRemoteEntryProviderService;
|
||||
}
|
||||
|
||||
public void addResponseContent(List<CreateEntry> createEntries,
|
||||
RemoteEntry remoteEntry) {
|
||||
createEntries.forEach(this::addCreateEntry);
|
||||
setRemoteEntry(remoteEntry);
|
||||
if (remoteEntry != null) {
|
||||
setRemoteEntry(remoteEntry);
|
||||
}
|
||||
}
|
||||
public void addCreateEntry(CreateEntry createEntry) {
|
||||
String id = generateUniqueId();
|
||||
@@ -321,13 +324,13 @@ public final class ProviderCreateSession extends ProviderSession<
|
||||
}
|
||||
|
||||
public void setRemoteEntry(@Nullable RemoteEntry remoteEntry) {
|
||||
if (remoteEntry == null) {
|
||||
mUiRemoteEntry = null;
|
||||
if (!enforceRemoteEntryRestrictions(mExpectedRemoteEntryProviderService)) {
|
||||
Log.i(TAG, "Remote entry being dropped as it does not meet the restriction"
|
||||
+ "checks.");
|
||||
return;
|
||||
}
|
||||
if (!mComponentName.equals(mExpectedRemoteEntryProviderService)) {
|
||||
Log.i(TAG, "Remote entry being dropped as it is not from the service "
|
||||
+ "configured by the OEM.");
|
||||
if (remoteEntry == null) {
|
||||
mUiRemoteEntry = null;
|
||||
return;
|
||||
}
|
||||
String id = generateUniqueId();
|
||||
|
||||
@@ -181,7 +181,6 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
/** Called when the provider response has been updated by an external source. */
|
||||
@Override // Callback from the remote provider
|
||||
public void onProviderResponseSuccess(@Nullable BeginGetCredentialResponse response) {
|
||||
Log.i(TAG, "in onProviderResponseSuccess");
|
||||
onSetInitialRemoteResponse(response);
|
||||
}
|
||||
|
||||
@@ -393,7 +392,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
.extractResponseContent(providerPendingIntentResponse
|
||||
.getResultData());
|
||||
if (response != null && !mProviderResponseDataHandler.isEmptyResponse(response)) {
|
||||
addToInitialRemoteResponse(response);
|
||||
addToInitialRemoteResponse(response, /*isInitialResponse=*/ false);
|
||||
// Additional content received is in the form of new response content.
|
||||
return true;
|
||||
}
|
||||
@@ -401,7 +400,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addToInitialRemoteResponse(BeginGetCredentialResponse content) {
|
||||
private void addToInitialRemoteResponse(BeginGetCredentialResponse content,
|
||||
boolean isInitialResponse) {
|
||||
if (content == null) {
|
||||
return;
|
||||
}
|
||||
@@ -409,7 +409,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
content.getCredentialEntries(),
|
||||
content.getActions(),
|
||||
content.getAuthenticationActions(),
|
||||
content.getRemoteCredentialEntry()
|
||||
content.getRemoteCredentialEntry(),
|
||||
isInitialResponse
|
||||
);
|
||||
}
|
||||
|
||||
@@ -424,7 +425,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
/** Updates the response being maintained in state by this provider session. */
|
||||
private void onSetInitialRemoteResponse(BeginGetCredentialResponse response) {
|
||||
mProviderResponse = response;
|
||||
addToInitialRemoteResponse(response);
|
||||
addToInitialRemoteResponse(response, /*isInitialResponse=*/true);
|
||||
if (mProviderResponseDataHandler.isEmptyResponse(response)) {
|
||||
updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE);
|
||||
return;
|
||||
@@ -463,7 +464,7 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
}
|
||||
|
||||
private class ProviderResponseDataHandler {
|
||||
private final ComponentName mExpectedRemoteEntryProviderService;
|
||||
@Nullable private final ComponentName mExpectedRemoteEntryProviderService;
|
||||
@NonNull
|
||||
private final Map<String, Pair<CredentialEntry, Entry>> mUiCredentialEntries =
|
||||
new HashMap<>();
|
||||
@@ -475,19 +476,27 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
|
||||
@Nullable private Pair<String, Pair<RemoteEntry, Entry>> mUiRemoteEntry = null;
|
||||
|
||||
ProviderResponseDataHandler(ComponentName expectedRemoteEntryProviderService) {
|
||||
ProviderResponseDataHandler(@Nullable ComponentName expectedRemoteEntryProviderService) {
|
||||
mExpectedRemoteEntryProviderService = expectedRemoteEntryProviderService;
|
||||
}
|
||||
|
||||
public void addResponseContent(List<CredentialEntry> credentialEntries,
|
||||
List<Action> actions, List<Action> authenticationActions,
|
||||
RemoteEntry remoteEntry) {
|
||||
RemoteEntry remoteEntry, boolean isInitialResponse) {
|
||||
credentialEntries.forEach(this::addCredentialEntry);
|
||||
actions.forEach(this::addAction);
|
||||
authenticationActions.forEach(
|
||||
authenticationAction -> addAuthenticationAction(authenticationAction,
|
||||
AuthenticationEntry.STATUS_LOCKED));
|
||||
setRemoteEntry(remoteEntry);
|
||||
// In the query phase, it is likely most providers will return a null remote entry
|
||||
// so no need to invoke the setter since it adds the overhead of checking for the
|
||||
// hybrid permission, and then sets an already null value to null.
|
||||
// If this is not the query phase, e.g. response after a locked entry is unlocked
|
||||
// then it is valid for the provider to remove the remote entry, and so we allow
|
||||
// them to set it to null.
|
||||
if (remoteEntry != null || !isInitialResponse) {
|
||||
setRemoteEntry(remoteEntry);
|
||||
}
|
||||
}
|
||||
public void addCredentialEntry(CredentialEntry credentialEntry) {
|
||||
String id = generateUniqueId();
|
||||
@@ -524,12 +533,13 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
}
|
||||
|
||||
public void setRemoteEntry(@Nullable RemoteEntry remoteEntry) {
|
||||
if (remoteEntry == null) {
|
||||
if (!enforceRemoteEntryRestrictions(mExpectedRemoteEntryProviderService)) {
|
||||
Log.i(TAG, "Remote entry being dropped as it does not meet the restriction"
|
||||
+ " checks.");
|
||||
return;
|
||||
}
|
||||
if (!mComponentName.equals(mExpectedRemoteEntryProviderService)) {
|
||||
Log.i(TAG, "Remote entry being dropped as it is not from the service "
|
||||
+ "configured by the OEM.");
|
||||
if (remoteEntry == null) {
|
||||
mUiRemoteEntry = null;
|
||||
return;
|
||||
}
|
||||
String id = generateUniqueId();
|
||||
@@ -538,6 +548,8 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
mUiRemoteEntry = new Pair<>(generateUniqueId(), new Pair<>(remoteEntry, entry));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public GetCredentialProviderData toGetCredentialProviderData() {
|
||||
return new GetCredentialProviderData.Builder(
|
||||
mComponentName.flattenToString()).setActionChips(prepareActionEntries())
|
||||
@@ -571,7 +583,6 @@ public final class ProviderGetSession extends ProviderSession<BeginGetCredential
|
||||
return credEntries;
|
||||
}
|
||||
|
||||
|
||||
private Entry prepareRemoteEntry() {
|
||||
if (mUiRemoteEntry == null || mUiRemoteEntry.first == null
|
||||
|| mUiRemoteEntry.second == null) {
|
||||
|
||||
@@ -19,10 +19,13 @@ package com.android.server.credentials;
|
||||
import static com.android.server.credentials.MetricUtilities.METRICS_PROVIDER_STATUS_QUERY_FAILURE;
|
||||
import static com.android.server.credentials.MetricUtilities.METRICS_PROVIDER_STATUS_QUERY_SUCCESS;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.credentials.Credential;
|
||||
import android.credentials.ui.ProviderData;
|
||||
import android.credentials.ui.ProviderPendingIntentResponse;
|
||||
@@ -228,6 +231,39 @@ public abstract class ProviderSession<T, R>
|
||||
return mProviderResponse;
|
||||
}
|
||||
|
||||
protected boolean enforceRemoteEntryRestrictions(
|
||||
@Nullable ComponentName expectedRemoteEntryProviderService) {
|
||||
// Check if the service is the one set by the OEM. If not silently reject this entry
|
||||
if (!mComponentName.equals(expectedRemoteEntryProviderService)) {
|
||||
Log.i(TAG, "Remote entry being dropped as it is not from the service "
|
||||
+ "configured by the OEM.");
|
||||
return false;
|
||||
}
|
||||
// Check if the service has the hybrid permission .If not, silently reject this entry.
|
||||
// This check is in addition to the permission check happening in the provider's process.
|
||||
try {
|
||||
ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
|
||||
mComponentName.getPackageName(),
|
||||
PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY));
|
||||
if (appInfo != null
|
||||
&& mContext.checkPermission(
|
||||
Manifest.permission.PROVIDE_REMOTE_CREDENTIALS,
|
||||
/*pId=*/-1, appInfo.uid) == PackageManager.PERMISSION_GRANTED) {
|
||||
return true;
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
Log.i(TAG, "Error getting info for "
|
||||
+ mComponentName.flattenToString() + ": " + e.getMessage());
|
||||
return false;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.i(TAG, "Error getting info for "
|
||||
+ mComponentName.flattenToString() + ": " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
Log.i(TAG, "In enforceRemoteEntryRestrictions - remote entry checks fail");
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Should be overridden to prepare, and stores state for {@link ProviderData} to be
|
||||
* shown on the UI. */
|
||||
@Nullable protected abstract ProviderData prepareUiData();
|
||||
|
||||
@@ -121,8 +121,6 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
|
||||
ProviderCallbacks<BeginGetCredentialResponse> callback) {
|
||||
Log.i(TAG, "In onGetCredentials in RemoteCredentialService");
|
||||
AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
|
||||
AtomicReference<CompletableFuture<BeginGetCredentialResponse>> futureRef =
|
||||
new AtomicReference<>();
|
||||
|
||||
CompletableFuture<BeginGetCredentialResponse> connectThenExecute = postAsync(service -> {
|
||||
CompletableFuture<BeginGetCredentialResponse> getCredentials =
|
||||
@@ -134,7 +132,6 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
|
||||
new IBeginGetCredentialCallback.Stub() {
|
||||
@Override
|
||||
public void onSuccess(BeginGetCredentialResponse response) {
|
||||
Log.i(TAG, "In onSuccess in RemoteCredentialService");
|
||||
getCredentials.complete(response);
|
||||
}
|
||||
|
||||
@@ -147,22 +144,15 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
|
||||
new GetCredentialException(errorType, errorMsg));
|
||||
}
|
||||
});
|
||||
CompletableFuture<BeginGetCredentialResponse> future = futureRef.get();
|
||||
if (future != null && future.isCancelled()) {
|
||||
dispatchCancellationSignal(cancellationSignal);
|
||||
} else {
|
||||
cancellationSink.set(cancellationSignal);
|
||||
}
|
||||
cancellationSink.set(cancellationSignal);
|
||||
return getCredentials;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(originalCallingUidToken);
|
||||
}
|
||||
}).orTimeout(TIMEOUT_REQUEST_MILLIS, TimeUnit.MILLISECONDS);
|
||||
|
||||
futureRef.set(connectThenExecute);
|
||||
connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
|
||||
handleExecutionResponse(result, error, cancellationSink, callback)));
|
||||
|
||||
return cancellationSink.get();
|
||||
}
|
||||
|
||||
@@ -178,8 +168,6 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
|
||||
ProviderCallbacks<BeginCreateCredentialResponse> callback) {
|
||||
Log.i(TAG, "In onCreateCredential in RemoteCredentialService");
|
||||
AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
|
||||
AtomicReference<CompletableFuture<BeginCreateCredentialResponse>> futureRef =
|
||||
new AtomicReference<>();
|
||||
|
||||
CompletableFuture<BeginCreateCredentialResponse> connectThenExecute =
|
||||
postAsync(service -> {
|
||||
@@ -205,19 +193,13 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
|
||||
new CreateCredentialException(errorType, errorMsg));
|
||||
}
|
||||
});
|
||||
CompletableFuture<BeginCreateCredentialResponse> future = futureRef.get();
|
||||
if (future != null && future.isCancelled()) {
|
||||
dispatchCancellationSignal(cancellationSignal);
|
||||
} else {
|
||||
cancellationSink.set(cancellationSignal);
|
||||
}
|
||||
cancellationSink.set(cancellationSignal);
|
||||
return createCredentialFuture;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(originalCallingUidToken);
|
||||
}
|
||||
}).orTimeout(TIMEOUT_REQUEST_MILLIS, TimeUnit.MILLISECONDS);
|
||||
|
||||
futureRef.set(connectThenExecute);
|
||||
connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
|
||||
handleExecutionResponse(result, error, cancellationSink, callback)));
|
||||
|
||||
@@ -236,7 +218,6 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
|
||||
ProviderCallbacks<Void> callback) {
|
||||
Log.i(TAG, "In onClearCredentialState in RemoteCredentialService");
|
||||
AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
|
||||
AtomicReference<CompletableFuture<Void>> futureRef = new AtomicReference<>();
|
||||
|
||||
CompletableFuture<Void> connectThenExecute =
|
||||
postAsync(service -> {
|
||||
@@ -263,19 +244,13 @@ public class RemoteCredentialService extends ServiceConnector.Impl<ICredentialPr
|
||||
errorMsg));
|
||||
}
|
||||
});
|
||||
CompletableFuture<Void> future = futureRef.get();
|
||||
if (future != null && future.isCancelled()) {
|
||||
dispatchCancellationSignal(cancellationSignal);
|
||||
} else {
|
||||
cancellationSink.set(cancellationSignal);
|
||||
}
|
||||
cancellationSink.set(cancellationSignal);
|
||||
return clearCredentialFuture;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(originalCallingUidToken);
|
||||
}
|
||||
}).orTimeout(TIMEOUT_REQUEST_MILLIS, TimeUnit.MILLISECONDS);
|
||||
|
||||
futureRef.set(connectThenExecute);
|
||||
connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
|
||||
handleExecutionResponse(result, error, cancellationSink, callback)));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user