1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.nfc.cardemulation;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.ArgumentMatchers.anyBoolean;
22 import static org.mockito.ArgumentMatchers.anyInt;
23 import static org.mockito.ArgumentMatchers.anyString;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.doNothing;
26 import static org.mockito.Mockito.doReturn;
27 import static org.mockito.Mockito.never;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.verifyNoMoreInteractions;
31 import static org.mockito.Mockito.when;
32 
33 import android.app.ActivityManager;
34 import android.content.ComponentName;
35 import android.content.Context;
36 import android.content.ContentResolver;
37 import android.content.ContextWrapper;
38 import android.os.UserHandle;
39 import android.os.UserManager;
40 import android.net.Uri;
41 import android.nfc.cardemulation.ApduServiceInfo;
42 import android.nfc.cardemulation.CardEmulation;
43 import android.provider.Settings;
44 
45 import androidx.test.platform.app.InstrumentationRegistry;
46 import androidx.test.runner.AndroidJUnit4;
47 
48 import com.android.dx.mockito.inline.extended.ExtendedMockito;
49 import com.android.nfc.ForegroundUtils;
50 
51 import java.io.PrintWriter;
52 import java.util.ArrayList;
53 import java.util.List;
54 
55 import org.junit.After;
56 import org.junit.Before;
57 import org.junit.Test;
58 import org.junit.runner.RunWith;
59 import org.mockito.ArgumentCaptor;
60 import org.mockito.Captor;
61 import org.mockito.Mock;
62 import org.mockito.Mockito;
63 import org.mockito.MockitoAnnotations;
64 import org.mockito.MockitoSession;
65 import org.mockito.quality.Strictness;
66 
67 @RunWith(AndroidJUnit4.class)
68 public class PreferredServicesTest {
69 
70   private PreferredServices services;
71   private MockitoSession mStaticMockSession;
72   private Context mContext;
73 
74   @Mock
75   private RegisteredServicesCache mServicesCache;
76   @Mock
77   private PreferredServices.Callback mCallback;
78   @Mock
79   private RegisteredAidCache mAidCache;
80   @Mock
81   private WalletRoleObserver mObserver;
82   @Mock
83   private ForegroundUtils mForegroundUtils;
84   @Mock
85   private ContentResolver mContentResolver;
86   @Mock
87   private UserManager mUserManager;
88   @Mock
89   private ActivityManager mActivityManager;
90   @Mock
91   private ApduServiceInfo mServiceInfoPayment;
92   @Mock
93   private ApduServiceInfo mServiceInfoNonPayment;
94   @Mock
95   private UserHandle mUserHandle;
96   @Mock
97   private PrintWriter mPrintWriter;
98   @Mock
99   private RegisteredAidCache.AidResolveInfo mResolveInfo;
100 
101   @Captor
102   private ArgumentCaptor<Integer> userIdCaptor;
103   @Captor
104   private ArgumentCaptor<ComponentName> candidateCaptor;
105 
106   private static final String WALLET_HOLDER_PACKAGE_NAME = "com.android.test.walletroleholder";
107   private static final ComponentName TEST_COMPONENT
108       = new ComponentName(WALLET_HOLDER_PACKAGE_NAME,
109       "com.android.test.walletroleholder.WalletRoleHolderApduService");
110   private static final int USER_ID = 1;
111   private static final int FOREGROUND_UID = 7;
112 
113   @Before
setUp()114   public void setUp() throws Exception {
115     mStaticMockSession = ExtendedMockito.mockitoSession()
116         .mockStatic(ForegroundUtils.class)
117         .mockStatic(ActivityManager.class)
118         .mockStatic(UserHandle.class)
119         .mockStatic(Settings.Secure.class)
120         .mockStatic(ComponentName.class)
121         .strictness(Strictness.LENIENT)
122         .startMocking();
123     MockitoAnnotations.initMocks(this);
124     mContext = new ContextWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext()) {
125       @Override
126       public Object getSystemService(String name) {
127         if (Context.ACTIVITY_SERVICE.equals(name)) {
128           return (ActivityManager) mActivityManager;
129         } else if (Context.USER_SERVICE.equals(name)) {
130           return (UserManager) mUserManager;
131         } else {
132           return null;
133         }
134       }
135 
136       @Override
137       public Context createContextAsUser(UserHandle user, int flags) {
138         return mContext;
139       }
140 
141       @Override
142       public ContentResolver getContentResolver() {
143         return mContentResolver;
144       }
145     };
146 
147     when(ForegroundUtils.getInstance(any(ActivityManager.class))).thenReturn(mForegroundUtils);
148     when(ActivityManager.getCurrentUser()).thenReturn(USER_ID);
149     doNothing().when(mContentResolver)
150         .registerContentObserverAsUser(any(Uri.class), anyBoolean(), any(), any(UserHandle.class));
151     doNothing().when(mCallback).onPreferredPaymentServiceChanged(anyInt(), any());
152     when(Settings.Secure.getString(any(ContentResolver.class), anyString())).thenReturn("");
153     when(Settings.Secure.getInt(any(ContentResolver.class), anyString())).thenReturn(USER_ID);
154     when(UserHandle.getUserHandleForUid(anyInt())).thenReturn(mUserHandle);
155     when(UserHandle.of(anyInt())).thenReturn(mUserHandle);
156     when(mUserHandle.getIdentifier()).thenReturn(FOREGROUND_UID);
157     when(mObserver.getDefaultWalletRoleHolder(anyInt())).thenReturn(null);
158     when(mServiceInfoPayment.getComponent()).thenReturn(TEST_COMPONENT);
159     when(mServiceInfoPayment.getAids()).thenReturn(getAids());
160     when(mServiceInfoPayment
161         .getCategoryForAid(anyString())).thenReturn(CardEmulation.CATEGORY_PAYMENT);
162     when(mServiceInfoPayment.hasCategory(eq(CardEmulation.CATEGORY_PAYMENT))).thenReturn(true);
163     when(mServiceInfoNonPayment.hasCategory(eq(CardEmulation.CATEGORY_PAYMENT))).thenReturn(false);
164     when(mServiceInfoNonPayment.getAids()).thenReturn(getAids());
165     when(mAidCache.resolveAid(anyString())).thenReturn(mResolveInfo);
166     when(mUserManager.getEnabledProfiles()).thenReturn(getUserHandles());
167     // Wallet role feature is enabled by default; several test cases set this value to false
168     when(mObserver.isWalletRoleFeatureEnabled()).thenReturn(true);
169   }
170 
171   @After
tearDown()172   public void tearDown() {
173     mStaticMockSession.finishMocking();
174   }
175 
176   @Test
testConstructorWhenWalletRoleFeatureIsNotEnabled()177   public void testConstructorWhenWalletRoleFeatureIsNotEnabled() {
178     when(mObserver.isWalletRoleFeatureEnabled()).thenReturn(false);
179 
180     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
181 
182     assertThat(services.mContext).isEqualTo(mContext);
183     assertThat(services.mWalletRoleObserver).isEqualTo(mObserver);
184     assertThat(services.mForegroundUtils).isEqualTo(mForegroundUtils);
185     assertThat(services.mServiceCache).isEqualTo(mServicesCache);
186     assertThat(services.mAidCache).isEqualTo(mAidCache);
187     assertThat(services.mCallback).isEqualTo(mCallback);
188     assertThat(services.mSettingsObserver).isNotNull();
189     verify(mContentResolver, times(2))
190         .registerContentObserverAsUser(any(), anyBoolean(), any(), any(UserHandle.class));
191     verify(mUserManager).getEnabledProfiles();
192     verify(mObserver, never()).getDefaultWalletRoleHolder(anyInt());
193   }
194 
195   @Test
testConstructorWhenWalletRoleFeatureIsEnabled()196   public void testConstructorWhenWalletRoleFeatureIsEnabled() {
197     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
198 
199     assertThat(services.mContext).isEqualTo(mContext);
200     assertThat(services.mWalletRoleObserver).isEqualTo(mObserver);
201     assertThat(services.mForegroundUtils).isEqualTo(mForegroundUtils);
202     assertThat(services.mServiceCache).isEqualTo(mServicesCache);
203     assertThat(services.mAidCache).isEqualTo(mAidCache);
204     assertThat(services.mCallback).isEqualTo(mCallback);
205     assertThat(services.mSettingsObserver).isNotNull();
206     verify(mContentResolver, times(2))
207         .registerContentObserverAsUser(any(), anyBoolean(), any(), any(UserHandle.class));
208     verify(mUserManager).getEnabledProfiles();
209     verify(mObserver).getDefaultWalletRoleHolder(anyInt());
210     assertThat(services.mDefaultWalletHolderPaymentService).isNull();
211     verify(mCallback).onPreferredPaymentServiceChanged(anyInt(), any());
212   }
213 
214   @Test
testOnWalletRoleHolderChangedWithNullPackageName()215   public void testOnWalletRoleHolderChangedWithNullPackageName() {
216     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
217 
218     services.onWalletRoleHolderChanged(null, USER_ID);
219 
220     verify(mCallback, times(2))
221         .onPreferredPaymentServiceChanged(userIdCaptor.capture(), candidateCaptor.capture());
222     List<Integer> userIds = userIdCaptor.getAllValues();
223     assertThat(userIds.get(0)).isEqualTo(USER_ID);
224     assertThat(userIds.get(1)).isEqualTo(USER_ID);
225     List<ComponentName> candidates = candidateCaptor.getAllValues();
226     assertThat(candidates.get(0)).isNull();
227     assertThat(candidates.get(1)).isNull();
228     assertThat(services.mDefaultWalletHolderPaymentService).isNull();
229   }
230 
231   @Test
testOnWalletRoleHolderChangedWithExistingPackageNameAndExistingServiceInfos()232   public void testOnWalletRoleHolderChangedWithExistingPackageNameAndExistingServiceInfos() {
233     when(mServicesCache.getInstalledServices(eq(USER_ID))).thenReturn(getPaymentServices());
234     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
235 
236     services.onWalletRoleHolderChanged(WALLET_HOLDER_PACKAGE_NAME, USER_ID);
237 
238     assertThat(services.mUserIdDefaultWalletHolder).isEqualTo(USER_ID);
239     verify(mCallback, times(2))
240         .onPreferredPaymentServiceChanged(userIdCaptor.capture(), candidateCaptor.capture());
241     List<Integer> userIds = userIdCaptor.getAllValues();
242     assertThat(userIds.get(0)).isEqualTo(USER_ID);
243     assertThat(userIds.get(1)).isEqualTo(USER_ID);
244     List<ComponentName> candidates = candidateCaptor.getAllValues();
245     assertThat(candidates.get(0)).isNull();
246     assertThat(candidates.get(1)).isEqualTo(TEST_COMPONENT);
247     assertThat(services.mDefaultWalletHolderPaymentService).isEqualTo(TEST_COMPONENT);
248   }
249 
250   @Test
testOnWalletRoleHolderChangedWithExistingPackageNameAndNoServiceInfo()251   public void testOnWalletRoleHolderChangedWithExistingPackageNameAndNoServiceInfo() {
252     ArrayList<ApduServiceInfo> emptyList = new ArrayList<>();
253     when(mServicesCache.getInstalledServices(eq(USER_ID))).thenReturn(emptyList);
254     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
255 
256     services.onWalletRoleHolderChanged(WALLET_HOLDER_PACKAGE_NAME, USER_ID);
257 
258     assertThat(services.mUserIdDefaultWalletHolder).isEqualTo(USER_ID);
259     verify(mCallback).onPreferredPaymentServiceChanged(anyInt(), any());
260     assertThat(services.mDefaultWalletHolderPaymentService).isNull();
261   }
262 
263   @Test
testOnWalletRoleHolderChangedWithIncorrectPackageName()264   public void testOnWalletRoleHolderChangedWithIncorrectPackageName() {
265     when(mServicesCache.getInstalledServices(eq(USER_ID))).thenReturn(getPaymentServices());
266     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
267 
268     services.onWalletRoleHolderChanged(/* defaultWalletHolderPackageName = */ "", USER_ID);
269 
270     assertThat(services.mUserIdDefaultWalletHolder).isEqualTo(USER_ID);
271     verify(mCallback).onPreferredPaymentServiceChanged(anyInt(), any());
272     assertThat(services.mDefaultWalletHolderPaymentService).isNull();
273   }
274 
275   @Test
testSetDefaultForNextTapWithNonNullService_NotifyChange()276   public void testSetDefaultForNextTapWithNonNullService_NotifyChange() {
277     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
278     services.mForegroundUid = FOREGROUND_UID;
279 
280     boolean result = services.setDefaultForNextTap(USER_ID, TEST_COMPONENT);
281 
282     assertThat(result).isTrue();
283     assertThat(services.mNextTapDefault).isEqualTo(TEST_COMPONENT);
284     assertThat(services.mNextTapDefaultUserId).isEqualTo(USER_ID);
285     assertThat(services.mForegroundCurrent).isEqualTo(TEST_COMPONENT);
286     assertThat(services.mForegroundCurrentUid).isEqualTo(FOREGROUND_UID);
287     verify(mCallback)
288         .onPreferredForegroundServiceChanged(userIdCaptor.capture(), candidateCaptor.capture());
289     assertThat(userIdCaptor.getValue()).isEqualTo(USER_ID);
290     assertThat(candidateCaptor.getValue()).isEqualTo(TEST_COMPONENT);
291   }
292 
293   @Test
testSetDefaultForNextTapWithNullService_NoChange()294   public void testSetDefaultForNextTapWithNullService_NoChange() {
295     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
296     services.mForegroundUid = FOREGROUND_UID;
297     services.mForegroundRequested = null;
298     services.mForegroundCurrent = null;
299 
300     boolean result = services.setDefaultForNextTap(USER_ID, /* service = */ null);
301 
302     assertThat(result).isTrue();
303     assertThat(services.mNextTapDefault).isNull();
304     assertThat(services.mNextTapDefaultUserId).isEqualTo(USER_ID);
305     assertThat(services.mForegroundCurrent).isEqualTo(null);
306     assertThat(services.mForegroundCurrentUid).isEqualTo(0);
307     verify(mCallback, never()).onPreferredForegroundServiceChanged(anyInt(), any());
308   }
309 
310   @Test
testSetDefaultForNextTapWithNonNullService_NoChange()311   public void testSetDefaultForNextTapWithNonNullService_NoChange() {
312     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
313     services.mForegroundCurrent = TEST_COMPONENT;
314 
315     boolean result = services.setDefaultForNextTap(FOREGROUND_UID, TEST_COMPONENT);
316 
317     assertThat(result).isTrue();
318     assertThat(services.mNextTapDefault).isEqualTo(TEST_COMPONENT);
319     assertThat(services.mNextTapDefaultUserId).isEqualTo(FOREGROUND_UID);
320     assertThat(services.mForegroundCurrent).isEqualTo(TEST_COMPONENT);
321     assertThat(services.mForegroundCurrentUid).isEqualTo(0);
322     verify(mCallback, never()).onPreferredForegroundServiceChanged(anyInt(), any());
323   }
324 
325   @Test
testSetDefaultForNextTapWithNullService_NotifyChange()326   public void testSetDefaultForNextTapWithNullService_NotifyChange() {
327     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
328     services.mForegroundUid = FOREGROUND_UID;
329     services.mForegroundRequested = null;
330     services.mForegroundCurrent = TEST_COMPONENT;
331 
332     boolean result = services.setDefaultForNextTap(USER_ID, /* service = */ null);
333 
334     assertThat(result).isTrue();
335     assertThat(services.mNextTapDefault).isNull();
336     assertThat(services.mNextTapDefaultUserId).isEqualTo(USER_ID);
337     assertThat(services.mForegroundCurrent).isEqualTo(null);
338     assertThat(services.mForegroundCurrentUid).isEqualTo(FOREGROUND_UID);
339     verify(mCallback)
340         .onPreferredForegroundServiceChanged(userIdCaptor.capture(), candidateCaptor.capture());
341     assertThat(userIdCaptor.getValue()).isEqualTo(FOREGROUND_UID);
342     assertThat(candidateCaptor.getValue()).isNull();
343   }
344 
345   @Test
testOnServicesUpdatedWithNullForeground_NoChange()346   public void testOnServicesUpdatedWithNullForeground_NoChange() {
347     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
348     services.mForegroundCurrent = null;
349 
350     services.onServicesUpdated();
351 
352     assertThat(services.mForegroundRequested).isNull();
353     assertThat(services.mForegroundUid).isEqualTo(0);
354     assertThat(services.mForegroundCurrentUid).isEqualTo(0);
355   }
356 
357   @Test
testOnServicesUpdatedWithNonNullForegroundAndPaymentServiceInfo_CommitsChange()358   public void testOnServicesUpdatedWithNonNullForegroundAndPaymentServiceInfo_CommitsChange() {
359     when(mObserver.isWalletRoleFeatureEnabled()).thenReturn(true);
360     when(mServicesCache.getInstalledServices(eq(USER_ID))).thenReturn(getPaymentServices());
361     when(mServicesCache.getService(anyInt(), any())).thenReturn(mServiceInfoPayment);
362     when(mObserver.getDefaultWalletRoleHolder(eq(USER_ID))).thenReturn(WALLET_HOLDER_PACKAGE_NAME);
363     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
364     services.mUserIdDefaultWalletHolder = USER_ID;
365     services.mForegroundCurrent = TEST_COMPONENT;
366     services.mForegroundCurrentUid = FOREGROUND_UID;
367     services.mPaymentDefaults.currentPreferred = null;
368     services.mPaymentDefaults.preferForeground = false;
369 
370     services.onServicesUpdated();
371 
372     assertThat(services.mForegroundRequested).isNull();
373     assertThat(services.mForegroundUid).isEqualTo(-1);
374     assertThat(services.mForegroundCurrentUid).isEqualTo(-1);
375     assertWalletRoleHolderUpdated();
376   }
377 
378   @Test
testOnServicesUpdatedWithNonNullForegroundAndNonPaymentServiceInfo_CommitsChange()379   public void testOnServicesUpdatedWithNonNullForegroundAndNonPaymentServiceInfo_CommitsChange() {
380     when(mObserver.isWalletRoleFeatureEnabled()).thenReturn(true);
381     when(mServicesCache.getInstalledServices(eq(USER_ID))).thenReturn(getPaymentServices());
382     when(mServicesCache.getService(anyInt(), any())).thenReturn(mServiceInfoNonPayment);
383     when(mObserver.getDefaultWalletRoleHolder(eq(USER_ID))).thenReturn(WALLET_HOLDER_PACKAGE_NAME);
384     mResolveInfo.category = CardEmulation.CATEGORY_PAYMENT;
385     mResolveInfo.defaultService = mServiceInfoNonPayment;
386     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
387     services.mUserIdDefaultWalletHolder = USER_ID;
388     services.mForegroundCurrent = TEST_COMPONENT;
389     services.mForegroundCurrentUid = FOREGROUND_UID;
390     services.mPaymentDefaults.currentPreferred = null;
391     services.mPaymentDefaults.mUserHandle = mUserHandle;
392     services.mPaymentDefaults.preferForeground = false;
393 
394     services.onServicesUpdated();
395 
396     assertThat(services.mForegroundRequested).isNull();
397     assertThat(services.mForegroundUid).isEqualTo(-1);
398     assertThat(services.mForegroundCurrentUid).isEqualTo(-1);
399     assertWalletRoleHolderUpdated();
400   }
401 
402   @Test
testOnServicesUpdatedWithNonNullForegroundAndNonPaymentServiceInfo_NoChange()403   public void testOnServicesUpdatedWithNonNullForegroundAndNonPaymentServiceInfo_NoChange() {
404     when(mObserver.isWalletRoleFeatureEnabled()).thenReturn(true);
405     when(mServicesCache.getInstalledServices(eq(USER_ID))).thenReturn(getPaymentServices());
406     when(mServicesCache.getService(anyInt(), any())).thenReturn(mServiceInfoNonPayment);
407     when(mObserver.getDefaultWalletRoleHolder(eq(USER_ID))).thenReturn(WALLET_HOLDER_PACKAGE_NAME);
408     mResolveInfo.category = CardEmulation.CATEGORY_PAYMENT;
409     mResolveInfo.defaultService = null;
410     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
411     services.mUserIdDefaultWalletHolder = USER_ID;
412     services.mForegroundCurrent = TEST_COMPONENT;
413     services.mForegroundCurrentUid = FOREGROUND_UID;
414     services.mPaymentDefaults.currentPreferred = null;
415     services.mPaymentDefaults.mUserHandle = mUserHandle;
416     services.mPaymentDefaults.preferForeground = false;
417 
418     services.onServicesUpdated();
419 
420     assertThat(services.mForegroundRequested).isNull();
421     assertThat(services.mForegroundUid).isEqualTo(0);
422     assertThat(services.mForegroundCurrentUid).isEqualTo(FOREGROUND_UID);
423     assertWalletRoleHolderUpdated();
424   }
425 
426   @Test
testRegisterPreferredForegroundServiceWithSuccess()427   public void testRegisterPreferredForegroundServiceWithSuccess() {
428     when(mForegroundUtils.registerUidToBackgroundCallback(any(), anyInt())).thenReturn(true);
429     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
430     services.mPaymentDefaults.currentPreferred = TEST_COMPONENT;
431 
432     boolean result = services.registerPreferredForegroundService(TEST_COMPONENT, USER_ID);
433 
434     assertThat(result).isTrue();
435     assertThat(services.mForegroundRequested).isEqualTo(TEST_COMPONENT);
436     assertThat(services.mForegroundUid).isEqualTo(USER_ID);
437   }
438 
439   @Test
testRegisterPreferredForegroundServiceWithFailure()440   public void testRegisterPreferredForegroundServiceWithFailure() {
441     when(mForegroundUtils.registerUidToBackgroundCallback(any(), anyInt())).thenReturn(false);
442     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
443     services.mPaymentDefaults.currentPreferred = TEST_COMPONENT;
444 
445     boolean result = services.registerPreferredForegroundService(TEST_COMPONENT, USER_ID);
446 
447     assertThat(result).isFalse();
448     assertThat(services.mForegroundRequested).isNull();
449     assertThat(services.mForegroundUid).isEqualTo(0);
450   }
451 
452   @Test
testUnregisteredPreferredForegroundServiceInForeground_ReturnsSuccess()453   public void testUnregisteredPreferredForegroundServiceInForeground_ReturnsSuccess() {
454     when(mForegroundUtils.isInForeground(anyInt())).thenReturn(true);
455     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
456     services.mForegroundUid = FOREGROUND_UID;
457 
458     boolean result = services.unregisteredPreferredForegroundService(FOREGROUND_UID);
459 
460     assertThat(result).isTrue();
461     assertThat(services.mForegroundRequested).isNull();
462     assertThat(services.mForegroundUid).isEqualTo(-1);
463   }
464 
465   @Test
testUnregisteredPreferredForegroundServiceInForeground_ReturnsFailure()466   public void testUnregisteredPreferredForegroundServiceInForeground_ReturnsFailure() {
467     when(mForegroundUtils.isInForeground(anyInt())).thenReturn(true);
468     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
469     services.mForegroundUid = FOREGROUND_UID;
470 
471     boolean result = services.unregisteredPreferredForegroundService(USER_ID);
472 
473     assertThat(result).isFalse();
474     assertThat(services.mForegroundRequested).isNull();
475     assertThat(services.mForegroundUid).isEqualTo(FOREGROUND_UID);
476   }
477 
478   @Test
testUnregisteredPreferredForegroundServiceNotInForeground_ReturnsFailure()479   public void testUnregisteredPreferredForegroundServiceNotInForeground_ReturnsFailure() {
480     when(mForegroundUtils.isInForeground(anyInt())).thenReturn(false);
481     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
482 
483     boolean result = services.unregisteredPreferredForegroundService(USER_ID);
484 
485     assertThat(result).isFalse();
486     assertThat(services.mForegroundRequested).isNull();
487     assertThat(services.mForegroundUid).isEqualTo(0);
488   }
489 
490   @Test
testOnUidToBackground_SuccessfullyUnregistersService()491   public void testOnUidToBackground_SuccessfullyUnregistersService() {
492     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
493     services.mForegroundUid = FOREGROUND_UID;
494 
495     services.onUidToBackground(FOREGROUND_UID);
496 
497     assertThat(services.mForegroundUid).isEqualTo(-1);
498   }
499 
500   @Test
testOnUidToBackground_FailsToUnregisterService()501   public void testOnUidToBackground_FailsToUnregisterService() {
502     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
503     services.mForegroundUid = FOREGROUND_UID;
504 
505     services.onUidToBackground(USER_ID);
506 
507     assertThat(services.mForegroundUid).isEqualTo(FOREGROUND_UID);
508   }
509 
510   @Test
testOnHostEmulationActivated()511   public void testOnHostEmulationActivated() {
512     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
513     services.mNextTapDefault = TEST_COMPONENT;
514 
515     services.onHostEmulationActivated();
516 
517     assertThat(services.mClearNextTapDefault).isTrue();
518   }
519 
520   @Test
testOnHostEmulationDeactivated()521   public void testOnHostEmulationDeactivated() {
522     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
523     services.mClearNextTapDefault = true;
524     services.mNextTapDefault = TEST_COMPONENT;
525 
526     services.onHostEmulationDeactivated();
527 
528     assertThat(services.mNextTapDefault).isNull();
529     assertThat(services.mClearNextTapDefault).isFalse();
530   }
531 
532   @Test
testOnUserSwitchedWithChange()533   public void testOnUserSwitchedWithChange() {
534     when(mObserver.isWalletRoleFeatureEnabled()).thenReturn(false);
535     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
536     services.mPaymentDefaults.preferForeground = false;
537     services.mPaymentDefaults.currentPreferred = TEST_COMPONENT;
538 
539     services.onUserSwitched(USER_ID);
540 
541     assertThat(services.mPaymentDefaults.preferForeground).isTrue();
542     assertThat(services.mPaymentDefaults.settingsDefault).isEqualTo(null);
543     assertThat(services.mPaymentDefaults.currentPreferred).isEqualTo(null);
544     assertThat(services.mPaymentDefaults.mUserHandle).isEqualTo(mUserHandle);
545     verify(mCallback)
546         .onPreferredPaymentServiceChanged(userIdCaptor.capture(), candidateCaptor.capture());
547     assertThat(userIdCaptor.getValue()).isEqualTo(FOREGROUND_UID);
548     assertThat(candidateCaptor.getValue()).isEqualTo(null);
549   }
550 
551   @Test
testOnUserSwitchedWithNoChange()552   public void testOnUserSwitchedWithNoChange() throws Exception {
553     when(mUserManager.getEnabledProfiles()).thenReturn(getUserHandles());
554     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
555     services.mPaymentDefaults.preferForeground = false;
556     services.mPaymentDefaults.currentPreferred = null;
557     verify(mCallback).onPreferredPaymentServiceChanged(anyInt(), any());
558 
559     services.onUserSwitched(USER_ID);
560 
561     assertThat(services.mPaymentDefaults.preferForeground).isTrue();
562     assertThat(services.mPaymentDefaults.settingsDefault).isEqualTo(null);
563     assertThat(services.mPaymentDefaults.currentPreferred).isEqualTo(null);
564     assertThat(services.mPaymentDefaults.mUserHandle).isEqualTo(null);
565     verifyNoMoreInteractions(mCallback);
566   }
567 
568   @Test
testPackageHasPreferredServiceWithNullPackageName_ReturnsFalse()569   public void testPackageHasPreferredServiceWithNullPackageName_ReturnsFalse() {
570     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
571 
572     boolean result = services.packageHasPreferredService(/* packageName = */ null);
573 
574     assertThat(result).isFalse();
575   }
576 
577   @Test
testPackageHasPreferredServiceWithMatchingPackageName_ReturnsTrue()578   public void testPackageHasPreferredServiceWithMatchingPackageName_ReturnsTrue() {
579     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
580     services.mPaymentDefaults.currentPreferred = TEST_COMPONENT;
581 
582     boolean result = services.packageHasPreferredService(WALLET_HOLDER_PACKAGE_NAME);
583 
584     assertThat(result).isTrue();
585   }
586 
587   @Test
testPackageHasPreferredServiceWithNonMatchingPackageName_ReturnsFalse()588   public void testPackageHasPreferredServiceWithNonMatchingPackageName_ReturnsFalse() {
589     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
590 
591     boolean result = services.packageHasPreferredService(WALLET_HOLDER_PACKAGE_NAME);
592 
593     assertThat(result).isFalse();
594   }
595 
596   @Test
testDump()597   public void testDump() {
598     when(mObserver.isWalletRoleFeatureEnabled()).thenReturn(false);
599     when(mUserManager.getUserName()).thenReturn("");
600     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
601 
602     services.dump(null, mPrintWriter, null);
603 
604     verify(mPrintWriter, times(8)).println(anyString());
605   }
606 
607   @Test
testDump_withWalletRole()608   public void testDump_withWalletRole() {
609     when(mObserver.isWalletRoleFeatureEnabled()).thenReturn(true);
610     when(mUserManager.getUserName()).thenReturn("");
611     services = new PreferredServices(mContext, mServicesCache, mAidCache, mObserver, mCallback);
612 
613     services.dump(null, mPrintWriter, null);
614 
615     verify(mPrintWriter, times(7)).println(anyString());
616   }
617 
assertWalletRoleHolderUpdated()618   private void assertWalletRoleHolderUpdated() {
619     verify(mObserver, times(4)).isWalletRoleFeatureEnabled();
620     verify(mObserver, times(2)).getDefaultWalletRoleHolder(eq(USER_ID));
621     assertThat(services.mUserIdDefaultWalletHolder).isEqualTo(USER_ID);
622     verify(mCallback)
623             .onPreferredPaymentServiceChanged(userIdCaptor.capture(), candidateCaptor.capture());
624     List<Integer> userIds = userIdCaptor.getAllValues();
625     assertThat(userIds.get(0)).isEqualTo(USER_ID);
626     List<ComponentName> candidates = candidateCaptor.getAllValues();
627     assertThat(candidates.get(0)).isEqualTo(TEST_COMPONENT);
628     assertThat(services.mDefaultWalletHolderPaymentService).isEqualTo(TEST_COMPONENT);
629   }
630 
getAids()631   private ArrayList<String> getAids() {
632     ArrayList<String> aids = new ArrayList<>();
633     aids.add("aid");
634     return aids;
635   }
636 
getPaymentServices()637   private ArrayList<ApduServiceInfo> getPaymentServices() {
638     ArrayList<ApduServiceInfo> serviceInfos = new ArrayList<>();
639     serviceInfos.add(mServiceInfoPayment);
640     return serviceInfos;
641   }
642 
getUserHandles()643   private ArrayList<UserHandle> getUserHandles() {
644     ArrayList<UserHandle> list = new ArrayList<>();
645     list.add(mUserHandle);
646     return list;
647   }
648 }