[Quick Access Wallet] Update docs, remove debug logs, and fix lint errors

Bug: 150134429
Bug: 149580068
Test: atest CtsQuickAccessWalletTestCases
Change-Id: I2173b270950a9174b7be67461ef8821ecde91194
diff --git a/api/test-current.txt b/api/test-current.txt
index b5a9075..a813bcb 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3435,13 +3435,15 @@
 
 package android.service.quickaccesswallet {
 
-  public interface QuickAccessWalletClient {
+  public interface QuickAccessWalletClient extends java.io.Closeable {
     method public void addWalletServiceEventListener(@NonNull android.service.quickaccesswallet.QuickAccessWalletClient.WalletServiceEventListener);
+    method public void addWalletServiceEventListener(@NonNull java.util.concurrent.Executor, @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 void getWalletCards(@NonNull java.util.concurrent.Executor, @NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.QuickAccessWalletClient.OnWalletCardsRetrievedCallback);
     method public boolean isWalletFeatureAvailable();
     method public boolean isWalletFeatureAvailableWhenDeviceLocked();
     method public boolean isWalletServiceAvailable();
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java b/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java
index d2494a5..ae67068 100644
--- a/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java
@@ -24,8 +24,6 @@
 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 @@
      *                 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 @@
     }
 
     private void onSuccessInternal(GetWalletCardsResponse response) {
-        Log.i(TAG, "onSuccessInternal");
         if (mCalled) {
             Log.w(TAG, "already called");
             return;
@@ -86,7 +82,6 @@
         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 @@
     }
 
     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 be9ab11..4f5b139 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 @@
             @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 @@
     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 37a8703..e4dd082 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
@@ -18,6 +18,7 @@
 
 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 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 @@
 
     @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 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 @@
                 serviceCallback.onGetWalletCardsFailure(new GetWalletCardsError(null, null));
             }
         });
+
     }
 
     @Override
     public void selectWalletCard(@NonNull SelectWalletCardRequest request) {
-        Log.i(TAG, "selectWalletCard");
         if (!isWalletServiceAvailable()) {
             return;
         }
@@ -153,7 +162,6 @@
         if (!isWalletServiceAvailable()) {
             return;
         }
-        Log.i(TAG, "notifyWalletDismissed");
         executeApiCall(new ApiCaller("onWalletDismissed") {
             @Override
             public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
@@ -164,15 +172,20 @@
 
     @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 @@
         if (!isWalletServiceAvailable()) {
             return;
         }
-        Log.i(TAG, "unregisterWalletServiceEventListener");
         executeApiCall(new ApiCaller("unregisterListener") {
             @Override
             public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
@@ -209,8 +221,12 @@
     }
 
     @Override
+    public void close() throws IOException {
+        disconnect();
+    }
+
+    @Override
     public void disconnect() {
-        Log.i(TAG, "disconnect");
         mHandler.post(() -> disconnectInternal(true));
     }
 
@@ -241,18 +257,15 @@
     }
 
     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 @@
     }
 
     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 @@
      * 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 @@
     }
 
     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 @@
     }
 
     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 @@
             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 @@
 
     @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 @@
     @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 23173a8..31e51bb 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
@@ -66,13 +66,11 @@
     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 e6ae0ab..b09d2e9 100644
--- a/core/java/android/service/quickaccesswallet/WalletCard.java
+++ b/core/java/android/service/quickaccesswallet/WalletCard.java
@@ -180,7 +180,7 @@
          *                           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
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 6d16253..b99d765 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -116,16 +116,17 @@
 import javax.inject.Inject;
 
 /**
- * Helper to show the global actions dialog.  Each item is an {@link Action} that
- * may show depending on whether the keyguard is showing, and whether the device
- * is provisioned.
+ * Helper to show the global actions dialog.  Each item is an {@link Action} that may show depending
+ * on whether the keyguard is showing, and whether the device is provisioned.
  */
 public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
-        DialogInterface.OnShowListener, ConfigurationController.ConfigurationListener {
+        DialogInterface.OnShowListener,
+        ConfigurationController.ConfigurationListener,
+        GlobalActionsPanelPlugin.Callbacks {
 
-    static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
-    static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
-    static public final String SYSTEM_DIALOG_REASON_DREAM = "dream";
+    public static final String SYSTEM_DIALOG_REASON_KEY = "reason";
+    public static final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
+    public static final String SYSTEM_DIALOG_REASON_DREAM = "dream";
 
     private static final String TAG = "GlobalActionsDialog";
 
@@ -271,8 +272,9 @@
             @Override
             public void onUnlockedChanged() {
                 if (mDialog != null && mDialog.mPanelController != null) {
-                    boolean locked = !keyguardStateController.canDismissLockScreen();
-                    mDialog.mPanelController.onDeviceLockStateChanged(locked);
+                    boolean unlocked = keyguardStateController.isUnlocked()
+                            || keyguardStateController.canDismissLockScreen();
+                    mDialog.mPanelController.onDeviceLockStateChanged(unlocked);
                 }
             }
         });
@@ -386,7 +388,7 @@
                 mItems.add(getSettingsAction());
             } else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) {
                 if (Settings.Secure.getIntForUser(mContentResolver,
-                            Settings.Secure.LOCKDOWN_IN_POWER_MENU, 0, getCurrentUser().id) != 0
+                        Settings.Secure.LOCKDOWN_IN_POWER_MENU, 0, getCurrentUser().id) != 0
                         && shouldDisplayLockdown()) {
                     mItems.add(getLockdownAction());
                 }
@@ -420,26 +422,7 @@
 
         mAdapter = new MyAdapter();
 
-        GlobalActionsPanelPlugin.PanelViewController panelViewController =
-                mPanelPlugin != null
-                        ? mPanelPlugin.onPanelShown(
-                                new GlobalActionsPanelPlugin.Callbacks() {
-                                    @Override
-                                    public void dismissGlobalActionsMenu() {
-                                        dismissDialog();
-                                    }
-
-                                    @Override
-                                    public void startPendingIntentDismissingKeyguard(
-                                            PendingIntent intent) {
-                                        mActivityStarter
-                                                .startPendingIntentDismissingKeyguard(intent);
-                                    }
-                                },
-                                !mKeyguardStateController.isUnlocked())
-                        : null;
-
-        ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, panelViewController,
+        ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, getWalletPanelViewController(),
                 mDepthController, mSysuiColorExtractor, mStatusBarService,
                 mNotificationShadeWindowController,
                 shouldShowControls() ? mControlsUiController : null, mBlurUtils);
@@ -477,6 +460,33 @@
         mConfigurationController.removeCallback(this);
     }
 
+    @Nullable
+    private GlobalActionsPanelPlugin.PanelViewController getWalletPanelViewController() {
+        if (mPanelPlugin == null) {
+            return null;
+        }
+        return mPanelPlugin.onPanelShown(this, !mKeyguardStateController.isUnlocked());
+    }
+
+    /**
+     * Implements {@link GlobalActionsPanelPlugin.Callbacks#dismissGlobalActionsMenu()}, which is
+     * called when the quick access wallet requests dismissal.
+     */
+    @Override
+    public void dismissGlobalActionsMenu() {
+        dismissDialog();
+    }
+
+    /**
+     * Implements {@link GlobalActionsPanelPlugin.Callbacks#dismissGlobalActionsMenu()}, which is
+     * called when the quick access wallet requests that an intent be started (with lock screen
+     * shown first if needed).
+     */
+    @Override
+    public void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent) {
+        mActivityStarter.startPendingIntentDismissingKeyguard(pendingIntent);
+    }
+
     private final class PowerAction extends SinglePressAction implements LongPressAction {
         private PowerAction() {
             super(R.drawable.ic_lock_power_off,
@@ -919,7 +929,9 @@
         }
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public void onDismiss(DialogInterface dialog) {
         if (mDialog == dialog) {
             mDialog = null;
@@ -935,17 +947,19 @@
         }
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
     public void onShow(DialogInterface dialog) {
         mMetricsLogger.visible(MetricsEvent.POWER_MENU);
     }
 
     /**
-     * The adapter used for the list within the global actions dialog, taking
-     * into account whether the keyguard is showing via
-     * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether
-     * the device is provisioned
-     * via {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}.
+     * The adapter used for the list within the global actions dialog, taking into account whether
+     * the keyguard is showing via
+     * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing}
+     * and whether the device is provisioned via
+     * {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}.
      */
     public class MyAdapter extends MultiListAdapter {
         private int countItems(boolean separated) {
@@ -1076,8 +1090,7 @@
      */
     public interface Action {
         /**
-         * @return Text that will be announced when dialog is created.  null
-         * for none.
+         * @return Text that will be announced when dialog is created.  null for none.
          */
         CharSequence getLabelForAccessibility(Context context);
 
@@ -1086,15 +1099,13 @@
         void onPress();
 
         /**
-         * @return whether this action should appear in the dialog when the keygaurd
-         * is showing.
+         * @return whether this action should appear in the dialog when the keygaurd is showing.
          */
         boolean showDuringKeyguard();
 
         /**
-         * @return whether this action should appear in the dialog before the
-         * device is provisioned.onlongpress
-         *
+         * @return whether this action should appear in the dialog before the device is
+         * provisioned.onlongpress
          */
         boolean showBeforeProvisioning();
 
@@ -1113,8 +1124,7 @@
     }
 
     /**
-     * A single press action maintains no state, just responds to a press
-     * and takes an action.
+     * A single press action maintains no state, just responds to a press and takes an action.
      */
 
     private abstract class SinglePressAction implements Action {
@@ -1188,8 +1198,8 @@
     }
 
     /**
-     * A toggle action knows whether it is on or off, and displays an icon
-     * and status message accordingly.
+     * A toggle action knows whether it is on or off, and displays an icon and status message
+     * accordingly.
      */
     private static abstract class ToggleAction implements Action {
 
@@ -1239,8 +1249,7 @@
         }
 
         /**
-         * Override to make changes to resource IDs just before creating the
-         * View.
+         * Override to make changes to resource IDs just before creating the View.
          */
         void willCreate() {
 
@@ -1296,9 +1305,9 @@
         }
 
         /**
-         * Implementations may override this if their state can be in on of the intermediate
-         * states until some notification is received (e.g airplane mode is 'turning off' until
-         * we know the wireless connections are back online
+         * Implementations may override this if their state can be in on of the intermediate states
+         * until some notification is received (e.g airplane mode is 'turning off' until we know the
+         * wireless connections are back online
          *
          * @param buttonOn Whether the button was turned on or off
          */
@@ -1316,12 +1325,13 @@
     private class AirplaneModeAction extends ToggleAction {
         AirplaneModeAction() {
             super(
-                R.drawable.ic_lock_airplane_mode,
-                R.drawable.ic_lock_airplane_mode_off,
-                R.string.global_actions_toggle_airplane_mode,
-                R.string.global_actions_airplane_mode_on_status,
-                R.string.global_actions_airplane_mode_off_status);
+                    R.drawable.ic_lock_airplane_mode,
+                    R.drawable.ic_lock_airplane_mode_off,
+                    R.string.global_actions_toggle_airplane_mode,
+                    R.string.global_actions_airplane_mode_on_status,
+                    R.string.global_actions_airplane_mode_off_status);
         }
+
         void onToggle(boolean on) {
             if (mHasTelephony && TelephonyProperties.in_ecm_mode().orElse(false)) {
                 mIsWaitingForEcmExit = true;
@@ -1607,11 +1617,11 @@
             window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
             window.addFlags(
                     WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
-                    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                            | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
+                            | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                            | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                            | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
             window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
             window.getAttributes().setFitInsetsTypes(0 /* types */);
             setTitle(R.string.global_actions);
@@ -1755,7 +1765,8 @@
 
         /**
          * Updates background and system bars according to current GradientColors.
-         * @param colors Colors and hints to use.
+         *
+         * @param colors  Colors and hints to use.
          * @param animate Interpolates gradient if true, just sets otherwise.
          */
         private void updateColors(GradientColors colors, boolean animate) {
@@ -1921,8 +1932,8 @@
     }
 
     /**
-     * Determines whether or not the Global Actions menu should be forced to
-     * use the newer grid-style layout.
+     * Determines whether or not the Global Actions menu should be forced to use the newer
+     * grid-style layout.
      */
     private static boolean isForceGridEnabled(Context context) {
         return isPanelDebugModeEnabled(context);