diff options
Diffstat (limited to 'core/java')
5 files changed, 120 insertions, 82 deletions
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java b/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java index d2494a544d7a..ae67068d9f32 100644 --- a/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java +++ b/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java @@ -24,8 +24,6 @@ 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} * @@ -56,7 +54,6 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback { * presented as the selected card. */ public void onSuccess(@NonNull GetWalletCardsResponse response) { - Log.i(TAG, "onSuccess"); if (isValidResponse(response)) { mHandler.post(() -> onSuccessInternal(response)); } else { @@ -78,7 +75,6 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback { } private void onSuccessInternal(GetWalletCardsResponse response) { - Log.i(TAG, "onSuccessInternal"); if (mCalled) { Log.w(TAG, "already called"); return; @@ -86,7 +82,6 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback { mCalled = true; try { mCallback.onGetWalletCardsSuccess(response); - Log.i(TAG, "onSuccessInternal: returned response"); } catch (RemoteException e) { Log.w(TAG, "Error returning wallet cards", e); } @@ -106,29 +101,53 @@ final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback { } 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) { + if (response == null) { + Log.w(TAG, "Invalid response: response is null"); + return false; + } + if (response.getWalletCards() == null) { + Log.w(TAG, "Invalid response: walletCards is null"); + return false; + } + if (response.getSelectedIndex() < 0) { + Log.w(TAG, "Invalid response: selectedIndex is negative"); + return false; + } + if (!response.getWalletCards().isEmpty() + && response.getSelectedIndex() >= response.getWalletCards().size()) { + Log.w(TAG, "Invalid response: selectedIndex out of bounds"); + return false; + } + if (response.getWalletCards().size() > mRequest.getMaxCards()) { + Log.w(TAG, "Invalid response: too many cards"); + return false; + } + for (WalletCard walletCard : response.getWalletCards()) { + if (walletCard == null) { + Log.w(TAG, "Invalid response: card is null"); + return false; + } + if (walletCard.getCardId() == null) { + Log.w(TAG, "Invalid response: cardId is null"); return false; } Icon cardImage = walletCard.getCardImage(); + if (cardImage == null) { + Log.w(TAG, "Invalid response: cardImage is null"); + return false; + } if (cardImage.getType() == Icon.TYPE_BITMAP - && walletCard.getCardImage().getBitmap().getConfig() - != Bitmap.Config.HARDWARE) { - Log.w(TAG, "WalletCard bitmaps should be hardware bitmaps"); + && cardImage.getBitmap().getConfig() != Bitmap.Config.HARDWARE) { + Log.w(TAG, "Invalid response: cardImage bitmaps must be hardware bitmaps"); + return false; + } + if (TextUtils.isEmpty(walletCard.getContentDescription())) { + Log.w(TAG, "Invalid response: contentDescription is null"); + return false; + } + if (walletCard.getPendingIntent() == null) { + Log.w(TAG, "Invalid response: pendingIntent is null"); + return false; } } return true; diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java index be9ab11fb3a2..4f5b13981d64 100644 --- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java +++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java @@ -16,19 +16,23 @@ package android.service.quickaccesswallet; +import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.content.Context; import android.content.Intent; +import java.io.Closeable; +import java.util.concurrent.Executor; + /** * Facilitates accessing cards from the {@link QuickAccessWalletService}. * * @hide */ @TestApi -public interface QuickAccessWalletClient { +public interface QuickAccessWalletClient extends Closeable { /** * Create a client for accessing wallet cards from the {@link QuickAccessWalletService}. If the @@ -92,6 +96,14 @@ public interface QuickAccessWalletClient { @NonNull OnWalletCardsRetrievedCallback callback); /** + * Get wallet cards from the {@link QuickAccessWalletService}. + */ + void getWalletCards( + @NonNull @CallbackExecutor Executor executor, + @NonNull GetWalletCardsRequest request, + @NonNull OnWalletCardsRetrievedCallback callback); + + /** * Callback for getWalletCards */ interface OnWalletCardsRetrievedCallback { @@ -111,12 +123,19 @@ public interface QuickAccessWalletClient { void notifyWalletDismissed(); /** - * Unregister event listener. + * Register an event listener. */ void addWalletServiceEventListener(@NonNull WalletServiceEventListener listener); /** - * Unregister event listener + * Register an event listener. + */ + void addWalletServiceEventListener( + @NonNull @CallbackExecutor Executor executor, + @NonNull WalletServiceEventListener listener); + + /** + * Unregister an event listener */ void removeWalletServiceEventListener(@NonNull WalletServiceEventListener listener); diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java index 37a8703ddebe..e4dd082edaa5 100644 --- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java +++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java @@ -18,6 +18,7 @@ package android.service.quickaccesswallet; import static android.service.quickaccesswallet.QuickAccessWalletService.SERVICE_INTERFACE; +import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -36,16 +37,19 @@ import android.util.Log; import com.android.internal.widget.LockPatternUtils; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; import java.util.UUID; +import java.util.concurrent.Executor; /** * Implements {@link QuickAccessWalletClient}. The client connects, performs requests, waits for - * responses, and disconnects automatically after a short period of time. The client may + * responses, and disconnects automatically one minute after the last call is performed. + * * @hide */ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, ServiceConnection { @@ -78,15 +82,14 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser @Override public boolean isWalletServiceAvailable() { - boolean available = mServiceInfo != null; - Log.i(TAG, "isWalletServiceAvailable: " + available); - return available; + return mServiceInfo != null; } @Override public boolean isWalletFeatureAvailable() { int currentUser = ActivityManager.getCurrentUser(); - return checkUserSetupComplete() + return currentUser == UserHandle.USER_SYSTEM + && checkUserSetupComplete() && checkSecureSetting(Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED) && !new LockPatternUtils(mContext).isUserInLockdown(currentUser); } @@ -101,23 +104,29 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser public void getWalletCards( @NonNull GetWalletCardsRequest request, @NonNull OnWalletCardsRetrievedCallback callback) { + getWalletCards(mContext.getMainExecutor(), request, callback); + } - Log.i(TAG, "getWalletCards"); - + @Override + public void getWalletCards( + @NonNull @CallbackExecutor Executor executor, + @NonNull GetWalletCardsRequest request, + @NonNull OnWalletCardsRetrievedCallback callback) { if (!isWalletServiceAvailable()) { - callback.onWalletCardRetrievalError(new GetWalletCardsError(null, null)); + executor.execute( + () -> callback.onWalletCardRetrievalError(new GetWalletCardsError(null, null))); return; } BaseCallbacks serviceCallback = new BaseCallbacks() { @Override public void onGetWalletCardsSuccess(GetWalletCardsResponse response) { - mHandler.post(() -> callback.onWalletCardsRetrieved(response)); + executor.execute(() -> callback.onWalletCardsRetrieved(response)); } @Override public void onGetWalletCardsFailure(GetWalletCardsError error) { - mHandler.post(() -> callback.onWalletCardRetrievalError(error)); + executor.execute(() -> callback.onWalletCardRetrievalError(error)); } }; @@ -132,11 +141,11 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser serviceCallback.onGetWalletCardsFailure(new GetWalletCardsError(null, null)); } }); + } @Override public void selectWalletCard(@NonNull SelectWalletCardRequest request) { - Log.i(TAG, "selectWalletCard"); if (!isWalletServiceAvailable()) { return; } @@ -153,7 +162,6 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser if (!isWalletServiceAvailable()) { return; } - Log.i(TAG, "notifyWalletDismissed"); executeApiCall(new ApiCaller("onWalletDismissed") { @Override public void performApiCall(IQuickAccessWalletService service) throws RemoteException { @@ -164,15 +172,20 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser @Override public void addWalletServiceEventListener(WalletServiceEventListener listener) { + addWalletServiceEventListener(mContext.getMainExecutor(), listener); + } + + @Override + public void addWalletServiceEventListener( + @NonNull @CallbackExecutor Executor executor, + @NonNull WalletServiceEventListener listener) { if (!isWalletServiceAvailable()) { return; } - Log.i(TAG, "registerWalletServiceEventListener"); BaseCallbacks callback = new BaseCallbacks() { @Override public void onWalletServiceEvent(WalletServiceEvent event) { - Log.i(TAG, "onWalletServiceEvent"); - mHandler.post(() -> listener.onWalletServiceEvent(event)); + executor.execute(() -> listener.onWalletServiceEvent(event)); } }; @@ -193,7 +206,6 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser if (!isWalletServiceAvailable()) { return; } - Log.i(TAG, "unregisterWalletServiceEventListener"); executeApiCall(new ApiCaller("unregisterListener") { @Override public void performApiCall(IQuickAccessWalletService service) throws RemoteException { @@ -209,8 +221,12 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser } @Override + public void close() throws IOException { + disconnect(); + } + + @Override public void disconnect() { - Log.i(TAG, "disconnect"); mHandler.post(() -> disconnectInternal(true)); } @@ -241,18 +257,15 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser } private void connect() { - Log.i(TAG, "connect"); mHandler.post(this::connectInternal); } private void connectInternal() { - Log.i(TAG, "connectInternal"); if (mServiceInfo == null) { Log.w(TAG, "Wallet service unavailable"); return; } if (mIsConnected) { - Log.w(TAG, "already connected"); return; } mIsConnected = true; @@ -264,23 +277,14 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser } private void onConnectedInternal(IQuickAccessWalletService service) { - Log.i(TAG, "onConnectedInternal"); if (!mIsConnected) { Log.w(TAG, "onConnectInternal but connection closed"); mService = null; return; } mService = service; - Log.i(TAG, "onConnectedInternal success: request queue size " + mRequestQueue.size()); for (ApiCaller apiCaller : new ArrayList<>(mRequestQueue)) { - try { - apiCaller.performApiCall(mService); - } catch (RemoteException e) { - Log.e(TAG, "onConnectedInternal error", e); - apiCaller.onApiError(); - disconnect(); - break; - } + performApiCallInternal(apiCaller, mService); mRequestQueue.remove(apiCaller); } } @@ -290,7 +294,6 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser * posting a new delayed message. */ private void resetServiceConnectionTimeout() { - Log.i(TAG, "resetServiceConnectionTimeout"); mHandler.removeMessages(MSG_TIMEOUT_SERVICE); mHandler.postDelayed( () -> disconnectInternal(true), @@ -299,13 +302,11 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser } private void disconnectInternal(boolean clearEventListeners) { - Log.i(TAG, "disconnectInternal: " + clearEventListeners); if (!mIsConnected) { Log.w(TAG, "already disconnected"); return; } if (clearEventListeners && !mEventListeners.isEmpty()) { - Log.i(TAG, "disconnectInternal: clear event listeners"); for (WalletServiceEventListener listener : mEventListeners.keySet()) { removeWalletServiceEventListener(listener); } @@ -320,29 +321,33 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser } private void executeApiCall(ApiCaller apiCaller) { - Log.i(TAG, "execute: " + apiCaller.mDesc); mHandler.post(() -> executeInternal(apiCaller)); } - private void executeInternal(ApiCaller apiCall) { - Log.i(TAG, "executeInternal: " + apiCall.mDesc); + private void executeInternal(ApiCaller apiCaller) { if (mIsConnected && mService != null) { - try { - apiCall.performApiCall(mService); - Log.i(TAG, "executeInternal success: " + apiCall.mDesc); - resetServiceConnectionTimeout(); - } catch (RemoteException e) { - Log.w(TAG, "executeInternal error: " + apiCall.mDesc, e); - apiCall.onApiError(); - disconnect(); - } + performApiCallInternal(apiCaller, mService); } else { - Log.i(TAG, "executeInternal: queued" + apiCall.mDesc); - mRequestQueue.add(apiCall); + mRequestQueue.add(apiCaller); connect(); } } + private void performApiCallInternal(ApiCaller apiCaller, IQuickAccessWalletService service) { + if (service == null) { + apiCaller.onApiError(); + return; + } + try { + apiCaller.performApiCall(service); + resetServiceConnectionTimeout(); + } catch (RemoteException e) { + Log.w(TAG, "executeInternal error: " + apiCaller.mDesc, e); + apiCaller.onApiError(); + disconnect(); + } + } + private abstract static class ApiCaller { private final String mDesc; @@ -350,7 +355,8 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser this.mDesc = desc; } - abstract void performApiCall(IQuickAccessWalletService service) throws RemoteException; + abstract void performApiCall(IQuickAccessWalletService service) + throws RemoteException; void onApiError() { Log.w(TAG, "api error: " + mDesc); @@ -359,7 +365,6 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser @Override // ServiceConnection public void onServiceConnected(ComponentName name, IBinder binder) { - Log.i(TAG, "onServiceConnected: " + name); IQuickAccessWalletService service = IQuickAccessWalletService.Stub.asInterface(binder); mHandler.post(() -> onConnectedInternal(service)); } @@ -367,19 +372,16 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser @Override // ServiceConnection public void onServiceDisconnected(ComponentName name) { // Do not disconnect, as we may later be re-connected - Log.w(TAG, "onServiceDisconnected"); } @Override // ServiceConnection public void onBindingDied(ComponentName name) { // This is a recoverable error but the client will need to reconnect. - Log.w(TAG, "onBindingDied"); disconnect(); } @Override // ServiceConnection public void onNullBinding(ComponentName name) { - Log.w(TAG, "onNullBinding"); disconnect(); } diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java index 23173a820a2e..31e51bb945d6 100644 --- a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java +++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java @@ -66,13 +66,11 @@ class QuickAccessWalletServiceInfo { static QuickAccessWalletServiceInfo tryCreate(@NonNull Context context) { ComponentName defaultPaymentApp = getDefaultPaymentApp(context); if (defaultPaymentApp == null) { - Log.d(TAG, "create: default payment app not set"); return null; } ServiceInfo serviceInfo = getWalletServiceInfo(context, defaultPaymentApp.getPackageName()); if (serviceInfo == null) { - Log.d(TAG, "create: unable to resolve service intent"); return null; } diff --git a/core/java/android/service/quickaccesswallet/WalletCard.java b/core/java/android/service/quickaccesswallet/WalletCard.java index e6ae0abef918..b09d2e9e7f13 100644 --- a/core/java/android/service/quickaccesswallet/WalletCard.java +++ b/core/java/android/service/quickaccesswallet/WalletCard.java @@ -180,7 +180,7 @@ public final class WalletCard implements Parcelable { * GetWalletCardsRequest#getCardWidthPx()} and a height of {@link * GetWalletCardsRequest#getCardHeightPx()}. If the card image * does not have these dimensions, it may appear distorted when it - * is scaled to fit these dimensions on screen. Bitmaps should be + * is scaled to fit these dimensions on screen. Bitmaps must be * of type {@link android.graphics.Bitmap.Config#HARDWARE} for * performance reasons. * @param contentDescription The content description of the card image. This field is |
