Adds fields to WalletCard to allow storage of valuables.

Bug: b/263156366
Test:  atest CtsQuickAccessWalletTestCases

Change-Id: I4bdc88fe721404c495c3807d3826d4c24c190c13
This commit is contained in:
Charles Wang
2023-01-04 18:55:15 +00:00
parent 968b7592c4
commit 3b9a50d134
2 changed files with 128 additions and 13 deletions

View File

@@ -40320,17 +40320,24 @@ package android.service.quickaccesswallet {
method @NonNull public String getCardId();
method @NonNull public android.graphics.drawable.Icon getCardImage();
method @Nullable public CharSequence getCardLabel();
method @NonNull public int getCardType();
method @NonNull public CharSequence getContentDescription();
method @NonNull public android.app.PendingIntent getPendingIntent();
method @Nullable public android.graphics.drawable.Icon getValuableCardSecondaryImage();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field public static final int CARD_TYPE_PAYMENT = 1; // 0x1
field public static final int CARD_TYPE_UNKNOWN = 0; // 0x0
field public static final int CARD_TYPE_VALUABLE = 2; // 0x2
field @NonNull public static final android.os.Parcelable.Creator<android.service.quickaccesswallet.WalletCard> CREATOR;
}
public static final class WalletCard.Builder {
ctor public WalletCard.Builder(@NonNull String, @NonNull int, @NonNull android.graphics.drawable.Icon, @NonNull CharSequence, @NonNull android.app.PendingIntent);
ctor public WalletCard.Builder(@NonNull String, @NonNull android.graphics.drawable.Icon, @NonNull CharSequence, @NonNull android.app.PendingIntent);
method @NonNull public android.service.quickaccesswallet.WalletCard build();
method @NonNull public android.service.quickaccesswallet.WalletCard.Builder setCardIcon(@Nullable android.graphics.drawable.Icon);
method @NonNull public android.service.quickaccesswallet.WalletCard.Builder setCardLabel(@Nullable CharSequence);
method @NonNull public android.service.quickaccesswallet.WalletCard.Builder setValuableCardSecondaryImage(@Nullable android.graphics.drawable.Icon);
}
public final class WalletServiceEvent implements android.os.Parcelable {

View File

@@ -16,6 +16,7 @@
package android.service.quickaccesswallet;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
@@ -24,28 +25,70 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* A {@link WalletCard} can represent anything that a user might carry in their wallet -- a credit
* card, library card, transit pass, etc. Cards are identified by a String identifier and contain a
* card image, card image content description, and a {@link PendingIntent} to be used if the user
* clicks on the card. Cards may be displayed with an icon and label, though these are optional.
* card type, card image, card image content description, and a {@link PendingIntent} to be used if
* the user clicks on the card. Cards may be displayed with an icon and label, though these are
* optional. Valuable cards will also have a second image that will be displayed when the card is
* tapped.
*/
public final class WalletCard implements Parcelable {
/**
* Unknown cards refer to cards whose types are unspecified.
*/
public static final int CARD_TYPE_UNKNOWN = 0;
/**
* Payment cards refer to credit cards, debit cards or any other cards in the wallet used to
* make cash-equivalent payments.
*/
public static final int CARD_TYPE_PAYMENT = 1;
/**
* Valuable cards refer to any cards that are not used for cash-equivalent payment.
* This includes event tickets, flights, offers, loyalty cards, gift cards and transit tickets.
*/
public static final int CARD_TYPE_VALUABLE = 2;
private final String mCardId;
private final int mCardType;
private final Icon mCardImage;
private final CharSequence mContentDescription;
private final PendingIntent mPendingIntent;
private final Icon mCardIcon;
private final CharSequence mCardLabel;
private final Icon mValuableCardSecondaryImage;
private WalletCard(Builder builder) {
this.mCardId = builder.mCardId;
this.mCardType = builder.mCardType;
this.mCardImage = builder.mCardImage;
this.mContentDescription = builder.mContentDescription;
this.mPendingIntent = builder.mPendingIntent;
this.mCardIcon = builder.mCardIcon;
this.mCardLabel = builder.mCardLabel;
this.mValuableCardSecondaryImage = builder.mValuableCardSecondaryImage;
}
/**
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"CARD_TYPE_"}, value = {
CARD_TYPE_UNKNOWN,
CARD_TYPE_PAYMENT,
CARD_TYPE_VALUABLE
})
public @interface CardType {
}
@Override
@@ -56,29 +99,44 @@ public final class WalletCard implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(mCardId);
dest.writeInt(mCardType);
mCardImage.writeToParcel(dest, flags);
TextUtils.writeToParcel(mContentDescription, dest, flags);
PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, dest);
if (mCardIcon == null) {
writeIconIfNonNull(mCardIcon, dest, flags);
TextUtils.writeToParcel(mCardLabel, dest, flags);
writeIconIfNonNull(mValuableCardSecondaryImage, dest, flags);
}
/** Utility function called by writeToParcel
*/
private void writeIconIfNonNull(Icon icon, Parcel dest, int flags) {
if (icon == null) {
dest.writeByte((byte) 0);
} else {
dest.writeByte((byte) 1);
mCardIcon.writeToParcel(dest, flags);
icon.writeToParcel(dest, flags);
}
TextUtils.writeToParcel(mCardLabel, dest, flags);
}
private static WalletCard readFromParcel(Parcel source) {
String cardId = source.readString();
int cardType = source.readInt();
Icon cardImage = Icon.CREATOR.createFromParcel(source);
CharSequence contentDesc = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
PendingIntent pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(source);
Icon cardIcon = source.readByte() == 0 ? null : Icon.CREATOR.createFromParcel(source);
CharSequence cardLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
return new Builder(cardId, cardImage, contentDesc, pendingIntent)
Icon valuableCardSecondaryImage = source.readByte() == 0 ? null :
Icon.CREATOR.createFromParcel(source);
Builder builder = new Builder(cardId, cardType, cardImage, contentDesc, pendingIntent)
.setCardIcon(cardIcon)
.setCardLabel(cardLabel)
.build();
.setCardLabel(cardLabel);
return cardType == CARD_TYPE_VALUABLE
? builder.setValuableCardSecondaryImage(valuableCardSecondaryImage).build() :
builder.build();
}
@NonNull
@@ -103,6 +161,15 @@ public final class WalletCard implements Parcelable {
return mCardId;
}
/**
* Returns the card type.
*/
@NonNull
@CardType
public int getCardType() {
return mCardType;
}
/**
* The visual representation of the card. If the card image Icon is a bitmap, it should have a
* width of {@link GetWalletCardsRequest#getCardWidthPx()} and a height of {@link
@@ -158,23 +225,36 @@ public final class WalletCard implements Parcelable {
}
/**
* Builder for {@link WalletCard} objects. You must to provide cardId, cardImage,
* Visual representation of the card when it is tapped. Includes a barcode to scan the card in
* addition to the information in the primary image.
*/
@Nullable
public Icon getValuableCardSecondaryImage() {
return mValuableCardSecondaryImage;
}
/**
* Builder for {@link WalletCard} objects. You must provide cardId, cardImage,
* contentDescription, and pendingIntent. If the card is opaque and should be shown with
* elevation, set hasShadow to true. cardIcon and cardLabel are optional.
*/
public static final class Builder {
private String mCardId;
private int mCardType;
private Icon mCardImage;
private CharSequence mContentDescription;
private PendingIntent mPendingIntent;
private Icon mCardIcon;
private CharSequence mCardLabel;
private Icon mValuableCardSecondaryImage;
/**
* @param cardId The card id must be non-null and unique within the list of
* cards returned. <b>Note:
* </b> this card ID should <b>not</b> contain PII (Personally
* Identifiable Information, such as username or email address).
* @param cardType Integer representing the card type. The card type must be
* non-null. If not provided, it defaults to unknown.
* @param cardImage The visual representation of the card. If the card image Icon
* is a bitmap, it should have a width of {@link
* GetWalletCardsRequest#getCardWidthPx()} and a height of {@link
@@ -193,15 +273,31 @@ public final class WalletCard implements Parcelable {
* request device unlock before sending the pending intent. It is
* recommended that the pending intent be immutable (use {@link
* PendingIntent#FLAG_IMMUTABLE}).
*
*/
public Builder(@NonNull String cardId,
@NonNull @CardType int cardType,
@NonNull Icon cardImage,
@NonNull CharSequence contentDescription,
@NonNull PendingIntent pendingIntent
) {
mCardId = cardId;
mCardType = cardType;
mCardImage = cardImage;
mContentDescription = contentDescription;
mPendingIntent = pendingIntent;
}
/**
* Called when a card type is not provided. Calls {@link
* Builder#Builder(String, int, Icon, CharSequence, PendingIntent)} with default card type
*/
public Builder(@NonNull String cardId,
@NonNull Icon cardImage,
@NonNull CharSequence contentDescription,
@NonNull PendingIntent pendingIntent) {
mCardId = cardId;
mCardImage = cardImage;
mContentDescription = contentDescription;
mPendingIntent = pendingIntent;
this(cardId, WalletCard.CARD_TYPE_UNKNOWN, cardImage, contentDescription,
pendingIntent);
}
/**
@@ -235,6 +331,18 @@ public final class WalletCard implements Parcelable {
return this;
}
/**
* Visual representation of the card when it is tapped. Includes a barcode to scan the card
* in addition to the information in the primary image.
*/
@NonNull
public Builder setValuableCardSecondaryImage(@Nullable Icon valuableCardSecondaryImage) {
Preconditions.checkState(mCardType == CARD_TYPE_VALUABLE,
"This field can only be set on valuable cards");
mValuableCardSecondaryImage = valuableCardSecondaryImage;
return this;
}
/**
* Builds a new {@link WalletCard} instance.
*