blob: 380bbb04e65ffdb844ec6c5410ab72b74235ec41 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.nfc.tech.cts;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;
import android.nfc.ErrorCodes;
import android.nfc.INfcTag;
import android.nfc.Tag;
import android.nfc.TransceiveResult;
import android.nfc.tech.NfcF;
import android.nfc.tech.TagTechnology;
import android.os.Bundle;
import android.os.RemoteException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.IOException;
public class NfcFTest {
private static final byte[] SYSTEM_CODE = new byte[]{0xA};
private static final byte[] MANUFACTURER = new byte[]{0xB};
@Mock
private INfcTag mNfcTagMock;
@Captor
private ArgumentCaptor<byte[]> mTransceiveDataCaptor;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void testGet_isNfcF() {
NfcF nfcF = createNfcF();
assertTrue("Expected to not be <null>", nfcF != null);
}
@Test
public void testGet_tagNotNfcF() {
Tag tag = new Tag(new byte[]{}, new int[]{TagTechnology.NFC_B}, new Bundle[]{}, 0, 0L,
null);
NfcF nfcF = NfcF.get(tag);
assertTrue("Expected: <null> ", nfcF == null);
}
@Test
public void testGetSystemCode() {
NfcF nfcF = createNfcF();
assertEquals(SYSTEM_CODE, nfcF.getSystemCode());
}
@Test
public void testGetManufacturer() {
NfcF nfcF = createNfcF();
assertEquals(MANUFACTURER, nfcF.getManufacturer());
}
@Test
public void testTransceive() throws RemoteException, IOException {
NfcF nfcF = createConnectedNfcF();
when(mNfcTagMock.transceive(anyInt(), any(), anyBoolean())).thenReturn(
new TransceiveResult(TransceiveResult.RESULT_SUCCESS, new byte[]{0xF}));
byte[] transceivedBytes = new byte[]{0xA, 0xB, 0xC, 0xD};
assertArrayEquals(new byte[]{0xF}, nfcF.transceive(transceivedBytes));
verify(mNfcTagMock, times(1)).transceive(anyInt(), mTransceiveDataCaptor.capture(),
anyBoolean());
assertArrayEquals(transceivedBytes, mTransceiveDataCaptor.getValue());
}
@Test
public void testGetMaxTransceiveLength() throws RemoteException, IOException {
NfcF nfcF = createNfcF();
when(mNfcTagMock.isTagUpToDate(anyLong())).thenReturn(true);
when(mNfcTagMock.getMaxTransceiveLength(TagTechnology.NFC_F)).thenReturn(16);
assertEquals(16, nfcF.getMaxTransceiveLength());
}
@Test
public void testSetTimeout() throws RemoteException, IOException {
NfcF nfcF = createNfcF();
when(mNfcTagMock.isTagUpToDate(anyLong())).thenReturn(true);
when(mNfcTagMock.setTimeout(anyInt(), anyInt())).thenReturn(ErrorCodes.SUCCESS);
nfcF.setTimeout(250);
ArgumentCaptor<Integer> timeout = ArgumentCaptor.forClass(Integer.class);
verify(mNfcTagMock, times(1)).setTimeout(anyInt(), timeout.capture());
assertTrue(250 == timeout.getValue());
}
@Test
public void testSetTimeout_invalidTimeout() throws RemoteException, IOException {
NfcF nfcF = createNfcF();
when(mNfcTagMock.isTagUpToDate(anyLong())).thenReturn(true);
when(mNfcTagMock.setTimeout(anyInt(), anyInt())).thenReturn(ErrorCodes.ERROR_INVALID_PARAM);
assertThrows(() -> nfcF.setTimeout(-1));
}
@Test
public void testGetTimeout() throws RemoteException, IOException {
NfcF nfcF = createConnectedNfcF();
when(mNfcTagMock.getTimeout(anyInt())).thenReturn(250);
assertEquals(250, nfcF.getTimeout());
}
@Test
public void testGetTimeout_serviceDead() throws RemoteException, IOException {
NfcF nfcF = createConnectedNfcF();
when(mNfcTagMock.getTimeout(anyInt())).thenThrow(new RemoteException());
assertEquals(0, nfcF.getTimeout());
}
@Test
public void testGetTag() {
Bundle extras = new Bundle();
extras.putByteArray("systemcode", SYSTEM_CODE);
extras.putByteArray("pmm", MANUFACTURER);
Tag tag = new Tag(new byte[]{}, new int[]{TagTechnology.NFC_F}, new Bundle[]{extras}, 0, 0L,
mNfcTagMock);
NfcF nfcF = NfcF.get(tag);
assertEquals(tag, nfcF.getTag());
}
@Test
public void testIsConnected_isConnected() throws RemoteException, IOException {
NfcF nfcF = createConnectedNfcF();
when(mNfcTagMock.isPresent(anyInt())).thenReturn(true);
assertEquals(true, nfcF.isConnected());
}
@Test
public void testIsConnected_notConnected() throws RemoteException, IOException {
NfcF nfcF = createNfcF();
when(mNfcTagMock.isPresent(anyInt())).thenReturn(false);
assertEquals(false, nfcF.isConnected());
}
@Test
public void testIsConnected_serviceDead() throws RemoteException, IOException {
NfcF nfcF = createConnectedNfcF();
when(mNfcTagMock.isPresent(anyInt())).thenThrow(new RemoteException());
assertEquals(false, nfcF.isConnected());
}
@Test
public void testReconnect() throws RemoteException, IOException {
NfcF nfcF = createConnectedNfcF();
when(mNfcTagMock.reconnect(anyInt())).thenReturn(ErrorCodes.SUCCESS);
nfcF.reconnect();
verify(mNfcTagMock, times(1)).reconnect(anyInt());
}
@Test
public void testReconnect_notConnected() throws RemoteException, IOException {
NfcF nfcF = createNfcF();
assertThrows(() -> nfcF.reconnect());
}
@Test
public void testReconnect_failReconnect() throws RemoteException, IOException {
NfcF nfcF = createConnectedNfcF();
when(mNfcTagMock.reconnect(anyInt())).thenReturn(ErrorCodes.ERROR_CONNECT);
assertThrows(() -> nfcF.reconnect());
}
@Test
public void testReconnect_remoteException() throws RemoteException, IOException {
NfcF nfcF = createConnectedNfcF();
when(mNfcTagMock.reconnect(anyInt())).thenThrow(new RemoteException());
assertThrows(() -> nfcF.reconnect());
}
@Test
public void testClose() throws RemoteException, IOException {
NfcF nfcF = createConnectedNfcF();
when(mNfcTagMock.reconnect(anyInt())).thenReturn(ErrorCodes.SUCCESS);
when(mNfcTagMock.isPresent(anyInt())).thenReturn(true);
nfcF.close();
assertEquals(false, nfcF.isConnected());
}
private NfcF createConnectedNfcF() throws RemoteException, IOException {
NfcF nfcF = createNfcF();
when(mNfcTagMock.isTagUpToDate(anyLong())).thenReturn(true);
when(mNfcTagMock.connect(anyInt(), anyInt())).thenReturn(ErrorCodes.SUCCESS);
nfcF.connect();
return nfcF;
}
private NfcF createNfcF() {
Bundle extras = new Bundle();
extras.putByteArray("systemcode", SYSTEM_CODE);
extras.putByteArray("pmm", MANUFACTURER);
Tag tag = new Tag(new byte[]{}, new int[]{TagTechnology.NFC_F}, new Bundle[]{extras}, 0, 0L,
mNfcTagMock);
return NfcF.get(tag);
}
}