diff options
5 files changed, 95 insertions, 27 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 2db3eae5fab6..2a16e12b23cb 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -12725,6 +12725,7 @@ package android.content.pm { field public static final String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute"; field public static final String FEATURE_VULKAN_HARDWARE_LEVEL = "android.hardware.vulkan.level"; field public static final String FEATURE_VULKAN_HARDWARE_VERSION = "android.hardware.vulkan.version"; + field public static final String FEATURE_WALLET_LOCATION_BASED_SUGGESTIONS = "android.software.wallet_location_based_suggestions"; field public static final String FEATURE_WATCH = "android.hardware.type.watch"; field public static final String FEATURE_WEBVIEW = "android.software.webview"; field public static final String FEATURE_WIFI = "android.hardware.wifi"; @@ -41086,6 +41087,7 @@ 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 java.util.List<android.location.Location> getCardLocations(); method @NonNull public int getCardType(); method @NonNull public CharSequence getContentDescription(); method @Nullable public android.graphics.drawable.Icon getNonPaymentCardSecondaryImage(); @@ -41103,6 +41105,7 @@ package android.service.quickaccesswallet { 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 setCardLocations(@NonNull java.util.List<android.location.Location>); method @NonNull public android.service.quickaccesswallet.WalletCard.Builder setNonPaymentCardSecondaryImage(@Nullable android.graphics.drawable.Icon); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index d927c5e37a80..7da23b28f3e4 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4353,19 +4353,26 @@ public abstract class PackageManager { public static final String FEATURE_CREDENTIALS = "android.software.credentials"; /** - * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: - * The device supports locking (for example, by a financing provider in case of a missed - * payment). + * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device + * supports locking (for example, by a financing provider in case of a missed payment). */ @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_DEVICE_LOCK = "android.software.device_lock"; + /** + * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device + * supports showing location-based suggestions for wallet cards provided by the default payment + * app. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_WALLET_LOCATION_BASED_SUGGESTIONS = + "android.software.wallet_location_based_suggestions"; + /** @hide */ public static final boolean APP_ENUMERATION_ENABLED_BY_DEFAULT = true; /** - * Extra field name for the URI to a verification file. Passed to a package - * verifier. + * Extra field name for the URI to a verification file. Passed to a package verifier. * * @hide */ diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java b/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java index ae67068d9f32..8409503d9b4c 100644 --- a/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java +++ b/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java @@ -17,6 +17,8 @@ package android.service.quickaccesswallet; import android.annotation.NonNull; +import android.content.Context; +import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.drawable.Icon; import android.os.Handler; @@ -36,13 +38,18 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback { private final IQuickAccessWalletServiceCallbacks mCallback; private final GetWalletCardsRequest mRequest; private final Handler mHandler; + private final Context mContext; private boolean mCalled; - GetWalletCardsCallbackImpl(GetWalletCardsRequest request, - IQuickAccessWalletServiceCallbacks callback, Handler handler) { + GetWalletCardsCallbackImpl( + GetWalletCardsRequest request, + IQuickAccessWalletServiceCallbacks callback, + Handler handler, + Context context) { mRequest = request; mCallback = callback; mHandler = handler; + mContext = context; } /** @@ -50,11 +57,17 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback { * was successfully handled by the service. * * @param response The response contains the list of {@link WalletCard walletCards} to be shown - * to the user as well as the index of the card that should initially be - * presented as the selected card. + * to the user as well as the index of the card that should initially be presented as the + * selected card. */ public void onSuccess(@NonNull GetWalletCardsResponse response) { if (isValidResponse(response)) { + // Strip location info from response if the feature is not enabled. + if (!mContext.getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_WALLET_LOCATION_BASED_SUGGESTIONS)) { + removeLocationsFromResponse(response); + } + mHandler.post(() -> onSuccessInternal(response)); } else { Log.w(TAG, "Invalid GetWalletCards response"); @@ -152,4 +165,10 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback { } return true; } + + private void removeLocationsFromResponse(@NonNull GetWalletCardsResponse response) { + for (WalletCard card : response.getWalletCards()) { + card.removeCardLocations(); + } + } } diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java index d004f34bc721..36fa21c19d27 100644 --- a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java +++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java @@ -262,8 +262,8 @@ public abstract class QuickAccessWalletService extends Service { private void onWalletCardsRequestedInternal( GetWalletCardsRequest request, IQuickAccessWalletServiceCallbacks callback) { - onWalletCardsRequested(request, - new GetWalletCardsCallbackImpl(request, callback, mHandler)); + onWalletCardsRequested( + request, new GetWalletCardsCallbackImpl(request, callback, mHandler, this)); } private void onTargetActivityIntentRequestedInternal( diff --git a/core/java/android/service/quickaccesswallet/WalletCard.java b/core/java/android/service/quickaccesswallet/WalletCard.java index e52adcc6345d..4a4fd041fb19 100644 --- a/core/java/android/service/quickaccesswallet/WalletCard.java +++ b/core/java/android/service/quickaccesswallet/WalletCard.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.PendingIntent; import android.graphics.drawable.Icon; +import android.location.Location; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -29,7 +30,8 @@ import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; - +import java.util.ArrayList; +import java.util.List; /** * A {@link WalletCard} can represent anything that a user might carry in their wallet -- a credit @@ -67,6 +69,7 @@ public final class WalletCard implements Parcelable { private final Icon mCardIcon; private final CharSequence mCardLabel; private final Icon mNonPaymentCardSecondaryImage; + private List<Location> mCardLocations; private WalletCard(Builder builder) { this.mCardId = builder.mCardId; @@ -77,6 +80,7 @@ public final class WalletCard implements Parcelable { this.mCardIcon = builder.mCardIcon; this.mCardLabel = builder.mCardLabel; this.mNonPaymentCardSecondaryImage = builder.mNonPaymentCardSecondaryImage; + this.mCardLocations = builder.mCardLocations; } /** @@ -106,7 +110,7 @@ public final class WalletCard implements Parcelable { writeIconIfNonNull(mCardIcon, dest, flags); TextUtils.writeToParcel(mCardLabel, dest, flags); writeIconIfNonNull(mNonPaymentCardSecondaryImage, dest, flags); - + dest.writeTypedList(mCardLocations, flags); } /** Utility function called by writeToParcel @@ -128,15 +132,20 @@ public final class WalletCard implements Parcelable { PendingIntent pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(source); Icon cardIcon = source.readByte() == 0 ? null : Icon.CREATOR.createFromParcel(source); CharSequence cardLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); - Icon nonPaymentCardSecondaryImage = source.readByte() == 0 ? null : - Icon.CREATOR.createFromParcel(source); - Builder builder = new Builder(cardId, cardType, cardImage, contentDesc, pendingIntent) - .setCardIcon(cardIcon) - .setCardLabel(cardLabel); - - return cardType == CARD_TYPE_NON_PAYMENT - ? builder.setNonPaymentCardSecondaryImage(nonPaymentCardSecondaryImage).build() : - builder.build(); + Icon nonPaymentCardSecondaryImage = + source.readByte() == 0 ? null : Icon.CREATOR.createFromParcel(source); + Builder builder = + new Builder(cardId, cardType, cardImage, contentDesc, pendingIntent) + .setCardIcon(cardIcon) + .setCardLabel(cardLabel); + if (cardType == CARD_TYPE_NON_PAYMENT) { + builder.setNonPaymentCardSecondaryImage(nonPaymentCardSecondaryImage); + } + List<Location> cardLocations = new ArrayList<>(); + source.readTypedList(cardLocations, Location.CREATOR); + builder.setCardLocations(cardLocations); + + return builder.build(); } @NonNull @@ -226,13 +235,29 @@ public final class WalletCard implements Parcelable { /** * Visual representation of the card when it is tapped. May include additional information - * unique to the card, such as a barcode or number. Only valid for CARD_TYPE_NON_PAYMENT. + * unique to the card, such as a barcode or number. Only valid for CARD_TYPE_NON_PAYMENT. */ @Nullable public Icon getNonPaymentCardSecondaryImage() { return mNonPaymentCardSecondaryImage; } + /** List of locations that this card might be useful at. */ + @NonNull + public List<Location> getCardLocations() { + return mCardLocations; + } + + /** + * Removes locations from card. Should be called if {@link + * PackageManager.FEATURE_WALLET_LOCATION_BASED_SUGGESTIONS} is disabled. + * + * @hide + */ + public void removeCardLocations() { + mCardLocations = new ArrayList<>(); + } + /** * Builder for {@link WalletCard} objects. You must provide cardId, cardImage, * contentDescription, and pendingIntent. If the card is opaque and should be shown with @@ -247,6 +272,7 @@ public final class WalletCard implements Parcelable { private Icon mCardIcon; private CharSequence mCardLabel; private Icon mNonPaymentCardSecondaryImage; + private List<Location> mCardLocations = new ArrayList<>(); /** * @param cardId The card id must be non-null and unique within the list of @@ -333,18 +359,31 @@ public final class WalletCard implements Parcelable { /** * Visual representation of the card when it is tapped. May include additional information - * unique to the card, such as a barcode or number. Only valid for CARD_TYPE_NON_PAYMENT. + * unique to the card, such as a barcode or number. Only valid for CARD_TYPE_NON_PAYMENT. */ @NonNull - public Builder - setNonPaymentCardSecondaryImage(@Nullable Icon nonPaymentCardSecondaryImage) { - Preconditions.checkState(mCardType == CARD_TYPE_NON_PAYMENT, + public Builder setNonPaymentCardSecondaryImage( + @Nullable Icon nonPaymentCardSecondaryImage) { + Preconditions.checkState( + mCardType == CARD_TYPE_NON_PAYMENT, "This field can only be set on non-payment cards"); mNonPaymentCardSecondaryImage = nonPaymentCardSecondaryImage; return this; } /** + * Set of locations this card might be useful at. If {@link + * PackageManager.FEATURE_WALLET_LOCATION_BASED_SUGGESTIONS} is enabled, the card might be + * shown to the user when a user is near one of these locations. + */ + @NonNull + public Builder setCardLocations(@NonNull List<Location> cardLocations) { + Preconditions.checkCollectionElementsNotNull(cardLocations, "cardLocations"); + mCardLocations = cardLocations; + return this; + } + + /** * Builds a new {@link WalletCard} instance. * * @return A built response. |