Add new config and API for QuickAccessWallet features.

Adds a new configuration attribute for use in
QuickAccessWalletService:
* useTargetActivityForQuickAccess - this is a boolean, false by default.
When true, the system will use the component specified by the
android:targetActivity attribute instead of the SysUi's WalletActivity.

Adds a new API method to QuickAccessWalletService: the method returns a
PendingIntent that can be used in place of the targetActivity specified
in the service's manifest entry. The method is not abstract; by default
it returns null so that existing services will not have to make any
changes to target android T.

To make use of this feature, define a new method in
QuickAccessWalletClient: useTargetActivityForQuickAccess() which
provides the configuration for use by QuickAccessWalletController.

Updates QuickAccessWalletController to define a new method: startQuickAccessUiIntent(),
which reads the configuration as well as whether the service is
providing any cards, and provides a centralized place to launch
the correct Quick Access intent.
The logic there is:
1. If a PendingIntent is provided from the service, use that.
2. If not, check for an active activity from the metadata in XML.
3. If that isn't available OR useTargetActivityForQuickAccess is false and the system is displaying cards, use WalletActivity provided by SystemUi.

Addes tests for QuickAccessWalletController. CTS Test for
QuickAccessWalletClient has new tests in a separate change in the same
topic. In the course of development, discovered that unit tests for
QuickAccessWalletController has been failing for as long as a year. Will
fix that and update in a follow-up.

Test: atest QuickAccessWalletControllerTest
Test: atest QuickAccessWalletClientTest
Bug: 215725263

Change-Id: Ifa3427d5e6f6b02e4afffa40453d1cb0f4f8ed67
This commit is contained in:
Scottie Biddle
2022-01-18 21:33:38 +00:00
parent 2262a4a733
commit 21d16aecd7
12 changed files with 270 additions and 13 deletions

View File

@@ -1642,6 +1642,7 @@ package android {
field public static final int useEmbeddedDex = 16844190; // 0x101059e
field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
field public static final int useLevel = 16843167; // 0x101019f
field public static final int useTargetActivityForQuickAccess;
field public static final int userVisible = 16843409; // 0x1010291
field public static final int usesCleartextTraffic = 16844012; // 0x10104ec
field public static final int usesPermissionFlags = 16844356; // 0x1010644
@@ -38990,6 +38991,7 @@ package android.service.quickaccesswallet {
public abstract class QuickAccessWalletService extends android.app.Service {
ctor public QuickAccessWalletService();
method @Nullable public android.app.PendingIntent getTargetActivityPendingIntent();
method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
method public abstract void onWalletCardSelected(@NonNull android.service.quickaccesswallet.SelectWalletCardRequest);
method public abstract void onWalletCardsRequested(@NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.GetWalletCardsCallback);

View File

@@ -2357,12 +2357,14 @@ package android.service.quickaccesswallet {
method public void disconnect();
method public void getWalletCards(@NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.QuickAccessWalletClient.OnWalletCardsRetrievedCallback);
method public void getWalletCards(@NonNull java.util.concurrent.Executor, @NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.QuickAccessWalletClient.OnWalletCardsRetrievedCallback);
method public void getWalletPendingIntent(@NonNull java.util.concurrent.Executor, @NonNull android.service.quickaccesswallet.QuickAccessWalletClient.WalletPendingIntentCallback);
method public boolean isWalletFeatureAvailable();
method public boolean isWalletFeatureAvailableWhenDeviceLocked();
method public boolean isWalletServiceAvailable();
method public void notifyWalletDismissed();
method public void removeWalletServiceEventListener(@NonNull android.service.quickaccesswallet.QuickAccessWalletClient.WalletServiceEventListener);
method public void selectWalletCard(@NonNull android.service.quickaccesswallet.SelectWalletCardRequest);
method public boolean useTargetActivityForQuickAccess();
}
public static interface QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
@@ -2370,6 +2372,10 @@ package android.service.quickaccesswallet {
method public void onWalletCardsRetrieved(@NonNull android.service.quickaccesswallet.GetWalletCardsResponse);
}
public static interface QuickAccessWalletClient.WalletPendingIntentCallback {
method public void onWalletPendingIntentRetrieved(@Nullable android.app.PendingIntent);
}
public static interface QuickAccessWalletClient.WalletServiceEventListener {
method public void onWalletServiceEvent(@NonNull android.service.quickaccesswallet.WalletServiceEvent);
}

View File

@@ -41,4 +41,6 @@ interface IQuickAccessWalletService {
in IQuickAccessWalletServiceCallbacks callback);
// Unregister an event listener
oneway void unregisterWalletServiceEventListener(in WalletServiceEventListenerRequest request);
}
// Request to get a PendingIntent to launch an activity from which the user can manage their cards.
oneway void onTargetActivityIntentRequested(in IQuickAccessWalletServiceCallbacks callbacks);
}

View File

@@ -16,6 +16,7 @@
package android.service.quickaccesswallet;
import android.app.PendingIntent;
import android.service.quickaccesswallet.GetWalletCardsError;
import android.service.quickaccesswallet.GetWalletCardsResponse;
import android.service.quickaccesswallet.WalletServiceEvent;
@@ -34,4 +35,6 @@ interface IQuickAccessWalletServiceCallbacks {
// Called in response to registerWalletServiceEventListener. May be called multiple times as
// long as the event listener is registered.
oneway void onWalletServiceEvent(in WalletServiceEvent event);
// Called in response to onTargetActivityIntentRequested. May only be called once per request.
oneway void onTargetActivityPendingIntentReceived(in PendingIntent pendingIntent);
}

View File

@@ -20,6 +20,7 @@ import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
@@ -152,6 +153,21 @@ public interface QuickAccessWalletClient extends Closeable {
*/
void disconnect();
/**
* The QuickAccessWalletService may provide a {@link PendingIntent} to start the activity that
* hosts the Wallet view. This is typically the home screen of the Wallet application. If this
* method returns null, the value returned by getWalletIntent() will be used instead.
*/
void getWalletPendingIntent(@NonNull @CallbackExecutor Executor executor,
@NonNull WalletPendingIntentCallback walletPendingIntentCallback);
/**
* Callback for getWalletPendingIntent.
*/
interface WalletPendingIntentCallback {
void onWalletPendingIntentRetrieved(@Nullable PendingIntent walletPendingIntent);
}
/**
* The manifest entry for the QuickAccessWalletService may also publish information about the
* activity that hosts the Wallet view. This is typically the home screen of the Wallet
@@ -212,4 +228,15 @@ public interface QuickAccessWalletClient extends Closeable {
*/
@Nullable
CharSequence getShortcutLongLabel();
/**
* Return whether the system should use the component specified by the
* {@link android:targetActivity} or
* {@link QuickAccessWalletService#getTargetActivityPendingIntent()}
* as the "quick access" , invoked directly by the system.
* If false, the system will use the built-in UI instead of the component specified
* in {@link android:targetActivity} or
* {@link QuickAccessWalletService#getTargetActivityPendingIntent()}.
*/
boolean useTargetActivityForQuickAccess();
}

View File

@@ -24,6 +24,7 @@ import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -67,10 +68,9 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
private final Queue<ApiCaller> mRequestQueue;
private final Map<WalletServiceEventListener, String> mEventListeners;
private boolean mIsConnected;
/**
* Timeout for active service connections (1 minute)
*/
/** Timeout for active service connections (1 minute) */
private static final long SERVICE_CONNECTION_TIMEOUT_MS = 60 * 1000;
@Nullable
private IQuickAccessWalletService mService;
@@ -146,7 +146,6 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
serviceCallback.onGetWalletCardsFailure(new GetWalletCardsError(null, null));
}
});
}
@Override
@@ -246,6 +245,25 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
return createIntent(walletActivity, packageName, ACTION_VIEW_WALLET);
}
@Override
public void getWalletPendingIntent(
@NonNull @CallbackExecutor Executor executor,
@NonNull WalletPendingIntentCallback pendingIntentCallback) {
BaseCallbacks callbacks = new BaseCallbacks() {
@Override
public void onTargetActivityPendingIntentReceived(PendingIntent pendingIntent) {
executor.execute(
() -> pendingIntentCallback.onWalletPendingIntentRetrieved(pendingIntent));
}
};
executeApiCall(new ApiCaller("getTargetActivityPendingIntent") {
@Override
void performApiCall(IQuickAccessWalletService service) throws RemoteException {
service.onTargetActivityIntentRequested(callbacks);
}
});
}
@Override
@Nullable
public Intent createWalletSettingsIntent() {
@@ -330,6 +348,11 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
return mServiceInfo == null ? null : mServiceInfo.getShortcutLongLabel(mContext);
}
@Override
public boolean useTargetActivityForQuickAccess() {
return mServiceInfo.getUseTargetActivityForQuickAccess();
}
private void connect() {
mHandler.post(this::connectInternal);
}
@@ -388,7 +411,7 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
return;
}
mIsConnected = false;
mContext.unbindService(/*conn=*/this);
mContext.unbindService(/*conn=*/ this);
mService = null;
mEventListeners.clear();
mRequestQueue.clear();
@@ -482,5 +505,9 @@ public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Ser
public void onWalletServiceEvent(WalletServiceEvent event) {
throw new IllegalStateException();
}
public void onTargetActivityPendingIntentReceived(PendingIntent pendingIntent) {
throw new IllegalStateException();
}
}
}

View File

@@ -19,6 +19,7 @@ package android.service.quickaccesswallet;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
@@ -238,6 +239,14 @@ public abstract class QuickAccessWalletService extends Service {
mHandler.post(QuickAccessWalletService.this::onWalletDismissed);
}
@Override
public void onTargetActivityIntentRequested(
@NonNull IQuickAccessWalletServiceCallbacks callbacks) {
mHandler.post(
() -> QuickAccessWalletService.this.onTargetActivityIntentRequestedInternal(
callbacks));
}
public void registerWalletServiceEventListener(
@NonNull WalletServiceEventListenerRequest request,
@NonNull IQuickAccessWalletServiceCallbacks callback) {
@@ -257,6 +266,15 @@ public abstract class QuickAccessWalletService extends Service {
new GetWalletCardsCallbackImpl(request, callback, mHandler));
}
private void onTargetActivityIntentRequestedInternal(
IQuickAccessWalletServiceCallbacks callbacks) {
try {
callbacks.onTargetActivityPendingIntentReceived(getTargetActivityPendingIntent());
} catch (RemoteException e) {
Log.w(TAG, "Error returning wallet cards", e);
}
}
@Override
@Nullable
public IBinder onBind(@NonNull Intent intent) {
@@ -318,6 +336,11 @@ public abstract class QuickAccessWalletService extends Service {
mHandler.post(() -> sendWalletServiceEventInternal(serviceEvent));
}
@Nullable
public PendingIntent getTargetActivityPendingIntent() {
return null;
}
private void sendWalletServiceEventInternal(WalletServiceEvent serviceEvent) {
if (mEventListener == null) {
Log.i(TAG, "No dismiss listener registered");

View File

@@ -144,20 +144,23 @@ class QuickAccessWalletServiceInfo {
private final CharSequence mShortcutShortLabel;
@Nullable
private final CharSequence mShortcutLongLabel;
private final boolean mUseTargetActivityForQuickAccess;
private static ServiceMetadata empty() {
return new ServiceMetadata(null, null, null, null);
return new ServiceMetadata(null, null, null, null, false);
}
private ServiceMetadata(
String targetActivity,
String settingsActivity,
CharSequence shortcutShortLabel,
CharSequence shortcutLongLabel) {
CharSequence shortcutLongLabel,
boolean useTargetActivityForQuickAccess) {
mTargetActivity = targetActivity;
mSettingsActivity = settingsActivity;
mShortcutShortLabel = shortcutShortLabel;
mShortcutLongLabel = shortcutLongLabel;
mUseTargetActivityForQuickAccess = useTargetActivityForQuickAccess;
}
}
@@ -191,8 +194,11 @@ class QuickAccessWalletServiceInfo {
R.styleable.QuickAccessWalletService_shortcutShortLabel);
CharSequence shortcutLongLabel = afsAttributes.getText(
R.styleable.QuickAccessWalletService_shortcutLongLabel);
boolean useTargetActivityForQuickAccess = afsAttributes.getBoolean(
R.styleable.QuickAccessWalletService_useTargetActivityForQuickAccess,
false);
return new ServiceMetadata(targetActivity, settingsActivity, shortcutShortLabel,
shortcutLongLabel);
shortcutLongLabel, useTargetActivityForQuickAccess);
} finally {
if (afsAttributes != null) {
afsAttributes.recycle();
@@ -271,4 +277,8 @@ class QuickAccessWalletServiceInfo {
CharSequence getServiceLabel(Context context) {
return mServiceInfo.loadLabel(context.getPackageManager());
}
boolean getUseTargetActivityForQuickAccess() {
return mServiceMetadata.mUseTargetActivityForQuickAccess;
}
}

View File

@@ -8821,7 +8821,8 @@
<attr name="shortcutLongLabel"/>
<!-- Text shown on the button that takes users to the wallet application -->
<attr name="shortcutShortLabel"/>
<!-- When true, launch the component specified in targetActivity for quick access -->
<attr name="useTargetActivityForQuickAccess" format="boolean"/>
</declare-styleable>
<!-- Use <code>recognition-service</code> as the root tag of the XML resource that

View File

@@ -3262,6 +3262,7 @@
<public name="allowGameFpsOverride" />
<public name="localeConfig" />
<public name="showBackground" />
<public name="useTargetActivityForQuickAccess"/>
<public name="inheritKeyStoreKeys" />
<public name="preferKeepClear" />
<public name="autoHandwritingEnabled" />

View File

@@ -19,7 +19,10 @@ 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.annotation.CallbackExecutor;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.provider.Settings;
import android.service.quickaccesswallet.GetWalletCardsRequest;
@@ -28,10 +31,13 @@ import android.service.quickaccesswallet.QuickAccessWalletClientImpl;
import android.util.Log;
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.SystemClock;
import com.android.systemui.wallet.ui.WalletActivity;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -57,6 +63,7 @@ public class QuickAccessWalletController {
private static final long RECREATION_TIME_WINDOW = TimeUnit.MINUTES.toMillis(10L);
private final Context mContext;
private final Executor mExecutor;
private final Executor mCallbackExecutor;
private final SecureSettings mSecureSettings;
private final SystemClock mClock;
@@ -72,11 +79,13 @@ public class QuickAccessWalletController {
public QuickAccessWalletController(
Context context,
@Main Executor executor,
@CallbackExecutor Executor callbackExecutor,
SecureSettings secureSettings,
QuickAccessWalletClient quickAccessWalletClient,
SystemClock clock) {
mContext = context;
mExecutor = executor;
mCallbackExecutor = callbackExecutor;
mSecureSettings = secureSettings;
mQuickAccessWalletClient = quickAccessWalletClient;
mClock = clock;
@@ -117,7 +126,6 @@ public class QuickAccessWalletController {
/**
* Unregister wallet change observers per {@link WalletChangeEvent} if needed.
*
*/
public void unregisterWalletChangeObservers(WalletChangeEvent... events) {
for (WalletChangeEvent event : events) {
@@ -178,6 +186,80 @@ public class QuickAccessWalletController {
mQawClientCreatedTimeMillis = mClock.elapsedRealtime();
}
/**
* Starts the QuickAccessWallet UI: either the app's designated UI, or the built-in Wallet UI.
*
* If the service has configured itself so that
* {@link QuickAccessWalletClient#useTargetActivityForQuickAccess()}
* is true, or the service isn't providing any cards, use the target activity. Otherwise, use
* the SysUi {@link WalletActivity}
*
* The Wallet target activity is defined as the {@link android.app.PendingIntent} returned by
* {@link QuickAccessWalletClient#getWalletPendingIntent} if that is not null. If that is null,
* then the {@link Intent} returned by {@link QuickAccessWalletClient#createWalletIntent()}. If
* that too is null, then fall back to {@link WalletActivity}.
*
* @param activityStarter an {@link ActivityStarter} to launch the Intent or PendingIntent.
* @param animationController an {@link ActivityLaunchAnimator.Controller} to provide a
* smooth animation for the activity launch.
* @param hasCard whether the service returns any cards.
*/
public void startQuickAccessUiIntent(ActivityStarter activityStarter,
ActivityLaunchAnimator.Controller animationController,
boolean hasCard) {
if (mQuickAccessWalletClient.useTargetActivityForQuickAccess() || !hasCard) {
mQuickAccessWalletClient.getWalletPendingIntent(mCallbackExecutor,
walletPendingIntent -> {
if (walletPendingIntent == null) {
Intent intent = mQuickAccessWalletClient.createWalletIntent();
if (intent == null) {
intent = getSysUiWalletIntent();
}
startQuickAccessViaIntent(intent, hasCard, activityStarter,
animationController);
return;
}
startQuickAccessViaPendingIntent(walletPendingIntent,
activityStarter, animationController);
});
} else {
startQuickAccessViaIntent(getSysUiWalletIntent(),
hasCard,
activityStarter,
animationController);
}
}
private Intent getSysUiWalletIntent() {
return new Intent(mContext, WalletActivity.class)
.setAction(Intent.ACTION_VIEW);
}
private void startQuickAccessViaIntent(Intent intent,
boolean hasCard,
ActivityStarter activityStarter,
ActivityLaunchAnimator.Controller animationController) {
if (hasCard) {
activityStarter.startActivity(intent, true /* dismissShade */,
animationController, true /* showOverLockscreenWhenLocked */);
} else {
activityStarter.postStartActivityDismissingKeyguard(
intent,
/* delay= */ 0,
animationController);
}
}
private void startQuickAccessViaPendingIntent(PendingIntent pendingIntent,
ActivityStarter activityStarter,
ActivityLaunchAnimator.Controller animationController) {
activityStarter.postStartActivityDismissingKeyguard(
pendingIntent,
animationController);
}
private void setupDefaultPaymentAppObserver(
QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever) {
if (mDefaultPaymentAppObserver == null) {

View File

@@ -23,10 +23,13 @@ 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.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.PendingIntent;
import android.content.Intent;
import android.service.quickaccesswallet.GetWalletCardsRequest;
import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.testing.AndroidTestingRunner;
@@ -36,6 +39,8 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.FakeSystemClock;
@@ -60,8 +65,16 @@ public class QuickAccessWalletControllerTest extends SysuiTestCase {
private SecureSettings mSecureSettings;
@Mock
private QuickAccessWalletClient.OnWalletCardsRetrievedCallback mCardsRetriever;
@Mock
private ActivityStarter mActivityStarter;
@Mock
private ActivityLaunchAnimator.Controller mAnimationController;
@Captor
private ArgumentCaptor<GetWalletCardsRequest> mRequestCaptor;
@Captor
private ArgumentCaptor<Intent> mIntentCaptor;
@Captor
private ArgumentCaptor<PendingIntent> mPendingIntentCaptor;
private FakeSystemClock mClock = new FakeSystemClock();
private QuickAccessWalletController mController;
@@ -69,14 +82,24 @@ public class QuickAccessWalletControllerTest extends SysuiTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true);
when(mQuickAccessWalletClient.isWalletFeatureAvailable()).thenReturn(true);
when(mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked()).thenReturn(true);
mClock.setElapsedRealtime(100L);
doAnswer(invocation -> {
QuickAccessWalletClient.WalletPendingIntentCallback callback =
(QuickAccessWalletClient.WalletPendingIntentCallback) invocation
.getArguments()[1];
callback.onWalletPendingIntentRetrieved(null);
return null;
}).when(mQuickAccessWalletClient).getWalletPendingIntent(any(), any());
mController = new QuickAccessWalletController(
mContext,
MoreExecutors.directExecutor(),
MoreExecutors.directExecutor(),
mSecureSettings,
mQuickAccessWalletClient,
mClock);
@@ -151,8 +174,7 @@ public class QuickAccessWalletControllerTest extends SysuiTestCase {
verify(mQuickAccessWalletClient)
.getWalletCards(
eq(MoreExecutors.directExecutor()),
mRequestCaptor.capture(),
eq(MoreExecutors.directExecutor()), mRequestCaptor.capture(),
eq(mCardsRetriever));
GetWalletCardsRequest request = mRequestCaptor.getValue();
@@ -173,4 +195,55 @@ public class QuickAccessWalletControllerTest extends SysuiTestCase {
verify(mQuickAccessWalletClient, never()).getWalletCards(any(), any(), any());
}
@Test
public void getQuickAccessUiIntent_hasCards_useTargetActivityFalse_startsWalletActivity() {
when(mQuickAccessWalletClient.useTargetActivityForQuickAccess()).thenReturn(false);
mController.startQuickAccessUiIntent(mActivityStarter, mAnimationController, true);
verify(mActivityStarter).startActivity(mIntentCaptor.capture(), eq(true),
any(ActivityLaunchAnimator.Controller.class), eq(true));
Intent intent = mIntentCaptor.getValue();
assertEquals(intent.getAction(), Intent.ACTION_VIEW);
assertEquals(
intent.getComponent().getClassName(),
"com.android.systemui.wallet.ui.WalletActivity");
}
@Test
public void getQuickAccessUiIntent_noCards_useTargetActivityFalse_isWalletActivity() {
when(mQuickAccessWalletClient.useTargetActivityForQuickAccess()).thenReturn(false);
mController.startQuickAccessUiIntent(mActivityStarter, mAnimationController, false);
verify(mActivityStarter).postStartActivityDismissingKeyguard(mIntentCaptor.capture(), eq(0),
any(ActivityLaunchAnimator.Controller.class));
Intent intent = mIntentCaptor.getValue();
assertEquals(intent.getAction(), Intent.ACTION_VIEW);
assertEquals(
intent.getComponent().getClassName(),
"com.android.systemui.wallet.ui.WalletActivity");
}
@Test
public void getQuickAccessUiIntent_targetActivityViaPendingIntent_intentComponentIsCorrect() {
doAnswer(invocation -> {
QuickAccessWalletClient.WalletPendingIntentCallback callback =
(QuickAccessWalletClient.WalletPendingIntentCallback) invocation
.getArguments()[1];
Intent intent = new Intent(Intent.ACTION_VIEW).setClassName(
"com.google.android.apps.testapp",
"com.google.android.apps.testapp.TestActivity");
callback.onWalletPendingIntentRetrieved(
PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE));
return null;
}).when(mQuickAccessWalletClient).getWalletPendingIntent(any(), any());
when(mQuickAccessWalletClient.useTargetActivityForQuickAccess()).thenReturn(true);
mController.startQuickAccessUiIntent(mActivityStarter, mAnimationController, true);
verify(mActivityStarter).postStartActivityDismissingKeyguard(mPendingIntentCaptor.capture(),
any(ActivityLaunchAnimator.Controller.class));
PendingIntent pendingIntent = mPendingIntentCaptor.getValue();
Intent intent = pendingIntent.getIntent();
assertEquals(intent.getAction(), Intent.ACTION_VIEW);
assertEquals(
intent.getComponent().getClassName(),
"com.google.android.apps.testapp.TestActivity");
}
}