Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7381a002 authored by Meng Wang's avatar Meng Wang
Browse files

Correct the apdu unit test

Should verify the channel is not closed.

Bug: 393304737
Test: atest ApduSenderTest
Flag: TEST_ONLY
Change-Id: Iae44c7a7eb1c329acf3675c12c171819a93decdc
parent e0f7674c
Loading
Loading
Loading
Loading
+42 −33
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.platform.test.flag.junit.SetFlagsRule;
@@ -42,10 +41,9 @@ import android.telephony.IccOpenLogicalChannelResponse;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

import androidx.test.InstrumentationRegistry;

import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.euicc.EuiccSession;
import com.android.internal.telephony.flags.Flags;
import com.android.internal.telephony.uicc.IccIoResult;
@@ -61,7 +59,7 @@ import org.mockito.Mockito;

@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class ApduSenderTest {
public class ApduSenderTest extends TelephonyTest {
    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    private static class ResponseCaptor extends ApduSenderResultCallback {
@@ -107,13 +105,15 @@ public class ApduSenderTest {
    private ResponseCaptor mResponseCaptor;
    private byte[] mSelectResponse;
    private ApduSender mSender;
    private Context mContext;

    @Before
    public void setUp() {
    public void setUp() throws Exception {
        super.setUp(getClass().getSimpleName());

        mSetFlagsRule.enableFlags(Flags.FLAG_OPTIMIZATION_APDU_SENDER);
        mContextFixture.putBooleanResource(
                com.android.internal.R.bool.euicc_optimize_apdu_sender, true);

        mContext = InstrumentationRegistry.getContext();
        mMockCi = mock(CommandsInterface.class);
        mLooper = TestableLooper.get(this);
        mHandler = new Handler(mLooper.getLooper());
@@ -125,7 +125,7 @@ public class ApduSenderTest {
    }

    @After
    public void tearDown() throws InterruptedException {
    public void tearDown() throws Exception {
        // Send an APDU to verify that the channel lock is not stuck (b/382549728).
        // Sameas testSend(), but not verifying mMockCi interactions.
        checkChannelLock();
@@ -138,21 +138,24 @@ public class ApduSenderTest {
        mSender = null;

        EuiccSession.get(mContext).endSession(SESSION_ID);
        resetEuiccSession();
        clearSharedPreferences();

        super.tearDown();
    }

    @Test
    public void testWrongAid_throwsIllegalArgumentException() {
    public void testWrongAid_throwsIllegalArgumentException() throws Exception {
        String wrongAid = "-1";

        assertThrows(IllegalArgumentException.class, () -> {
            new ApduSender(InstrumentationRegistry.getContext(), 0 /* phoneId= */,
            new ApduSender(mContext, 0 /* phoneId= */,
                            mMockCi, wrongAid, false /* supportExtendedApdu */);
        });
    }

    @Test
    public void testSendEmptyCommands() throws InterruptedException {
    public void testSendEmptyCommands() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "A1A1A19000");
        LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel, /* error= */ null);

@@ -168,7 +171,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testOpenChannelErrorStatus() throws InterruptedException {
    public void testOpenChannelErrorStatus() throws Exception {
        LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi,
                new CommandException(CommandException.Error.NO_SUCH_ELEMENT));

@@ -183,7 +186,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testSend() throws InterruptedException {
    public void testSend() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, "A1A1A19000");
        LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel, /* error= */ null);
@@ -201,7 +204,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testSendMultiApdus() throws InterruptedException {
    public void testSendMultiApdus() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, "A19000", "A29000",
                "A39000", "A49000");
@@ -230,7 +233,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testSendMultiApdusStopEarly() throws InterruptedException {
    public void testSendMultiApdusStopEarly() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, "A19000", "A29000",
                "A39000", "A49000");
@@ -255,7 +258,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testSendLongResponse() throws InterruptedException {
    public void testSendLongResponse() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, "A1A1A16104",
                "B2B2B2B26102", "C3C39000");
@@ -275,7 +278,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testSendStoreDataLongDataLongResponse() throws InterruptedException {
    public void testSendStoreDataLongDataLongResponse() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, "A19000", "9000", "9000",
                "B22B6103", "B2222B9000", "C39000");
@@ -307,7 +310,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testSendStoreDataLongDataMod0() throws InterruptedException {
    public void testSendStoreDataLongDataMod0() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, "9000", "B2222B9000");
        LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel, /* error= */ null);
@@ -329,7 +332,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testSendStoreDataLen0() throws InterruptedException {
    public void testSendStoreDataLen0() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, "B2222B9000");
        LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel, /* error= */ null);
@@ -345,7 +348,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testSendErrorResponseInMiddle() throws InterruptedException {
    public void testSendErrorResponseInMiddle() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, "A19000", "9000",
                "B22B6103", "6985");
@@ -374,7 +377,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testChannelAlreadyOpened() throws InterruptedException {
    public void testChannelAlreadyOpened() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel, /* error= */ null);

@@ -393,7 +396,8 @@ public class ApduSenderTest {
    }

    @Test
    public void testSend_OpenChannelFailedNoSuchElement_useChannelInSharedPreference() {
    public void testSend_OpenChannelFailedNoSuchElement_useChannelInSharedPreference()
            throws Exception {
        // Open a channel but not close, by making CI.iccTransmitApduLogicalChannel throw.
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        doThrow(new RuntimeException()).when(mMockCi).iccTransmitApduLogicalChannel(
@@ -402,7 +406,7 @@ public class ApduSenderTest {
        mSender.send((selectResponse, requestBuilder) -> requestBuilder.addApdu(
                10, 1, 2, 3, 0, "a"), mResponseCaptor, mHandler);
        mLooper.processAllMessages();
        mSender = new ApduSender(InstrumentationRegistry.getContext(), PHONE_ID,
        mSender = new ApduSender(mContext, PHONE_ID,
                            mMockCi, ApduSender.ISD_R_AID, false /* supportExtendedApdu */);
        reset(mMockCi);
        // Stub open channel failure NO_SUCH_ELEMENT
@@ -426,8 +430,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testSend_euiccSession_shouldNotCloseChannel()
            throws InterruptedException {
    public void testSend_euiccSession_shouldNotCloseChannel() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, "A1A1A19000");
        LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel, /* error= */ null);
@@ -442,7 +445,7 @@ public class ApduSenderTest {
        inOrder.verify(mMockCi).iccOpenLogicalChannel(eq(ApduSender.ISD_R_AID), anyInt(), any());
        inOrder.verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10),
                eq(1), eq(2), eq(3), eq(0), eq("a"), anyBoolean(), any());
        inOrder.verify(mMockCi).iccCloseLogicalChannel(eq(channel), eq(true /*isEs10*/), any());
        // No iccCloseLogicalChannel
        inOrder.verifyNoMoreInteractions();
    }

@@ -468,8 +471,7 @@ public class ApduSenderTest {
    }

    @Test
    public void testSendTwice_euiccSession_shouldOpenChannelOnceNotCloseChannel()
            throws InterruptedException {
    public void testSendTwice_euiccSession_shouldOpenChannelOnceNotCloseChannel() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(
                    mMockCi, channel, "A1A1A19000", "A1A1A19000");
@@ -490,12 +492,12 @@ public class ApduSenderTest {
        // iccTransmitApduLogicalChannel twice
        inOrder.verify(mMockCi, times(2)).iccTransmitApduLogicalChannel(eq(channel),
                 eq(channel | 10), eq(1), eq(2), eq(3), eq(0), eq("a"), anyBoolean(), any());
        inOrder.verify(mMockCi).iccCloseLogicalChannel(eq(channel), eq(true /*isEs10*/), any());
        // No iccCloseLogicalChannel
        inOrder.verifyNoMoreInteractions();
    }

    @Test
    public void testSendTwice_thenEndSession() throws InterruptedException {
    public void testSendTwice_thenEndSession() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel,
                "A1A1A19000", "A1A1A19000");
@@ -523,12 +525,12 @@ public class ApduSenderTest {
    }

    private int getChannelIdFromSharedPreferences() {
        return PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getContext())
        return PreferenceManager.getDefaultSharedPreferences(mContext)
                .getInt(SHARED_PREFS_KEY_CHANNEL_ID, -1);
    }

    private void clearSharedPreferences() {
        PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getContext())
        PreferenceManager.getDefaultSharedPreferences(mContext)
                .edit()
                .remove(SHARED_PREFS_KEY_CHANNEL_ID)
                .remove(SHARED_PREFS_KEY_CHANNEL_RESPONSE)
@@ -539,7 +541,7 @@ public class ApduSenderTest {
     * Send an APDU to verify that the channel lock is not stuck (b/382549728).
     * Same as testSend(), but not verifying mMockCi interactions.
     */
    private void checkChannelLock() throws InterruptedException {
    private void checkChannelLock() throws Exception {
        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "9000");
        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, "A1A1A19000");
        LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel, /* error= */ null);
@@ -550,4 +552,11 @@ public class ApduSenderTest {

        assertEquals("A1A1A1", IccUtils.bytesToHexString(mResponseCaptor.response));
    }

    /** Clears the static states of EuiccSession. */
    private void resetEuiccSession() throws Exception {
        java.lang.reflect.Field field = EuiccSession.class.getDeclaredField("sInstance");
        field.setAccessible(true);
        field.set(null, null);
    }
}