blob: d2494a544d7aa915a82f11054fb30d00854836eb [file] [log] [blame]
Sean Pont72fc25f2020-02-11 19:02:44 -08001/*
2 * Copyright (C) 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.graphics.Bitmap;
21import android.graphics.drawable.Icon;
22import android.os.Handler;
23import android.os.RemoteException;
24import android.text.TextUtils;
25import android.util.Log;
26
27import java.util.List;
28
29/**
30 * Handles response from the {@link QuickAccessWalletService} for {@link GetWalletCardsRequest}
31 *
32 * @hide
33 */
34final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback {
35
36 private static final String TAG = "QAWalletCallback";
37
38 private final IQuickAccessWalletServiceCallbacks mCallback;
39 private final GetWalletCardsRequest mRequest;
40 private final Handler mHandler;
41 private boolean mCalled;
42
43 GetWalletCardsCallbackImpl(GetWalletCardsRequest request,
44 IQuickAccessWalletServiceCallbacks callback, Handler handler) {
45 mRequest = request;
46 mCallback = callback;
47 mHandler = handler;
48 }
49
50 /**
51 * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
52 * was successfully handled by the service.
53 *
54 * @param response The response contains the list of {@link WalletCard walletCards} to be shown
55 * to the user as well as the index of the card that should initially be
56 * presented as the selected card.
57 */
58 public void onSuccess(@NonNull GetWalletCardsResponse response) {
59 Log.i(TAG, "onSuccess");
60 if (isValidResponse(response)) {
61 mHandler.post(() -> onSuccessInternal(response));
62 } else {
63 Log.w(TAG, "Invalid GetWalletCards response");
64 mHandler.post(() -> onFailureInternal(new GetWalletCardsError(null, null)));
65 }
66 }
67
68 /**
69 * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
70 * could not be handled by the service.
71 *
72 * @param error The error message. <b>Note: </b> this message should <b>not</b> contain PII
73 * (Personally Identifiable Information, such as username or email address).
74 * @throws IllegalStateException if this method or {@link #onSuccess} was already called.
75 */
76 public void onFailure(@NonNull GetWalletCardsError error) {
77 mHandler.post(() -> onFailureInternal(error));
78 }
79
80 private void onSuccessInternal(GetWalletCardsResponse response) {
81 Log.i(TAG, "onSuccessInternal");
82 if (mCalled) {
83 Log.w(TAG, "already called");
84 return;
85 }
86 mCalled = true;
87 try {
88 mCallback.onGetWalletCardsSuccess(response);
89 Log.i(TAG, "onSuccessInternal: returned response");
90 } catch (RemoteException e) {
91 Log.w(TAG, "Error returning wallet cards", e);
92 }
93 }
94
95 private void onFailureInternal(GetWalletCardsError error) {
96 if (mCalled) {
97 Log.w(TAG, "already called");
98 return;
99 }
100 mCalled = true;
101 try {
102 mCallback.onGetWalletCardsFailure(error);
103 } catch (RemoteException e) {
104 Log.e(TAG, "Error returning failure message", e);
105 }
106 }
107
108 private boolean isValidResponse(@NonNull GetWalletCardsResponse response) {
109 return response != null
110 && response.getWalletCards() != null
111 && response.getSelectedIndex() >= 0
112 && (response.getWalletCards().isEmpty() // selectedIndex may be 0 when list is empty
113 || response.getSelectedIndex() < response.getWalletCards().size())
114 && response.getWalletCards().size() < mRequest.getMaxCards()
115 && areValidCards(response.getWalletCards());
116 }
117
118 private boolean areValidCards(List<WalletCard> walletCards) {
119 for (WalletCard walletCard : walletCards) {
120 if (walletCard == null
121 || walletCard.getCardId() == null
122 || walletCard.getCardImage() == null
123 || TextUtils.isEmpty(walletCard.getContentDescription())
124 || walletCard.getPendingIntent() == null) {
125 return false;
126 }
127 Icon cardImage = walletCard.getCardImage();
128 if (cardImage.getType() == Icon.TYPE_BITMAP
129 && walletCard.getCardImage().getBitmap().getConfig()
130 != Bitmap.Config.HARDWARE) {
131 Log.w(TAG, "WalletCard bitmaps should be hardware bitmaps");
132 }
133 }
134 return true;
135 }
136}