Merge "Recreate QuickAccessWallet for Wallet Tile and Lockscreen Icon when the default payment app has changed." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
1d4a672528
@@ -18,13 +18,14 @@ package com.android.systemui.qs.tiles;
|
|||||||
|
|
||||||
import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT;
|
import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT;
|
||||||
|
|
||||||
|
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
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.WalletCard;
|
import android.service.quickaccesswallet.WalletCard;
|
||||||
@@ -51,6 +52,7 @@ import com.android.systemui.qs.tileimpl.QSTileImpl;
|
|||||||
import com.android.systemui.statusbar.FeatureFlags;
|
import com.android.systemui.statusbar.FeatureFlags;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
import com.android.systemui.wallet.controller.QuickAccessWalletController;
|
||||||
import com.android.systemui.wallet.ui.WalletActivity;
|
import com.android.systemui.wallet.ui.WalletActivity;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -66,16 +68,15 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
|
|||||||
|
|
||||||
private final CharSequence mLabel = mContext.getString(R.string.wallet_title);
|
private final CharSequence mLabel = mContext.getString(R.string.wallet_title);
|
||||||
private final WalletCardRetriever mCardRetriever = new WalletCardRetriever();
|
private final WalletCardRetriever mCardRetriever = new WalletCardRetriever();
|
||||||
// TODO(b/180959290): Re-create the QAW Client when the default NFC payment app changes.
|
|
||||||
private final QuickAccessWalletClient mQuickAccessWalletClient;
|
|
||||||
private final KeyguardStateController mKeyguardStateController;
|
private final KeyguardStateController mKeyguardStateController;
|
||||||
private final PackageManager mPackageManager;
|
private final PackageManager mPackageManager;
|
||||||
private final SecureSettings mSecureSettings;
|
private final SecureSettings mSecureSettings;
|
||||||
private final Executor mExecutor;
|
private final Executor mExecutor;
|
||||||
|
private final QuickAccessWalletController mController;
|
||||||
private final FeatureFlags mFeatureFlags;
|
private final FeatureFlags mFeatureFlags;
|
||||||
|
|
||||||
@VisibleForTesting Drawable mCardViewDrawable;
|
|
||||||
private WalletCard mSelectedCard;
|
private WalletCard mSelectedCard;
|
||||||
|
@VisibleForTesting Drawable mCardViewDrawable;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public QuickAccessWalletTile(
|
public QuickAccessWalletTile(
|
||||||
@@ -87,15 +88,15 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
|
|||||||
StatusBarStateController statusBarStateController,
|
StatusBarStateController statusBarStateController,
|
||||||
ActivityStarter activityStarter,
|
ActivityStarter activityStarter,
|
||||||
QSLogger qsLogger,
|
QSLogger qsLogger,
|
||||||
QuickAccessWalletClient quickAccessWalletClient,
|
|
||||||
KeyguardStateController keyguardStateController,
|
KeyguardStateController keyguardStateController,
|
||||||
PackageManager packageManager,
|
PackageManager packageManager,
|
||||||
SecureSettings secureSettings,
|
SecureSettings secureSettings,
|
||||||
@Background Executor executor,
|
@Main Executor executor,
|
||||||
|
QuickAccessWalletController quickAccessWalletController,
|
||||||
FeatureFlags featureFlags) {
|
FeatureFlags featureFlags) {
|
||||||
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
|
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
|
||||||
statusBarStateController, activityStarter, qsLogger);
|
statusBarStateController, activityStarter, qsLogger);
|
||||||
mQuickAccessWalletClient = quickAccessWalletClient;
|
mController = quickAccessWalletController;
|
||||||
mKeyguardStateController = keyguardStateController;
|
mKeyguardStateController = keyguardStateController;
|
||||||
mPackageManager = packageManager;
|
mPackageManager = packageManager;
|
||||||
mSecureSettings = secureSettings;
|
mSecureSettings = secureSettings;
|
||||||
@@ -115,7 +116,11 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
|
|||||||
protected void handleSetListening(boolean listening) {
|
protected void handleSetListening(boolean listening) {
|
||||||
super.handleSetListening(listening);
|
super.handleSetListening(listening);
|
||||||
if (listening) {
|
if (listening) {
|
||||||
queryWalletCards();
|
mController.setupWalletChangeObservers(mCardRetriever, DEFAULT_PAYMENT_APP_CHANGE);
|
||||||
|
if (!mController.getWalletClient().isWalletServiceAvailable()) {
|
||||||
|
mController.reCreateWalletClient();
|
||||||
|
}
|
||||||
|
mController.queryWalletCards(mCardRetriever);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,12 +144,13 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
|
|||||||
mContext.startActivity(intent);
|
mContext.startActivity(intent);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mQuickAccessWalletClient.createWalletIntent() == null) {
|
if (mController.getWalletClient().createWalletIntent() == null) {
|
||||||
Log.w(TAG, "Could not get intent of the wallet app.");
|
Log.w(TAG, "Could not get intent of the wallet app.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mActivityStarter.postStartActivityDismissingKeyguard(
|
mActivityStarter.postStartActivityDismissingKeyguard(
|
||||||
mQuickAccessWalletClient.createWalletIntent(), /* delay= */ 0,
|
mController.getWalletClient().createWalletIntent(),
|
||||||
|
/* delay= */ 0,
|
||||||
animationController);
|
animationController);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -152,30 +158,34 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleUpdateState(State state, Object arg) {
|
protected void handleUpdateState(State state, Object arg) {
|
||||||
CharSequence label = mQuickAccessWalletClient.getServiceLabel();
|
CharSequence label = mController.getWalletClient().getServiceLabel();
|
||||||
state.label = label == null ? mLabel : label;
|
state.label = label == null ? mLabel : label;
|
||||||
state.contentDescription = state.label;
|
state.contentDescription = state.label;
|
||||||
state.icon = ResourceIcon.get(R.drawable.ic_wallet_lockscreen);
|
state.icon = ResourceIcon.get(R.drawable.ic_wallet_lockscreen);
|
||||||
boolean isDeviceLocked = !mKeyguardStateController.isUnlocked();
|
boolean isDeviceLocked = !mKeyguardStateController.isUnlocked();
|
||||||
if (mQuickAccessWalletClient.isWalletServiceAvailable()) {
|
if (mController.getWalletClient().isWalletServiceAvailable()) {
|
||||||
if (mSelectedCard != null) {
|
if (mSelectedCard != null) {
|
||||||
if (isDeviceLocked) {
|
if (isDeviceLocked) {
|
||||||
state.state = Tile.STATE_INACTIVE;
|
state.state = Tile.STATE_INACTIVE;
|
||||||
state.secondaryLabel =
|
state.secondaryLabel =
|
||||||
mContext.getString(R.string.wallet_secondary_label_device_locked);
|
mContext.getString(R.string.wallet_secondary_label_device_locked);
|
||||||
|
state.sideViewCustomDrawable = null;
|
||||||
} else {
|
} else {
|
||||||
state.state = Tile.STATE_ACTIVE;
|
state.state = Tile.STATE_ACTIVE;
|
||||||
state.secondaryLabel = mSelectedCard.getContentDescription();
|
state.secondaryLabel = mSelectedCard.getContentDescription();
|
||||||
|
state.sideViewCustomDrawable = mCardViewDrawable;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
state.state = Tile.STATE_INACTIVE;
|
state.state = Tile.STATE_INACTIVE;
|
||||||
state.secondaryLabel = mContext.getString(R.string.wallet_secondary_label_no_card);
|
state.secondaryLabel = mContext.getString(R.string.wallet_secondary_label_no_card);
|
||||||
|
state.sideViewCustomDrawable = null;
|
||||||
}
|
}
|
||||||
state.stateDescription = state.secondaryLabel;
|
state.stateDescription = state.secondaryLabel;
|
||||||
} else {
|
} else {
|
||||||
state.state = Tile.STATE_UNAVAILABLE;
|
state.state = Tile.STATE_UNAVAILABLE;
|
||||||
|
state.secondaryLabel = null;
|
||||||
|
state.sideViewCustomDrawable = null;
|
||||||
}
|
}
|
||||||
state.sideViewCustomDrawable = isDeviceLocked ? null : mCardViewDrawable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -198,19 +208,14 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getTileLabel() {
|
public CharSequence getTileLabel() {
|
||||||
CharSequence label = mQuickAccessWalletClient.getServiceLabel();
|
CharSequence label = mController.getWalletClient().getServiceLabel();
|
||||||
return label == null ? mLabel : label;
|
return label == null ? mLabel : label;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void queryWalletCards() {
|
@Override
|
||||||
int cardWidth =
|
protected void handleDestroy() {
|
||||||
mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_width);
|
super.handleDestroy();
|
||||||
int cardHeight =
|
mController.unregisterWalletChangeObservers(DEFAULT_PAYMENT_APP_CHANGE);
|
||||||
mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_height);
|
|
||||||
int iconSizePx = mContext.getResources().getDimensionPixelSize(R.dimen.wallet_icon_size);
|
|
||||||
GetWalletCardsRequest request =
|
|
||||||
new GetWalletCardsRequest(cardWidth, cardHeight, iconSizePx, /* maxCards= */ 1);
|
|
||||||
mQuickAccessWalletClient.getWalletCards(mExecutor, request, mCardRetriever);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class WalletCardRetriever implements
|
private class WalletCardRetriever implements
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTT
|
|||||||
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
|
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
|
||||||
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON;
|
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON;
|
||||||
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_UNLOCK;
|
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_UNLOCK;
|
||||||
|
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE;
|
||||||
|
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
@@ -39,7 +41,6 @@ import android.content.pm.ActivityInfo;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.database.ContentObserver;
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -49,13 +50,10 @@ import android.os.Messenger;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.provider.Settings;
|
|
||||||
import android.service.media.CameraPrewarmService;
|
import android.service.media.CameraPrewarmService;
|
||||||
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.QuickAccessWalletClientImpl;
|
|
||||||
import android.telecom.TelecomManager;
|
import android.telecom.TelecomManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@@ -71,7 +69,6 @@ import android.widget.ImageView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
@@ -97,11 +94,9 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
|
|||||||
import com.android.systemui.statusbar.policy.PreviewInflater;
|
import com.android.systemui.statusbar.policy.PreviewInflater;
|
||||||
import com.android.systemui.tuner.LockscreenFragment.LockButtonFactory;
|
import com.android.systemui.tuner.LockscreenFragment.LockButtonFactory;
|
||||||
import com.android.systemui.tuner.TunerService;
|
import com.android.systemui.tuner.TunerService;
|
||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.wallet.controller.QuickAccessWalletController;
|
||||||
import com.android.systemui.wallet.ui.WalletActivity;
|
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
|
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
|
||||||
* text.
|
* text.
|
||||||
@@ -137,10 +132,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
private KeyguardAffordanceView mLeftAffordanceView;
|
private KeyguardAffordanceView mLeftAffordanceView;
|
||||||
|
|
||||||
private ImageView mWalletButton;
|
private ImageView mWalletButton;
|
||||||
private boolean mWalletEnabled = false;
|
|
||||||
private boolean mHasCard = false;
|
private boolean mHasCard = false;
|
||||||
private WalletCardRetriever mCardRetriever = new WalletCardRetriever();
|
private WalletCardRetriever mCardRetriever = new WalletCardRetriever();
|
||||||
private QuickAccessWalletClient mQuickAccessWalletClient;
|
private QuickAccessWalletController mQuickAccessWalletController;
|
||||||
|
|
||||||
private ViewGroup mIndicationArea;
|
private ViewGroup mIndicationArea;
|
||||||
private TextView mIndicationText;
|
private TextView mIndicationText;
|
||||||
@@ -159,7 +153,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
private StatusBar mStatusBar;
|
private StatusBar mStatusBar;
|
||||||
private KeyguardAffordanceHelper mAffordanceHelper;
|
private KeyguardAffordanceHelper mAffordanceHelper;
|
||||||
private FalsingManager mFalsingManager;
|
private FalsingManager mFalsingManager;
|
||||||
@Nullable private Executor mUiExecutor;
|
|
||||||
private boolean mUserSetupComplete;
|
private boolean mUserSetupComplete;
|
||||||
private boolean mPrewarmBound;
|
private boolean mPrewarmBound;
|
||||||
private Messenger mPrewarmMessenger;
|
private Messenger mPrewarmMessenger;
|
||||||
@@ -193,8 +186,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
private int mBurnInYOffset;
|
private int mBurnInYOffset;
|
||||||
private ActivityIntentHelper mActivityIntentHelper;
|
private ActivityIntentHelper mActivityIntentHelper;
|
||||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||||
private ContentObserver mWalletPreferenceObserver;
|
|
||||||
private SecureSettings mSecureSettings;
|
|
||||||
|
|
||||||
public KeyguardBottomAreaView(Context context) {
|
public KeyguardBottomAreaView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@@ -332,8 +323,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
getContext().unregisterReceiver(mDevicePolicyReceiver);
|
getContext().unregisterReceiver(mDevicePolicyReceiver);
|
||||||
mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
|
mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
|
||||||
|
|
||||||
if (mWalletPreferenceObserver != null) {
|
if (mQuickAccessWalletController != null) {
|
||||||
mSecureSettings.unregisterContentObserver(mWalletPreferenceObserver);
|
mQuickAccessWalletController.unregisterWalletChangeObservers(
|
||||||
|
WALLET_PREFERENCE_CHANGE, DEFAULT_PAYMENT_APP_CHANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,7 +448,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateWalletVisibility() {
|
private void updateWalletVisibility() {
|
||||||
if (mDozing || !mWalletEnabled || !mHasCard) {
|
if (mDozing
|
||||||
|
|| mQuickAccessWalletController == null
|
||||||
|
|| !mQuickAccessWalletController.isWalletEnabled()
|
||||||
|
|| !mHasCard) {
|
||||||
mWalletButton.setVisibility(GONE);
|
mWalletButton.setVisibility(GONE);
|
||||||
mIndicationArea.setPadding(0, 0, 0, 0);
|
mIndicationArea.setPadding(0, 0, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
@@ -690,7 +685,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
@Override
|
@Override
|
||||||
public void onKeyguardShowingChanged() {
|
public void onKeyguardShowingChanged() {
|
||||||
if (mKeyguardStateController.isShowing()) {
|
if (mKeyguardStateController.isShowing()) {
|
||||||
queryWalletCards();
|
if (mQuickAccessWalletController != null) {
|
||||||
|
mQuickAccessWalletController.queryWalletCards(mCardRetriever);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -935,50 +932,17 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
/**
|
/**
|
||||||
* Initialize the wallet feature, only enabling if the feature is enabled within the platform.
|
* Initialize the wallet feature, only enabling if the feature is enabled within the platform.
|
||||||
*/
|
*/
|
||||||
public void initWallet(QuickAccessWalletClient client, Executor uiExecutor,
|
public void initWallet(
|
||||||
SecureSettings secureSettings) {
|
QuickAccessWalletController controller) {
|
||||||
mQuickAccessWalletClient = client;
|
mQuickAccessWalletController = controller;
|
||||||
mSecureSettings = secureSettings;
|
mQuickAccessWalletController.setupWalletChangeObservers(
|
||||||
setupWalletPreferenceObserver();
|
mCardRetriever, WALLET_PREFERENCE_CHANGE, DEFAULT_PAYMENT_APP_CHANGE);
|
||||||
updateWalletPreference();
|
mQuickAccessWalletController.updateWalletPreference();
|
||||||
|
mQuickAccessWalletController.queryWalletCards(mCardRetriever);
|
||||||
mUiExecutor = uiExecutor;
|
|
||||||
queryWalletCards();
|
|
||||||
|
|
||||||
updateWalletVisibility();
|
updateWalletVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupWalletPreferenceObserver() {
|
|
||||||
if (mWalletPreferenceObserver == null) {
|
|
||||||
mWalletPreferenceObserver = new ContentObserver(null /* handler */) {
|
|
||||||
@Override
|
|
||||||
public void onChange(boolean selfChange) {
|
|
||||||
mUiExecutor.execute(() -> updateWalletPreference());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mSecureSettings.registerContentObserver(
|
|
||||||
Settings.Secure.getUriFor(QuickAccessWalletClientImpl.SETTING_KEY),
|
|
||||||
false /* notifyForDescendants */,
|
|
||||||
mWalletPreferenceObserver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateWalletPreference() {
|
|
||||||
mWalletEnabled = mQuickAccessWalletClient.isWalletFeatureAvailable()
|
|
||||||
&& mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void queryWalletCards() {
|
|
||||||
if (!mWalletEnabled || mUiExecutor == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
GetWalletCardsRequest request =
|
|
||||||
new GetWalletCardsRequest(1 /* cardWidth */, 1 /* cardHeight */,
|
|
||||||
1 /* iconSizePx */, 1 /* maxCards */);
|
|
||||||
mQuickAccessWalletClient.getWalletCards(mUiExecutor, request, mCardRetriever);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onWalletClick(View v) {
|
private void onWalletClick(View v) {
|
||||||
// More coming here; need to inform the user about how to proceed
|
// More coming here; need to inform the user about how to proceed
|
||||||
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
@@ -991,12 +955,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
mContext.startActivity(intent);
|
mContext.startActivity(intent);
|
||||||
} else {
|
} else {
|
||||||
if (mQuickAccessWalletClient.createWalletIntent() == null) {
|
if (mQuickAccessWalletController.getWalletClient().createWalletIntent() == null) {
|
||||||
Log.w(TAG, "Could not get intent of the wallet app.");
|
Log.w(TAG, "Could not get intent of the wallet app.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mActivityStarter.postStartActivityDismissingKeyguard(
|
mActivityStarter.postStartActivityDismissingKeyguard(
|
||||||
mQuickAccessWalletClient.createWalletIntent(), /* delay= */ 0);
|
mQuickAccessWalletController.getWalletClient().createWalletIntent(),
|
||||||
|
/* delay= */ 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ import android.os.PowerManager;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.os.VibrationEffect;
|
import android.os.VibrationEffect;
|
||||||
import android.service.quickaccesswallet.QuickAccessWalletClient;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.MathUtils;
|
import android.util.MathUtils;
|
||||||
import android.view.DisplayCutout;
|
import android.view.DisplayCutout;
|
||||||
@@ -153,6 +152,7 @@ import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
|
|||||||
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
|
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
|
||||||
import com.android.systemui.util.Utils;
|
import com.android.systemui.util.Utils;
|
||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
import com.android.systemui.wallet.controller.QuickAccessWalletController;
|
||||||
import com.android.wm.shell.animation.FlingAnimationUtils;
|
import com.android.wm.shell.animation.FlingAnimationUtils;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
@@ -310,6 +310,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
private final FeatureFlags mFeatureFlags;
|
private final FeatureFlags mFeatureFlags;
|
||||||
private final ScrimController mScrimController;
|
private final ScrimController mScrimController;
|
||||||
private final PrivacyDotViewController mPrivacyDotViewController;
|
private final PrivacyDotViewController mPrivacyDotViewController;
|
||||||
|
private final QuickAccessWalletController mQuickAccessWalletController;
|
||||||
|
|
||||||
// Maximum # notifications to show on Keyguard; extras will be collapsed in an overflow card.
|
// Maximum # notifications to show on Keyguard; extras will be collapsed in an overflow card.
|
||||||
// If there are exactly 1 + mMaxKeyguardNotifications, then still shows all notifications
|
// If there are exactly 1 + mMaxKeyguardNotifications, then still shows all notifications
|
||||||
@@ -584,7 +585,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
private int mNotificationScrimPadding;
|
private int mNotificationScrimPadding;
|
||||||
private boolean mQSAnimatingHiddenFromCollapsed;
|
private boolean mQSAnimatingHiddenFromCollapsed;
|
||||||
|
|
||||||
private final QuickAccessWalletClient mQuickAccessWalletClient;
|
|
||||||
private final Executor mUiExecutor;
|
private final Executor mUiExecutor;
|
||||||
private final SecureSettings mSecureSettings;
|
private final SecureSettings mSecureSettings;
|
||||||
|
|
||||||
@@ -665,11 +665,11 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
AmbientState ambientState,
|
AmbientState ambientState,
|
||||||
LockIconViewController lockIconViewController,
|
LockIconViewController lockIconViewController,
|
||||||
FeatureFlags featureFlags,
|
FeatureFlags featureFlags,
|
||||||
QuickAccessWalletClient quickAccessWalletClient,
|
|
||||||
KeyguardMediaController keyguardMediaController,
|
KeyguardMediaController keyguardMediaController,
|
||||||
PrivacyDotViewController privacyDotViewController,
|
PrivacyDotViewController privacyDotViewController,
|
||||||
TapAgainViewController tapAgainViewController,
|
TapAgainViewController tapAgainViewController,
|
||||||
FragmentService fragmentService,
|
FragmentService fragmentService,
|
||||||
|
QuickAccessWalletController quickAccessWalletController,
|
||||||
@Main Executor uiExecutor,
|
@Main Executor uiExecutor,
|
||||||
SecureSettings secureSettings) {
|
SecureSettings secureSettings) {
|
||||||
super(view, falsingManager, dozeLog, keyguardStateController,
|
super(view, falsingManager, dozeLog, keyguardStateController,
|
||||||
@@ -680,6 +680,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
mVibratorHelper = vibratorHelper;
|
mVibratorHelper = vibratorHelper;
|
||||||
mKeyguardMediaController = keyguardMediaController;
|
mKeyguardMediaController = keyguardMediaController;
|
||||||
mPrivacyDotViewController = privacyDotViewController;
|
mPrivacyDotViewController = privacyDotViewController;
|
||||||
|
mQuickAccessWalletController = quickAccessWalletController;
|
||||||
mMetricsLogger = metricsLogger;
|
mMetricsLogger = metricsLogger;
|
||||||
mActivityManager = activityManager;
|
mActivityManager = activityManager;
|
||||||
mConfigurationController = configurationController;
|
mConfigurationController = configurationController;
|
||||||
@@ -722,7 +723,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
mScrimController.setClipsQsScrim(!mShouldUseSplitNotificationShade);
|
mScrimController.setClipsQsScrim(!mShouldUseSplitNotificationShade);
|
||||||
mUserManager = userManager;
|
mUserManager = userManager;
|
||||||
mMediaDataManager = mediaDataManager;
|
mMediaDataManager = mediaDataManager;
|
||||||
mQuickAccessWalletClient = quickAccessWalletClient;
|
|
||||||
mTapAgainViewController = tapAgainViewController;
|
mTapAgainViewController = tapAgainViewController;
|
||||||
mUiExecutor = uiExecutor;
|
mUiExecutor = uiExecutor;
|
||||||
mSecureSettings = secureSettings;
|
mSecureSettings = secureSettings;
|
||||||
@@ -1123,7 +1123,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
mKeyguardBottomArea.setFalsingManager(mFalsingManager);
|
mKeyguardBottomArea.setFalsingManager(mFalsingManager);
|
||||||
|
|
||||||
if (mFeatureFlags.isQuickAccessWalletEnabled()) {
|
if (mFeatureFlags.isQuickAccessWalletEnabled()) {
|
||||||
mKeyguardBottomArea.initWallet(mQuickAccessWalletClient, mUiExecutor, mSecureSettings);
|
mKeyguardBottomArea.initWallet(mQuickAccessWalletController);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.wallet.controller;
|
||||||
|
|
||||||
|
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE;
|
||||||
|
import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.ContentObserver;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.service.quickaccesswallet.GetWalletCardsRequest;
|
||||||
|
import android.service.quickaccesswallet.QuickAccessWalletClient;
|
||||||
|
import android.service.quickaccesswallet.QuickAccessWalletClientImpl;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller to handle communication between SystemUI and Quick Access Wallet Client.
|
||||||
|
*/
|
||||||
|
@SysUISingleton
|
||||||
|
public class QuickAccessWalletController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event for the wallet status change, e.g. the default payment app change and the wallet
|
||||||
|
* preference change.
|
||||||
|
*/
|
||||||
|
public enum WalletChangeEvent {
|
||||||
|
DEFAULT_PAYMENT_APP_CHANGE,
|
||||||
|
WALLET_PREFERENCE_CHANGE,
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String TAG = "QAWController";
|
||||||
|
private final Context mContext;
|
||||||
|
private final Executor mExecutor;
|
||||||
|
private final SecureSettings mSecureSettings;
|
||||||
|
|
||||||
|
private QuickAccessWalletClient mQuickAccessWalletClient;
|
||||||
|
private ContentObserver mWalletPreferenceObserver;
|
||||||
|
private ContentObserver mDefaultPaymentAppObserver;
|
||||||
|
private int mWalletPreferenceChangeEvents = 0;
|
||||||
|
private int mDefaultPaymentAppChangeEvents = 0;
|
||||||
|
private boolean mWalletEnabled = false;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public QuickAccessWalletController(
|
||||||
|
Context context,
|
||||||
|
@Main Executor executor,
|
||||||
|
SecureSettings secureSettings,
|
||||||
|
QuickAccessWalletClient quickAccessWalletClient) {
|
||||||
|
mContext = context;
|
||||||
|
mExecutor = executor;
|
||||||
|
mSecureSettings = secureSettings;
|
||||||
|
mQuickAccessWalletClient = quickAccessWalletClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the Quick Access Wallet service & feature is available.
|
||||||
|
*/
|
||||||
|
public boolean isWalletEnabled() {
|
||||||
|
return mWalletEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current instance of {@link QuickAccessWalletClient} in the controller.
|
||||||
|
*/
|
||||||
|
public QuickAccessWalletClient getWalletClient() {
|
||||||
|
return mQuickAccessWalletClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the wallet change observers per {@link WalletChangeEvent}
|
||||||
|
*
|
||||||
|
* @param cardsRetriever a callback that retrieves the wallet cards
|
||||||
|
* @param events {@link WalletChangeEvent} need to be handled.
|
||||||
|
*/
|
||||||
|
public void setupWalletChangeObservers(
|
||||||
|
QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever,
|
||||||
|
WalletChangeEvent... events) {
|
||||||
|
for (WalletChangeEvent event : events) {
|
||||||
|
if (event == WALLET_PREFERENCE_CHANGE) {
|
||||||
|
setupWalletPreferenceObserver();
|
||||||
|
} else if (event == DEFAULT_PAYMENT_APP_CHANGE) {
|
||||||
|
setupDefaultPaymentAppObserver(cardsRetriever);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister wallet change observers per {@link WalletChangeEvent} if needed.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void unregisterWalletChangeObservers(WalletChangeEvent... events) {
|
||||||
|
for (WalletChangeEvent event : events) {
|
||||||
|
if (event == WALLET_PREFERENCE_CHANGE && mWalletPreferenceObserver != null) {
|
||||||
|
mWalletPreferenceChangeEvents--;
|
||||||
|
if (mWalletPreferenceChangeEvents == 0) {
|
||||||
|
mSecureSettings.unregisterContentObserver(mWalletPreferenceObserver);
|
||||||
|
}
|
||||||
|
} else if (event == DEFAULT_PAYMENT_APP_CHANGE && mDefaultPaymentAppObserver != null) {
|
||||||
|
mDefaultPaymentAppChangeEvents--;
|
||||||
|
if (mDefaultPaymentAppChangeEvents == 0) {
|
||||||
|
mSecureSettings.unregisterContentObserver(mDefaultPaymentAppObserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the "show wallet" preference.
|
||||||
|
*/
|
||||||
|
public void updateWalletPreference() {
|
||||||
|
mWalletEnabled = mQuickAccessWalletClient.isWalletServiceAvailable()
|
||||||
|
&& mQuickAccessWalletClient.isWalletFeatureAvailable()
|
||||||
|
&& mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query the wallet cards from {@link QuickAccessWalletClient}.
|
||||||
|
*
|
||||||
|
* @param cardsRetriever a callback to retrieve wallet cards.
|
||||||
|
*/
|
||||||
|
public void queryWalletCards(
|
||||||
|
QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever) {
|
||||||
|
if (!mWalletEnabled) {
|
||||||
|
Log.w(TAG, "QuickAccessWallet is unavailable, unable to query cards.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int cardWidth =
|
||||||
|
mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_width);
|
||||||
|
int cardHeight =
|
||||||
|
mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_height);
|
||||||
|
int iconSizePx = mContext.getResources().getDimensionPixelSize(R.dimen.wallet_icon_size);
|
||||||
|
GetWalletCardsRequest request =
|
||||||
|
new GetWalletCardsRequest(cardWidth, cardHeight, iconSizePx, /* maxCards= */ 1);
|
||||||
|
mQuickAccessWalletClient.getWalletCards(mExecutor, request, cardsRetriever);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-create the {@link QuickAccessWalletClient} of the controller.
|
||||||
|
*/
|
||||||
|
public void reCreateWalletClient() {
|
||||||
|
mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupDefaultPaymentAppObserver(
|
||||||
|
QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever) {
|
||||||
|
if (mDefaultPaymentAppObserver == null) {
|
||||||
|
mDefaultPaymentAppObserver = new ContentObserver(null /* handler */) {
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
mExecutor.execute(() -> {
|
||||||
|
reCreateWalletClient();
|
||||||
|
updateWalletPreference();
|
||||||
|
queryWalletCards(cardsRetriever);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mSecureSettings.registerContentObserver(
|
||||||
|
Settings.Secure.getUriFor(Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT),
|
||||||
|
false /* notifyForDescendants */,
|
||||||
|
mDefaultPaymentAppObserver);
|
||||||
|
}
|
||||||
|
mDefaultPaymentAppChangeEvents++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupWalletPreferenceObserver() {
|
||||||
|
if (mWalletPreferenceObserver == null) {
|
||||||
|
mWalletPreferenceObserver = new ContentObserver(null /* handler */) {
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
mExecutor.execute(() -> {
|
||||||
|
updateWalletPreference();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mSecureSettings.registerContentObserver(
|
||||||
|
Settings.Secure.getUriFor(QuickAccessWalletClientImpl.SETTING_KEY),
|
||||||
|
false /* notifyForDescendants */,
|
||||||
|
mWalletPreferenceObserver);
|
||||||
|
}
|
||||||
|
mWalletPreferenceChangeEvents++;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable;
|
|||||||
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;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
@@ -52,7 +53,7 @@ import javax.inject.Inject;
|
|||||||
*/
|
*/
|
||||||
public class WalletActivity extends LifecycleActivity {
|
public class WalletActivity extends LifecycleActivity {
|
||||||
|
|
||||||
private final QuickAccessWalletClient mQuickAccessWalletClient;
|
private static final String TAG = "WalletActivity";
|
||||||
private final KeyguardStateController mKeyguardStateController;
|
private final KeyguardStateController mKeyguardStateController;
|
||||||
private final KeyguardDismissUtil mKeyguardDismissUtil;
|
private final KeyguardDismissUtil mKeyguardDismissUtil;
|
||||||
private final ActivityStarter mActivityStarter;
|
private final ActivityStarter mActivityStarter;
|
||||||
@@ -65,7 +66,6 @@ public class WalletActivity extends LifecycleActivity {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public WalletActivity(
|
public WalletActivity(
|
||||||
QuickAccessWalletClient quickAccessWalletClient,
|
|
||||||
KeyguardStateController keyguardStateController,
|
KeyguardStateController keyguardStateController,
|
||||||
KeyguardDismissUtil keyguardDismissUtil,
|
KeyguardDismissUtil keyguardDismissUtil,
|
||||||
ActivityStarter activityStarter,
|
ActivityStarter activityStarter,
|
||||||
@@ -74,7 +74,6 @@ public class WalletActivity extends LifecycleActivity {
|
|||||||
FalsingManager falsingManager,
|
FalsingManager falsingManager,
|
||||||
UserTracker userTracker,
|
UserTracker userTracker,
|
||||||
StatusBarKeyguardViewManager keyguardViewManager) {
|
StatusBarKeyguardViewManager keyguardViewManager) {
|
||||||
mQuickAccessWalletClient = quickAccessWalletClient;
|
|
||||||
mKeyguardStateController = keyguardStateController;
|
mKeyguardStateController = keyguardStateController;
|
||||||
mKeyguardDismissUtil = keyguardDismissUtil;
|
mKeyguardDismissUtil = keyguardDismissUtil;
|
||||||
mActivityStarter = activityStarter;
|
mActivityStarter = activityStarter;
|
||||||
@@ -103,10 +102,11 @@ public class WalletActivity extends LifecycleActivity {
|
|||||||
getActionBar().setHomeActionContentDescription(R.string.accessibility_desc_close);
|
getActionBar().setHomeActionContentDescription(R.string.accessibility_desc_close);
|
||||||
WalletView walletView = requireViewById(R.id.wallet_view);
|
WalletView walletView = requireViewById(R.id.wallet_view);
|
||||||
|
|
||||||
|
QuickAccessWalletClient walletClient = QuickAccessWalletClient.create(this);
|
||||||
mWalletScreenController = new WalletScreenController(
|
mWalletScreenController = new WalletScreenController(
|
||||||
this,
|
this,
|
||||||
walletView,
|
walletView,
|
||||||
mQuickAccessWalletClient,
|
walletClient,
|
||||||
mActivityStarter,
|
mActivityStarter,
|
||||||
mExecutor,
|
mExecutor,
|
||||||
mHandler,
|
mHandler,
|
||||||
@@ -116,6 +116,10 @@ public class WalletActivity extends LifecycleActivity {
|
|||||||
|
|
||||||
walletView.getAppButton().setOnClickListener(
|
walletView.getAppButton().setOnClickListener(
|
||||||
v -> {
|
v -> {
|
||||||
|
if (walletClient.createWalletIntent() == null) {
|
||||||
|
Log.w(TAG, "Unable to create wallet app intent.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!mKeyguardStateController.isUnlocked()
|
if (!mKeyguardStateController.isUnlocked()
|
||||||
&& mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
&& mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
return;
|
return;
|
||||||
@@ -123,12 +127,12 @@ public class WalletActivity extends LifecycleActivity {
|
|||||||
|
|
||||||
if (mKeyguardStateController.isUnlocked()) {
|
if (mKeyguardStateController.isUnlocked()) {
|
||||||
mActivityStarter.startActivity(
|
mActivityStarter.startActivity(
|
||||||
mQuickAccessWalletClient.createWalletIntent(), true);
|
walletClient.createWalletIntent(), true);
|
||||||
finish();
|
finish();
|
||||||
} else {
|
} else {
|
||||||
mKeyguardDismissUtil.executeWhenUnlocked(() -> {
|
mKeyguardDismissUtil.executeWhenUnlocked(() -> {
|
||||||
mActivityStarter.startActivity(
|
mActivityStarter.startActivity(
|
||||||
mQuickAccessWalletClient.createWalletIntent(), true);
|
walletClient.createWalletIntent(), true);
|
||||||
finish();
|
finish();
|
||||||
return false;
|
return false;
|
||||||
}, false, true);
|
}, false, true);
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ import com.android.systemui.qs.tileimpl.QSTileImpl;
|
|||||||
import com.android.systemui.statusbar.FeatureFlags;
|
import com.android.systemui.statusbar.FeatureFlags;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
import com.android.systemui.wallet.controller.QuickAccessWalletController;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
|
|
||||||
@@ -119,6 +120,8 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private SecureSettings mSecureSettings;
|
private SecureSettings mSecureSettings;
|
||||||
@Mock
|
@Mock
|
||||||
|
private QuickAccessWalletController mController;
|
||||||
|
@Mock
|
||||||
private FeatureFlags mFeatureFlags;
|
private FeatureFlags mFeatureFlags;
|
||||||
@Captor
|
@Captor
|
||||||
ArgumentCaptor<Intent> mIntentCaptor;
|
ArgumentCaptor<Intent> mIntentCaptor;
|
||||||
@@ -145,6 +148,8 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
|||||||
when(mQuickAccessWalletClient.getServiceLabel()).thenReturn(LABEL);
|
when(mQuickAccessWalletClient.getServiceLabel()).thenReturn(LABEL);
|
||||||
when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
|
when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
|
||||||
when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true);
|
when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true);
|
||||||
|
when(mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked()).thenReturn(true);
|
||||||
|
when(mController.getWalletClient()).thenReturn(mQuickAccessWalletClient);
|
||||||
|
|
||||||
mTile = new QuickAccessWalletTile(
|
mTile = new QuickAccessWalletTile(
|
||||||
mHost,
|
mHost,
|
||||||
@@ -155,11 +160,11 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
|||||||
mStatusBarStateController,
|
mStatusBarStateController,
|
||||||
mActivityStarter,
|
mActivityStarter,
|
||||||
mQSLogger,
|
mQSLogger,
|
||||||
mQuickAccessWalletClient,
|
|
||||||
mKeyguardStateController,
|
mKeyguardStateController,
|
||||||
mPackageManager,
|
mPackageManager,
|
||||||
mSecureSettings,
|
mSecureSettings,
|
||||||
MoreExecutors.directExecutor(),
|
MoreExecutors.directExecutor(),
|
||||||
|
mController,
|
||||||
mFeatureFlags);
|
mFeatureFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +179,15 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
|||||||
assertFalse(mTile.isAvailable());
|
assertFalse(mTile.isAvailable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWalletServiceUnavailable_recreateWalletClient() {
|
||||||
|
when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(false);
|
||||||
|
|
||||||
|
mTile.handleSetListening(true);
|
||||||
|
|
||||||
|
verify(mController, times(1)).reCreateWalletClient();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsAvailable_qawFeatureAvailable() {
|
public void testIsAvailable_qawFeatureAvailable() {
|
||||||
when(mPackageManager.hasSystemFeature(FEATURE_NFC_HOST_CARD_EMULATION)).thenReturn(true);
|
when(mPackageManager.hasSystemFeature(FEATURE_NFC_HOST_CARD_EMULATION)).thenReturn(true);
|
||||||
@@ -330,17 +344,8 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
|||||||
public void testHandleSetListening_queryCards() {
|
public void testHandleSetListening_queryCards() {
|
||||||
mTile.handleSetListening(true);
|
mTile.handleSetListening(true);
|
||||||
|
|
||||||
verify(mQuickAccessWalletClient)
|
verify(mController).queryWalletCards(mCallbackCaptor.capture());
|
||||||
.getWalletCards(any(), mRequestCaptor.capture(), mCallbackCaptor.capture());
|
|
||||||
|
|
||||||
GetWalletCardsRequest request = mRequestCaptor.getValue();
|
|
||||||
assertEquals(
|
|
||||||
mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_width),
|
|
||||||
request.getCardWidthPx());
|
|
||||||
assertEquals(
|
|
||||||
mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_height),
|
|
||||||
request.getCardHeightPx());
|
|
||||||
assertEquals(1, request.getMaxCards());
|
|
||||||
assertThat(mCallbackCaptor.getValue()).isInstanceOf(
|
assertThat(mCallbackCaptor.getValue()).isInstanceOf(
|
||||||
QuickAccessWalletClient.OnWalletCardsRetrievedCallback.class);
|
QuickAccessWalletClient.OnWalletCardsRetrievedCallback.class);
|
||||||
}
|
}
|
||||||
@@ -353,37 +358,6 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
|||||||
assertNotNull(mTile.getState().sideViewCustomDrawable);
|
assertNotNull(mTile.getState().sideViewCustomDrawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testState_queryCards_hasCards_then_noCards() {
|
|
||||||
when(mKeyguardStateController.isUnlocked()).thenReturn(true);
|
|
||||||
GetWalletCardsResponse responseWithCards =
|
|
||||||
new GetWalletCardsResponse(
|
|
||||||
Collections.singletonList(createWalletCard(mContext)), 0);
|
|
||||||
GetWalletCardsResponse responseWithoutCards =
|
|
||||||
new GetWalletCardsResponse(Collections.EMPTY_LIST, 0);
|
|
||||||
|
|
||||||
mTile.handleSetListening(true);
|
|
||||||
|
|
||||||
verify(mQuickAccessWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
|
|
||||||
|
|
||||||
// query wallet cards, has cards
|
|
||||||
mCallbackCaptor.getValue().onWalletCardsRetrieved(responseWithCards);
|
|
||||||
mTestableLooper.processAllMessages();
|
|
||||||
|
|
||||||
assertNotNull(mTile.getState().sideViewCustomDrawable);
|
|
||||||
|
|
||||||
mTile.handleSetListening(true);
|
|
||||||
|
|
||||||
verify(mQuickAccessWalletClient, times(2))
|
|
||||||
.getWalletCards(any(), any(), mCallbackCaptor.capture());
|
|
||||||
|
|
||||||
// query wallet cards, has no cards
|
|
||||||
mCallbackCaptor.getValue().onWalletCardsRetrieved(responseWithoutCards);
|
|
||||||
mTestableLooper.processAllMessages();
|
|
||||||
|
|
||||||
assertNull(mTile.getState().sideViewCustomDrawable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQueryCards_noCards_notUpdateSideViewDrawable() {
|
public void testQueryCards_noCards_notUpdateSideViewDrawable() {
|
||||||
setUpWalletCard(/* hasCard= */ false);
|
setUpWalletCard(/* hasCard= */ false);
|
||||||
@@ -398,7 +372,7 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
|||||||
|
|
||||||
mTile.handleSetListening(true);
|
mTile.handleSetListening(true);
|
||||||
|
|
||||||
verify(mQuickAccessWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
|
verify(mController).queryWalletCards(mCallbackCaptor.capture());
|
||||||
|
|
||||||
mCallbackCaptor.getValue().onWalletCardRetrievalError(error);
|
mCallbackCaptor.getValue().onWalletCardRetrievalError(error);
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
@@ -422,7 +396,7 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
|||||||
|
|
||||||
mTile.handleSetListening(true);
|
mTile.handleSetListening(true);
|
||||||
|
|
||||||
verify(mQuickAccessWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
|
verify(mController).queryWalletCards(mCallbackCaptor.capture());
|
||||||
|
|
||||||
mCallbackCaptor.getValue().onWalletCardsRetrieved(response);
|
mCallbackCaptor.getValue().onWalletCardsRetrieved(response);
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import android.content.res.Resources;
|
|||||||
import android.hardware.biometrics.BiometricSourceType;
|
import android.hardware.biometrics.BiometricSourceType;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.service.quickaccesswallet.QuickAccessWalletClient;
|
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
@@ -112,6 +111,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
|
|||||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
import com.android.systemui.util.time.FakeSystemClock;
|
import com.android.systemui.util.time.FakeSystemClock;
|
||||||
|
import com.android.systemui.wallet.controller.QuickAccessWalletController;
|
||||||
import com.android.wm.shell.animation.FlingAnimationUtils;
|
import com.android.wm.shell.animation.FlingAnimationUtils;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -252,8 +252,6 @@ public class NotificationPanelViewTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private LockIconViewController mLockIconViewController;
|
private LockIconViewController mLockIconViewController;
|
||||||
@Mock
|
@Mock
|
||||||
private QuickAccessWalletClient mQuickAccessWalletClient;
|
|
||||||
@Mock
|
|
||||||
private KeyguardMediaController mKeyguardMediaController;
|
private KeyguardMediaController mKeyguardMediaController;
|
||||||
@Mock
|
@Mock
|
||||||
private PrivacyDotViewController mPrivacyDotViewController;
|
private PrivacyDotViewController mPrivacyDotViewController;
|
||||||
@@ -267,6 +265,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
|
|||||||
private FragmentService mFragmentService;
|
private FragmentService mFragmentService;
|
||||||
@Mock
|
@Mock
|
||||||
private FragmentHostManager mFragmentHostManager;
|
private FragmentHostManager mFragmentHostManager;
|
||||||
|
@Mock
|
||||||
|
private QuickAccessWalletController mQuickAccessWalletController;
|
||||||
|
|
||||||
private SysuiStatusBarStateController mStatusBarStateController;
|
private SysuiStatusBarStateController mStatusBarStateController;
|
||||||
private NotificationPanelViewController mNotificationPanelViewController;
|
private NotificationPanelViewController mNotificationPanelViewController;
|
||||||
@@ -380,11 +380,11 @@ public class NotificationPanelViewTest extends SysuiTestCase {
|
|||||||
mAmbientState,
|
mAmbientState,
|
||||||
mLockIconViewController,
|
mLockIconViewController,
|
||||||
mFeatureFlags,
|
mFeatureFlags,
|
||||||
mQuickAccessWalletClient,
|
|
||||||
mKeyguardMediaController,
|
mKeyguardMediaController,
|
||||||
mPrivacyDotViewController,
|
mPrivacyDotViewController,
|
||||||
mTapAgainViewController,
|
mTapAgainViewController,
|
||||||
mFragmentService,
|
mFragmentService,
|
||||||
|
mQuickAccessWalletController,
|
||||||
new FakeExecutor(new FakeSystemClock()),
|
new FakeExecutor(new FakeSystemClock()),
|
||||||
mSecureSettings);
|
mSecureSettings);
|
||||||
mNotificationPanelViewController.initDependencies(
|
mNotificationPanelViewController.initDependencies(
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.wallet.controller;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotSame;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.service.quickaccesswallet.GetWalletCardsRequest;
|
||||||
|
import android.service.quickaccesswallet.QuickAccessWalletClient;
|
||||||
|
import android.testing.AndroidTestingRunner;
|
||||||
|
import android.testing.TestableLooper;
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
@RunWith(AndroidTestingRunner.class)
|
||||||
|
@TestableLooper.RunWithLooper
|
||||||
|
@SmallTest
|
||||||
|
public class QuickAccessWalletControllerTest extends SysuiTestCase {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private QuickAccessWalletClient mQuickAccessWalletClient;
|
||||||
|
@Mock
|
||||||
|
private SecureSettings mSecureSettings;
|
||||||
|
@Mock
|
||||||
|
private QuickAccessWalletClient.OnWalletCardsRetrievedCallback mCardsRetriever;
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<GetWalletCardsRequest> mRequestCaptor;
|
||||||
|
|
||||||
|
private QuickAccessWalletController mController;
|
||||||
|
private TestableLooper mTestableLooper;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mTestableLooper = TestableLooper.get(this);
|
||||||
|
when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true);
|
||||||
|
when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
|
||||||
|
when(mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked()).thenReturn(true);
|
||||||
|
|
||||||
|
mController = new QuickAccessWalletController(
|
||||||
|
mContext,
|
||||||
|
MoreExecutors.directExecutor(),
|
||||||
|
mSecureSettings,
|
||||||
|
mQuickAccessWalletClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void walletEnabled() {
|
||||||
|
mController.updateWalletPreference();
|
||||||
|
|
||||||
|
assertTrue(mController.isWalletEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void walletServiceUnavailable_walletNotEnabled() {
|
||||||
|
when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(false);
|
||||||
|
|
||||||
|
mController.updateWalletPreference();
|
||||||
|
|
||||||
|
assertFalse(mController.isWalletEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void walletFeatureUnavailable_walletNotEnabled() {
|
||||||
|
when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(false);
|
||||||
|
|
||||||
|
mController.updateWalletPreference();
|
||||||
|
|
||||||
|
assertFalse(mController.isWalletEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void walletFeatureWhenLockedUnavailable_walletNotEnabled() {
|
||||||
|
when(mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked()).thenReturn(false);
|
||||||
|
|
||||||
|
mController.updateWalletPreference();
|
||||||
|
|
||||||
|
assertFalse(mController.isWalletEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getWalletClient_NoRecreation_sameClient() {
|
||||||
|
assertSame(mQuickAccessWalletClient, mController.getWalletClient());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getWalletClient_reCreateClient_notSameClient() {
|
||||||
|
mController.reCreateWalletClient();
|
||||||
|
|
||||||
|
assertNotSame(mQuickAccessWalletClient, mController.getWalletClient());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryWalletCards_walletNotEnabled_notQuery() {
|
||||||
|
when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(false);
|
||||||
|
|
||||||
|
mController.queryWalletCards(mCardsRetriever);
|
||||||
|
|
||||||
|
verify(mQuickAccessWalletClient, never()).getWalletCards(any(), any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryWalletCards_walletEnabled_queryCards() {
|
||||||
|
mController.updateWalletPreference();
|
||||||
|
mController.queryWalletCards(mCardsRetriever);
|
||||||
|
|
||||||
|
verify(mQuickAccessWalletClient)
|
||||||
|
.getWalletCards(
|
||||||
|
eq(MoreExecutors.directExecutor()),
|
||||||
|
mRequestCaptor.capture(),
|
||||||
|
eq(mCardsRetriever));
|
||||||
|
|
||||||
|
GetWalletCardsRequest request = mRequestCaptor.getValue();
|
||||||
|
assertEquals(1, mRequestCaptor.getValue().getMaxCards());
|
||||||
|
assertEquals(
|
||||||
|
mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_width),
|
||||||
|
request.getCardWidthPx());
|
||||||
|
assertEquals(
|
||||||
|
mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_height),
|
||||||
|
request.getCardHeightPx());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user