Merge "Add OutcomeReceiver to provider APIs and share classes with developer APIs Test: Built locally CTS-Coverage-Bug:247549381"
This commit is contained in:
@@ -16,13 +16,12 @@
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.slice.Slice;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -32,29 +31,26 @@ import java.util.Objects;
|
||||
* @hide
|
||||
*/
|
||||
public final class Action implements Parcelable {
|
||||
/** Info to be displayed with this action on the UI. */
|
||||
private final @NonNull Slice mInfo;
|
||||
/**
|
||||
* The pending intent to be invoked when the user selects this action.
|
||||
*/
|
||||
/** Slice object containing display content to be displayed with this action on the UI. */
|
||||
private final @NonNull Slice mSlice;
|
||||
/** The pending intent to be invoked when the user selects this action. */
|
||||
private final @NonNull PendingIntent mPendingIntent;
|
||||
|
||||
/**
|
||||
* Constructs an action to be displayed on the UI.
|
||||
*
|
||||
* @param actionInfo The info to be displayed along with this action.
|
||||
* @param pendingIntent The intent to be invoked when the user selects this action.
|
||||
* @throws NullPointerException If {@code actionInfo}, or {@code pendingIntent} is null.
|
||||
* @param slice the display content to be displayed on the UI, along with this action
|
||||
* @param pendingIntent the intent to be invoked when the user selects this action
|
||||
*/
|
||||
public Action(@NonNull Slice actionInfo, @NonNull PendingIntent pendingIntent) {
|
||||
Objects.requireNonNull(actionInfo, "actionInfo must not be null");
|
||||
public Action(@NonNull Slice slice, @NonNull PendingIntent pendingIntent) {
|
||||
Objects.requireNonNull(slice, "slice must not be null");
|
||||
Objects.requireNonNull(pendingIntent, "pendingIntent must not be null");
|
||||
mInfo = actionInfo;
|
||||
mSlice = slice;
|
||||
mPendingIntent = pendingIntent;
|
||||
}
|
||||
|
||||
private Action(@NonNull Parcel in) {
|
||||
mInfo = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
|
||||
mSlice = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
|
||||
mPendingIntent = in.readParcelable(PendingIntent.class.getClassLoader(),
|
||||
PendingIntent.class);
|
||||
}
|
||||
@@ -78,15 +74,15 @@ public final class Action implements Parcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
mInfo.writeToParcel(dest, flags);
|
||||
mSlice.writeToParcel(dest, flags);
|
||||
mPendingIntent.writeToParcel(dest, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the action info as a {@link Slice} object, to be displayed on the UI.
|
||||
* Returns a {@code Slice} object containing the display content to be displayed on the UI.
|
||||
*/
|
||||
public @NonNull Slice getActionInfo() {
|
||||
return mInfo;
|
||||
public @NonNull Slice getSlice() {
|
||||
return mSlice;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Callback to be invoked as a response to {@link CreateCredentialRequest}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class CreateCredentialCallback {
|
||||
private static final String TAG = "CreateCredentialCallback";
|
||||
|
||||
private final ICreateCredentialCallback mCallback;
|
||||
|
||||
/** @hide */
|
||||
public CreateCredentialCallback(@NonNull ICreateCredentialCallback callback) {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked on a successful response for {@link CreateCredentialRequest}
|
||||
* @param response The response from the credential provider.
|
||||
*/
|
||||
public void onSuccess(@NonNull CreateCredentialResponse response) {
|
||||
try {
|
||||
mCallback.onSuccess(response);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked on a failure response for {@link CreateCredentialRequest}
|
||||
* @param errorCode The code defining the type of error.
|
||||
* @param message The message corresponding to the failure.
|
||||
*/
|
||||
public void onFailure(int errorCode, @Nullable CharSequence message) {
|
||||
Log.w(TAG, "onFailure: " + message);
|
||||
try {
|
||||
mCallback.onFailure(errorCode, message);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
/**
|
||||
* A Credential object that contains type specific data that is returned from the credential
|
||||
* provider to the framework. Framework then converts it to an app facing representation and
|
||||
* returns to the calling app.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class Credential implements Parcelable {
|
||||
/** The type of this credential. */
|
||||
private final @NonNull String mType;
|
||||
|
||||
/** The data associated with this credential. */
|
||||
private final @NonNull Bundle mData;
|
||||
|
||||
/**
|
||||
* Constructs a credential object.
|
||||
*
|
||||
* @param type The type of the credential.
|
||||
* @param data The data of the credential that is passed back to the framework, and eventually
|
||||
* to the calling app.
|
||||
* @throws NullPointerException If {@code data} is null.
|
||||
* @throws IllegalArgumentException If {@code type} is null or empty.
|
||||
*/
|
||||
public Credential(@NonNull String type, @NonNull Bundle data) {
|
||||
Preconditions.checkStringNotEmpty(type, "type must not be null, or empty");
|
||||
requireNonNull(data, "data must not be null");
|
||||
this.mType = type;
|
||||
this.mData = data;
|
||||
}
|
||||
|
||||
private Credential(@NonNull Parcel in) {
|
||||
mType = in.readString16NoHelper();
|
||||
mData = in.readBundle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the credential.
|
||||
*/
|
||||
public @NonNull String getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data associated with the credential.
|
||||
*/
|
||||
public @NonNull Bundle getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<Credential> CREATOR = new Creator<Credential>() {
|
||||
@Override
|
||||
public Credential createFromParcel(@NonNull Parcel in) {
|
||||
return new Credential(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Credential[] newArray(int size) {
|
||||
return new Credential[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeString8(mType);
|
||||
dest.writeBundle(mData);
|
||||
}
|
||||
}
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.slice.Slice;
|
||||
import android.credentials.Credential;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -38,8 +38,9 @@ public final class CredentialEntry implements Parcelable {
|
||||
/** The type of the credential entry to be shown on the UI. */
|
||||
private final @NonNull String mType;
|
||||
|
||||
/** The info to be displayed along with this credential entry on the UI. */
|
||||
private final @NonNull Slice mInfo;
|
||||
/** The object containing display content to be shown along with this credential entry
|
||||
* on the UI. */
|
||||
private final @NonNull Slice mSlice;
|
||||
|
||||
/** The pending intent to be invoked when this credential entry is selected. */
|
||||
private final @Nullable PendingIntent mPendingIntent;
|
||||
@@ -53,11 +54,11 @@ public final class CredentialEntry implements Parcelable {
|
||||
/** A flag denoting whether auto-select is enabled for this entry. */
|
||||
private final @NonNull boolean mAutoSelectAllowed;
|
||||
|
||||
private CredentialEntry(@NonNull String type, @NonNull Slice entryInfo,
|
||||
private CredentialEntry(@NonNull String type, @NonNull Slice slice,
|
||||
@Nullable PendingIntent pendingIntent, @Nullable Credential credential,
|
||||
@NonNull boolean autoSeletAllowed) {
|
||||
mType = type;
|
||||
mInfo = entryInfo;
|
||||
mSlice = slice;
|
||||
mPendingIntent = pendingIntent;
|
||||
mCredential = credential;
|
||||
mAutoSelectAllowed = autoSeletAllowed;
|
||||
@@ -65,7 +66,7 @@ public final class CredentialEntry implements Parcelable {
|
||||
|
||||
private CredentialEntry(@NonNull Parcel in) {
|
||||
mType = in.readString();
|
||||
mInfo = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
|
||||
mSlice = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
|
||||
mPendingIntent = in.readParcelable(PendingIntent.class.getClassLoader(),
|
||||
PendingIntent.class);
|
||||
mCredential = in.readParcelable(Credential.class.getClassLoader(),
|
||||
@@ -94,7 +95,7 @@ public final class CredentialEntry implements Parcelable {
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeString8(mType);
|
||||
mInfo.writeToParcel(dest, flags);
|
||||
mSlice.writeToParcel(dest, flags);
|
||||
mPendingIntent.writeToParcel(dest, flags);
|
||||
mCredential.writeToParcel(dest, flags);
|
||||
dest.writeBoolean(mAutoSelectAllowed);
|
||||
@@ -108,10 +109,10 @@ public final class CredentialEntry implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UI info to be displayed for this entry.
|
||||
* Returns the {@link Slice} object containing UI display content to be shown for this entry.
|
||||
*/
|
||||
public @NonNull Slice getInfo() {
|
||||
return mInfo;
|
||||
public @NonNull Slice getSlice() {
|
||||
return mSlice;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,7 +132,7 @@ public final class CredentialEntry implements Parcelable {
|
||||
/**
|
||||
* Returns whether this entry can be auto selected if it is the only option for the user.
|
||||
*/
|
||||
public @NonNull boolean isAutoSelectAllowed() {
|
||||
public boolean isAutoSelectAllowed() {
|
||||
return mAutoSelectAllowed;
|
||||
}
|
||||
|
||||
@@ -140,28 +141,35 @@ public final class CredentialEntry implements Parcelable {
|
||||
*/
|
||||
public static final class Builder {
|
||||
private String mType;
|
||||
private Slice mInfo;
|
||||
private Slice mSlice;
|
||||
private PendingIntent mPendingIntent;
|
||||
private Credential mCredential;
|
||||
private boolean mAutoSelectAllowed = false;
|
||||
|
||||
/**
|
||||
* Builds the instance.
|
||||
* @param type The type of credential underlying this credential entry.
|
||||
* @param info The info to be displayed with this entry on the UI.
|
||||
* @param type the type of credential underlying this credential entry
|
||||
* @param slice the content to be displayed with this entry on the UI
|
||||
*
|
||||
* @throws IllegalArgumentException If {@code type} is null or empty.
|
||||
* @throws NullPointerException If {@code info} is null.
|
||||
* @throws NullPointerException If {@code slice} is null.
|
||||
*/
|
||||
public Builder(@NonNull String type, @NonNull Slice info) {
|
||||
public Builder(@NonNull String type, @NonNull Slice slice) {
|
||||
mType = Preconditions.checkStringNotEmpty(type, "type must not be "
|
||||
+ "null, or empty");
|
||||
mInfo = Objects.requireNonNull(info, "info must not be null");
|
||||
mSlice = Objects.requireNonNull(slice,
|
||||
"slice must not be null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pendingIntent to be invoked if the user selects this entry.
|
||||
*
|
||||
* The pending intent can be used to launch activities that require some user engagement
|
||||
* before getting the credential corresponding to this entry, e.g. authentication,
|
||||
* confirmation etc.
|
||||
* Once the activity fulfills the required user engagement, a {@link Credential} object
|
||||
* must be returned as an extra on activity finish.
|
||||
*
|
||||
* @throws IllegalStateException If {@code credential} is already set. Must either set the
|
||||
* {@code credential}, or the {@code pendingIntent}.
|
||||
*/
|
||||
@@ -199,7 +207,7 @@ public final class CredentialEntry implements Parcelable {
|
||||
/**
|
||||
* Creates a new {@link CredentialEntry} instance.
|
||||
*
|
||||
* @throws NullPointerException If {@code info} is null.
|
||||
* @throws NullPointerException If {@code slice} is null.
|
||||
* @throws IllegalArgumentException If {@code type} is null, or empty.
|
||||
* @throws IllegalStateException If neither {@code pendingIntent} nor {@code credential}
|
||||
* is set, or if both are set.
|
||||
@@ -209,7 +217,7 @@ public final class CredentialEntry implements Parcelable {
|
||||
"Either pendingIntent or credential must be set");
|
||||
Preconditions.checkState(mPendingIntent != null && mCredential != null,
|
||||
"Cannot set both the pendingIntent and credential");
|
||||
return new CredentialEntry(mType, mInfo, mPendingIntent,
|
||||
return new CredentialEntry(mType, mSlice, mPendingIntent,
|
||||
mCredential, mAutoSelectAllowed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Contains custom exceptions to be used by credential providers on failure.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class CredentialProviderException extends Exception {
|
||||
public static final int ERROR_UNKNOWN = 0;
|
||||
|
||||
private final int mErrorCode;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@IntDef(prefix = {"ERROR_"}, value = {
|
||||
ERROR_UNKNOWN,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface CredentialProviderError { }
|
||||
|
||||
|
||||
public CredentialProviderException(@CredentialProviderError int errorCode,
|
||||
@NonNull String message) {
|
||||
super(message);
|
||||
mErrorCode = errorCode;
|
||||
}
|
||||
|
||||
public CredentialProviderException(@CredentialProviderError int errorCode,
|
||||
@NonNull Throwable cause) {
|
||||
super(cause);
|
||||
mErrorCode = errorCode;
|
||||
}
|
||||
|
||||
public CredentialProviderException(@CredentialProviderError int errorCode) {
|
||||
super();
|
||||
mErrorCode = errorCode;
|
||||
}
|
||||
|
||||
public @CredentialProviderError int getErrorCode() {
|
||||
return mErrorCode;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa
|
||||
|
||||
import android.annotation.CallSuper;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SdkConstant;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.CancellationSignal;
|
||||
@@ -27,13 +28,14 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.ICancellationSignal;
|
||||
import android.os.Looper;
|
||||
import android.os.OutcomeReceiver;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Main service to be extended by credential providers, in order to return user credentials
|
||||
* Service to be extended by credential providers, in order to return user credentials
|
||||
* to the framework.
|
||||
*
|
||||
* @hide
|
||||
@@ -42,6 +44,12 @@ public abstract class CredentialProviderService extends Service {
|
||||
private static final String TAG = "CredProviderService";
|
||||
private Handler mHandler;
|
||||
|
||||
/**
|
||||
* The {@link Intent} that must be declared as handled by the service. The service must also
|
||||
* require the {android.Manifest.permission#BIND_CREDENTIAL_PROVIDER_SERVICE} permission
|
||||
* so that only the system can bind to it.
|
||||
*/
|
||||
@SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
|
||||
public static final String SERVICE_INTERFACE =
|
||||
"android.service.credentials.CredentialProviderService";
|
||||
|
||||
@@ -64,7 +72,7 @@ public abstract class CredentialProviderService extends Service {
|
||||
private final ICredentialProviderService mInterface = new ICredentialProviderService.Stub() {
|
||||
@Override
|
||||
public void onGetCredentials(GetCredentialsRequest request, ICancellationSignal transport,
|
||||
IGetCredentialsCallback callback) throws RemoteException {
|
||||
IGetCredentialsCallback callback) {
|
||||
Objects.requireNonNull(request);
|
||||
Objects.requireNonNull(transport);
|
||||
Objects.requireNonNull(callback);
|
||||
@@ -73,14 +81,30 @@ public abstract class CredentialProviderService extends Service {
|
||||
CredentialProviderService::onGetCredentials,
|
||||
CredentialProviderService.this, request,
|
||||
CancellationSignal.fromTransport(transport),
|
||||
new GetCredentialsCallback(callback)
|
||||
new OutcomeReceiver<GetCredentialsResponse, CredentialProviderException>() {
|
||||
@Override
|
||||
public void onResult(GetCredentialsResponse result) {
|
||||
try {
|
||||
callback.onSuccess(result);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onError(CredentialProviderException e) {
|
||||
try {
|
||||
callback.onFailure(e.getErrorCode(), e.getMessage());
|
||||
} catch (RemoteException ex) {
|
||||
ex.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateCredential(CreateCredentialRequest request,
|
||||
ICancellationSignal transport, ICreateCredentialCallback callback)
|
||||
throws RemoteException {
|
||||
ICancellationSignal transport, ICreateCredentialCallback callback) {
|
||||
Objects.requireNonNull(request);
|
||||
Objects.requireNonNull(transport);
|
||||
Objects.requireNonNull(callback);
|
||||
@@ -89,7 +113,24 @@ public abstract class CredentialProviderService extends Service {
|
||||
CredentialProviderService::onCreateCredential,
|
||||
CredentialProviderService.this, request,
|
||||
CancellationSignal.fromTransport(transport),
|
||||
new CreateCredentialCallback(callback)
|
||||
new OutcomeReceiver<CreateCredentialResponse, CredentialProviderException>() {
|
||||
@Override
|
||||
public void onResult(CreateCredentialResponse result) {
|
||||
try {
|
||||
callback.onSuccess(result);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onError(CredentialProviderException e) {
|
||||
try {
|
||||
callback.onFailure(e.getErrorCode(), e.getMessage());
|
||||
} catch (RemoteException ex) {
|
||||
ex.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
};
|
||||
@@ -97,14 +138,14 @@ public abstract class CredentialProviderService extends Service {
|
||||
/**
|
||||
* Called by the android system to retrieve user credentials from the connected provider
|
||||
* service.
|
||||
* @param request The credential request for the provider to handle.
|
||||
* @param cancellationSignal Signal for providers to listen to any cancellation requests from
|
||||
* the android system.
|
||||
* @param callback Object used to relay the response of the credentials request.
|
||||
* @param request the credential request for the provider to handle
|
||||
* @param cancellationSignal signal for providers to listen to any cancellation requests from
|
||||
* the android system
|
||||
* @param callback object used to relay the response of the credentials request
|
||||
*/
|
||||
public abstract void onGetCredentials(@NonNull GetCredentialsRequest request,
|
||||
@NonNull CancellationSignal cancellationSignal,
|
||||
@NonNull GetCredentialsCallback callback);
|
||||
@NonNull OutcomeReceiver<GetCredentialsResponse, CredentialProviderException> callback);
|
||||
|
||||
/**
|
||||
* Called by the android system to create a credential.
|
||||
@@ -115,5 +156,6 @@ public abstract class CredentialProviderService extends Service {
|
||||
*/
|
||||
public abstract void onCreateCredential(@NonNull CreateCredentialRequest request,
|
||||
@NonNull CancellationSignal cancellationSignal,
|
||||
@NonNull CreateCredentialCallback callback);
|
||||
@NonNull OutcomeReceiver<CreateCredentialResponse,
|
||||
CredentialProviderException> callback);
|
||||
}
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* A type specific credential request, containing the associated data to be used for
|
||||
* retrieving credentials.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class GetCredentialOption implements Parcelable {
|
||||
/** The type of credential requested. */
|
||||
private final @NonNull String mType;
|
||||
|
||||
/** The data associated with the request. */
|
||||
private final @NonNull Bundle mData;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@link GetCredentialOption}
|
||||
*
|
||||
* @throws IllegalArgumentException If {@code type} string is null or empty.
|
||||
* @throws NullPointerException If {@code data} is null.
|
||||
*/
|
||||
public GetCredentialOption(@NonNull String type, @NonNull Bundle data) {
|
||||
Preconditions.checkStringNotEmpty(type, "type must not be null, or empty");
|
||||
requireNonNull(data, "data must not be null");
|
||||
mType = type;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data associated with this credential request option.
|
||||
*/
|
||||
public @NonNull Bundle getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type associated with this credential request option.
|
||||
*/
|
||||
public @NonNull String getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
private GetCredentialOption(@NonNull Parcel in) {
|
||||
mType = in.readString16NoHelper();
|
||||
mData = in.readBundle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeString16NoHelper(mType);
|
||||
dest.writeBundle(mData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<GetCredentialOption> CREATOR =
|
||||
new Creator<GetCredentialOption>() {
|
||||
@Override
|
||||
public GetCredentialOption createFromParcel(@NonNull Parcel in) {
|
||||
return new GetCredentialOption(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetCredentialOption[] newArray(int size) {
|
||||
return new GetCredentialOption[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Callback to be invoked as a response to {@link GetCredentialsRequest}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class GetCredentialsCallback {
|
||||
|
||||
private static final String TAG = "GetCredentialsCallback";
|
||||
|
||||
private final IGetCredentialsCallback mCallback;
|
||||
|
||||
/** @hide */
|
||||
public GetCredentialsCallback(@NonNull IGetCredentialsCallback callback) {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked on a successful response for {@link GetCredentialsRequest}
|
||||
* @param response The response from the credential provider.
|
||||
*/
|
||||
public void onSuccess(@NonNull GetCredentialsResponse response) {
|
||||
try {
|
||||
mCallback.onSuccess(response);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked on a failure response for {@link GetCredentialsRequest}
|
||||
* @param errorCode The code defining the kind of error.
|
||||
* @param message The message corresponding to the failure.
|
||||
*/
|
||||
public void onFailure(int errorCode, @Nullable CharSequence message) {
|
||||
Log.w(TAG, "onFailure: " + message);
|
||||
try {
|
||||
mCallback.onFailure(errorCode, message);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.credentials.GetCredentialOption;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -100,7 +100,7 @@ public final class GetCredentialsRequest implements Parcelable {
|
||||
|
||||
/**
|
||||
* Creates a new builder.
|
||||
* @param callingPackage The calling package of the app requesting credentials.
|
||||
* @param callingPackage the calling package of the app requesting credentials
|
||||
*
|
||||
* @throws IllegalArgumentException If {@code callingPackag}e is null or empty.
|
||||
*/
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -44,6 +43,11 @@ public final class GetCredentialsResponse implements Parcelable {
|
||||
* Creates a {@link GetCredentialsRequest} instance with an authentication action set.
|
||||
* Providers must use this method when no content can be shown before authentication.
|
||||
*
|
||||
* Once the authentication action activity is launched, and the user is authenticated, providers
|
||||
* should create another response with {@link CredentialsDisplayContent} using
|
||||
* {@code createWithDisplayContent}, and add that response to the result of the authentication
|
||||
* activity.
|
||||
*
|
||||
* @throws NullPointerException If {@code authenticationAction} is null.
|
||||
*/
|
||||
public static @NonNull GetCredentialsResponse createWithAuthentication(
|
||||
@@ -103,18 +107,11 @@ public final class GetCredentialsResponse implements Parcelable {
|
||||
dest.writeParcelable(mAuthenticationAction, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the response contains a top level authentication action.
|
||||
*/
|
||||
public @NonNull boolean isAuthenticationActionSet() {
|
||||
return mAuthenticationAction != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authentication action to be invoked before any other content
|
||||
* can be shown to the user.
|
||||
*/
|
||||
public @NonNull Action getAuthenticationAction() {
|
||||
public @Nullable Action getAuthenticationAction() {
|
||||
return mAuthenticationAction;
|
||||
}
|
||||
|
||||
@@ -122,7 +119,7 @@ public final class GetCredentialsResponse implements Parcelable {
|
||||
* Returns the credentialDisplayContent that does not require authentication, and
|
||||
* can be shown to the user on the account selector UI.
|
||||
*/
|
||||
public @NonNull CredentialsDisplayContent getCredentialsDisplayContent() {
|
||||
public @Nullable CredentialsDisplayContent getCredentialsDisplayContent() {
|
||||
return mCredentialsDisplayContent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package android.service.credentials;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.slice.Slice;
|
||||
import android.credentials.Credential;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -35,12 +35,12 @@ import java.util.Objects;
|
||||
* @hide
|
||||
*/
|
||||
public final class SaveEntry implements Parcelable {
|
||||
private final @NonNull Slice mInfo;
|
||||
private final @NonNull Slice mSlice;
|
||||
private final @Nullable PendingIntent mPendingIntent;
|
||||
private final @Nullable Credential mCredential;
|
||||
|
||||
private SaveEntry(@NonNull Parcel in) {
|
||||
mInfo = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
|
||||
mSlice = in.readParcelable(Slice.class.getClassLoader(), Slice.class);
|
||||
mPendingIntent = in.readParcelable(PendingIntent.class.getClassLoader(),
|
||||
PendingIntent.class);
|
||||
mCredential = in.readParcelable(Credential.class.getClassLoader(), Credential.class);
|
||||
@@ -65,25 +65,25 @@ public final class SaveEntry implements Parcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
mInfo.writeToParcel(dest, flags);
|
||||
mSlice.writeToParcel(dest, flags);
|
||||
mPendingIntent.writeToParcel(dest, flags);
|
||||
mCredential.writeToParcel(dest, flags);
|
||||
}
|
||||
|
||||
/* package-private */ SaveEntry(
|
||||
@NonNull Slice info,
|
||||
@NonNull Slice slice,
|
||||
@Nullable PendingIntent pendingIntent,
|
||||
@Nullable Credential credential) {
|
||||
this.mInfo = info;
|
||||
this.mSlice = slice;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mInfo);
|
||||
NonNull.class, null, mSlice);
|
||||
this.mPendingIntent = pendingIntent;
|
||||
this.mCredential = credential;
|
||||
}
|
||||
|
||||
/** Returns the info to be displayed with this save entry on the UI. */
|
||||
public @NonNull Slice getInfo() {
|
||||
return mInfo;
|
||||
/** Returns the content to be displayed with this save entry on the UI. */
|
||||
public @NonNull Slice getSlice() {
|
||||
return mSlice;
|
||||
}
|
||||
|
||||
/** Returns the pendingIntent to be invoked when this save entry on the UI is selectcd. */
|
||||
@@ -101,18 +101,18 @@ public final class SaveEntry implements Parcelable {
|
||||
*/
|
||||
public static final class Builder {
|
||||
|
||||
private @NonNull Slice mInfo;
|
||||
private @NonNull Slice mSlice;
|
||||
private @Nullable PendingIntent mPendingIntent;
|
||||
private @Nullable Credential mCredential;
|
||||
|
||||
/**
|
||||
* Builds the instance.
|
||||
* @param info The info to be displayed with this save entry.
|
||||
* @param slice the content to be displayed with this save entry
|
||||
*
|
||||
* @throws NullPointerException If {@code info} is null.
|
||||
* @throws NullPointerException If {@code slice} is null.
|
||||
*/
|
||||
public Builder(@NonNull Slice info) {
|
||||
mInfo = Objects.requireNonNull(info, "info must not be null");
|
||||
public Builder(@NonNull Slice slice) {
|
||||
mSlice = Objects.requireNonNull(slice, "slice must not be null");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,7 +154,7 @@ public final class SaveEntry implements Parcelable {
|
||||
"pendingIntent and credential both must not be null. Must set "
|
||||
+ "either the pendingIntnet or the credential");
|
||||
return new SaveEntry(
|
||||
mInfo,
|
||||
mSlice,
|
||||
mPendingIntent,
|
||||
mCredential);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user