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 17 package android.nfc.tech.cts; 18 19 import static org.junit.Assert.*; 20 import static org.mockito.ArgumentMatchers.any; 21 import static org.mockito.Mockito.anyBoolean; 22 import static org.mockito.Mockito.anyInt; 23 import static org.mockito.Mockito.anyLong; 24 import static org.mockito.Mockito.times; 25 import static org.mockito.Mockito.verify; 26 import static org.mockito.Mockito.when; 27 import static org.testng.Assert.assertThrows; 28 29 import android.nfc.ErrorCodes; 30 import android.nfc.INfcTag; 31 import android.nfc.Tag; 32 import android.nfc.TransceiveResult; 33 import android.nfc.tech.NfcB; 34 import android.nfc.tech.TagTechnology; 35 import android.os.Bundle; 36 import android.os.RemoteException; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.mockito.ArgumentCaptor; 41 import org.mockito.Captor; 42 import org.mockito.Mock; 43 import org.mockito.MockitoAnnotations; 44 45 import java.io.IOException; 46 47 public class NfcBTest { 48 49 private static final byte[] APP_DATA = new byte[]{0xA}; 50 private static final byte[] PROTOCOL_INFO = new byte[]{0xB}; 51 52 @Mock 53 private INfcTag mNfcTagMock; 54 @Captor 55 private ArgumentCaptor<byte[]> mTransceiveDataCaptor; 56 57 @Before setUp()58 public void setUp() throws Exception { 59 MockitoAnnotations.initMocks(this); 60 } 61 62 @Test testGet_isNfcB()63 public void testGet_isNfcB() { 64 NfcB nfcB = createNfcB(); 65 66 assertTrue("Expected to not be <null>", nfcB != null); 67 } 68 69 @Test testGet_notNfcB()70 public void testGet_notNfcB() { 71 Tag tag = new Tag(new byte[]{}, new int[]{TagTechnology.NFC_A}, new Bundle[]{}, 0, 0L, 72 null); 73 NfcB nfcB = NfcB.get(tag); 74 75 assertTrue("Expected: <null> ", nfcB == null); 76 } 77 78 @Test testGetApplicationData()79 public void testGetApplicationData() { 80 NfcB nfcB = createNfcB(); 81 82 assertEquals(APP_DATA, nfcB.getApplicationData()); 83 } 84 85 @Test testGetProtocolInfo()86 public void testGetProtocolInfo() { 87 NfcB nfcB = createNfcB(); 88 89 assertEquals(PROTOCOL_INFO, nfcB.getProtocolInfo()); 90 } 91 92 @Test 93 testTransceive()94 public void testTransceive() throws RemoteException, IOException { 95 NfcB nfcB = createConnectedNfcB(); 96 97 when(mNfcTagMock.transceive(anyInt(), any(), anyBoolean())).thenReturn( 98 new TransceiveResult(TransceiveResult.RESULT_SUCCESS, new byte[]{0xF})); 99 byte[] transceivedBytes = new byte[]{0xA, 0xB, 0xC, 0xD}; 100 101 assertArrayEquals(new byte[]{0xF}, nfcB.transceive(transceivedBytes)); 102 verify(mNfcTagMock, times(1)).transceive(anyInt(), mTransceiveDataCaptor.capture(), 103 anyBoolean()); 104 assertArrayEquals(transceivedBytes, mTransceiveDataCaptor.getValue()); 105 } 106 107 @Test testGetMaxTransceieveLength()108 public void testGetMaxTransceieveLength() throws RemoteException, IOException { 109 NfcB nfcB = createNfcB(); 110 111 when(mNfcTagMock.isTagUpToDate(anyLong())).thenReturn(true); 112 when(mNfcTagMock.getMaxTransceiveLength(TagTechnology.NFC_B)).thenReturn(16); 113 114 assertEquals(16, nfcB.getMaxTransceiveLength()); 115 } 116 117 118 @Test testGetTag()119 public void testGetTag() { 120 Bundle extras = new Bundle(); 121 extras.putByteArray("appdata", APP_DATA); 122 extras.putByteArray("protinfo", PROTOCOL_INFO); 123 Tag tag = new Tag(new byte[]{}, new int[]{TagTechnology.NFC_B}, new Bundle[]{extras}, 0, 0L, 124 null); 125 126 NfcB nfcB = NfcB.get(tag); 127 128 assertEquals(tag, nfcB.getTag()); 129 } 130 131 @Test testIsConnected_isConnected()132 public void testIsConnected_isConnected() throws RemoteException, IOException { 133 NfcB nfcB = createConnectedNfcB(); 134 when(mNfcTagMock.isPresent(anyInt())).thenReturn(true); 135 136 assertEquals(true, nfcB.isConnected()); 137 } 138 139 @Test testIsConnected_notConnected()140 public void testIsConnected_notConnected() throws RemoteException, IOException { 141 NfcB nfcB = createNfcB(); 142 when(mNfcTagMock.isPresent(anyInt())).thenReturn(false); 143 144 assertEquals(false, nfcB.isConnected()); 145 } 146 147 148 @Test testIsConnected_serviceDead()149 public void testIsConnected_serviceDead() throws RemoteException, IOException { 150 NfcB nfcB = createConnectedNfcB(); 151 when(mNfcTagMock.isPresent(anyInt())).thenThrow(new RemoteException()); 152 153 assertEquals(false, nfcB.isConnected()); 154 } 155 156 @Test testReconnect()157 public void testReconnect() throws RemoteException, IOException { 158 NfcB nfcB = createConnectedNfcB(); 159 when(mNfcTagMock.reconnect(anyInt())).thenReturn(ErrorCodes.SUCCESS); 160 161 nfcB.reconnect(); 162 verify(mNfcTagMock, times(1)).reconnect(anyInt()); 163 } 164 165 @Test testReconnect_notConnected()166 public void testReconnect_notConnected() throws RemoteException, IOException { 167 NfcB nfcB = createNfcB(); 168 169 assertThrows(() -> nfcB.reconnect()); 170 } 171 172 @Test testReconnect_failReconnect()173 public void testReconnect_failReconnect() throws RemoteException, IOException { 174 NfcB nfcB = createConnectedNfcB(); 175 when(mNfcTagMock.reconnect(anyInt())).thenReturn(ErrorCodes.ERROR_CONNECT); 176 177 assertThrows(() -> nfcB.reconnect()); 178 } 179 180 @Test testReconnect_remoteException()181 public void testReconnect_remoteException() throws RemoteException, IOException { 182 NfcB nfcB = createConnectedNfcB(); 183 when(mNfcTagMock.reconnect(anyInt())).thenThrow(new RemoteException()); 184 185 assertThrows(() -> nfcB.reconnect()); 186 } 187 188 @Test testClose()189 public void testClose() throws RemoteException, IOException { 190 NfcB nfcB = createConnectedNfcB(); 191 when(mNfcTagMock.reconnect(anyInt())).thenReturn(ErrorCodes.SUCCESS); 192 when(mNfcTagMock.isPresent(anyInt())).thenReturn(true); 193 nfcB.close(); 194 195 assertEquals(false, nfcB.isConnected()); 196 } 197 198 createConnectedNfcB()199 private NfcB createConnectedNfcB() throws RemoteException, IOException { 200 NfcB nfcB = createNfcB(); 201 202 when(mNfcTagMock.isTagUpToDate(anyLong())).thenReturn(true); 203 when(mNfcTagMock.connect(anyInt(), anyInt())).thenReturn(ErrorCodes.SUCCESS); 204 nfcB.connect(); 205 206 return nfcB; 207 } 208 createNfcB()209 private NfcB createNfcB() { 210 Bundle extras = new Bundle(); 211 extras.putByteArray("appdata", APP_DATA); 212 extras.putByteArray("protinfo", PROTOCOL_INFO); 213 Tag tag = new Tag(new byte[]{}, new int[]{TagTechnology.NFC_B}, new Bundle[]{extras}, 0, 0L, 214 mNfcTagMock); 215 216 return NfcB.get(tag); 217 } 218 } 219