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
This commit is contained in:
@@ -153,25 +153,9 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
|
||||
});
|
||||
}
|
||||
|
||||
@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();
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<GetWalletCardsRequest> 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);
|
||||
|
||||
Reference in New Issue
Block a user