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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user