• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
18 
19 
20 import static org.mockito.ArgumentMatchers.any;
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.times;
23 import static org.mockito.Mockito.when;
24 
25 import android.annotation.NonNull;
26 import android.annotation.Nullable;
27 import android.annotation.RequiresPermission;
28 import android.app.ActivityManager;
29 import android.content.BroadcastReceiver;
30 import android.content.ComponentName;
31 import android.content.ContentResolver;
32 import android.content.Context;
33 import android.content.ContextWrapper;
34 import android.content.Intent;
35 import android.content.IntentFilter;
36 import android.content.ServiceConnection;
37 import android.content.pm.PackageManager;
38 import android.nfc.Constants;
39 import android.nfc.cardemulation.HostNfcFService;
40 import android.nfc.cardemulation.NfcFServiceInfo;
41 import android.os.Build;
42 import android.os.Handler;
43 import android.os.IBinder;
44 import android.os.Message;
45 import android.os.Messenger;
46 import android.os.UserHandle;
47 import android.provider.Settings;
48 import android.util.Log;
49 
50 import androidx.test.ext.junit.runners.AndroidJUnit4;
51 import androidx.test.platform.app.InstrumentationRegistry;
52 
53 import com.android.dx.mockito.inline.extended.ExtendedMockito;
54 import com.android.nfc.cardemulation.AidRoutingManager;
55 import com.android.nfc.cardemulation.CardEmulationManager;
56 import com.android.nfc.cardemulation.HostNfcFEmulationManager;
57 import com.android.nfc.cardemulation.RegisteredAidCache;
58 import com.android.nfc.cardemulation.RegisteredT3tIdentifiersCache;
59 import com.android.nfc.cardemulation.RoutingOptionManager;
60 
61 import org.junit.After;
62 import org.junit.Assert;
63 import org.junit.Before;
64 import org.junit.Test;
65 import org.junit.runner.RunWith;
66 import org.mockito.MockitoSession;
67 import org.mockito.quality.Strictness;
68 
69 import com.android.nfc.flags.Flags;
70 
71 @RunWith(AndroidJUnit4.class)
72 public class HostNfcFEmulationManagerTest {
73 
74     private static final String TAG = HostNfcFEmulationManagerTest.class.getSimpleName();
75     private MockitoSession mStaticMockSession;
76     private HostNfcFEmulationManager mHostNfcFEmulationManager;
77     private ComponentName componentName;
78 
79     @Before
setUp()80     public void setUp() throws Exception {
81         mStaticMockSession = ExtendedMockito.mockitoSession()
82                 .mockStatic(Flags.class)
83                 .mockStatic(NfcStatsLog.class)
84                 .mockStatic(Message.class)
85                 .strictness(Strictness.LENIENT)
86                 .startMocking();
87 	Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
88         Context mockContext = new ContextWrapper(context) {
89 
90             public Context createContextAsUser(@NonNull UserHandle user,
91                     @CreatePackageOptions int flags) {
92                 if (Build.IS_ENG) {
93                     throw new IllegalStateException("createContextAsUser not overridden!");
94                 }
95                 return this;
96             }
97 
98             public Intent registerReceiverForAllUsers(@Nullable BroadcastReceiver receiver,
99                     @NonNull IntentFilter filter, @Nullable String broadcastPermission,
100                     @Nullable Handler scheduler) {
101                 return mock(Intent.class);
102             }
103 
104             public ContentResolver getContentResolver() {
105                 return mock(ContentResolver.class);
106             }
107 
108             public boolean bindServiceAsUser(
109                     @NonNull @RequiresPermission Intent service, @NonNull ServiceConnection conn,
110                     int flags,
111                     @NonNull UserHandle user) {
112                 return true;
113             }
114 
115             public void unbindService(@NonNull ServiceConnection conn) {
116 
117             }
118 
119 
120         };
121 
122         when(Flags.statsdCeEventsFlag()).thenReturn(false);
123         RegisteredT3tIdentifiersCache t3tIdentifiersCache = mock(
124                 RegisteredT3tIdentifiersCache.class);
125         NfcFServiceInfo nfcFServiceInfo = mock(NfcFServiceInfo.class);
126         componentName = mock(ComponentName.class);
127         when(nfcFServiceInfo.getComponent()).thenReturn(componentName);
128         when(t3tIdentifiersCache.resolveNfcid2("6D2E616E64726F69")).thenReturn(nfcFServiceInfo);
129         Message message = new Message();
130         when(Message.obtain(null, HostNfcFService.MSG_COMMAND_PACKET)).thenReturn(message);
131         when(Message.obtain(null, HostNfcFService.MSG_DEACTIVATED)).thenReturn(message);
132         when(Message.obtain()).thenReturn(message);
133 
134         InstrumentationRegistry.getInstrumentation().runOnMainSync(
135                 () -> mHostNfcFEmulationManager =
136                         new HostNfcFEmulationManager(mockContext, t3tIdentifiersCache));
137         Assert.assertNotNull(mHostNfcFEmulationManager);
138     }
139 
140     @After
tearDown()141     public void tearDown() throws Exception {
142         mStaticMockSession.finishMocking();
143     }
144 
145     @Test
testOnEnabledForegroundNfcFServiceChanged()146     public void testOnEnabledForegroundNfcFServiceChanged() {
147         String packageName = mHostNfcFEmulationManager.getEnabledFgServiceName();
148         Assert.assertNull(packageName);
149         when(componentName.getPackageName()).thenReturn("com.android.nfc");
150         mHostNfcFEmulationManager.onEnabledForegroundNfcFServiceChanged(0, componentName);
151         packageName = mHostNfcFEmulationManager.getEnabledFgServiceName();
152         Assert.assertNotNull(packageName);
153         Assert.assertEquals("com.android.nfc", packageName);
154 
155     }
156 
157     @Test
testOnHostEmulationData()158     public void testOnHostEmulationData() {
159         testOnEnabledForegroundNfcFServiceChanged();
160         mHostNfcFEmulationManager.onHostEmulationData("com.android.nfc".getBytes());
161         ExtendedMockito.verify(() -> NfcStatsLog.write(NfcStatsLog.NFC_CARDEMULATION_OCCURRED,
162                 NfcStatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__HCE_PAYMENT,
163                 "HCEF",
164                 0));
165     }
166 
167     @Test
testOnNfcDisabled()168     public void testOnNfcDisabled() {
169         testOnHostEmulationData();
170         ServiceConnection serviceConnection = mHostNfcFEmulationManager.getServiceConnection();
171         Message message = mock(Message.class);
172         when(Message.obtain(null, HostNfcFService.MSG_COMMAND_PACKET)).thenReturn(message);
173         serviceConnection.onServiceConnected(mock(ComponentName.class), mock(IBinder.class));
174         int userId = mHostNfcFEmulationManager.getServiceUserId();
175         Assert.assertEquals(0, userId);
176         mHostNfcFEmulationManager.onNfcDisabled();
177         userId = mHostNfcFEmulationManager.getServiceUserId();
178         Assert.assertEquals(-1, userId);
179         ExtendedMockito.verify(() -> Message.obtain(null, HostNfcFService.MSG_COMMAND_PACKET));
180     }
181 
182 
183     @Test
testOnUserSwitched()184     public void testOnUserSwitched() {
185         testOnHostEmulationData();
186         ServiceConnection serviceConnection = mHostNfcFEmulationManager.getServiceConnection();
187         Message message = mock(Message.class);
188         when(Message.obtain(null, HostNfcFService.MSG_COMMAND_PACKET)).thenReturn(message);
189         serviceConnection.onServiceConnected(mock(ComponentName.class), mock(IBinder.class));
190         int userId = mHostNfcFEmulationManager.getServiceUserId();
191         Assert.assertEquals(0, userId);
192         mHostNfcFEmulationManager.onUserSwitched();
193         boolean isUserSwitched = mHostNfcFEmulationManager.isUserSwitched();
194         Assert.assertTrue(isUserSwitched);
195         userId = mHostNfcFEmulationManager.getServiceUserId();
196         Assert.assertEquals(-1, userId);
197         ExtendedMockito.verify(() -> Message.obtain(null, HostNfcFService.MSG_COMMAND_PACKET));
198     }
199 
200     @Test
testOnHostEmulationDeactivated()201     public void testOnHostEmulationDeactivated() {
202         testOnHostEmulationData();
203         ServiceConnection serviceConnection = mHostNfcFEmulationManager.getServiceConnection();
204         Message message = mock(Message.class);
205         when(Message.obtain(null, HostNfcFService.MSG_COMMAND_PACKET)).thenReturn(message);
206         serviceConnection.onServiceConnected(mock(ComponentName.class), mock(IBinder.class));
207         ComponentName serviceName = mHostNfcFEmulationManager.getServiceName();
208         Assert.assertNotNull(serviceName);
209         mHostNfcFEmulationManager.onHostEmulationDeactivated();
210         serviceName = mHostNfcFEmulationManager.getServiceName();
211         Assert.assertNull(serviceName);
212     }
213 }
214