1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.service.credentials;
18 
19 import android.annotation.NonNull;
20 import android.os.Bundle;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 import com.android.internal.util.AnnotationValidations;
25 import com.android.internal.util.Preconditions;
26 
27 /**
28  * A specific type of credential request to be sent to the provider during the query phase of
29  * a get flow. This request contains limited parameters needed to populate a list of
30  * {@link CredentialEntry} on the {@link BeginGetCredentialResponse}.
31  */
32 public final class BeginGetCredentialOption implements Parcelable {
33     private static final String BUNDLE_ID_KEY =
34             "android.service.credentials.BeginGetCredentialOption.BUNDLE_ID_KEY";
35     /**
36      * A unique id associated with this request option.
37      */
38     @NonNull
39     private final String mId;
40 
41     /**
42      * The requested credential type.
43      */
44     @NonNull
45     private final String mType;
46 
47     /**
48      * The request candidateQueryData.
49      */
50     @NonNull
51     private final Bundle mCandidateQueryData;
52 
53     /**
54      * Returns the unique id associated with this request. This is for internal use only.
55      */
56     @NonNull
getId()57     public String getId() {
58         return mId;
59     }
60 
61     /**
62      * Returns the requested credential type.
63      */
64     @NonNull
getType()65     public String getType() {
66         return mType;
67     }
68 
69     /**
70      * Returns the request candidate query data, denoting a set of parameters
71      * that can be used to populate a candidate list of credentials, as
72      * {@link CredentialEntry} on {@link BeginGetCredentialResponse}. This list
73      * of entries is then presented to the user on a selector.
74      *
75      * <p>This data does not contain any sensitive parameters, and will be sent
76      * to all eligible providers.
77      * The complete set of parameters will only be set on the {@link android.app.PendingIntent}
78      * set on the {@link CredentialEntry} that is selected by the user.
79      */
80     @NonNull
getCandidateQueryData()81     public Bundle getCandidateQueryData() {
82         return mCandidateQueryData;
83     }
84 
85     @Override
writeToParcel(@onNull Parcel dest, int flags)86     public void writeToParcel(@NonNull Parcel dest, int flags) {
87         dest.writeString8(mType);
88         dest.writeBundle(mCandidateQueryData);
89         dest.writeString8(mId);
90     }
91 
92     @Override
describeContents()93     public int describeContents() {
94         return 0;
95     }
96 
97     @Override
toString()98     public String toString() {
99         return "GetCredentialOption {"
100                 + "type=" + mType
101                 + ", candidateQueryData=" + mCandidateQueryData
102                 + ", id=" + mId
103                 + "}";
104     }
105 
106     /**
107      * Constructs a {@link BeginGetCredentialOption}.
108      *
109      * @param id the unique id associated with this option
110      * @param type               the requested credential type
111      * @param candidateQueryData the request candidateQueryData
112      * @throws IllegalArgumentException If id or type is empty.
113      */
BeginGetCredentialOption( @onNull String id, @NonNull String type, @NonNull Bundle candidateQueryData)114     public BeginGetCredentialOption(
115             @NonNull String id, @NonNull String type,
116             @NonNull Bundle candidateQueryData) {
117         mId = Preconditions.checkStringNotEmpty(id, "id must not be empty");
118         mType = Preconditions.checkStringNotEmpty(type, "type must not be empty");
119         Bundle bundle = new Bundle();
120         bundle.putAll(candidateQueryData);
121         mCandidateQueryData = bundle;
122         addIdToBundle();
123     }
124 
addIdToBundle()125     private void addIdToBundle() {
126         mCandidateQueryData.putString(BUNDLE_ID_KEY, mId);
127     }
128 
BeginGetCredentialOption(@onNull Parcel in)129     private BeginGetCredentialOption(@NonNull Parcel in) {
130         String type = in.readString8();
131         Bundle candidateQueryData = in.readBundle();
132         String id = in.readString8();
133 
134         mType = type;
135         AnnotationValidations.validate(NonNull.class, null, mType);
136         mCandidateQueryData = candidateQueryData;
137         AnnotationValidations.validate(NonNull.class, null, mCandidateQueryData);
138         mId = id;
139     }
140 
141     public static final @NonNull Creator<BeginGetCredentialOption> CREATOR =
142             new Creator<BeginGetCredentialOption>() {
143                 @Override
144                 public BeginGetCredentialOption[] newArray(int size) {
145                     return new BeginGetCredentialOption[size];
146                 }
147 
148                 @Override
149                 public BeginGetCredentialOption createFromParcel(@NonNull Parcel in) {
150                     return new BeginGetCredentialOption(in);
151                 }
152             };
153 }
154