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