Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59ecddf8 authored by Sean Pont's avatar Sean Pont Committed by Android (Google) Code Review
Browse files

Merge "Improve QuickAccessWallet documentation and client."

parents 4d07258e 72fc25f5
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -43967,7 +43967,7 @@ package android.service.notification {
package android.service.quickaccesswallet {
  public final class GetWalletCardsCallback {
  public interface GetWalletCardsCallback {
    method public void onFailure(@NonNull android.service.quickaccesswallet.GetWalletCardsError);
    method public void onSuccess(@NonNull android.service.quickaccesswallet.GetWalletCardsResponse);
  }
@@ -44008,7 +44008,6 @@ package android.service.quickaccesswallet {
    method public abstract void onWalletCardsRequested(@NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.GetWalletCardsCallback);
    method public abstract void onWalletDismissed();
    method public final void sendWalletServiceEvent(@NonNull android.service.quickaccesswallet.WalletServiceEvent);
    field public static final String ACTION_DISMISS_WALLET = "android.service.quickaccesswallet.action.DISMISS_WALLET";
    field public static final String ACTION_VIEW_WALLET = "android.service.quickaccesswallet.action.VIEW_WALLET";
    field public static final String ACTION_VIEW_WALLET_SETTINGS = "android.service.quickaccesswallet.action.VIEW_WALLET_SETTINGS";
    field public static final String SERVICE_INTERFACE = "android.service.quickaccesswallet.QuickAccessWalletService";
+31 −0
Original line number Diff line number Diff line
@@ -2976,6 +2976,9 @@ package android.provider {
    field public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners";
    field public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS = "location_access_check_delay_millis";
    field public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS = "location_access_check_interval_millis";
    field public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS = "lock_screen_allow_private_notifications";
    field public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS = "lock_screen_show_notifications";
    field public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
    field public static final String NOTIFICATION_BADGING = "notification_badging";
    field @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds";
    field public static final String USER_SETUP_COMPLETE = "user_setup_complete";
@@ -3399,6 +3402,34 @@ package android.service.notification {

}

package android.service.quickaccesswallet {

  public interface QuickAccessWalletClient {
    method public void addWalletServiceEventListener(@NonNull android.service.quickaccesswallet.QuickAccessWalletClient.WalletServiceEventListener);
    method @NonNull public static android.service.quickaccesswallet.QuickAccessWalletClient create(@NonNull android.content.Context);
    method @Nullable public android.content.Intent createWalletIntent();
    method @Nullable public android.content.Intent createWalletSettingsIntent();
    method public void disconnect();
    method public void getWalletCards(@NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.QuickAccessWalletClient.OnWalletCardsRetrievedCallback);
    method public boolean isWalletFeatureAvailable();
    method public boolean isWalletFeatureAvailableWhenDeviceLocked();
    method public boolean isWalletServiceAvailable();
    method public void notifyWalletDismissed();
    method public void removeWalletServiceEventListener(@NonNull android.service.quickaccesswallet.QuickAccessWalletClient.WalletServiceEventListener);
    method public void selectWalletCard(@NonNull android.service.quickaccesswallet.SelectWalletCardRequest);
  }

  public static interface QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
    method public void onWalletCardRetrievalError(@NonNull android.service.quickaccesswallet.GetWalletCardsError);
    method public void onWalletCardsRetrieved(@NonNull android.service.quickaccesswallet.GetWalletCardsResponse);
  }

  public static interface QuickAccessWalletClient.WalletServiceEventListener {
    method public void onWalletServiceEvent(@NonNull android.service.quickaccesswallet.WalletServiceEvent);
  }

}

package android.service.quicksettings {

  public class TileService extends android.app.Service {
+3 −0
Original line number Diff line number Diff line
@@ -6462,6 +6462,7 @@ public final class Settings {
         * @hide
         */
        @SystemApi
        @TestApi
        public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS =
                "lock_screen_allow_private_notifications";
@@ -7880,6 +7881,7 @@ public final class Settings {
         * @hide
         */
        @UnsupportedAppUsage
        @TestApi
        public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
        /**
@@ -8082,6 +8084,7 @@ public final class Settings {
         * @hide
         */
        @SystemApi
        @TestApi
        public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS =
                "lock_screen_show_notifications";
+5 −51
Original line number Diff line number Diff line
@@ -17,28 +17,11 @@
package android.service.quickaccesswallet;

import android.annotation.NonNull;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;

/**
 * Handles response from the {@link QuickAccessWalletService} for {@link GetWalletCardsRequest}
 */
public final class GetWalletCardsCallback {

    private static final String TAG = "QAWalletCallback";

    private final IQuickAccessWalletServiceCallbacks mCallback;
    private final Handler mHandler;
    private boolean mCalled;

    /**
     * @hide
     */
    GetWalletCardsCallback(IQuickAccessWalletServiceCallbacks callback, Handler handler) {
        mCallback = callback;
        mHandler = handler;
    }
public interface GetWalletCardsCallback {

    /**
     * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
@@ -46,11 +29,10 @@ public final class GetWalletCardsCallback {
     *
     * @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.
     *                 presented as the selected card. The list should not contain more than the
     *                 maximum number of cards requested.
     */
    public void onSuccess(@NonNull GetWalletCardsResponse response) {
        mHandler.post(() -> onSuccessInternal(response));
    }
    void onSuccess(@NonNull GetWalletCardsResponse response);

    /**
     * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
@@ -60,33 +42,5 @@ public final class GetWalletCardsCallback {
     *              (Personally Identifiable Information, such as username or email address).
     * @throws IllegalStateException if this method or {@link #onSuccess} was already called.
     */
    public void onFailure(@NonNull GetWalletCardsError error) {
        mHandler.post(() -> onFailureInternal(error));
    }

    private void onSuccessInternal(GetWalletCardsResponse response) {
        if (mCalled) {
            Log.w(TAG, "already called");
            return;
        }
        mCalled = true;
        try {
            mCallback.onGetWalletCardsSuccess(response);
        } catch (RemoteException e) {
            Log.e(TAG, "Error returning wallet cards", e);
        }
    }

    private void onFailureInternal(GetWalletCardsError error) {
        if (mCalled) {
            Log.w(TAG, "already called");
            return;
        }
        mCalled = true;
        try {
            mCallback.onGetWalletCardsFailure(error);
        } catch (RemoteException e) {
            Log.e(TAG, "Error returning failure message", e);
        }
    }
    void onFailure(@NonNull GetWalletCardsError error);
}
+136 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.service.quickaccesswallet;

import android.annotation.NonNull;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.os.Handler;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;

import java.util.List;

/**
 * Handles response from the {@link QuickAccessWalletService} for {@link GetWalletCardsRequest}
 *
 * @hide
 */
final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback {

    private static final String TAG = "QAWalletCallback";

    private final IQuickAccessWalletServiceCallbacks mCallback;
    private final GetWalletCardsRequest mRequest;
    private final Handler mHandler;
    private boolean mCalled;

    GetWalletCardsCallbackImpl(GetWalletCardsRequest request,
            IQuickAccessWalletServiceCallbacks callback, Handler handler) {
        mRequest = request;
        mCallback = callback;
        mHandler = handler;
    }

    /**
     * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
     * 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.
     */
    public void onSuccess(@NonNull GetWalletCardsResponse response) {
        Log.i(TAG, "onSuccess");
        if (isValidResponse(response)) {
            mHandler.post(() -> onSuccessInternal(response));
        } else {
            Log.w(TAG, "Invalid GetWalletCards response");
            mHandler.post(() -> onFailureInternal(new GetWalletCardsError(null, null)));
        }
    }

    /**
     * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
     * could not be handled by the service.
     *
     * @param error The error message. <b>Note: </b> this message should <b>not</b> contain PII
     *              (Personally Identifiable Information, such as username or email address).
     * @throws IllegalStateException if this method or {@link #onSuccess} was already called.
     */
    public void onFailure(@NonNull GetWalletCardsError error) {
        mHandler.post(() -> onFailureInternal(error));
    }

    private void onSuccessInternal(GetWalletCardsResponse response) {
        Log.i(TAG, "onSuccessInternal");
        if (mCalled) {
            Log.w(TAG, "already called");
            return;
        }
        mCalled = true;
        try {
            mCallback.onGetWalletCardsSuccess(response);
            Log.i(TAG, "onSuccessInternal: returned response");
        } catch (RemoteException e) {
            Log.w(TAG, "Error returning wallet cards", e);
        }
    }

    private void onFailureInternal(GetWalletCardsError error) {
        if (mCalled) {
            Log.w(TAG, "already called");
            return;
        }
        mCalled = true;
        try {
            mCallback.onGetWalletCardsFailure(error);
        } catch (RemoteException e) {
            Log.e(TAG, "Error returning failure message", e);
        }
    }

    private boolean isValidResponse(@NonNull GetWalletCardsResponse response) {
        return response != null
                && response.getWalletCards() != null
                && response.getSelectedIndex() >= 0
                && (response.getWalletCards().isEmpty() // selectedIndex may be 0 when list is empty
                || response.getSelectedIndex() < response.getWalletCards().size())
                && response.getWalletCards().size() < mRequest.getMaxCards()
                && areValidCards(response.getWalletCards());
    }

    private boolean areValidCards(List<WalletCard> walletCards) {
        for (WalletCard walletCard : walletCards) {
            if (walletCard == null
                    || walletCard.getCardId() == null
                    || walletCard.getCardImage() == null
                    || TextUtils.isEmpty(walletCard.getContentDescription())
                    || walletCard.getPendingIntent() == null) {
                return false;
            }
            Icon cardImage = walletCard.getCardImage();
            if (cardImage.getType() == Icon.TYPE_BITMAP
                    && walletCard.getCardImage().getBitmap().getConfig()
                    != Bitmap.Config.HARDWARE) {
                Log.w(TAG, "WalletCard bitmaps should be hardware bitmaps");
            }
        }
        return true;
    }
}
Loading