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.selection;
18 
19 import static android.credentials.flags.Flags.FLAG_CONFIGURABLE_SELECTOR_UI_ENABLED;
20 
21 import android.annotation.FlaggedApi;
22 import android.annotation.NonNull;
23 import android.annotation.SystemApi;
24 import android.os.IBinder;
25 import android.os.Parcel;
26 import android.os.Parcelable;
27 
28 import com.android.internal.util.AnnotationValidations;
29 
30 /**
31  * A request to cancel the ongoing selection UI matching the identifier token in this request.
32  *
33  * Upon receiving this request, the UI should gracefully finish itself if the given request token
34  * {@link CancelSelectionRequest#getToken()} matches that of the selection UI is currently rendered
35  * for. Also, the UI should display some informational cancellation message (e.g. "Request is
36  * cancelled by the app") before closing when the
37  * {@link CancelSelectionRequest#shouldShowCancellationExplanation()} is true.
38  *
39  * @hide
40  */
41 @SystemApi
42 @FlaggedApi(FLAG_CONFIGURABLE_SELECTOR_UI_ENABLED)
43 public final class CancelSelectionRequest implements Parcelable {
44 
45     /**
46      * The intent extra key for the {@code CancelUiRequest} object when launching the UX
47      * activities.
48      *
49      * @hide
50      */
51     @NonNull
52     public static final String EXTRA_CANCEL_UI_REQUEST =
53             "android.credentials.selection.extra.CANCEL_UI_REQUEST";
54 
55     @NonNull
56     private final IBinder mToken;
57 
58     private final boolean mShouldShowCancellationExplanation;
59 
60     @NonNull
61     private final String mPackageName;
62 
63     /**
64      * Returns the request token matching the user request that should be cancelled.
65      *
66      * The request token for the current UI can be found from the UI launch intent, mapping to
67      * {@link RequestInfo#getToken()}.
68      *
69      * @hide
70      */
71     @NonNull
getToken()72     public IBinder getToken() {
73         return mToken;
74     }
75 
76     /** Returns the request token matching the app request that should be cancelled. */
77     @NonNull
getRequestToken()78     public RequestToken getRequestToken() {
79         return new RequestToken(mToken);
80     }
81 
82     /**
83      * Returns the app package name invoking this request, that can be used to derive display
84      * metadata (e.g. "Cancelled by `App Name`").
85      */
86     @NonNull
getPackageName()87     public String getPackageName() {
88         return mPackageName;
89     }
90 
91     /**
92      * Returns whether the UI should display some informational cancellation message (e.g.
93      * "Request is cancelled by the app") before closing. If false, the UI should be silently
94      * cancelled.
95      */
shouldShowCancellationExplanation()96     public boolean shouldShowCancellationExplanation() {
97         return mShouldShowCancellationExplanation;
98     }
99 
100 
101     /**
102      * Constructs a {@link CancelSelectionRequest}.
103      *
104      * @param requestToken request token matching the app request that should be cancelled
105      * @param shouldShowCancellationExplanation whether the UI should display some informational
106      *                                          cancellation message before closing
107      * @param packageName package that is invoking this request
108      *
109      */
CancelSelectionRequest(@onNull RequestToken requestToken, boolean shouldShowCancellationExplanation, @NonNull String packageName)110     public CancelSelectionRequest(@NonNull RequestToken requestToken,
111             boolean shouldShowCancellationExplanation, @NonNull String packageName) {
112         mToken = requestToken.getToken();
113         mShouldShowCancellationExplanation = shouldShowCancellationExplanation;
114         mPackageName = packageName;
115     }
116 
CancelSelectionRequest(@onNull Parcel in)117     private CancelSelectionRequest(@NonNull Parcel in) {
118         mToken = in.readStrongBinder();
119         AnnotationValidations.validate(NonNull.class, null, mToken);
120         mShouldShowCancellationExplanation = in.readBoolean();
121         mPackageName = in.readString8();
122         AnnotationValidations.validate(NonNull.class, null, mPackageName);
123     }
124 
125     @Override
writeToParcel(@onNull Parcel dest, int flags)126     public void writeToParcel(@NonNull Parcel dest, int flags) {
127         dest.writeStrongBinder(mToken);
128         dest.writeBoolean(mShouldShowCancellationExplanation);
129         dest.writeString8(mPackageName);
130     }
131 
132     @Override
describeContents()133     public int describeContents() {
134         return 0;
135     }
136 
137     @NonNull
138     public static final Creator<CancelSelectionRequest> CREATOR = new Creator<>() {
139         @Override
140         public CancelSelectionRequest createFromParcel(@NonNull Parcel in) {
141             return new CancelSelectionRequest(in);
142         }
143 
144         @Override
145         public CancelSelectionRequest[] newArray(int size) {
146             return new CancelSelectionRequest[size];
147         }
148     };
149 }
150