blob: e6ae0abef9181401719e15330409338dc8db8342 [file] [log] [blame]
Sean Pontd00aefb2020-01-07 12:05:09 -08001/*
2 * Copyright 2020 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
17package android.service.quickaccesswallet;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.app.PendingIntent;
22import android.graphics.drawable.Icon;
23import android.os.Parcel;
24import android.os.Parcelable;
25import android.text.TextUtils;
26
27/**
28 * A {@link WalletCard} can represent anything that a user might carry in their wallet -- a credit
29 * card, library card, transit pass, etc. Cards are identified by a String identifier and contain a
30 * card image, card image content description, and a {@link PendingIntent} to be used if the user
31 * clicks on the card. Cards may be displayed with an icon and label, though these are optional.
32 */
33public final class WalletCard implements Parcelable {
34
35 private final String mCardId;
36 private final Icon mCardImage;
37 private final CharSequence mContentDescription;
38 private final PendingIntent mPendingIntent;
39 private final Icon mCardIcon;
40 private final CharSequence mCardLabel;
41
42 private WalletCard(Builder builder) {
43 this.mCardId = builder.mCardId;
44 this.mCardImage = builder.mCardImage;
45 this.mContentDescription = builder.mContentDescription;
46 this.mPendingIntent = builder.mPendingIntent;
47 this.mCardIcon = builder.mCardIcon;
48 this.mCardLabel = builder.mCardLabel;
49 }
50
51 @Override
52 public int describeContents() {
53 return 0;
54 }
55
56 @Override
57 public void writeToParcel(@NonNull Parcel dest, int flags) {
58 dest.writeString(mCardId);
59 mCardImage.writeToParcel(dest, flags);
60 TextUtils.writeToParcel(mContentDescription, dest, flags);
61 PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, dest);
62 if (mCardIcon == null) {
63 dest.writeByte((byte) 0);
64 } else {
65 dest.writeByte((byte) 1);
66 mCardIcon.writeToParcel(dest, flags);
67 }
68 TextUtils.writeToParcel(mCardLabel, dest, flags);
69 }
70
71 private static WalletCard readFromParcel(Parcel source) {
72 String cardId = source.readString();
73 Icon cardImage = Icon.CREATOR.createFromParcel(source);
74 CharSequence contentDesc = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
75 PendingIntent pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(source);
76 Icon cardIcon = source.readByte() == 0 ? null : Icon.CREATOR.createFromParcel(source);
77 CharSequence cardLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
78 return new Builder(cardId, cardImage, contentDesc, pendingIntent)
79 .setCardIcon(cardIcon)
80 .setCardLabel(cardLabel)
81 .build();
82 }
83
84 @NonNull
85 public static final Creator<WalletCard> CREATOR =
86 new Creator<WalletCard>() {
87 @Override
88 public WalletCard createFromParcel(Parcel source) {
89 return readFromParcel(source);
90 }
91
92 @Override
93 public WalletCard[] newArray(int size) {
94 return new WalletCard[size];
95 }
96 };
97
98 /**
99 * The card id must be unique within the list of cards returned.
100 */
101 @NonNull
102 public String getCardId() {
103 return mCardId;
104 }
105
106 /**
107 * The visual representation of the card. If the card image Icon is a bitmap, it should have a
108 * width of {@link GetWalletCardsRequest#getCardWidthPx()} and a height of {@link
109 * GetWalletCardsRequest#getCardHeightPx()}.
110 */
111 @NonNull
112 public Icon getCardImage() {
113 return mCardImage;
114 }
115
116 /**
117 * The content description of the card image.
118 */
119 @NonNull
120 public CharSequence getContentDescription() {
121 return mContentDescription;
122 }
123
124 /**
125 * If the user performs a click on the card, this PendingIntent will be sent. If the device is
126 * locked, the wallet will first request device unlock before sending the pending intent.
127 */
128 @NonNull
129 public PendingIntent getPendingIntent() {
130 return mPendingIntent;
131 }
132
133 /**
134 * An icon may be shown alongside the card image to convey information about how the card can be
135 * used, or if some other action must be taken before using the card. For example, an NFC logo
136 * could indicate that the card is NFC-enabled and will be provided to an NFC terminal if the
137 * phone is held in close proximity to the NFC reader.
138 *
139 * <p>If the supplied Icon is backed by a bitmap, it should have width and height
140 * {@link GetWalletCardsRequest#getIconSizePx()}.
141 */
142 @Nullable
143 public Icon getCardIcon() {
144 return mCardIcon;
145 }
146
147 /**
148 * A card label may be shown alongside the card image to convey information about how the card
149 * can be used, or if some other action must be taken before using the card. For example, an
150 * NFC-enabled card could be labeled "Hold near reader" to inform the user of how to use NFC
151 * cards when interacting with an NFC reader.
152 *
153 * <p>If the provided label is too long to fit on one line, it may be truncated and ellipsized.
154 */
155 @Nullable
156 public CharSequence getCardLabel() {
157 return mCardLabel;
158 }
159
160 /**
161 * Builder for {@link WalletCard} objects. You must to provide cardId, cardImage,
162 * contentDescription, and pendingIntent. If the card is opaque and should be shown with
163 * elevation, set hasShadow to true. cardIcon and cardLabel are optional.
164 */
165 public static final class Builder {
166 private String mCardId;
167 private Icon mCardImage;
168 private CharSequence mContentDescription;
169 private PendingIntent mPendingIntent;
170 private Icon mCardIcon;
171 private CharSequence mCardLabel;
172
173 /**
174 * @param cardId The card id must be non-null and unique within the list of
175 * cards returned. <b>Note:
176 * </b> this card ID should <b>not</b> contain PII (Personally
Sean Pont72fc25f2020-02-11 19:02:44 -0800177 * Identifiable Information, such as username or email address).
Sean Pontd00aefb2020-01-07 12:05:09 -0800178 * @param cardImage The visual representation of the card. If the card image Icon
179 * is a bitmap, it should have a width of {@link
180 * GetWalletCardsRequest#getCardWidthPx()} and a height of {@link
181 * GetWalletCardsRequest#getCardHeightPx()}. If the card image
182 * does not have these dimensions, it may appear distorted when it
Sean Pont72fc25f2020-02-11 19:02:44 -0800183 * is scaled to fit these dimensions on screen. Bitmaps should be
184 * of type {@link android.graphics.Bitmap.Config#HARDWARE} for
185 * performance reasons.
Sean Pontd00aefb2020-01-07 12:05:09 -0800186 * @param contentDescription The content description of the card image. This field is
Sean Pont72fc25f2020-02-11 19:02:44 -0800187 * required and may not be null or empty.
Sean Pontd00aefb2020-01-07 12:05:09 -0800188 * <b>Note: </b> this message should <b>not</b> contain PII
189 * (Personally Identifiable Information, such as username or email
190 * address).
191 * @param pendingIntent If the user performs a click on the card, this PendingIntent
192 * will be sent. If the device is locked, the wallet will first
Sean Pont72fc25f2020-02-11 19:02:44 -0800193 * request device unlock before sending the pending intent. It is
194 * recommended that the pending intent be immutable (use {@link
195 * PendingIntent#FLAG_IMMUTABLE}).
Sean Pontd00aefb2020-01-07 12:05:09 -0800196 */
197 public Builder(@NonNull String cardId,
198 @NonNull Icon cardImage,
199 @NonNull CharSequence contentDescription,
200 @NonNull PendingIntent pendingIntent) {
201 mCardId = cardId;
202 mCardImage = cardImage;
203 mContentDescription = contentDescription;
204 mPendingIntent = pendingIntent;
205 }
206
207 /**
208 * An icon may be shown alongside the card image to convey information about how the card
209 * can be used, or if some other action must be taken before using the card. For example, an
210 * NFC logo could indicate that the card is NFC-enabled and will be provided to an NFC
211 * terminal if the phone is held in close proximity to the NFC reader. This field is
212 * optional.
213 *
214 * <p>If the supplied Icon is backed by a bitmap, it should have width and height
215 * {@link GetWalletCardsRequest#getIconSizePx()}.
216 */
217 @NonNull
218 public Builder setCardIcon(@Nullable Icon cardIcon) {
219 mCardIcon = cardIcon;
220 return this;
221 }
222
223 /**
224 * A card label may be shown alongside the card image to convey information about how the
225 * card can be used, or if some other action must be taken before using the card. For
226 * example, an NFC-enabled card could be labeled "Hold near reader" to inform the user of
227 * how to use NFC cards when interacting with an NFC reader. This field is optional.
228 * <b>Note: </b> this card label should <b>not</b> contain PII (Personally Identifiable
229 * Information, such as username or email address). If the provided label is too long to fit
230 * on one line, it may be truncated and ellipsized.
231 */
232 @NonNull
233 public Builder setCardLabel(@Nullable CharSequence cardLabel) {
234 mCardLabel = cardLabel;
235 return this;
236 }
237
238 /**
239 * Builds a new {@link WalletCard} instance.
240 *
241 * @return A built response.
242 */
243 @NonNull
244 public WalletCard build() {
245 return new WalletCard(this);
246 }
247 }
248}