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