Merge "Launch WalletActivity on Wallet Tile clicked." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0047549232
@@ -18,5 +18,6 @@
|
||||
<size
|
||||
android:height="50dp"
|
||||
android:width="50dp" />
|
||||
<solid android:color="#1A73E8" />
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<stroke android:width="2dp" android:color="#AECBFA" />
|
||||
</shape>
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.android.systemui.qs.tileimpl.QSTileImpl;
|
||||
import com.android.systemui.statusbar.FeatureFlags;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
import com.android.systemui.wallet.ui.WalletActivity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -117,8 +118,22 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
|
||||
|
||||
@Override
|
||||
protected void handleClick() {
|
||||
mActivityStarter.postStartActivityDismissingKeyguard(
|
||||
mQuickAccessWalletClient.createWalletIntent(), /* delay= */ 0);
|
||||
mUiHandler.post(() -> {
|
||||
mHost.collapsePanels();
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,9 +162,7 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
|
||||
} else {
|
||||
state.state = Tile.STATE_UNAVAILABLE;
|
||||
}
|
||||
if (!isDeviceLocked) {
|
||||
state.sideViewDrawable = mCardViewDrawable;
|
||||
}
|
||||
state.sideViewDrawable = isDeviceLocked ? null : mCardViewDrawable;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,8 +28,10 @@ import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.util.LifecycleActivity;
|
||||
|
||||
@@ -44,6 +46,7 @@ public class WalletActivity extends LifecycleActivity {
|
||||
|
||||
private final QuickAccessWalletClient mQuickAccessWalletClient;
|
||||
private final KeyguardStateController mKeyguardStateController;
|
||||
private final KeyguardDismissUtil mKeyguardDismissUtil;
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final Executor mExecutor;
|
||||
private final Handler mHandler;
|
||||
@@ -54,12 +57,14 @@ public class WalletActivity extends LifecycleActivity {
|
||||
public WalletActivity(
|
||||
QuickAccessWalletClient quickAccessWalletClient,
|
||||
KeyguardStateController keyguardStateController,
|
||||
KeyguardDismissUtil keyguardDismissUtil,
|
||||
ActivityStarter activityStarter,
|
||||
@Background Executor executor,
|
||||
@Background Handler handler,
|
||||
@Main Handler handler,
|
||||
UserTracker userTracker) {
|
||||
mQuickAccessWalletClient = quickAccessWalletClient;
|
||||
mKeyguardStateController = keyguardStateController;
|
||||
mKeyguardDismissUtil = keyguardDismissUtil;
|
||||
mActivityStarter = activityStarter;
|
||||
mExecutor = executor;
|
||||
mHandler = handler;
|
||||
@@ -88,20 +93,30 @@ public class WalletActivity extends LifecycleActivity {
|
||||
mExecutor,
|
||||
mHandler,
|
||||
mUserTracker,
|
||||
!mKeyguardStateController.isUnlocked());
|
||||
mKeyguardStateController);
|
||||
// Clicking the wallet button will open the wallet app if the device is unlocked; bring up
|
||||
// the security bouncer otherwise.
|
||||
walletView.getWalletButton().setOnClickListener(
|
||||
v -> mActivityStarter.startActivity(
|
||||
mQuickAccessWalletClient.createWalletIntent(), true));
|
||||
v -> {
|
||||
if (mKeyguardStateController.isUnlocked()) {
|
||||
mActivityStarter.startActivity(
|
||||
mQuickAccessWalletClient.createWalletIntent(), true);
|
||||
} else {
|
||||
mKeyguardDismissUtil.executeWhenUnlocked(() -> false, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mKeyguardStateController.addCallback(mWalletScreenController);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mWalletScreenController.queryWalletCards();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,6 +131,7 @@ public class WalletActivity extends LifecycleActivity {
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
mKeyguardStateController.removeCallback(mWalletScreenController);
|
||||
mWalletScreenController.onDismissed();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -52,7 +53,8 @@ import java.util.concurrent.TimeUnit;
|
||||
public class WalletScreenController implements
|
||||
WalletCardCarousel.OnSelectionListener,
|
||||
QuickAccessWalletClient.OnWalletCardsRetrievedCallback,
|
||||
QuickAccessWalletClient.WalletServiceEventListener {
|
||||
QuickAccessWalletClient.WalletServiceEventListener,
|
||||
KeyguardStateController.Callback {
|
||||
|
||||
private static final String TAG = "WalletScreenCtrl";
|
||||
private static final String PREFS_HAS_CARDS = "has_cards";
|
||||
@@ -65,6 +67,7 @@ public class WalletScreenController implements
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final Executor mExecutor;
|
||||
private final Handler mHandler;
|
||||
private final KeyguardStateController mKeyguardStateController;
|
||||
private final Runnable mSelectionRunnable = this::selectCard;
|
||||
private final SharedPreferences mPrefs;
|
||||
private final WalletView mWalletView;
|
||||
@@ -72,7 +75,6 @@ public class WalletScreenController implements
|
||||
|
||||
@VisibleForTesting String mSelectedCardId;
|
||||
@VisibleForTesting boolean mIsDismissed;
|
||||
private boolean mIsDeviceLocked;
|
||||
private boolean mHasRegisteredListener;
|
||||
|
||||
public WalletScreenController(
|
||||
@@ -83,12 +85,13 @@ public class WalletScreenController implements
|
||||
Executor executor,
|
||||
Handler handler,
|
||||
UserTracker userTracker,
|
||||
boolean isDeviceLocked) {
|
||||
KeyguardStateController keyguardStateController) {
|
||||
mContext = context;
|
||||
mWalletClient = walletClient;
|
||||
mActivityStarter = activityStarter;
|
||||
mExecutor = executor;
|
||||
mHandler = handler;
|
||||
mKeyguardStateController = keyguardStateController;
|
||||
mPrefs = userTracker.getUserContext().getSharedPreferences(TAG, Context.MODE_PRIVATE);
|
||||
mWalletView = walletView;
|
||||
mWalletView.setMinimumHeight(getExpectedMinHeight());
|
||||
@@ -105,7 +108,6 @@ public class WalletScreenController implements
|
||||
// to decrease perceived latency.
|
||||
showEmptyStateView();
|
||||
}
|
||||
mIsDeviceLocked = isDeviceLocked;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,11 +124,17 @@ public class WalletScreenController implements
|
||||
for (WalletCard card : walletCards) {
|
||||
data.add(new QAWalletCardViewInfo(mContext, card));
|
||||
}
|
||||
|
||||
// Get on main thread for UI updates.
|
||||
mHandler.post(() -> {
|
||||
if (mIsDismissed) {
|
||||
return;
|
||||
}
|
||||
if (data.isEmpty()) {
|
||||
showEmptyStateView();
|
||||
} else {
|
||||
mWalletView.showCardCarousel(data, response.getSelectedIndex(), mIsDeviceLocked);
|
||||
mWalletView.showCardCarousel(
|
||||
data, response.getSelectedIndex(), !mKeyguardStateController.isUnlocked());
|
||||
}
|
||||
// The empty state view will not be shown preemptively next time if cards were returned
|
||||
mPrefs.edit().putBoolean(PREFS_HAS_CARDS, !data.isEmpty()).apply();
|
||||
@@ -140,10 +148,10 @@ public class WalletScreenController implements
|
||||
*/
|
||||
@Override
|
||||
public void onWalletCardRetrievalError(@NonNull GetWalletCardsError error) {
|
||||
if (mIsDismissed) {
|
||||
return;
|
||||
}
|
||||
mHandler.post(() -> {
|
||||
if (mIsDismissed) {
|
||||
return;
|
||||
}
|
||||
mWalletView.showErrorMessage(error.getMessage());
|
||||
});
|
||||
}
|
||||
@@ -169,6 +177,11 @@ public class WalletScreenController implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyguardFadingAwayChanged() {
|
||||
queryWalletCards();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCardSelected(@NonNull WalletCardViewInfo card) {
|
||||
if (mIsDismissed) {
|
||||
|
||||
@@ -103,7 +103,9 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
|
||||
CharSequence centerCardText = centerCard.getLabel();
|
||||
Drawable icon = centerCard.getIcon();
|
||||
if (icon != null) {
|
||||
mIcon.setImageDrawable(resizeDrawable(getResources(), icon));
|
||||
Drawable drawable = resizeDrawable(getResources(), icon);
|
||||
drawable.setTint(mContext.getColor(R.color.GM2_blue_600));
|
||||
mIcon.setImageDrawable(drawable);
|
||||
mIcon.setVisibility(VISIBLE);
|
||||
} else {
|
||||
mIcon.setVisibility(INVISIBLE);
|
||||
@@ -126,7 +128,6 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
|
||||
mCardCarouselContainer.setVisibility(VISIBLE);
|
||||
mErrorView.setVisibility(GONE);
|
||||
if (isDeviceLocked) {
|
||||
// TODO(b/182964813): Add click action to prompt device unlock.
|
||||
mWalletButton.setText(R.string.wallet_button_label_device_locked);
|
||||
} else {
|
||||
mWalletButton.setText(R.string.wallet_button_label_device_unlocked);
|
||||
|
||||
@@ -30,6 +30,8 @@ import static junit.framework.TestCase.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
@@ -117,10 +119,13 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private FeatureFlags mFeatureFlags;
|
||||
@Captor
|
||||
ArgumentCaptor<Intent> mIntentCaptor;
|
||||
@Captor
|
||||
ArgumentCaptor<GetWalletCardsRequest> mRequestCaptor;
|
||||
@Captor
|
||||
ArgumentCaptor<QuickAccessWalletClient.OnWalletCardsRetrievedCallback> mCallbackCaptor;
|
||||
|
||||
private Context mSpiedContext;
|
||||
private TestableLooper mTestableLooper;
|
||||
private QuickAccessWalletTile mTile;
|
||||
|
||||
@@ -129,8 +134,10 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mTestableLooper = TestableLooper.get(this);
|
||||
mSpiedContext = spy(mContext);
|
||||
|
||||
when(mHost.getContext()).thenReturn(mContext);
|
||||
doNothing().when(mSpiedContext).startActivity(any(Intent.class));
|
||||
when(mHost.getContext()).thenReturn(mSpiedContext);
|
||||
when(mHost.getUiEventLogger()).thenReturn(mUiEventLogger);
|
||||
when(mFeatureFlags.isQuickAccessWalletEnabled()).thenReturn(true);
|
||||
when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
|
||||
@@ -179,15 +186,45 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleClick_openGPay() {
|
||||
public void testHandleClick_noCards_hasIntent_openWalletApp() {
|
||||
Intent intent = new Intent("WalletIntent");
|
||||
when(mQuickAccessWalletClient.createWalletIntent()).thenReturn(intent);
|
||||
setUpWalletCard(/* hasCard= */ false);
|
||||
|
||||
mTile.handleClick();
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
verify(mActivityStarter, times(1))
|
||||
.postStartActivityDismissingKeyguard(eq(intent), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleClick_noCards_noIntent_doNothing() {
|
||||
when(mQuickAccessWalletClient.createWalletIntent()).thenReturn(null);
|
||||
setUpWalletCard(/* hasCard= */ false);
|
||||
|
||||
mTile.handleClick();
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
verifyZeroInteractions(mActivityStarter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleClick_hasCards_startWalletActivity() {
|
||||
setUpWalletCard(/* hasCard= */ true);
|
||||
|
||||
mTile.handleClick();
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
verify(mSpiedContext).startActivity(mIntentCaptor.capture());
|
||||
|
||||
Intent nextStartedIntent = mIntentCaptor.getValue();
|
||||
String walletClassName = "com.android.systemui.wallet.ui.WalletActivity";
|
||||
|
||||
assertNotNull(nextStartedIntent);
|
||||
assertThat(nextStartedIntent.getComponent().getClassName()).isEqualTo(walletClassName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleUpdateState_updateLabelAndIcon() {
|
||||
QSTile.State state = new QSTile.State();
|
||||
|
||||
@@ -51,6 +51,7 @@ import androidx.test.filters.SmallTest;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
|
||||
@@ -85,6 +86,8 @@ public class WalletScreenControllerTest extends SysuiTestCase {
|
||||
ActivityStarter mActivityStarter;
|
||||
@Mock
|
||||
UserTracker mUserTracker;
|
||||
@Mock
|
||||
KeyguardStateController mKeyguardStateController;
|
||||
@Captor
|
||||
ArgumentCaptor<Intent> mIntentCaptor;
|
||||
@Captor
|
||||
@@ -106,6 +109,7 @@ public class WalletScreenControllerTest extends SysuiTestCase {
|
||||
when(mWalletClient.getShortcutShortLabel()).thenReturn(SHORTCUT_SHORT_LABEL);
|
||||
when(mWalletClient.getServiceLabel()).thenReturn(SERVICE_LABEL);
|
||||
when(mWalletClient.createWalletIntent()).thenReturn(mWalletIntent);
|
||||
when(mKeyguardStateController.isUnlocked()).thenReturn(true);
|
||||
mController = new WalletScreenController(
|
||||
mContext,
|
||||
mWalletView,
|
||||
@@ -114,7 +118,7 @@ public class WalletScreenControllerTest extends SysuiTestCase {
|
||||
MoreExecutors.directExecutor(),
|
||||
new Handler(mTestableLooper.getLooper()),
|
||||
mUserTracker,
|
||||
/* isDeviceLocked= */false);
|
||||
mKeyguardStateController);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -205,6 +209,14 @@ public class WalletScreenControllerTest extends SysuiTestCase {
|
||||
assertEquals(MAX_CARDS, request.getMaxCards());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onKeyguardFadingAwayChanged_queryCards() {
|
||||
mController.onKeyguardFadingAwayChanged();
|
||||
|
||||
verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
|
||||
assertEquals(mController, mCallbackCaptor.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCardSelected() {
|
||||
mController.onCardSelected(createCardViewInfo());
|
||||
|
||||
Reference in New Issue
Block a user