Merge "Launch WalletActivity on Wallet Tile clicked." into sc-dev

This commit is contained in:
TreeHugger Robot
2021-04-07 18:43:03 +00:00
committed by Android (Google) Code Review
7 changed files with 116 additions and 23 deletions

View File

@@ -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>

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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();

View File

@@ -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());