script-astra/Android/Sdk/sources/android-35/android/credentials/CreateCredentialRequest.java

343 lines
13 KiB
Java
Raw Permalink Normal View History

2025-01-20 15:15:20 +00:00
/*
* Copyright 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.credentials;
import static android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN;
import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.AnnotationValidations;
import com.android.internal.util.Preconditions;
/**
* A request to register a specific type of user credential, potentially launching UI flows to
* collect user consent and any other operation needed.
*/
public final class CreateCredentialRequest implements Parcelable {
/**
* True/false value to determine if the calling app info should be
* sent to the provider at every stage.
*
* Developers must set this to false if they wish to remove the
* {@link android.service.credentials.CallingAppInfo} from the query phase request
* that providers receive. Note, that providers will still receive the app info in
* the final phase after the user has selected the entry.
*/
private final boolean mAlwaysSendAppInfoToProvider;
/**
* The requested credential type.
*/
@NonNull
private final String mType;
/**
* The full credential creation request data.
*/
@NonNull
private final Bundle mCredentialData;
/**
* The partial request data that will be sent to the provider during the initial creation
* candidate query stage.
*/
@NonNull
private final Bundle mCandidateQueryData;
/**
* Determines whether the request must only be fulfilled by a system provider.
*/
private final boolean mIsSystemProviderRequired;
/**
* The origin of the calling app. Callers of this special API (e.g. browsers)
* can set this origin for an app different from their own, to be able to get credentials
* on behalf of that app.
*/
@Nullable
private final String mOrigin;
/**
* Returns the requested credential type.
*/
@NonNull
public String getType() {
return mType;
}
/**
* Returns the full credential creation request data.
*
* For security reason, a provider will receive the request data in two stages. First it gets
* a partial request, {@link #getCandidateQueryData()} that do not contain sensitive user
* information; it uses this information to provide credential creation candidates that the
* [@code CredentialManager] will show to the user. Next, this full request data will be sent to
* a provider only if the user further grants the consent by choosing a candidate from the
* provider.
*/
@NonNull
public Bundle getCredentialData() {
return mCredentialData;
}
/**
* Returns the partial request data that will be sent to the provider during the initial
* creation candidate query stage.
*
* For security reason, a provider will receive the request data in two stages. First it gets
* this partial request that do not contain sensitive user information; it uses this information
* to provide credential creation candidates that the [@code CredentialManager] will show to
* the user. Next, the full request data, {@link #getCredentialData()}, will be sent to a
* provider only if the user further grants the consent by choosing a candidate from the
* provider.
*/
@NonNull
public Bundle getCandidateQueryData() {
return mCandidateQueryData;
}
/**
* Returns true if the request must only be fulfilled by a system provider, and false
* otherwise.
*/
public boolean isSystemProviderRequired() {
return mIsSystemProviderRequired;
}
/**
* Return true/false value to determine if the calling app info should always be sent
* to providers (if true), or removed from the query phase (if false).
*/
public boolean alwaysSendAppInfoToProvider() {
return mAlwaysSendAppInfoToProvider;
}
/**
* Returns the origin of the calling app if set otherwise returns null.
*/
@Nullable
public String getOrigin() {
return mOrigin;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString8(mType);
dest.writeBundle(mCredentialData);
dest.writeBundle(mCandidateQueryData);
dest.writeBoolean(mIsSystemProviderRequired);
dest.writeBoolean(mAlwaysSendAppInfoToProvider);
dest.writeString8(mOrigin);
}
@Override
public int describeContents() {
return 0;
}
@Override
public String toString() {
return "CreateCredentialRequest {"
+ "type=" + mType
+ ", credentialData=" + mCredentialData
+ ", candidateQueryData=" + mCandidateQueryData
+ ", isSystemProviderRequired=" + mIsSystemProviderRequired
+ ", alwaysSendAppInfoToProvider="
+ mAlwaysSendAppInfoToProvider
+ ", origin=" + mOrigin
+ "}";
}
/**
* Constructs a {@link CreateCredentialRequest}.
*
* @param type the requested credential type
* @param credentialData the full credential creation request data
* @param candidateQueryData the partial request data that will be sent to the provider
* during the initial creation candidate query stage
* @param isSystemProviderRequired whether the request must only be fulfilled by a system
* provider
* @param alwaysSendAppInfoToProvider whether the
* {@link android.service.credentials.CallingAppInfo} should be propagated to the provider
* at every stage of the request. If set to false,
* the calling app info will be removed from
* the query phase, and will only be sent along
* with the final request, after the user has selected
* an entry on the UI.
* @param origin the origin of the calling app. Callers of this special setter (e.g. browsers)
* can set this origin for an app different from their own, to be able to get
* credentials on behalf of that app.
*
* @throws IllegalArgumentException If type is empty.
*/
private CreateCredentialRequest(
@NonNull String type,
@NonNull Bundle credentialData,
@NonNull Bundle candidateQueryData,
boolean isSystemProviderRequired,
boolean alwaysSendAppInfoToProvider,
@NonNull String origin) {
mType = Preconditions.checkStringNotEmpty(type, "type must not be empty");
mCredentialData = requireNonNull(credentialData, "credentialData must not be null");
mCandidateQueryData = requireNonNull(candidateQueryData,
"candidateQueryData must not be null");
mIsSystemProviderRequired = isSystemProviderRequired;
mAlwaysSendAppInfoToProvider = alwaysSendAppInfoToProvider;
mOrigin = origin;
}
private CreateCredentialRequest(@NonNull Parcel in) {
String type = in.readString8();
Bundle credentialData = in.readBundle();
Bundle candidateQueryData = in.readBundle();
boolean isSystemProviderRequired = in.readBoolean();
boolean alwaysSendAppInfoToProvider = in.readBoolean();
mOrigin = in.readString8();
mType = type;
AnnotationValidations.validate(NonNull.class, null, mType);
mCredentialData = credentialData;
AnnotationValidations.validate(NonNull.class, null, mCredentialData);
mCandidateQueryData = candidateQueryData;
AnnotationValidations.validate(NonNull.class, null, mCandidateQueryData);
mIsSystemProviderRequired = isSystemProviderRequired;
mAlwaysSendAppInfoToProvider = alwaysSendAppInfoToProvider;
}
public static final @NonNull Parcelable.Creator<CreateCredentialRequest> CREATOR =
new Parcelable.Creator<CreateCredentialRequest>() {
@Override
public CreateCredentialRequest[] newArray(int size) {
return new CreateCredentialRequest[size];
}
@Override
public CreateCredentialRequest createFromParcel(@NonNull Parcel in) {
return new CreateCredentialRequest(in);
}
};
/** A builder for {@link CreateCredentialRequest}. */
public static final class Builder {
private boolean mAlwaysSendAppInfoToProvider = true;
@NonNull
private String mType;
@NonNull
private final Bundle mCredentialData;
@NonNull
private final Bundle mCandidateQueryData;
private boolean mIsSystemProviderRequired;
private String mOrigin;
/**
* @param type the type of the credential to be stored
* @param credentialData the full credential creation request data, which must at minimum
* contain the required fields observed at the
* {@link androidx.credentials.CreateCredentialRequest} Bundle conversion static methods,
* because they are required for properly displaying the system credential selector UI
* @param candidateQueryData the partial request data that will be sent to the provider
* during the initial creation candidate query stage
*/
public Builder(
@NonNull String type,
@NonNull Bundle credentialData,
@NonNull Bundle candidateQueryData) {
mType = Preconditions.checkStringNotEmpty(type,
"type must not be null or empty");
mCredentialData = requireNonNull(credentialData,
"credentialData must not be null");
mCandidateQueryData = requireNonNull(candidateQueryData,
"candidateQueryData must not be null");
}
/**
* Sets a true/false value to determine if the calling app info should be
* removed from the request that is sent to the providers.
*
* Developers must set this to false if they wish to remove the
* {@link android.service.credentials.CallingAppInfo} from the query phases requests that
* providers receive. Note that the calling app info will still be sent in the
* final phase after the user has made a selection on the UI.
*
* If not set, the default value will be true and the calling app info will be
* propagated to the providers in every phase.
*/
@SuppressLint("MissingGetterMatchingBuilder")
@NonNull
public CreateCredentialRequest.Builder setAlwaysSendAppInfoToProvider(boolean value) {
mAlwaysSendAppInfoToProvider = value;
return this;
}
/**
* Sets whether the request must only be fulfilled by a system provider.
* This defaults to false
*/
@SuppressLint("MissingGetterMatchingBuilder")
@NonNull
public CreateCredentialRequest.Builder setIsSystemProviderRequired(boolean value) {
mIsSystemProviderRequired = value;
return this;
}
/**
* Sets the origin of the calling app. Callers of this special setter (e.g. browsers)
* can set this origin for an app different from their own, to be able to get
* credentials on behalf of that app. The permission check only happens later when this
* instance is passed and processed by the Credential Manager.
*/
@SuppressLint({"MissingGetterMatchingBuilder", "AndroidFrameworkRequiresPermission"})
@RequiresPermission(CREDENTIAL_MANAGER_SET_ORIGIN)
@NonNull
public CreateCredentialRequest.Builder setOrigin(@NonNull String origin) {
mOrigin = origin;
return this;
}
/**
* Builds a {@link GetCredentialRequest}.
*
* @throws IllegalArgumentException If credentialOptions is empty.
*/
@NonNull
public CreateCredentialRequest build() {
Preconditions.checkStringNotEmpty(
mType,
"type must not be empty");
return new CreateCredentialRequest(mType, mCredentialData, mCandidateQueryData,
mIsSystemProviderRequired, mAlwaysSendAppInfoToProvider, mOrigin);
}
}
}