From afe19132578a599c1803d1177905791e51ba111e Mon Sep 17 00:00:00 2001 From: Silin Huang Date: Fri, 16 Jul 2021 14:25:58 -0700 Subject: [PATCH] Recreate the Wallet client before query the wallet cards with a time window. The previous approach won't working because we can't catch the IOException in the tile; so we need to avoid using a staled QAW client, and the re-create call is relatively cheap. The re-creation will happen at most once per 10-minute time window. Test: atest Fixes: 188789272 Change-Id: I2c4dd25d4eb7a983c7ca7870fdba147ff8452a3d --- .../qs/tiles/QuickAccessWalletTile.java | 18 +-------------- .../QuickAccessWalletController.java | 16 ++++++++++++- .../qs/tiles/QuickAccessWalletTileTest.java | 14 ----------- .../QuickAccessWalletControllerTest.java | 23 ++++++++++++++++++- 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java index ab81ac1fd577c..82b6c0c1805d4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java @@ -153,25 +153,9 @@ public class QuickAccessWalletTile extends QSTileImpl { }); } - @Nullable - private CharSequence getServiceLabelSafe() { - try { - return mController.getWalletClient().getServiceLabel(); - } catch (RuntimeException e) { - Log.e(TAG, "Failed to get the service label safely, recreating wallet client", e); - mController.reCreateWalletClient(); - try { - return mController.getWalletClient().getServiceLabel(); - } catch (RuntimeException e2) { - Log.e(TAG, "The QAW service label is broken.", e2); - return null; - } - } - } - @Override protected void handleUpdateState(State state, Object arg) { - CharSequence label = getServiceLabelSafe(); + CharSequence label = mController.getWalletClient().getServiceLabel(); state.label = label == null ? mLabel : label; state.contentDescription = state.label; Drawable tileIcon = mController.getWalletClient().getTileIcon(); diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java index 0ecc4e25047f9..4a4f2e9710dd4 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java @@ -31,8 +31,10 @@ 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 com.android.systemui.util.time.SystemClock; import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; import javax.inject.Inject; @@ -52,9 +54,11 @@ public class QuickAccessWalletController { } private static final String TAG = "QAWController"; + private static final long RECREATION_TIME_WINDOW = TimeUnit.MINUTES.toMillis(10L); private final Context mContext; private final Executor mExecutor; private final SecureSettings mSecureSettings; + private final SystemClock mClock; private QuickAccessWalletClient mQuickAccessWalletClient; private ContentObserver mWalletPreferenceObserver; @@ -62,17 +66,21 @@ public class QuickAccessWalletController { private int mWalletPreferenceChangeEvents = 0; private int mDefaultPaymentAppChangeEvents = 0; private boolean mWalletEnabled = false; + private long mQawClientCreatedTimeMillis; @Inject public QuickAccessWalletController( Context context, @Main Executor executor, SecureSettings secureSettings, - QuickAccessWalletClient quickAccessWalletClient) { + QuickAccessWalletClient quickAccessWalletClient, + SystemClock clock) { mContext = context; mExecutor = executor; mSecureSettings = secureSettings; mQuickAccessWalletClient = quickAccessWalletClient; + mClock = clock; + mQawClientCreatedTimeMillis = mClock.elapsedRealtime(); } /** @@ -143,6 +151,11 @@ public class QuickAccessWalletController { */ public void queryWalletCards( QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever) { + if (mClock.elapsedRealtime() - mQawClientCreatedTimeMillis + > RECREATION_TIME_WINDOW) { + Log.i(TAG, "Re-creating the QAW client to avoid stale."); + reCreateWalletClient(); + } if (!mQuickAccessWalletClient.isWalletFeatureAvailable()) { Log.d(TAG, "QuickAccessWallet feature is not available."); return; @@ -162,6 +175,7 @@ public class QuickAccessWalletController { */ public void reCreateWalletClient() { mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext); + mQawClientCreatedTimeMillis = mClock.elapsedRealtime(); } private void setupDefaultPaymentAppObserver( diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java index 17797b70c4af2..a70c2be4954e1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java @@ -30,7 +30,6 @@ 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.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -256,19 +255,6 @@ public class QuickAccessWalletTileTest extends SysuiTestCase { assertThat(nextStartedIntent.getComponent().getClassName()).isEqualTo(walletClassName); } - @Test - public void testGetServiceLabelUnsafe_recreateWalletClient() { - doAnswer(invocation -> { - throw new Exception("Bad service label."); - }).when(mQuickAccessWalletClient).getServiceLabel(); - - QSTile.State state = new QSTile.State(); - - mTile.handleUpdateState(state, null); - - verify(mController).reCreateWalletClient(); - } - @Test public void testHandleUpdateState_updateLabelAndIcon() { QSTile.State state = new QSTile.State(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java index ce0098e7672ca..72a329a0f0ba6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java @@ -37,6 +37,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.settings.SecureSettings; +import com.android.systemui.util.time.FakeSystemClock; import com.google.common.util.concurrent.MoreExecutors; @@ -62,6 +63,7 @@ public class QuickAccessWalletControllerTest extends SysuiTestCase { @Captor private ArgumentCaptor mRequestCaptor; + private FakeSystemClock mClock = new FakeSystemClock(); private QuickAccessWalletController mController; @Before @@ -70,12 +72,14 @@ public class QuickAccessWalletControllerTest extends SysuiTestCase { when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true); when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true); when(mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked()).thenReturn(true); + mClock.setElapsedRealtime(100L); mController = new QuickAccessWalletController( mContext, MoreExecutors.directExecutor(), mSecureSettings, - mQuickAccessWalletClient); + mQuickAccessWalletClient, + mClock); } @Test @@ -124,6 +128,23 @@ public class QuickAccessWalletControllerTest extends SysuiTestCase { assertNotSame(mQuickAccessWalletClient, mController.getWalletClient()); } + @Test + public void queryWalletCards_avoidStale_recreateClient() { + // advance current time by 100 seconds, should not recreate the client. + mClock.setElapsedRealtime(100100L); + + mController.queryWalletCards(mCardsRetriever); + + assertSame(mQuickAccessWalletClient, mController.getWalletClient()); + + // advance current time by another 501 seconds, should recreate the client. + mClock.setElapsedRealtime(601100L); + + mController.queryWalletCards(mCardsRetriever); + + assertNotSame(mQuickAccessWalletClient, mController.getWalletClient()); + } + @Test public void queryWalletCards_walletEnabled_queryCards() { mController.queryWalletCards(mCardsRetriever);