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.credentials.ui;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.StringDef;
22 import android.annotation.TestApi;
23 import android.credentials.CreateCredentialRequest;
24 import android.credentials.GetCredentialRequest;
25 import android.os.IBinder;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 
29 import com.android.internal.util.AnnotationValidations;
30 
31 import java.lang.annotation.Retention;
32 import java.lang.annotation.RetentionPolicy;
33 import java.util.ArrayList;
34 import java.util.List;
35 
36 /**
37  * Contains information about the request that initiated this UX flow.
38  *
39  * @hide
40  */
41 @TestApi
42 public final class RequestInfo implements Parcelable {
43 
44     /**
45      * The intent extra key for the {@code RequestInfo} object when launching the UX
46      * activities.
47      */
48     @NonNull public static final String EXTRA_REQUEST_INFO =
49             "android.credentials.ui.extra.REQUEST_INFO";
50 
51     /** Type value for any request that does not require UI. */
52     @NonNull public static final String TYPE_UNDEFINED = "android.credentials.ui.TYPE_UNDEFINED";
53     /** Type value for a getCredential request. */
54     @NonNull public static final String TYPE_GET = "android.credentials.ui.TYPE_GET";
55     /** Type value for a getCredential request that utilizes the credential registry.
56      *
57      * @hide
58      **/
59     @NonNull public static final String TYPE_GET_VIA_REGISTRY =
60             "android.credentials.ui.TYPE_GET_VIA_REGISTRY";
61     /** Type value for a createCredential request. */
62     @NonNull public static final String TYPE_CREATE = "android.credentials.ui.TYPE_CREATE";
63 
64     /** @hide */
65     @Retention(RetentionPolicy.SOURCE)
66     @StringDef(value = { TYPE_GET, TYPE_CREATE })
67     public @interface RequestType {}
68 
69     @NonNull
70     private final IBinder mToken;
71 
72     @Nullable
73     private final CreateCredentialRequest mCreateCredentialRequest;
74 
75     @NonNull
76     private final List<String> mDefaultProviderIds;
77 
78     @Nullable
79     private final GetCredentialRequest mGetCredentialRequest;
80 
81     @NonNull
82     @RequestType
83     private final String mType;
84 
85     @NonNull
86     private final String mAppPackageName;
87 
88     private final boolean mHasPermissionToOverrideDefault;
89 
90     /** Creates new {@code RequestInfo} for a create-credential flow. */
91     @NonNull
newCreateRequestInfo( @onNull IBinder token, @NonNull CreateCredentialRequest createCredentialRequest, @NonNull String appPackageName)92     public static RequestInfo newCreateRequestInfo(
93             @NonNull IBinder token, @NonNull CreateCredentialRequest createCredentialRequest,
94             @NonNull String appPackageName) {
95         return new RequestInfo(
96                 token, TYPE_CREATE, appPackageName, createCredentialRequest, null,
97                 /*hasPermissionToOverrideDefault=*/ false,
98                 /*defaultProviderIds=*/ new ArrayList<>());
99     }
100 
101     /**
102      * Creates new {@code RequestInfo} for a create-credential flow.
103      *
104      * @hide
105      */
106     @NonNull
newCreateRequestInfo( @onNull IBinder token, @NonNull CreateCredentialRequest createCredentialRequest, @NonNull String appPackageName, boolean hasPermissionToOverrideDefault, @NonNull List<String> defaultProviderIds)107     public static RequestInfo newCreateRequestInfo(
108             @NonNull IBinder token, @NonNull CreateCredentialRequest createCredentialRequest,
109             @NonNull String appPackageName, boolean hasPermissionToOverrideDefault,
110             @NonNull List<String> defaultProviderIds) {
111         return new RequestInfo(
112                 token, TYPE_CREATE, appPackageName, createCredentialRequest, null,
113                 hasPermissionToOverrideDefault, defaultProviderIds);
114     }
115 
116     /**
117      * Creates new {@code RequestInfo} for a get-credential flow.
118      *
119      * @hide
120      */
121     @NonNull
newGetRequestInfo( @onNull IBinder token, @NonNull GetCredentialRequest getCredentialRequest, @NonNull String appPackageName, boolean hasPermissionToOverrideDefault)122     public static RequestInfo newGetRequestInfo(
123             @NonNull IBinder token, @NonNull GetCredentialRequest getCredentialRequest,
124             @NonNull String appPackageName, boolean hasPermissionToOverrideDefault) {
125         return new RequestInfo(
126                 token, TYPE_GET, appPackageName, null, getCredentialRequest,
127                 hasPermissionToOverrideDefault,
128                 /*defaultProviderIds=*/ new ArrayList<>());
129     }
130 
131     /** Creates new {@code RequestInfo} for a get-credential flow. */
132     @NonNull
newGetRequestInfo( @onNull IBinder token, @NonNull GetCredentialRequest getCredentialRequest, @NonNull String appPackageName)133     public static RequestInfo newGetRequestInfo(
134             @NonNull IBinder token, @NonNull GetCredentialRequest getCredentialRequest,
135             @NonNull String appPackageName) {
136         return new RequestInfo(
137                 token, TYPE_GET, appPackageName, null, getCredentialRequest,
138                 /*hasPermissionToOverrideDefault=*/ false,
139                 /*defaultProviderIds=*/ new ArrayList<>());
140     }
141 
142 
143     /**
144      * Returns whether the calling package has the permission
145      *
146      * @hide
147      */
hasPermissionToOverrideDefault()148     public boolean hasPermissionToOverrideDefault() {
149         return mHasPermissionToOverrideDefault;
150     }
151 
152     /** Returns the request token matching the user request. */
153     @NonNull
getToken()154     public IBinder getToken() {
155         return mToken;
156     }
157 
158     /** Returns the request type. */
159     @NonNull
160     @RequestType
getType()161     public String getType() {
162         return mType;
163     }
164 
165     /** Returns the display name of the app that made this request. */
166     @NonNull
getAppPackageName()167     public String getAppPackageName() {
168         return mAppPackageName;
169     }
170 
171     /**
172      * Returns the non-null CreateCredentialRequest when the type of the request is {@link
173      * #TYPE_CREATE}, or null otherwise.
174      */
175     @Nullable
getCreateCredentialRequest()176     public CreateCredentialRequest getCreateCredentialRequest() {
177         return mCreateCredentialRequest;
178     }
179 
180     /**
181      * Returns default provider identifier (flattened component name) configured from the user
182      * settings.
183      *
184      * Will only be possibly non-empty for the create use case. Not meaningful for the sign-in use
185      * case.
186      *
187      * @hide
188      */
189     @NonNull
getDefaultProviderIds()190     public List<String> getDefaultProviderIds() {
191         return mDefaultProviderIds;
192     }
193 
194     /**
195      * Returns the non-null GetCredentialRequest when the type of the request is {@link
196      * #TYPE_GET}, or null otherwise.
197      */
198     @Nullable
getGetCredentialRequest()199     public GetCredentialRequest getGetCredentialRequest() {
200         return mGetCredentialRequest;
201     }
202 
RequestInfo(@onNull IBinder token, @NonNull @RequestType String type, @NonNull String appPackageName, @Nullable CreateCredentialRequest createCredentialRequest, @Nullable GetCredentialRequest getCredentialRequest, boolean hasPermissionToOverrideDefault, @NonNull List<String> defaultProviderIds)203     private RequestInfo(@NonNull IBinder token, @NonNull @RequestType String type,
204             @NonNull String appPackageName,
205             @Nullable CreateCredentialRequest createCredentialRequest,
206             @Nullable GetCredentialRequest getCredentialRequest,
207             boolean hasPermissionToOverrideDefault,
208             @NonNull List<String> defaultProviderIds) {
209         mToken = token;
210         mType = type;
211         mAppPackageName = appPackageName;
212         mCreateCredentialRequest = createCredentialRequest;
213         mGetCredentialRequest = getCredentialRequest;
214         mHasPermissionToOverrideDefault = hasPermissionToOverrideDefault;
215         mDefaultProviderIds = defaultProviderIds == null ? new ArrayList<>() : defaultProviderIds;
216     }
217 
RequestInfo(@onNull Parcel in)218     private RequestInfo(@NonNull Parcel in) {
219         IBinder token = in.readStrongBinder();
220         String type = in.readString8();
221         String appPackageName = in.readString8();
222         CreateCredentialRequest createCredentialRequest =
223                 in.readTypedObject(CreateCredentialRequest.CREATOR);
224         GetCredentialRequest getCredentialRequest =
225                 in.readTypedObject(GetCredentialRequest.CREATOR);
226 
227         mToken = token;
228         AnnotationValidations.validate(NonNull.class, null, mToken);
229         mType = type;
230         AnnotationValidations.validate(NonNull.class, null, mType);
231         mAppPackageName = appPackageName;
232         AnnotationValidations.validate(NonNull.class, null, mAppPackageName);
233         mCreateCredentialRequest = createCredentialRequest;
234         mGetCredentialRequest = getCredentialRequest;
235         mHasPermissionToOverrideDefault = in.readBoolean();
236         mDefaultProviderIds = in.createStringArrayList();
237     }
238 
239     @Override
writeToParcel(@onNull Parcel dest, int flags)240     public void writeToParcel(@NonNull Parcel dest, int flags) {
241         dest.writeStrongBinder(mToken);
242         dest.writeString8(mType);
243         dest.writeString8(mAppPackageName);
244         dest.writeTypedObject(mCreateCredentialRequest, flags);
245         dest.writeTypedObject(mGetCredentialRequest, flags);
246         dest.writeBoolean(mHasPermissionToOverrideDefault);
247         dest.writeStringList(mDefaultProviderIds);
248     }
249 
250     @Override
describeContents()251     public int describeContents() {
252         return 0;
253     }
254 
255     @NonNull public static final Creator<RequestInfo> CREATOR = new Creator<>() {
256         @Override
257         public RequestInfo createFromParcel(@NonNull Parcel in) {
258             return new RequestInfo(in);
259         }
260 
261         @Override
262         public RequestInfo[] newArray(int size) {
263             return new RequestInfo[size];
264         }
265     };
266 }
267