Loading packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java +29 −3 Original line number Original line Diff line number Diff line Loading @@ -19,8 +19,8 @@ package com.android.systemui.wallet.ui; import static android.provider.Settings.ACTION_LOCKSCREEN_SETTINGS; import static android.provider.Settings.ACTION_LOCKSCREEN_SETTINGS; import android.content.Intent; import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricSourceType; import android.os.Bundle; import android.os.Bundle; import android.os.Handler; import android.os.Handler; import android.service.quickaccesswallet.QuickAccessWalletClient; import android.service.quickaccesswallet.QuickAccessWalletClient; Loading @@ -34,6 +34,9 @@ import android.widget.Toolbar; import androidx.annotation.NonNull; import androidx.annotation.NonNull; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main; Loading Loading @@ -63,7 +66,10 @@ public class WalletActivity extends LifecycleActivity implements private final Handler mHandler; private final Handler mHandler; private final FalsingManager mFalsingManager; private final FalsingManager mFalsingManager; private final UserTracker mUserTracker; private final UserTracker mUserTracker; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final StatusBarKeyguardViewManager mKeyguardViewManager; private final StatusBarKeyguardViewManager mKeyguardViewManager; private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback; private WalletScreenController mWalletScreenController; private WalletScreenController mWalletScreenController; private QuickAccessWalletClient mWalletClient; private QuickAccessWalletClient mWalletClient; private boolean mHasRegisteredListener; private boolean mHasRegisteredListener; Loading @@ -77,6 +83,7 @@ public class WalletActivity extends LifecycleActivity implements @Main Handler handler, @Main Handler handler, FalsingManager falsingManager, FalsingManager falsingManager, UserTracker userTracker, UserTracker userTracker, KeyguardUpdateMonitor keyguardUpdateMonitor, StatusBarKeyguardViewManager keyguardViewManager) { StatusBarKeyguardViewManager keyguardViewManager) { mKeyguardStateController = keyguardStateController; mKeyguardStateController = keyguardStateController; mKeyguardDismissUtil = keyguardDismissUtil; mKeyguardDismissUtil = keyguardDismissUtil; Loading @@ -85,6 +92,7 @@ public class WalletActivity extends LifecycleActivity implements mHandler = handler; mHandler = handler; mFalsingManager = falsingManager; mFalsingManager = falsingManager; mUserTracker = userTracker; mUserTracker = userTracker; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardViewManager = keyguardViewManager; mKeyguardViewManager = keyguardViewManager; } } Loading Loading @@ -116,7 +124,17 @@ public class WalletActivity extends LifecycleActivity implements mHandler, mHandler, mUserTracker, mUserTracker, mFalsingManager, mFalsingManager, mKeyguardUpdateMonitor, mKeyguardStateController); mKeyguardStateController); mKeyguardUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() { @Override public void onBiometricRunningStateChanged( boolean running, BiometricSourceType biometricSourceType) { Log.d(TAG, "Biometric running state has changed."); mWalletScreenController.queryWalletCards(); } }; walletView.getAppButton().setOnClickListener( walletView.getAppButton().setOnClickListener( v -> { v -> { Loading Loading @@ -146,7 +164,9 @@ public class WalletActivity extends LifecycleActivity implements // Click the action button to re-render the screen when the device is unlocked. // Click the action button to re-render the screen when the device is unlocked. walletView.setDeviceLockedActionOnClickListener( walletView.setDeviceLockedActionOnClickListener( v -> { v -> { Log.d(TAG, "Wallet action button is clicked."); if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { Log.d(TAG, "False tap detected on wallet action button."); return; return; } } Loading @@ -164,13 +184,17 @@ public class WalletActivity extends LifecycleActivity implements mHasRegisteredListener = true; mHasRegisteredListener = true; } } mKeyguardStateController.addCallback(mWalletScreenController); mKeyguardStateController.addCallback(mWalletScreenController); mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback); } } @Override @Override protected void onResume() { protected void onResume() { super.onResume(); super.onResume(); mWalletScreenController.queryWalletCards(); mWalletScreenController.queryWalletCards(); mKeyguardViewManager.requestFp(true, Color.BLACK); mKeyguardViewManager.requestFp( true, Utils.getColorAttrDefaultColor( this, com.android.internal.R.attr.colorAccentPrimary)); mKeyguardViewManager.requestFace(true); mKeyguardViewManager.requestFace(true); } } Loading @@ -195,7 +219,6 @@ public class WalletActivity extends LifecycleActivity implements public void onWalletServiceEvent(WalletServiceEvent event) { public void onWalletServiceEvent(WalletServiceEvent event) { switch (event.getEventType()) { switch (event.getEventType()) { case WalletServiceEvent.TYPE_NFC_PAYMENT_STARTED: case WalletServiceEvent.TYPE_NFC_PAYMENT_STARTED: finish(); break; break; case WalletServiceEvent.TYPE_WALLET_CARDS_UPDATED: case WalletServiceEvent.TYPE_WALLET_CARDS_UPDATED: mWalletScreenController.queryWalletCards(); mWalletScreenController.queryWalletCards(); Loading Loading @@ -224,6 +247,9 @@ public class WalletActivity extends LifecycleActivity implements @Override @Override protected void onDestroy() { protected void onDestroy() { mKeyguardStateController.removeCallback(mWalletScreenController); mKeyguardStateController.removeCallback(mWalletScreenController); if (mKeyguardUpdateMonitorCallback != null) { mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback); } mWalletScreenController.onDismissed(); mWalletScreenController.onDismissed(); mWalletClient.removeWalletServiceEventListener(this); mWalletClient.removeWalletServiceEventListener(this); mHasRegisteredListener = false; mHasRegisteredListener = false; Loading packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java +10 −1 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.widget.FrameLayout; import androidx.annotation.NonNull; import androidx.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.FalsingManager; Loading Loading @@ -66,6 +67,7 @@ public class WalletScreenController implements private final ActivityStarter mActivityStarter; private final ActivityStarter mActivityStarter; private final Executor mExecutor; private final Executor mExecutor; private final Handler mHandler; private final Handler mHandler; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final KeyguardStateController mKeyguardStateController; private final KeyguardStateController mKeyguardStateController; private final Runnable mSelectionRunnable = this::selectCard; private final Runnable mSelectionRunnable = this::selectCard; private final SharedPreferences mPrefs; private final SharedPreferences mPrefs; Loading @@ -85,6 +87,7 @@ public class WalletScreenController implements Handler handler, Handler handler, UserTracker userTracker, UserTracker userTracker, FalsingManager falsingManager, FalsingManager falsingManager, KeyguardUpdateMonitor keyguardUpdateMonitor, KeyguardStateController keyguardStateController) { KeyguardStateController keyguardStateController) { mContext = context; mContext = context; mWalletClient = walletClient; mWalletClient = walletClient; Loading @@ -92,6 +95,7 @@ public class WalletScreenController implements mExecutor = executor; mExecutor = executor; mHandler = handler; mHandler = handler; mFalsingManager = falsingManager; mFalsingManager = falsingManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardStateController = keyguardStateController; mKeyguardStateController = keyguardStateController; mPrefs = userTracker.getUserContext().getSharedPreferences(TAG, Context.MODE_PRIVATE); mPrefs = userTracker.getUserContext().getSharedPreferences(TAG, Context.MODE_PRIVATE); mWalletView = walletView; mWalletView = walletView; Loading Loading @@ -134,8 +138,13 @@ public class WalletScreenController implements Log.w(TAG, "Invalid selected card index, showing empty state."); Log.w(TAG, "Invalid selected card index, showing empty state."); showEmptyStateView(); showEmptyStateView(); } else { } else { boolean isUdfpsEnabled = mKeyguardUpdateMonitor.isUdfpsEnrolled() && mKeyguardUpdateMonitor.isFingerprintDetectionRunning(); mWalletView.showCardCarousel( mWalletView.showCardCarousel( data, selectedIndex, !mKeyguardStateController.isUnlocked()); data, selectedIndex, !mKeyguardStateController.isUnlocked(), isUdfpsEnabled); } } } } removeMinHeightAndRecordHeightOnLayout(); removeMinHeightAndRecordHeightOnLayout(); Loading packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java +12 −6 Original line number Original line Diff line number Diff line Loading @@ -63,6 +63,7 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard private final ViewGroup mEmptyStateView; private final ViewGroup mEmptyStateView; private CharSequence mCenterCardText; private CharSequence mCenterCardText; private boolean mIsDeviceLocked = false; private boolean mIsDeviceLocked = false; private boolean mIsUdfpsEnabled = false; private OnClickListener mDeviceLockedActionOnClickListener; private OnClickListener mDeviceLockedActionOnClickListener; public WalletView(Context context) { public WalletView(Context context) { Loading Loading @@ -108,7 +109,7 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard mCardLabel.setText(centerCardText); mCardLabel.setText(centerCardText); mIcon.setImageDrawable(centerCardIcon); mIcon.setImageDrawable(centerCardIcon); } } renderActionButton(centerCard, mIsDeviceLocked); renderActionButton(centerCard, mIsDeviceLocked, mIsUdfpsEnabled); if (TextUtils.equals(centerCardText, getLabelText(nextCard))) { if (TextUtils.equals(centerCardText, getLabelText(nextCard))) { mCardLabel.setAlpha(1f); mCardLabel.setAlpha(1f); } else { } else { Loading @@ -128,15 +129,19 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard * @param isDeviceLocked indicates whether the device is locked. * @param isDeviceLocked indicates whether the device is locked. */ */ void showCardCarousel( void showCardCarousel( List<WalletCardViewInfo> data, int selectedIndex, boolean isDeviceLocked) { List<WalletCardViewInfo> data, int selectedIndex, boolean isDeviceLocked, boolean isUdfpsEnabled) { boolean shouldAnimate = boolean shouldAnimate = mCardCarousel.setData(data, selectedIndex, mIsDeviceLocked != isDeviceLocked); mCardCarousel.setData(data, selectedIndex, mIsDeviceLocked != isDeviceLocked); mIsDeviceLocked = isDeviceLocked; mIsDeviceLocked = isDeviceLocked; mIsUdfpsEnabled = isUdfpsEnabled; mCardCarouselContainer.setVisibility(VISIBLE); mCardCarouselContainer.setVisibility(VISIBLE); mErrorView.setVisibility(GONE); mErrorView.setVisibility(GONE); mEmptyStateView.setVisibility(GONE); mEmptyStateView.setVisibility(GONE); mIcon.setImageDrawable(getHeaderIcon(mContext, data.get(selectedIndex))); mIcon.setImageDrawable(getHeaderIcon(mContext, data.get(selectedIndex))); renderActionButton(data.get(selectedIndex), isDeviceLocked); renderActionButton(data.get(selectedIndex), isDeviceLocked, mIsUdfpsEnabled); if (shouldAnimate) { if (shouldAnimate) { animateViewsShown(mIcon, mCardLabel, mActionButton); animateViewsShown(mIcon, mCardLabel, mActionButton); } } Loading Loading @@ -240,13 +245,14 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard return icon; return icon; } } private void renderActionButton(WalletCardViewInfo walletCard, boolean isDeviceLocked) { private void renderActionButton( WalletCardViewInfo walletCard, boolean isDeviceLocked, boolean isUdfpsEnabled) { CharSequence actionButtonText = getActionButtonText(walletCard); CharSequence actionButtonText = getActionButtonText(walletCard); if (isDeviceLocked) { if (!isUdfpsEnabled && isDeviceLocked) { mActionButton.setVisibility(VISIBLE); mActionButton.setVisibility(VISIBLE); mActionButton.setText(R.string.wallet_action_button_label_unlock); mActionButton.setText(R.string.wallet_action_button_label_unlock); mActionButton.setOnClickListener(mDeviceLockedActionOnClickListener); mActionButton.setOnClickListener(mDeviceLockedActionOnClickListener); } else if (actionButtonText != null) { } else if (!isDeviceLocked && actionButtonText != null) { mActionButton.setText(actionButtonText); mActionButton.setText(actionButtonText); mActionButton.setVisibility(VISIBLE); mActionButton.setVisibility(VISIBLE); mActionButton.setOnClickListener(v -> { mActionButton.setOnClickListener(v -> { Loading packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java +56 −5 Original line number Original line Diff line number Diff line Loading @@ -34,7 +34,6 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.graphics.drawable.Icon; import android.os.Handler; import android.os.Handler; import android.service.quickaccesswallet.GetWalletCardsError; import android.service.quickaccesswallet.GetWalletCardsError; import android.service.quickaccesswallet.GetWalletCardsRequest; import android.service.quickaccesswallet.GetWalletCardsResponse; import android.service.quickaccesswallet.GetWalletCardsResponse; import android.service.quickaccesswallet.QuickAccessWalletClient; import android.service.quickaccesswallet.QuickAccessWalletClient; import android.service.quickaccesswallet.QuickAccessWalletService; import android.service.quickaccesswallet.QuickAccessWalletService; Loading @@ -44,6 +43,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.FalsingManager; Loading Loading @@ -89,15 +89,13 @@ public class WalletScreenControllerTest extends SysuiTestCase { @Mock @Mock FalsingManager mFalsingManager; FalsingManager mFalsingManager; @Mock @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor; @Mock KeyguardStateController mKeyguardStateController; KeyguardStateController mKeyguardStateController; @Captor @Captor ArgumentCaptor<Intent> mIntentCaptor; ArgumentCaptor<Intent> mIntentCaptor; @Captor @Captor ArgumentCaptor<GetWalletCardsRequest> mRequestCaptor; @Captor ArgumentCaptor<QuickAccessWalletClient.OnWalletCardsRetrievedCallback> mCallbackCaptor; ArgumentCaptor<QuickAccessWalletClient.OnWalletCardsRetrievedCallback> mCallbackCaptor; @Captor ArgumentCaptor<QuickAccessWalletClient.WalletServiceEventListener> mListenerCaptor; private WalletScreenController mController; private WalletScreenController mController; private TestableLooper mTestableLooper; private TestableLooper mTestableLooper; Loading @@ -114,6 +112,8 @@ public class WalletScreenControllerTest extends SysuiTestCase { when(mWalletClient.getServiceLabel()).thenReturn(SERVICE_LABEL); when(mWalletClient.getServiceLabel()).thenReturn(SERVICE_LABEL); when(mWalletClient.createWalletIntent()).thenReturn(mWalletIntent); when(mWalletClient.createWalletIntent()).thenReturn(mWalletIntent); when(mKeyguardStateController.isUnlocked()).thenReturn(true); when(mKeyguardStateController.isUnlocked()).thenReturn(true); when(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(false); when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false); mController = new WalletScreenController( mController = new WalletScreenController( mContext, mContext, mWalletView, mWalletView, Loading @@ -123,9 +123,60 @@ public class WalletScreenControllerTest extends SysuiTestCase { new Handler(mTestableLooper.getLooper()), new Handler(mTestableLooper.getLooper()), mUserTracker, mUserTracker, mFalsingManager, mFalsingManager, mKeyguardUpdateMonitor, mKeyguardStateController); mKeyguardStateController); } } @Test public void queryCards_deviceLocked_udfpsEnabled_hideUnlockButton() { when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); when(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(true); when(mKeyguardStateController.isUnlocked()).thenReturn(false); GetWalletCardsResponse response = new GetWalletCardsResponse( Collections.singletonList(createWalletCard(mContext)), 0); mController.queryWalletCards(); mTestableLooper.processAllMessages(); verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = mCallbackCaptor.getValue(); assertEquals(mController, callback); callback.onWalletCardsRetrieved(response); mTestableLooper.processAllMessages(); assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility()); assertEquals(GONE, mWalletView.getActionButton().getVisibility()); } @Test public void queryCards_deviceLocked_udfpsNotEnabled_showUnlockButton() { when(mKeyguardStateController.isUnlocked()).thenReturn(false); GetWalletCardsResponse response = new GetWalletCardsResponse( Collections.singletonList(createWalletCard(mContext)), 0); mController.queryWalletCards(); mTestableLooper.processAllMessages(); verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = mCallbackCaptor.getValue(); assertEquals(mController, callback); callback.onWalletCardsRetrieved(response); mTestableLooper.processAllMessages(); assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility()); assertEquals(VISIBLE, mWalletView.getActionButton().getVisibility()); } @Test @Test public void queryCards_hasCards_showCarousel_activeCard() { public void queryCards_hasCards_showCarousel_activeCard() { GetWalletCardsResponse response = GetWalletCardsResponse response = Loading Loading
packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java +29 −3 Original line number Original line Diff line number Diff line Loading @@ -19,8 +19,8 @@ package com.android.systemui.wallet.ui; import static android.provider.Settings.ACTION_LOCKSCREEN_SETTINGS; import static android.provider.Settings.ACTION_LOCKSCREEN_SETTINGS; import android.content.Intent; import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricSourceType; import android.os.Bundle; import android.os.Bundle; import android.os.Handler; import android.os.Handler; import android.service.quickaccesswallet.QuickAccessWalletClient; import android.service.quickaccesswallet.QuickAccessWalletClient; Loading @@ -34,6 +34,9 @@ import android.widget.Toolbar; import androidx.annotation.NonNull; import androidx.annotation.NonNull; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main; Loading Loading @@ -63,7 +66,10 @@ public class WalletActivity extends LifecycleActivity implements private final Handler mHandler; private final Handler mHandler; private final FalsingManager mFalsingManager; private final FalsingManager mFalsingManager; private final UserTracker mUserTracker; private final UserTracker mUserTracker; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final StatusBarKeyguardViewManager mKeyguardViewManager; private final StatusBarKeyguardViewManager mKeyguardViewManager; private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback; private WalletScreenController mWalletScreenController; private WalletScreenController mWalletScreenController; private QuickAccessWalletClient mWalletClient; private QuickAccessWalletClient mWalletClient; private boolean mHasRegisteredListener; private boolean mHasRegisteredListener; Loading @@ -77,6 +83,7 @@ public class WalletActivity extends LifecycleActivity implements @Main Handler handler, @Main Handler handler, FalsingManager falsingManager, FalsingManager falsingManager, UserTracker userTracker, UserTracker userTracker, KeyguardUpdateMonitor keyguardUpdateMonitor, StatusBarKeyguardViewManager keyguardViewManager) { StatusBarKeyguardViewManager keyguardViewManager) { mKeyguardStateController = keyguardStateController; mKeyguardStateController = keyguardStateController; mKeyguardDismissUtil = keyguardDismissUtil; mKeyguardDismissUtil = keyguardDismissUtil; Loading @@ -85,6 +92,7 @@ public class WalletActivity extends LifecycleActivity implements mHandler = handler; mHandler = handler; mFalsingManager = falsingManager; mFalsingManager = falsingManager; mUserTracker = userTracker; mUserTracker = userTracker; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardViewManager = keyguardViewManager; mKeyguardViewManager = keyguardViewManager; } } Loading Loading @@ -116,7 +124,17 @@ public class WalletActivity extends LifecycleActivity implements mHandler, mHandler, mUserTracker, mUserTracker, mFalsingManager, mFalsingManager, mKeyguardUpdateMonitor, mKeyguardStateController); mKeyguardStateController); mKeyguardUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() { @Override public void onBiometricRunningStateChanged( boolean running, BiometricSourceType biometricSourceType) { Log.d(TAG, "Biometric running state has changed."); mWalletScreenController.queryWalletCards(); } }; walletView.getAppButton().setOnClickListener( walletView.getAppButton().setOnClickListener( v -> { v -> { Loading Loading @@ -146,7 +164,9 @@ public class WalletActivity extends LifecycleActivity implements // Click the action button to re-render the screen when the device is unlocked. // Click the action button to re-render the screen when the device is unlocked. walletView.setDeviceLockedActionOnClickListener( walletView.setDeviceLockedActionOnClickListener( v -> { v -> { Log.d(TAG, "Wallet action button is clicked."); if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { Log.d(TAG, "False tap detected on wallet action button."); return; return; } } Loading @@ -164,13 +184,17 @@ public class WalletActivity extends LifecycleActivity implements mHasRegisteredListener = true; mHasRegisteredListener = true; } } mKeyguardStateController.addCallback(mWalletScreenController); mKeyguardStateController.addCallback(mWalletScreenController); mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback); } } @Override @Override protected void onResume() { protected void onResume() { super.onResume(); super.onResume(); mWalletScreenController.queryWalletCards(); mWalletScreenController.queryWalletCards(); mKeyguardViewManager.requestFp(true, Color.BLACK); mKeyguardViewManager.requestFp( true, Utils.getColorAttrDefaultColor( this, com.android.internal.R.attr.colorAccentPrimary)); mKeyguardViewManager.requestFace(true); mKeyguardViewManager.requestFace(true); } } Loading @@ -195,7 +219,6 @@ public class WalletActivity extends LifecycleActivity implements public void onWalletServiceEvent(WalletServiceEvent event) { public void onWalletServiceEvent(WalletServiceEvent event) { switch (event.getEventType()) { switch (event.getEventType()) { case WalletServiceEvent.TYPE_NFC_PAYMENT_STARTED: case WalletServiceEvent.TYPE_NFC_PAYMENT_STARTED: finish(); break; break; case WalletServiceEvent.TYPE_WALLET_CARDS_UPDATED: case WalletServiceEvent.TYPE_WALLET_CARDS_UPDATED: mWalletScreenController.queryWalletCards(); mWalletScreenController.queryWalletCards(); Loading Loading @@ -224,6 +247,9 @@ public class WalletActivity extends LifecycleActivity implements @Override @Override protected void onDestroy() { protected void onDestroy() { mKeyguardStateController.removeCallback(mWalletScreenController); mKeyguardStateController.removeCallback(mWalletScreenController); if (mKeyguardUpdateMonitorCallback != null) { mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback); } mWalletScreenController.onDismissed(); mWalletScreenController.onDismissed(); mWalletClient.removeWalletServiceEventListener(this); mWalletClient.removeWalletServiceEventListener(this); mHasRegisteredListener = false; mHasRegisteredListener = false; Loading
packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java +10 −1 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.widget.FrameLayout; import androidx.annotation.NonNull; import androidx.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.FalsingManager; Loading Loading @@ -66,6 +67,7 @@ public class WalletScreenController implements private final ActivityStarter mActivityStarter; private final ActivityStarter mActivityStarter; private final Executor mExecutor; private final Executor mExecutor; private final Handler mHandler; private final Handler mHandler; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final KeyguardStateController mKeyguardStateController; private final KeyguardStateController mKeyguardStateController; private final Runnable mSelectionRunnable = this::selectCard; private final Runnable mSelectionRunnable = this::selectCard; private final SharedPreferences mPrefs; private final SharedPreferences mPrefs; Loading @@ -85,6 +87,7 @@ public class WalletScreenController implements Handler handler, Handler handler, UserTracker userTracker, UserTracker userTracker, FalsingManager falsingManager, FalsingManager falsingManager, KeyguardUpdateMonitor keyguardUpdateMonitor, KeyguardStateController keyguardStateController) { KeyguardStateController keyguardStateController) { mContext = context; mContext = context; mWalletClient = walletClient; mWalletClient = walletClient; Loading @@ -92,6 +95,7 @@ public class WalletScreenController implements mExecutor = executor; mExecutor = executor; mHandler = handler; mHandler = handler; mFalsingManager = falsingManager; mFalsingManager = falsingManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardStateController = keyguardStateController; mKeyguardStateController = keyguardStateController; mPrefs = userTracker.getUserContext().getSharedPreferences(TAG, Context.MODE_PRIVATE); mPrefs = userTracker.getUserContext().getSharedPreferences(TAG, Context.MODE_PRIVATE); mWalletView = walletView; mWalletView = walletView; Loading Loading @@ -134,8 +138,13 @@ public class WalletScreenController implements Log.w(TAG, "Invalid selected card index, showing empty state."); Log.w(TAG, "Invalid selected card index, showing empty state."); showEmptyStateView(); showEmptyStateView(); } else { } else { boolean isUdfpsEnabled = mKeyguardUpdateMonitor.isUdfpsEnrolled() && mKeyguardUpdateMonitor.isFingerprintDetectionRunning(); mWalletView.showCardCarousel( mWalletView.showCardCarousel( data, selectedIndex, !mKeyguardStateController.isUnlocked()); data, selectedIndex, !mKeyguardStateController.isUnlocked(), isUdfpsEnabled); } } } } removeMinHeightAndRecordHeightOnLayout(); removeMinHeightAndRecordHeightOnLayout(); Loading
packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java +12 −6 Original line number Original line Diff line number Diff line Loading @@ -63,6 +63,7 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard private final ViewGroup mEmptyStateView; private final ViewGroup mEmptyStateView; private CharSequence mCenterCardText; private CharSequence mCenterCardText; private boolean mIsDeviceLocked = false; private boolean mIsDeviceLocked = false; private boolean mIsUdfpsEnabled = false; private OnClickListener mDeviceLockedActionOnClickListener; private OnClickListener mDeviceLockedActionOnClickListener; public WalletView(Context context) { public WalletView(Context context) { Loading Loading @@ -108,7 +109,7 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard mCardLabel.setText(centerCardText); mCardLabel.setText(centerCardText); mIcon.setImageDrawable(centerCardIcon); mIcon.setImageDrawable(centerCardIcon); } } renderActionButton(centerCard, mIsDeviceLocked); renderActionButton(centerCard, mIsDeviceLocked, mIsUdfpsEnabled); if (TextUtils.equals(centerCardText, getLabelText(nextCard))) { if (TextUtils.equals(centerCardText, getLabelText(nextCard))) { mCardLabel.setAlpha(1f); mCardLabel.setAlpha(1f); } else { } else { Loading @@ -128,15 +129,19 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard * @param isDeviceLocked indicates whether the device is locked. * @param isDeviceLocked indicates whether the device is locked. */ */ void showCardCarousel( void showCardCarousel( List<WalletCardViewInfo> data, int selectedIndex, boolean isDeviceLocked) { List<WalletCardViewInfo> data, int selectedIndex, boolean isDeviceLocked, boolean isUdfpsEnabled) { boolean shouldAnimate = boolean shouldAnimate = mCardCarousel.setData(data, selectedIndex, mIsDeviceLocked != isDeviceLocked); mCardCarousel.setData(data, selectedIndex, mIsDeviceLocked != isDeviceLocked); mIsDeviceLocked = isDeviceLocked; mIsDeviceLocked = isDeviceLocked; mIsUdfpsEnabled = isUdfpsEnabled; mCardCarouselContainer.setVisibility(VISIBLE); mCardCarouselContainer.setVisibility(VISIBLE); mErrorView.setVisibility(GONE); mErrorView.setVisibility(GONE); mEmptyStateView.setVisibility(GONE); mEmptyStateView.setVisibility(GONE); mIcon.setImageDrawable(getHeaderIcon(mContext, data.get(selectedIndex))); mIcon.setImageDrawable(getHeaderIcon(mContext, data.get(selectedIndex))); renderActionButton(data.get(selectedIndex), isDeviceLocked); renderActionButton(data.get(selectedIndex), isDeviceLocked, mIsUdfpsEnabled); if (shouldAnimate) { if (shouldAnimate) { animateViewsShown(mIcon, mCardLabel, mActionButton); animateViewsShown(mIcon, mCardLabel, mActionButton); } } Loading Loading @@ -240,13 +245,14 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard return icon; return icon; } } private void renderActionButton(WalletCardViewInfo walletCard, boolean isDeviceLocked) { private void renderActionButton( WalletCardViewInfo walletCard, boolean isDeviceLocked, boolean isUdfpsEnabled) { CharSequence actionButtonText = getActionButtonText(walletCard); CharSequence actionButtonText = getActionButtonText(walletCard); if (isDeviceLocked) { if (!isUdfpsEnabled && isDeviceLocked) { mActionButton.setVisibility(VISIBLE); mActionButton.setVisibility(VISIBLE); mActionButton.setText(R.string.wallet_action_button_label_unlock); mActionButton.setText(R.string.wallet_action_button_label_unlock); mActionButton.setOnClickListener(mDeviceLockedActionOnClickListener); mActionButton.setOnClickListener(mDeviceLockedActionOnClickListener); } else if (actionButtonText != null) { } else if (!isDeviceLocked && actionButtonText != null) { mActionButton.setText(actionButtonText); mActionButton.setText(actionButtonText); mActionButton.setVisibility(VISIBLE); mActionButton.setVisibility(VISIBLE); mActionButton.setOnClickListener(v -> { mActionButton.setOnClickListener(v -> { Loading
packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java +56 −5 Original line number Original line Diff line number Diff line Loading @@ -34,7 +34,6 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.graphics.drawable.Icon; import android.os.Handler; import android.os.Handler; import android.service.quickaccesswallet.GetWalletCardsError; import android.service.quickaccesswallet.GetWalletCardsError; import android.service.quickaccesswallet.GetWalletCardsRequest; import android.service.quickaccesswallet.GetWalletCardsResponse; import android.service.quickaccesswallet.GetWalletCardsResponse; import android.service.quickaccesswallet.QuickAccessWalletClient; import android.service.quickaccesswallet.QuickAccessWalletClient; import android.service.quickaccesswallet.QuickAccessWalletService; import android.service.quickaccesswallet.QuickAccessWalletService; Loading @@ -44,6 +43,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.FalsingManager; Loading Loading @@ -89,15 +89,13 @@ public class WalletScreenControllerTest extends SysuiTestCase { @Mock @Mock FalsingManager mFalsingManager; FalsingManager mFalsingManager; @Mock @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor; @Mock KeyguardStateController mKeyguardStateController; KeyguardStateController mKeyguardStateController; @Captor @Captor ArgumentCaptor<Intent> mIntentCaptor; ArgumentCaptor<Intent> mIntentCaptor; @Captor @Captor ArgumentCaptor<GetWalletCardsRequest> mRequestCaptor; @Captor ArgumentCaptor<QuickAccessWalletClient.OnWalletCardsRetrievedCallback> mCallbackCaptor; ArgumentCaptor<QuickAccessWalletClient.OnWalletCardsRetrievedCallback> mCallbackCaptor; @Captor ArgumentCaptor<QuickAccessWalletClient.WalletServiceEventListener> mListenerCaptor; private WalletScreenController mController; private WalletScreenController mController; private TestableLooper mTestableLooper; private TestableLooper mTestableLooper; Loading @@ -114,6 +112,8 @@ public class WalletScreenControllerTest extends SysuiTestCase { when(mWalletClient.getServiceLabel()).thenReturn(SERVICE_LABEL); when(mWalletClient.getServiceLabel()).thenReturn(SERVICE_LABEL); when(mWalletClient.createWalletIntent()).thenReturn(mWalletIntent); when(mWalletClient.createWalletIntent()).thenReturn(mWalletIntent); when(mKeyguardStateController.isUnlocked()).thenReturn(true); when(mKeyguardStateController.isUnlocked()).thenReturn(true); when(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(false); when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false); mController = new WalletScreenController( mController = new WalletScreenController( mContext, mContext, mWalletView, mWalletView, Loading @@ -123,9 +123,60 @@ public class WalletScreenControllerTest extends SysuiTestCase { new Handler(mTestableLooper.getLooper()), new Handler(mTestableLooper.getLooper()), mUserTracker, mUserTracker, mFalsingManager, mFalsingManager, mKeyguardUpdateMonitor, mKeyguardStateController); mKeyguardStateController); } } @Test public void queryCards_deviceLocked_udfpsEnabled_hideUnlockButton() { when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true); when(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(true); when(mKeyguardStateController.isUnlocked()).thenReturn(false); GetWalletCardsResponse response = new GetWalletCardsResponse( Collections.singletonList(createWalletCard(mContext)), 0); mController.queryWalletCards(); mTestableLooper.processAllMessages(); verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = mCallbackCaptor.getValue(); assertEquals(mController, callback); callback.onWalletCardsRetrieved(response); mTestableLooper.processAllMessages(); assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility()); assertEquals(GONE, mWalletView.getActionButton().getVisibility()); } @Test public void queryCards_deviceLocked_udfpsNotEnabled_showUnlockButton() { when(mKeyguardStateController.isUnlocked()).thenReturn(false); GetWalletCardsResponse response = new GetWalletCardsResponse( Collections.singletonList(createWalletCard(mContext)), 0); mController.queryWalletCards(); mTestableLooper.processAllMessages(); verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture()); QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback = mCallbackCaptor.getValue(); assertEquals(mController, callback); callback.onWalletCardsRetrieved(response); mTestableLooper.processAllMessages(); assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility()); assertEquals(VISIBLE, mWalletView.getActionButton().getVisibility()); } @Test @Test public void queryCards_hasCards_showCarousel_activeCard() { public void queryCards_hasCards_showCarousel_activeCard() { GetWalletCardsResponse response = GetWalletCardsResponse response = Loading