1 /* 2 * Copyright (C) 2022 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 package com.android.nfc.cardemulation; 17 18 import static org.mockito.ArgumentMatchers.anyString; 19 import static org.mockito.Mockito.when; 20 21 import android.bluetooth.BluetoothProtoEnums; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.ContextWrapper; 25 import android.content.Intent; 26 import android.content.pm.PackageManager; 27 import android.nfc.cardemulation.ApduServiceInfo; 28 import android.nfc.cardemulation.CardEmulation; 29 import android.os.UserHandle; 30 import android.util.Log; 31 import androidx.test.ext.junit.runners.AndroidJUnit4; 32 import androidx.test.platform.app.InstrumentationRegistry; 33 34 import com.android.dx.mockito.inline.extended.ExtendedMockito; 35 import com.android.nfc.cardemulation.RegisteredAidCache.AidResolveInfo; 36 import com.android.nfc.NfcStatsLog; 37 38 import java.util.ArrayList; 39 import java.util.List; 40 41 import org.junit.After; 42 import org.junit.Assert; 43 import org.junit.Before; 44 import org.junit.Test; 45 import org.junit.runner.RunWith; 46 import org.mockito.Mockito; 47 import org.mockito.MockitoSession; 48 49 @RunWith(AndroidJUnit4.class) 50 public final class NfcCardEmulationOccurredTest { 51 52 private static final String TAG = NfcCardEmulationOccurredTest.class.getSimpleName(); 53 private boolean mNfcSupported; 54 55 private MockitoSession mStaticMockSession; 56 private HostEmulationManager mHostEmulation; 57 58 private static final int UID_1 = 111; 59 60 @Before setUp()61 public void setUp() { 62 mStaticMockSession = ExtendedMockito.mockitoSession() 63 .mockStatic(NfcStatsLog.class) 64 .startMocking(); 65 66 Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); 67 PackageManager pm = context.getPackageManager(); 68 if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) { 69 mNfcSupported = false; 70 return; 71 } 72 mNfcSupported = true; 73 74 Context mockContext = new ContextWrapper(context) { 75 @Override 76 public void sendBroadcastAsUser(Intent intent, UserHandle user) { 77 Log.i(TAG, "[Mock] sendBroadcastAsUser"); 78 } 79 }; 80 81 RegisteredAidCache mockAidCache = Mockito.mock(RegisteredAidCache.class); 82 ApduServiceInfo apduServiceInfo = Mockito.mock(ApduServiceInfo.class); 83 when(apduServiceInfo.requiresUnlock()).thenReturn(false); 84 when(apduServiceInfo.requiresScreenOn()).thenReturn(false); 85 when(apduServiceInfo.isOnHost()).thenReturn(true); 86 when(apduServiceInfo.getComponent()).thenReturn(new ComponentName("packageName", "name")); 87 when(apduServiceInfo.getUid()).thenReturn(UID_1); 88 AidResolveInfo aidResolveInfo = mockAidCache.new AidResolveInfo(); 89 aidResolveInfo.defaultService = apduServiceInfo; 90 aidResolveInfo.category = CardEmulation.CATEGORY_OTHER; 91 aidResolveInfo.services = new ArrayList<ApduServiceInfo>(); 92 aidResolveInfo.services.add(apduServiceInfo); 93 when(mockAidCache.resolveAid(anyString())).thenReturn(aidResolveInfo); 94 95 InstrumentationRegistry.getInstrumentation().runOnMainSync( 96 () -> mHostEmulation = new HostEmulationManager(mockContext, mockAidCache)); 97 Assert.assertNotNull(mHostEmulation); 98 99 mHostEmulation.onHostEmulationActivated(); 100 } 101 102 @After tearDown()103 public void tearDown() { 104 mHostEmulation.onHostEmulationDeactivated(); 105 mStaticMockSession.finishMocking(); 106 } 107 108 @Test testHCEOther()109 public void testHCEOther() { 110 if (!mNfcSupported) return; 111 112 byte[] aidBytes = new byte[] { 113 0x00, (byte)0xA4, 0x04, 0x00, // command 114 0x08, // data length 115 (byte)0xA0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 116 0x00, // card manager AID 117 0x00 // trailer 118 }; 119 mHostEmulation.onHostEmulationData(aidBytes); 120 ExtendedMockito.verify(() -> NfcStatsLog.write( 121 NfcStatsLog.NFC_CARDEMULATION_OCCURRED, 122 NfcStatsLog.NFC_CARDEMULATION_OCCURRED__CATEGORY__HCE_OTHER, 123 "HCE", 124 UID_1)); 125 } 126 } 127