Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f672c54 authored by Silin Huang's avatar Silin Huang Committed by android-build-team Robot
Browse files

Recreate QuickAccessWallet for Wallet Tile and Lockscreen Icon when the...

Recreate QuickAccessWallet for Wallet Tile and Lockscreen Icon when the default payment app has changed.

Also to avoid a wallet client that doesn't have ServiceInfo is living
too long, don't make it final and re-create the wallet client if it has a null service info.

Fix: 187972400
Test: manual, see demo- the default payment app is GPay, check Tile and
Lockscreen Icon, then change the default payment app and check again.
https://drive.google.com/file/d/10-I339VPuxJRGXJT-XmwmnZs4MHaH3gm/view?usp=sharing&resourcekey=0-wDtRXNNr_Tg9ptxk1Tpxsw

Change-Id: Ie9a05795bff447424b299132fa60ae2efb2092be
(cherry picked from commit bda8ed85a711776dae6ecdd3dfa647b0f9aea9ae)
parent a0fee7da
Loading
Loading
Loading
Loading
+60 −6
Original line number Diff line number Diff line
@@ -20,9 +20,11 @@ import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.service.quickaccesswallet.GetWalletCardsError;
import android.service.quickaccesswallet.GetWalletCardsRequest;
import android.service.quickaccesswallet.GetWalletCardsResponse;
@@ -66,16 +68,16 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {

    private final CharSequence mLabel = mContext.getString(R.string.wallet_title);
    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 PackageManager mPackageManager;
    private final SecureSettings mSecureSettings;
    private final Executor mExecutor;
    private final FeatureFlags mFeatureFlags;

    @VisibleForTesting Drawable mCardViewDrawable;
    private QuickAccessWalletClient mQuickAccessWalletClient;
    private ContentObserver mDefaultPaymentAppObserver;
    private WalletCard mSelectedCard;
    @VisibleForTesting Drawable mCardViewDrawable;

    @Inject
    public QuickAccessWalletTile(
@@ -87,15 +89,14 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
            StatusBarStateController statusBarStateController,
            ActivityStarter activityStarter,
            QSLogger qsLogger,
            QuickAccessWalletClient quickAccessWalletClient,
            KeyguardStateController keyguardStateController,
            PackageManager packageManager,
            SecureSettings secureSettings,
            @Background Executor executor,
            @Main Executor executor,
            FeatureFlags featureFlags) {
        super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                statusBarStateController, activityStarter, qsLogger);
        mQuickAccessWalletClient = quickAccessWalletClient;
        mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext);
        mKeyguardStateController = keyguardStateController;
        mPackageManager = packageManager;
        mSecureSettings = secureSettings;
@@ -115,6 +116,12 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
    protected void handleSetListening(boolean listening) {
        super.handleSetListening(listening);
        if (listening) {
            setupDefaultPaymentAppObserver();
            // Re-create wallet client to avoid a client that doesn't have service info is living
            // too long.
            if (!mQuickAccessWalletClient.isWalletServiceAvailable()) {
                reCreateWalletClient();
            }
            queryWalletCards();
        }
    }
@@ -174,6 +181,7 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
            state.stateDescription = state.secondaryLabel;
        } else {
            state.state = Tile.STATE_UNAVAILABLE;
            state.secondaryLabel = null;
        }
        state.sideViewCustomDrawable = isDeviceLocked ? null : mCardViewDrawable;
    }
@@ -202,7 +210,30 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
        return label == null ? mLabel : label;
    }

    @Override
    protected void handleDestroy() {
        super.handleDestroy();
        if (mDefaultPaymentAppObserver != null) {
            mSecureSettings.unregisterContentObserver(mDefaultPaymentAppObserver);
        }
        mQuickAccessWalletClient = null;
    }

    @VisibleForTesting
    void overrideQuickAccessWalletClientForTest(QuickAccessWalletClient quickAccessWalletClient) {
        mQuickAccessWalletClient = quickAccessWalletClient;
    }

    @VisibleForTesting
    QuickAccessWalletClient getQuickAccessWalletClient() {
        return mQuickAccessWalletClient;
    }

    private void queryWalletCards() {
        if (!mQuickAccessWalletClient.isWalletFeatureAvailable()) {
            Log.w(TAG, "QAW feature not unavailable, unable to query wallet cards,");
            return;
        }
        int cardWidth =
                mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_width);
        int cardHeight =
@@ -213,6 +244,29 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
        mQuickAccessWalletClient.getWalletCards(mExecutor, request, mCardRetriever);
    }

    private void reCreateWalletClient() {
        mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext);
    }

    private void setupDefaultPaymentAppObserver() {
        if (mDefaultPaymentAppObserver == null) {
            mDefaultPaymentAppObserver = new ContentObserver(null /* handler */) {
                @Override
                public void onChange(boolean selfChange) {
                    mExecutor.execute(() -> {
                        reCreateWalletClient();
                        queryWalletCards();
                    });
                }
            };

            mSecureSettings.registerContentObserver(
                    Settings.Secure.getUriFor(Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT),
                    false /* notifyForDescendants */,
                    mDefaultPaymentAppObserver);
        }
    }

    private class WalletCardRetriever implements
            QuickAccessWalletClient.OnWalletCardsRetrievedCallback {

+30 −5
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
    private ActivityIntentHelper mActivityIntentHelper;
    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    private ContentObserver mWalletPreferenceObserver;
    private ContentObserver mDefaultPaymentAppObserver;
    private SecureSettings mSecureSettings;

    public KeyguardBottomAreaView(Context context) {
@@ -335,6 +336,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
        if (mWalletPreferenceObserver != null) {
            mSecureSettings.unregisterContentObserver(mWalletPreferenceObserver);
        }
        if (mDefaultPaymentAppObserver != null) {
            mSecureSettings.unregisterContentObserver(mDefaultPaymentAppObserver);
        }
    }

    private void initAccessibility() {
@@ -935,9 +939,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
    /**
     * Initialize the wallet feature, only enabling if the feature is enabled within the platform.
     */
    public void initWallet(QuickAccessWalletClient client, Executor uiExecutor,
            SecureSettings secureSettings) {
        mQuickAccessWalletClient = client;
    public void initWallet(Executor uiExecutor, SecureSettings secureSettings) {
        mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext);
        mSecureSettings = secureSettings;
        setupWalletPreferenceObserver();
        updateWalletPreference();
@@ -953,7 +956,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
            mWalletPreferenceObserver = new ContentObserver(null /* handler */) {
                @Override
                public void onChange(boolean selfChange) {
                    mUiExecutor.execute(() -> updateWalletPreference());
                    mUiExecutor.execute(() -> {
                        updateWalletPreference();
                    });
                }
            };

@@ -962,10 +967,30 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
                    false /* notifyForDescendants */,
                    mWalletPreferenceObserver);
        }

        if (mDefaultPaymentAppObserver == null) {
            mDefaultPaymentAppObserver = new ContentObserver(null /* handler */) {
                @Override
                public void onChange(boolean selfChange) {
                    mUiExecutor.execute(() -> {
                        mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext);
                        updateWalletPreference();
                        queryWalletCards();
                        updateWalletVisibility();
                    });
                }
            };

            mSecureSettings.registerContentObserver(
                    Settings.Secure.getUriFor(Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT),
                    false /* notifyForDescendants */,
                    mDefaultPaymentAppObserver);
        }
    }

    private void updateWalletPreference() {
        mWalletEnabled = mQuickAccessWalletClient.isWalletFeatureAvailable()
        mWalletEnabled = mQuickAccessWalletClient.isWalletServiceAvailable()
                && mQuickAccessWalletClient.isWalletFeatureAvailable()
                && mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked();
    }

+1 −5
Original line number Diff line number Diff line
@@ -54,7 +54,6 @@ import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserManager;
import android.os.VibrationEffect;
import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.util.Log;
import android.util.MathUtils;
import android.view.DisplayCutout;
@@ -573,7 +572,6 @@ public class NotificationPanelViewController extends PanelViewController {
    private int mScreenCornerRadius;
    private int mNotificationScrimPadding;

    private final QuickAccessWalletClient mQuickAccessWalletClient;
    private final Executor mUiExecutor;
    private final SecureSettings mSecureSettings;

@@ -649,7 +647,6 @@ public class NotificationPanelViewController extends PanelViewController {
            AmbientState ambientState,
            LockIconViewController lockIconViewController,
            FeatureFlags featureFlags,
            QuickAccessWalletClient quickAccessWalletClient,
            KeyguardMediaController keyguardMediaController,
            PrivacyDotViewController privacyDotViewController,
            @Main Executor uiExecutor,
@@ -703,7 +700,6 @@ public class NotificationPanelViewController extends PanelViewController {
        mScrimController.setClipsQsScrim(!mShouldUseSplitNotificationShade);
        mUserManager = userManager;
        mMediaDataManager = mediaDataManager;
        mQuickAccessWalletClient = quickAccessWalletClient;
        mUiExecutor = uiExecutor;
        mSecureSettings = secureSettings;
        pulseExpansionHandler.setPulseExpandAbortListener(() -> {
@@ -1098,7 +1094,7 @@ public class NotificationPanelViewController extends PanelViewController {
        mKeyguardBottomArea.setFalsingManager(mFalsingManager);

        if (mFeatureFlags.isQuickAccessWalletEnabled()) {
            mKeyguardBottomArea.initWallet(mQuickAccessWalletClient, mUiExecutor, mSecureSettings);
            mKeyguardBottomArea.initWallet(mUiExecutor, mSecureSettings);
        }
    }

+10 −6
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
@@ -52,7 +53,7 @@ import javax.inject.Inject;
 */
public class WalletActivity extends LifecycleActivity {

    private final QuickAccessWalletClient mQuickAccessWalletClient;
    private static final String TAG = "WalletActivity";
    private final KeyguardStateController mKeyguardStateController;
    private final KeyguardDismissUtil mKeyguardDismissUtil;
    private final ActivityStarter mActivityStarter;
@@ -65,7 +66,6 @@ public class WalletActivity extends LifecycleActivity {

    @Inject
    public WalletActivity(
            QuickAccessWalletClient quickAccessWalletClient,
            KeyguardStateController keyguardStateController,
            KeyguardDismissUtil keyguardDismissUtil,
            ActivityStarter activityStarter,
@@ -74,7 +74,6 @@ public class WalletActivity extends LifecycleActivity {
            FalsingManager falsingManager,
            UserTracker userTracker,
            StatusBarKeyguardViewManager keyguardViewManager) {
        mQuickAccessWalletClient = quickAccessWalletClient;
        mKeyguardStateController = keyguardStateController;
        mKeyguardDismissUtil = keyguardDismissUtil;
        mActivityStarter = activityStarter;
@@ -103,10 +102,11 @@ public class WalletActivity extends LifecycleActivity {
        getActionBar().setHomeActionContentDescription(R.string.accessibility_desc_close);
        WalletView walletView = requireViewById(R.id.wallet_view);

        QuickAccessWalletClient walletClient = QuickAccessWalletClient.create(this);
        mWalletScreenController = new WalletScreenController(
                this,
                walletView,
                mQuickAccessWalletClient,
                walletClient,
                mActivityStarter,
                mExecutor,
                mHandler,
@@ -116,6 +116,10 @@ public class WalletActivity extends LifecycleActivity {

        walletView.getAppButton().setOnClickListener(
                v -> {
                    if (walletClient.createWalletIntent() == null) {
                        Log.w(TAG, "Unable to create wallet app intent.");
                        return;
                    }
                    if (!mKeyguardStateController.isUnlocked()
                            && mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
                        return;
@@ -123,12 +127,12 @@ public class WalletActivity extends LifecycleActivity {

                    if (mKeyguardStateController.isUnlocked()) {
                        mActivityStarter.startActivity(
                                mQuickAccessWalletClient.createWalletIntent(), true);
                                walletClient.createWalletIntent(), true);
                        finish();
                    } else {
                        mKeyguardDismissUtil.executeWhenUnlocked(() -> {
                            mActivityStarter.startActivity(
                                    mQuickAccessWalletClient.createWalletIntent(), true);
                                    walletClient.createWalletIntent(), true);
                            finish();
                            return false;
                        }, false, true);
+11 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT;

import static com.google.common.truth.Truth.assertThat;

import static junit.framework.Assert.assertNotSame;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertNotNull;
@@ -155,12 +156,12 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
                mStatusBarStateController,
                mActivityStarter,
                mQSLogger,
                mQuickAccessWalletClient,
                mKeyguardStateController,
                mPackageManager,
                mSecureSettings,
                MoreExecutors.directExecutor(),
                mFeatureFlags);
        mTile.overrideQuickAccessWalletClientForTest(mQuickAccessWalletClient);
    }

    @Test
@@ -174,6 +175,15 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
        assertFalse(mTile.isAvailable());
    }

    @Test
    public void testWalletServiceUnavailable_recreateWalletClient() {
        when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(false);

        mTile.handleSetListening(true);

        assertNotSame(mQuickAccessWalletClient, mTile.getQuickAccessWalletClient());
    }

    @Test
    public void testIsAvailable_qawFeatureAvailable() {
        when(mPackageManager.hasSystemFeature(FEATURE_NFC_HOST_CARD_EMULATION)).thenReturn(true);
Loading