Loading android/app/src/com/android/bluetooth/sap/SapRilReceiver.java +0 −54 Original line number Diff line number Diff line Loading @@ -279,60 +279,6 @@ public class SapRilReceiver { } } /** * Read the message into buffer * @param is * @param buffer * @return the length of the message * @throws IOException */ private static int readMessage(InputStream is, byte[] buffer) throws IOException { int countRead; int offset; int remaining; int messageLength; // Read in the length of the message offset = 0; remaining = 4; do { countRead = is.read(buffer, offset, remaining); if (countRead < 0) { Log.e(TAG, "Hit EOS reading message length"); return -1; } offset += countRead; remaining -= countRead; } while (remaining > 0); messageLength = ((buffer[0] & 0xff) << 24) | ((buffer[1] & 0xff) << 16) | ((buffer[2] & 0xff) << 8) | (buffer[3] & 0xff); if (VERBOSE) { Log.e(TAG, "Message length found to be: " + messageLength); } // Read the message offset = 0; remaining = messageLength; do { countRead = is.read(buffer, offset, remaining); if (countRead < 0) { Log.e(TAG, "Hit EOS reading message. messageLength=" + messageLength + " remaining=" + remaining); return -1; } offset += countRead; remaining -= countRead; } while (remaining > 0); return messageLength; } /** * Notify SapServer that the RIL socket is connected */ Loading android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java 0 → 100644 +435 −0 Original line number Diff line number Diff line /* * Copyright 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 com.android.bluetooth.sap; import static com.android.bluetooth.sap.SapMessage.CON_STATUS_OK; import static com.android.bluetooth.sap.SapMessage.DISC_GRACEFULL; import static com.android.bluetooth.sap.SapMessage.ID_CONNECT_RESP; import static com.android.bluetooth.sap.SapMessage.ID_DISCONNECT_RESP; import static com.android.bluetooth.sap.SapMessage.ID_POWER_SIM_OFF_REQ; import static com.android.bluetooth.sap.SapMessage.ID_POWER_SIM_OFF_RESP; import static com.android.bluetooth.sap.SapMessage.ID_POWER_SIM_ON_REQ; import static com.android.bluetooth.sap.SapMessage.ID_POWER_SIM_ON_RESP; import static com.android.bluetooth.sap.SapMessage.ID_RESET_SIM_RESP; import static com.android.bluetooth.sap.SapMessage.ID_RIL_UNKNOWN; import static com.android.bluetooth.sap.SapMessage.ID_RIL_UNSOL_DISCONNECT_IND; import static com.android.bluetooth.sap.SapMessage.ID_SET_TRANSPORT_PROTOCOL_RESP; import static com.android.bluetooth.sap.SapMessage.ID_STATUS_IND; import static com.android.bluetooth.sap.SapMessage.ID_TRANSFER_APDU_RESP; import static com.android.bluetooth.sap.SapMessage.ID_TRANSFER_ATR_RESP; import static com.android.bluetooth.sap.SapMessage.ID_TRANSFER_CARD_READER_STATUS_RESP; import static com.android.bluetooth.sap.SapMessage.RESULT_OK; import static com.android.bluetooth.sap.SapMessage.STATUS_CARD_INSERTED; import static com.android.bluetooth.sap.SapServer.ISAP_GET_SERVICE_DELAY_MILLIS; import static com.android.bluetooth.sap.SapServer.SAP_MSG_RFC_REPLY; import static com.android.bluetooth.sap.SapServer.SAP_MSG_RIL_CONNECT; import static com.android.bluetooth.sap.SapServer.SAP_MSG_RIL_IND; import static com.android.bluetooth.sap.SapServer.SAP_PROXY_DEAD; import static com.android.bluetooth.sap.SapServer.SAP_RIL_SOCK_CLOSED; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.argThat; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import android.hardware.radio.V1_0.ISap; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; import java.util.ArrayList; import java.util.Arrays; @LargeTest @RunWith(AndroidJUnit4.class) public class SapRilReceiverTest { private static final long TIMEOUT_MS = 1_000; private HandlerThread mHandlerThread; private Handler mServerMsgHandler; @Spy private TestHandlerCallback mCallback = new TestHandlerCallback(); @Mock private Handler mServiceHandler; @Mock private ISap mSapProxy; private SapRilReceiver mReceiver; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mHandlerThread = new HandlerThread("SapRilReceiverTest"); mHandlerThread.start(); mServerMsgHandler = new Handler(mHandlerThread.getLooper(), mCallback); mReceiver = new SapRilReceiver(mServerMsgHandler, mServiceHandler); mReceiver.mSapProxy = mSapProxy; } @After public void tearDown() { mHandlerThread.quit(); } @Test public void getSapProxyLock() { assertThat(mReceiver.getSapProxyLock()).isNotNull(); } @Test public void resetSapProxy() throws Exception { mReceiver.resetSapProxy(); assertThat(mReceiver.mSapProxy).isNull(); verify(mSapProxy).unlinkToDeath(any()); } @Test public void notifyShutdown() throws Exception { mReceiver.notifyShutdown(); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_RIL_SOCK_CLOSED), any()); } @Test public void sendRilConnectMessage() throws Exception { mReceiver.sendRilConnectMessage(); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_CONNECT), any()); } @Test public void serviceDied() throws Exception { long cookie = 1; mReceiver.mSapProxyDeathRecipient.serviceDied(cookie); verify(mCallback, timeout(ISAP_GET_SERVICE_DELAY_MILLIS + TIMEOUT_MS)) .receiveMessage(eq(SAP_PROXY_DEAD), argThat( arg -> (arg instanceof Long) && ((Long) arg == cookie) )); } @Test public void callback_connectResponse() throws Exception { int token = 1; int sapConnectRsp = CON_STATUS_OK; int maxMsgSize = 512; mReceiver.mSapCallback.connectResponse(token, sapConnectRsp, maxMsgSize); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_CONNECT_RESP && sapMsg.getConnectionStatus() == sapConnectRsp; } } )); } @Test public void callback_disconnectResponse() throws Exception { int token = 1; mReceiver.mSapCallback.disconnectResponse(token); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_DISCONNECT_RESP; } } )); } @Test public void callback_disconnectIndication() throws Exception { int token = 1; int disconnectType = DISC_GRACEFULL; mReceiver.mSapCallback.disconnectIndication(token, disconnectType); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_IND), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_RIL_UNSOL_DISCONNECT_IND && sapMsg.getDisconnectionType() == disconnectType; } } )); } @Test public void callback_apduResponse() throws Exception { int token = 1; int resultCode = RESULT_OK; byte[] apduRsp = new byte[]{0x03, 0x04}; ArrayList<Byte> apduRspList = new ArrayList<>(); for (byte b : apduRsp) { apduRspList.add(b); } mReceiver.mSapCallback.apduResponse(token, resultCode, apduRspList); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_TRANSFER_APDU_RESP && sapMsg.getResultCode() == resultCode && Arrays.equals(sapMsg.getApduResp(), apduRsp); } } )); } @Test public void callback_transferAtrResponse() throws Exception { int token = 1; int resultCode = RESULT_OK; byte[] atr = new byte[]{0x03, 0x04}; ArrayList<Byte> atrList = new ArrayList<>(); for (byte b : atr) { atrList.add(b); } mReceiver.mSapCallback.transferAtrResponse(token, resultCode, atrList); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_TRANSFER_ATR_RESP && sapMsg.getResultCode() == resultCode && Arrays.equals(sapMsg.getAtr(), atr); } } )); } @Test public void callback_powerResponse_powerOff() throws Exception { int token = 1; int reqType = ID_POWER_SIM_OFF_REQ; int resultCode = RESULT_OK; SapMessage.sOngoingRequests.clear(); SapMessage.sOngoingRequests.put(token, reqType); mReceiver.mSapCallback.powerResponse(token, resultCode); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_POWER_SIM_OFF_RESP && sapMsg.getResultCode() == resultCode; } } )); } @Test public void callback_powerResponse_powerOn() throws Exception { int token = 1; int reqType = ID_POWER_SIM_ON_REQ; int resultCode = RESULT_OK; SapMessage.sOngoingRequests.clear(); SapMessage.sOngoingRequests.put(token, reqType); mReceiver.mSapCallback.powerResponse(token, resultCode); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_POWER_SIM_ON_RESP && sapMsg.getResultCode() == resultCode; } } )); } @Test public void callback_resetSimResponse() throws Exception { int token = 1; int resultCode = RESULT_OK; mReceiver.mSapCallback.resetSimResponse(token, resultCode); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_RESET_SIM_RESP && sapMsg.getResultCode() == resultCode; } } )); } @Test public void callback_statusIndication() throws Exception { int token = 1; int statusChange = 2; mReceiver.mSapCallback.statusIndication(token, statusChange); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_STATUS_IND && sapMsg.getStatusChange() == statusChange; } } )); } @Test public void callback_transferCardReaderStatusResponse() throws Exception { int token = 1; int resultCode = RESULT_OK; int cardReaderStatus = STATUS_CARD_INSERTED; mReceiver.mSapCallback.transferCardReaderStatusResponse( token, resultCode, cardReaderStatus); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_TRANSFER_CARD_READER_STATUS_RESP && sapMsg.getResultCode() == resultCode; } } )); } @Test public void callback_errorResponse() throws Exception { int token = 1; mReceiver.mSapCallback.errorResponse(token); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_IND), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_RIL_UNKNOWN; } } )); } @Test public void callback_transferProtocolResponse() throws Exception { int token = 1; int resultCode = RESULT_OK; mReceiver.mSapCallback.transferProtocolResponse(token, resultCode); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_SET_TRANSPORT_PROTOCOL_RESP && sapMsg.getResultCode() == resultCode; } } )); } public static class TestHandlerCallback implements Handler.Callback { @Override public boolean handleMessage(Message msg) { receiveMessage(msg.what, msg.obj); return true; } public void receiveMessage(int what, Object obj) {} } } Loading
android/app/src/com/android/bluetooth/sap/SapRilReceiver.java +0 −54 Original line number Diff line number Diff line Loading @@ -279,60 +279,6 @@ public class SapRilReceiver { } } /** * Read the message into buffer * @param is * @param buffer * @return the length of the message * @throws IOException */ private static int readMessage(InputStream is, byte[] buffer) throws IOException { int countRead; int offset; int remaining; int messageLength; // Read in the length of the message offset = 0; remaining = 4; do { countRead = is.read(buffer, offset, remaining); if (countRead < 0) { Log.e(TAG, "Hit EOS reading message length"); return -1; } offset += countRead; remaining -= countRead; } while (remaining > 0); messageLength = ((buffer[0] & 0xff) << 24) | ((buffer[1] & 0xff) << 16) | ((buffer[2] & 0xff) << 8) | (buffer[3] & 0xff); if (VERBOSE) { Log.e(TAG, "Message length found to be: " + messageLength); } // Read the message offset = 0; remaining = messageLength; do { countRead = is.read(buffer, offset, remaining); if (countRead < 0) { Log.e(TAG, "Hit EOS reading message. messageLength=" + messageLength + " remaining=" + remaining); return -1; } offset += countRead; remaining -= countRead; } while (remaining > 0); return messageLength; } /** * Notify SapServer that the RIL socket is connected */ Loading
android/app/tests/unit/src/com/android/bluetooth/sap/SapRilReceiverTest.java 0 → 100644 +435 −0 Original line number Diff line number Diff line /* * Copyright 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 com.android.bluetooth.sap; import static com.android.bluetooth.sap.SapMessage.CON_STATUS_OK; import static com.android.bluetooth.sap.SapMessage.DISC_GRACEFULL; import static com.android.bluetooth.sap.SapMessage.ID_CONNECT_RESP; import static com.android.bluetooth.sap.SapMessage.ID_DISCONNECT_RESP; import static com.android.bluetooth.sap.SapMessage.ID_POWER_SIM_OFF_REQ; import static com.android.bluetooth.sap.SapMessage.ID_POWER_SIM_OFF_RESP; import static com.android.bluetooth.sap.SapMessage.ID_POWER_SIM_ON_REQ; import static com.android.bluetooth.sap.SapMessage.ID_POWER_SIM_ON_RESP; import static com.android.bluetooth.sap.SapMessage.ID_RESET_SIM_RESP; import static com.android.bluetooth.sap.SapMessage.ID_RIL_UNKNOWN; import static com.android.bluetooth.sap.SapMessage.ID_RIL_UNSOL_DISCONNECT_IND; import static com.android.bluetooth.sap.SapMessage.ID_SET_TRANSPORT_PROTOCOL_RESP; import static com.android.bluetooth.sap.SapMessage.ID_STATUS_IND; import static com.android.bluetooth.sap.SapMessage.ID_TRANSFER_APDU_RESP; import static com.android.bluetooth.sap.SapMessage.ID_TRANSFER_ATR_RESP; import static com.android.bluetooth.sap.SapMessage.ID_TRANSFER_CARD_READER_STATUS_RESP; import static com.android.bluetooth.sap.SapMessage.RESULT_OK; import static com.android.bluetooth.sap.SapMessage.STATUS_CARD_INSERTED; import static com.android.bluetooth.sap.SapServer.ISAP_GET_SERVICE_DELAY_MILLIS; import static com.android.bluetooth.sap.SapServer.SAP_MSG_RFC_REPLY; import static com.android.bluetooth.sap.SapServer.SAP_MSG_RIL_CONNECT; import static com.android.bluetooth.sap.SapServer.SAP_MSG_RIL_IND; import static com.android.bluetooth.sap.SapServer.SAP_PROXY_DEAD; import static com.android.bluetooth.sap.SapServer.SAP_RIL_SOCK_CLOSED; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.argThat; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import android.hardware.radio.V1_0.ISap; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; import java.util.ArrayList; import java.util.Arrays; @LargeTest @RunWith(AndroidJUnit4.class) public class SapRilReceiverTest { private static final long TIMEOUT_MS = 1_000; private HandlerThread mHandlerThread; private Handler mServerMsgHandler; @Spy private TestHandlerCallback mCallback = new TestHandlerCallback(); @Mock private Handler mServiceHandler; @Mock private ISap mSapProxy; private SapRilReceiver mReceiver; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mHandlerThread = new HandlerThread("SapRilReceiverTest"); mHandlerThread.start(); mServerMsgHandler = new Handler(mHandlerThread.getLooper(), mCallback); mReceiver = new SapRilReceiver(mServerMsgHandler, mServiceHandler); mReceiver.mSapProxy = mSapProxy; } @After public void tearDown() { mHandlerThread.quit(); } @Test public void getSapProxyLock() { assertThat(mReceiver.getSapProxyLock()).isNotNull(); } @Test public void resetSapProxy() throws Exception { mReceiver.resetSapProxy(); assertThat(mReceiver.mSapProxy).isNull(); verify(mSapProxy).unlinkToDeath(any()); } @Test public void notifyShutdown() throws Exception { mReceiver.notifyShutdown(); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_RIL_SOCK_CLOSED), any()); } @Test public void sendRilConnectMessage() throws Exception { mReceiver.sendRilConnectMessage(); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_CONNECT), any()); } @Test public void serviceDied() throws Exception { long cookie = 1; mReceiver.mSapProxyDeathRecipient.serviceDied(cookie); verify(mCallback, timeout(ISAP_GET_SERVICE_DELAY_MILLIS + TIMEOUT_MS)) .receiveMessage(eq(SAP_PROXY_DEAD), argThat( arg -> (arg instanceof Long) && ((Long) arg == cookie) )); } @Test public void callback_connectResponse() throws Exception { int token = 1; int sapConnectRsp = CON_STATUS_OK; int maxMsgSize = 512; mReceiver.mSapCallback.connectResponse(token, sapConnectRsp, maxMsgSize); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_CONNECT_RESP && sapMsg.getConnectionStatus() == sapConnectRsp; } } )); } @Test public void callback_disconnectResponse() throws Exception { int token = 1; mReceiver.mSapCallback.disconnectResponse(token); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_DISCONNECT_RESP; } } )); } @Test public void callback_disconnectIndication() throws Exception { int token = 1; int disconnectType = DISC_GRACEFULL; mReceiver.mSapCallback.disconnectIndication(token, disconnectType); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_IND), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_RIL_UNSOL_DISCONNECT_IND && sapMsg.getDisconnectionType() == disconnectType; } } )); } @Test public void callback_apduResponse() throws Exception { int token = 1; int resultCode = RESULT_OK; byte[] apduRsp = new byte[]{0x03, 0x04}; ArrayList<Byte> apduRspList = new ArrayList<>(); for (byte b : apduRsp) { apduRspList.add(b); } mReceiver.mSapCallback.apduResponse(token, resultCode, apduRspList); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_TRANSFER_APDU_RESP && sapMsg.getResultCode() == resultCode && Arrays.equals(sapMsg.getApduResp(), apduRsp); } } )); } @Test public void callback_transferAtrResponse() throws Exception { int token = 1; int resultCode = RESULT_OK; byte[] atr = new byte[]{0x03, 0x04}; ArrayList<Byte> atrList = new ArrayList<>(); for (byte b : atr) { atrList.add(b); } mReceiver.mSapCallback.transferAtrResponse(token, resultCode, atrList); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_TRANSFER_ATR_RESP && sapMsg.getResultCode() == resultCode && Arrays.equals(sapMsg.getAtr(), atr); } } )); } @Test public void callback_powerResponse_powerOff() throws Exception { int token = 1; int reqType = ID_POWER_SIM_OFF_REQ; int resultCode = RESULT_OK; SapMessage.sOngoingRequests.clear(); SapMessage.sOngoingRequests.put(token, reqType); mReceiver.mSapCallback.powerResponse(token, resultCode); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_POWER_SIM_OFF_RESP && sapMsg.getResultCode() == resultCode; } } )); } @Test public void callback_powerResponse_powerOn() throws Exception { int token = 1; int reqType = ID_POWER_SIM_ON_REQ; int resultCode = RESULT_OK; SapMessage.sOngoingRequests.clear(); SapMessage.sOngoingRequests.put(token, reqType); mReceiver.mSapCallback.powerResponse(token, resultCode); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_POWER_SIM_ON_RESP && sapMsg.getResultCode() == resultCode; } } )); } @Test public void callback_resetSimResponse() throws Exception { int token = 1; int resultCode = RESULT_OK; mReceiver.mSapCallback.resetSimResponse(token, resultCode); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_RESET_SIM_RESP && sapMsg.getResultCode() == resultCode; } } )); } @Test public void callback_statusIndication() throws Exception { int token = 1; int statusChange = 2; mReceiver.mSapCallback.statusIndication(token, statusChange); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_STATUS_IND && sapMsg.getStatusChange() == statusChange; } } )); } @Test public void callback_transferCardReaderStatusResponse() throws Exception { int token = 1; int resultCode = RESULT_OK; int cardReaderStatus = STATUS_CARD_INSERTED; mReceiver.mSapCallback.transferCardReaderStatusResponse( token, resultCode, cardReaderStatus); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_TRANSFER_CARD_READER_STATUS_RESP && sapMsg.getResultCode() == resultCode; } } )); } @Test public void callback_errorResponse() throws Exception { int token = 1; mReceiver.mSapCallback.errorResponse(token); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RIL_IND), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_RIL_UNKNOWN; } } )); } @Test public void callback_transferProtocolResponse() throws Exception { int token = 1; int resultCode = RESULT_OK; mReceiver.mSapCallback.transferProtocolResponse(token, resultCode); verify(mCallback, timeout(TIMEOUT_MS)).receiveMessage(eq(SAP_MSG_RFC_REPLY), argThat( new ArgumentMatcher<Object>() { @Override public boolean matches(Object arg) { if (!(arg instanceof SapMessage)) { return false; } SapMessage sapMsg = (SapMessage) arg; return sapMsg.getMsgType() == ID_SET_TRANSPORT_PROTOCOL_RESP && sapMsg.getResultCode() == resultCode; } } )); } public static class TestHandlerCallback implements Handler.Callback { @Override public boolean handleMessage(Message msg) { receiveMessage(msg.what, msg.obj); return true; } public void receiveMessage(int what, Object obj) {} } }