diff --git a/packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml b/packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml
new file mode 100644
index 0000000000000..2f8f11d72331b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/wallet_lockscreen_bg.xml b/packages/SystemUI/res/drawable/wallet_lockscreen_bg.xml
new file mode 100644
index 0000000000000..1535e7276a6f3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/wallet_lockscreen_bg.xml
@@ -0,0 +1,33 @@
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index cf9de5e7e226d..69d73c1b94e14 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -90,9 +90,11 @@
android:layout_width="@dimen/keyguard_affordance_width"
android:layout_gravity="bottom|end"
android:scaleType="center"
- android:tint="?attr/wallpaperTextColor"
- android:layout_marginStart="24dp"
- android:layout_marginBottom="48dp"
+ android:tint="?android:attr/textColorPrimary"
+ android:src="@drawable/ic_wallet_lockscreen"
+ android:background="@drawable/wallet_lockscreen_bg"
+ android:layout_marginEnd="@dimen/keyguard_affordance_horizontal_offset"
+ android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
android:visibility="gone" />
56dp
-
- 56dp
- 56dp
+
+ 48dp
+ 48dp
+ 32dp
+ 32dp
+
42dp
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 411a2a3a29113..c3325b103022b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -48,8 +48,11 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.MediaStore;
-import android.provider.Settings;
import android.service.media.CameraPrewarmService;
+import android.service.quickaccesswallet.GetWalletCardsError;
+import android.service.quickaccesswallet.GetWalletCardsRequest;
+import android.service.quickaccesswallet.GetWalletCardsResponse;
+import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -64,6 +67,8 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -75,6 +80,7 @@ import com.android.systemui.animation.Interpolators;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.camera.CameraIntents;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.IntentButtonProvider;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
@@ -87,6 +93,9 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.PreviewInflater;
import com.android.systemui.tuner.LockscreenFragment.LockButtonFactory;
import com.android.systemui.tuner.TunerService;
+import com.android.systemui.wallet.ui.WalletActivity;
+
+import java.util.concurrent.Executor;
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
@@ -121,7 +130,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private KeyguardAffordanceView mRightAffordanceView;
private KeyguardAffordanceView mLeftAffordanceView;
+
private ImageView mWalletButton;
+ private boolean mWalletEnabled = false;
+ private boolean mHasCard = false;
+ private WalletCardRetriever mCardRetriever = new WalletCardRetriever();
+ private QuickAccessWalletClient mQuickAccessWalletClient;
+
private ViewGroup mIndicationArea;
private TextView mIndicationText;
private TextView mIndicationTextBottom;
@@ -138,7 +153,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private AccessibilityController mAccessibilityController;
private StatusBar mStatusBar;
private KeyguardAffordanceHelper mAffordanceHelper;
-
+ private FalsingManager mFalsingManager;
private boolean mUserSetupComplete;
private boolean mPrewarmBound;
private Messenger mPrewarmMessenger;
@@ -170,7 +185,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private int mBurnInXOffset;
private int mBurnInYOffset;
private ActivityIntentHelper mActivityIntentHelper;
- private int mLockScreenMode;
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
public KeyguardBottomAreaView(Context context) {
@@ -415,10 +429,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
private void updateWalletVisibility() {
- if (mDozing) {
+ if (mDozing || !mWalletEnabled) {
mWalletButton.setVisibility(GONE);
} else {
mWalletButton.setVisibility(VISIBLE);
+ mWalletButton.setOnClickListener(this::onWalletClick);
}
}
@@ -871,25 +886,63 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
return insets;
}
- private void setupWallet() {
- boolean inNewLayout = mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
- boolean settingEnabled = Settings.Global.getInt(mContext.getContentResolver(),
- "controls_lockscreen", 0) == 1;
- if (!inNewLayout || !settingEnabled) {
- mWalletButton.setVisibility(View.GONE);
- return;
- }
-
- // TODO: add image
- // mWalletButton.setImageDrawable(list.get(0).loadIcon());
- updateWalletVisibility();
+ /** Set the falsing manager */
+ public void setFalsingManager(FalsingManager falsingManager) {
+ mFalsingManager = falsingManager;
}
/**
- * Optionally add controls when in the new lockscreen mode
+ * Initialize the wallet feature, only enabling if the feature is enabled within the platform.
*/
- public void onLockScreenModeChanged(int mode) {
- mLockScreenMode = mode;
- setupWallet();
+ public void initWallet(QuickAccessWalletClient client, Executor uiExecutor, boolean enabled) {
+ mQuickAccessWalletClient = client;
+ mWalletEnabled = enabled && client.isWalletFeatureAvailable();
+
+ if (mWalletEnabled) {
+ queryWalletCards(uiExecutor);
+ }
+ updateWalletVisibility();
+ }
+
+ private void queryWalletCards(Executor uiExecutor) {
+ GetWalletCardsRequest request =
+ new GetWalletCardsRequest(1 /* cardWidth */, 1 /* cardHeight */,
+ 1 /* iconSizePx */, 2 /* maxCards */);
+ mQuickAccessWalletClient.getWalletCards(uiExecutor, request, mCardRetriever);
+ }
+
+ private void onWalletClick(View v) {
+ // More coming here; need to inform the user about how to proceed
+ mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY);
+
+ if (mHasCard) {
+ Intent intent = new Intent(mContext, WalletActivity.class)
+ .setAction(Intent.ACTION_VIEW)
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ } else {
+ if (mQuickAccessWalletClient.createWalletIntent() == null) {
+ Log.w(TAG, "Could not get intent of the wallet app.");
+ return;
+ }
+ mActivityStarter.postStartActivityDismissingKeyguard(
+ mQuickAccessWalletClient.createWalletIntent(), /* delay= */ 0);
+ }
+ }
+
+ private class WalletCardRetriever implements
+ QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
+
+ @Override
+ public void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response) {
+ mHasCard = !response.getWalletCards().isEmpty();
+ updateWalletVisibility();
+ }
+
+ @Override
+ public void onWalletCardRetrievalError(@NonNull GetWalletCardsError error) {
+ mHasCard = false;
+ updateWalletVisibility();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 7032aefc7a4dd..6a35293def766 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -53,6 +53,7 @@ import android.os.Bundle;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserManager;
+import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.util.Log;
import android.util.MathUtils;
import android.view.DisplayCutout;
@@ -154,6 +155,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -517,6 +519,9 @@ public class NotificationPanelViewController extends PanelViewController {
private int mOldLayoutDirection;
private NotificationShelfController mNotificationShelfController;
+ private final QuickAccessWalletClient mQuickAccessWalletClient;
+ private final Executor mUiExecutor;
+
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
@@ -578,7 +583,9 @@ public class NotificationPanelViewController extends PanelViewController {
NotificationShadeDepthController notificationShadeDepthController,
AmbientState ambientState,
LockIconViewController lockIconViewController,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ QuickAccessWalletClient quickAccessWalletClient,
+ @Main Executor uiExecutor) {
super(view, falsingManager, dozeLog, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
statusBarKeyguardViewManager, latencyTracker, flingAnimationUtilsBuilder.get(),
@@ -624,6 +631,8 @@ public class NotificationPanelViewController extends PanelViewController {
mScrimController = scrimController;
mUserManager = userManager;
mMediaDataManager = mediaDataManager;
+ mQuickAccessWalletClient = quickAccessWalletClient;
+ mUiExecutor = uiExecutor;
pulseExpansionHandler.setPulseExpandAbortListener(() -> {
if (mQs != null) {
mQs.animateHeaderSlidingOut();
@@ -975,6 +984,9 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
mKeyguardBottomArea.setStatusBar(mStatusBar);
mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
+ mKeyguardBottomArea.setFalsingManager(mFalsingManager);
+ mKeyguardBottomArea.initWallet(mQuickAccessWalletClient, mUiExecutor,
+ mFeatureFlags.isQuickAccessWalletEnabled());
}
private void updateMaxDisplayedNotifications(boolean recompute) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 7d052b910cc62..cebf8be491504 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -39,6 +39,7 @@ import android.content.res.Resources;
import android.hardware.biometrics.BiometricSourceType;
import android.os.PowerManager;
import android.os.UserManager;
+import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.DisplayMetrics;
@@ -98,6 +99,8 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import com.android.wm.shell.animation.FlingAnimationUtils;
import org.junit.Before;
@@ -235,6 +238,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private UiEventLogger mUiEventLogger;
@Mock
private LockIconViewController mLockIconViewController;
+ @Mock
+ private QuickAccessWalletClient mQuickAccessWalletClient;
private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
@@ -339,7 +344,9 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mNotificationShadeDepthController,
mAmbientState,
mLockIconViewController,
- mFeatureFlags);
+ mFeatureFlags,
+ mQuickAccessWalletClient,
+ new FakeExecutor(new FakeSystemClock()));
mNotificationPanelViewController.initDependencies(
mStatusBar,
mNotificationShelfController);