Loading src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java +85 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.internal.telephony.uicc.euicc; import android.annotation.Nullable; import android.content.Context; import android.content.res.Resources; import android.os.AsyncResult; import android.os.Handler; import android.os.Registrant; Loading Loading @@ -84,6 +85,16 @@ public class EuiccCard extends UiccCard { private static final EuiccSpecVersion SGP_2_0 = new EuiccSpecVersion(2, 0, 0); // Device capabilities. private static final String DEV_CAP_GSM = "gsm"; private static final String DEV_CAP_UTRAN = "utran"; private static final String DEV_CAP_CDMA_1X = "cdma_1x"; private static final String DEV_CAP_HRPD = "hrpd"; private static final String DEV_CAP_EHRPD = "ehrpd"; private static final String DEV_CAP_EUTRAN = "eutran"; private static final String DEV_CAP_NFC = "nfc"; private static final String DEV_CAP_CRL = "crl"; // These interfaces are used for simplifying the code by leveraging lambdas. private interface ApduRequestBuilder { void build(RequestBuilder requestBuilder) Loading Loading @@ -599,8 +610,16 @@ public class EuiccCard extends UiccCard { byte[] tacBytes = new byte[4]; System.arraycopy(imeiBytes, 0, tacBytes, 0, 4); // TODO: Get device capabilities. Asn1Node.Builder devCapsBuilder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1); String[] devCapsStrings = getResources().getStringArray( com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities); if (devCapsStrings != null) { for (String devCapItem : devCapsStrings) { addDeviceCapability(devCapsBuilder, devCapItem); } } else { if (DBG) logd("No device capabilities set."); } Asn1Node.Builder ctxParams1Builder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0) .addChildAsString(Tags.TAG_CTX_0, matchingId) Loading Loading @@ -875,6 +894,62 @@ public class EuiccCard extends UiccCard { callback, handler); } /** * Sets a device capability version as the child of the given device capability ASN1 node * builder. * * @param devCapBuilder The ASN1 node builder to modify. * @param devCapItem The device capability and its supported version in pair. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) public void addDeviceCapability(Asn1Node.Builder devCapBuilder, String devCapItem) { String[] split = devCapItem.split(","); if (split.length != 2) { loge("Invalid device capability item: " + Arrays.toString(split)); return; } String devCap = split[0].trim(); Integer version; try { version = Integer.parseInt(split[1].trim()); } catch (NumberFormatException e) { loge("Invalid device capability version number.", e); return; } byte[] versionBytes = new byte[] { version.byteValue(), 0, 0 }; switch (devCap) { case DEV_CAP_GSM: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_0, versionBytes); break; case DEV_CAP_UTRAN: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_1, versionBytes); break; case DEV_CAP_CDMA_1X: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_2, versionBytes); break; case DEV_CAP_HRPD: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_3, versionBytes); break; case DEV_CAP_EHRPD: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_4, versionBytes); break; case DEV_CAP_EUTRAN: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_5, versionBytes); break; case DEV_CAP_NFC: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_6, versionBytes); break; case DEV_CAP_CRL: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_7, versionBytes); break; default: loge("Invalid device capability name: " + devCap); break; } } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected byte[] getDeviceId() { byte[] imeiBytes = new byte[8]; Loading @@ -885,6 +960,11 @@ public class EuiccCard extends UiccCard { return imeiBytes; } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected Resources getResources() { return Resources.getSystem(); } private RequestProvider newRequestProvider(ApduRequestBuilder builder) { return (selectResponse, requestBuilder) -> { EuiccSpecVersion ver = getOrExtractSpecVersion(selectResponse); Loading Loading @@ -1150,6 +1230,10 @@ public class EuiccCard extends UiccCard { Rlog.e(LOG_TAG, message); } private static void loge(String message, Throwable tr) { Rlog.e(LOG_TAG, message, tr); } private static void logi(String message) { Rlog.i(LOG_TAG, message); } Loading tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java +132 −0 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.res.Resources; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; Loading @@ -44,6 +46,8 @@ import com.android.internal.telephony.uicc.IccCardApplicationStatus; import com.android.internal.telephony.uicc.IccCardStatus; import com.android.internal.telephony.uicc.IccUtils; import com.android.internal.telephony.uicc.asn1.Asn1Node; import com.android.internal.telephony.uicc.asn1.InvalidAsn1DataException; import com.android.internal.telephony.uicc.asn1.TagNotFoundException; import com.android.internal.telephony.uicc.euicc.apdu.LogicalChannelMocker; import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback; Loading @@ -52,6 +56,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -106,6 +111,12 @@ public class EuiccCardTest extends TelephonyTest { @Override protected void loadEidAndNotifyRegistrants() {} @Override protected Resources getResources() { return mMockResources; } }; mHandler = new Handler(mTestHandlerThread.getLooper()); setReady(true); Loading @@ -122,6 +133,9 @@ public class EuiccCardTest extends TelephonyTest { private EuiccCard mEuiccCard; @Mock private Resources mMockResources; @Before public void setUp() throws Exception { super.setUp(getClass().getSimpleName()); Loading Loading @@ -520,6 +534,10 @@ public class EuiccCardTest extends TelephonyTest { @Test public void testAuthenticateServer() { when(mMockResources.getStringArray( com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities)) .thenReturn(new String[] {}); int channel = mockLogicalChannelResponses("BF3802A0009000"); ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); Loading @@ -542,6 +560,10 @@ public class EuiccCardTest extends TelephonyTest { @Test public void testAuthenticateServer_Error() { when(mMockResources.getStringArray( com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities)) .thenReturn(new String[] {}); int channel = mockLogicalChannelResponses("BF38038101039000"); ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); Loading @@ -561,6 +583,39 @@ public class EuiccCardTest extends TelephonyTest { + "82088967452301214305"); // IMEI } @Test public void testAuthenticateService_devCap() { when(mMockResources.getStringArray( com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities)) .thenReturn(new String[] { "gsm,11", "utran,11", "cdma1x,1", "hrpd,3", "ehrpd,12", "eutran,11"}); int channel = mockLogicalChannelResponses("BF3802A0009000"); ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id Asn1Node.newBuilder(0xA0).build().toBytes(), Asn1Node.newBuilder(0xA1).build().toBytes(), Asn1Node.newBuilder(0xA2).build().toBytes(), Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler); resultCaptor.await(); assertUnexpectedException(resultCaptor.exception); assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result)); verifyStoreData(channel, "BF3846" + "A000" + "A100" + "A200" + "A300" + "A03C" + "800D4131423243332D583459355A36" // Matching id + "A12B800489674523" // TAC // Device capabilities + "A11980030B000081030B0000830303000084030C000085030B0000" + "82088967452301214305"); // IMEI } @Test public void testPrepareDownload() { int channel = mockLogicalChannelResponses("BF2102A0009000"); Loading Loading @@ -852,6 +907,83 @@ public class EuiccCardTest extends TelephonyTest { verifyStoreData(channel, "BF3003800105"); } @Test public void testAddDeviceCapability() throws InvalidAsn1DataException, TagNotFoundException { Asn1Node.Builder devCapsBuilder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1); String devCapItem = "gsm,11"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); Asn1Node node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_0)); Asn1Node child = node.getChild(Tags.TAG_CTX_0); assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes())); devCapItem = "utran,11"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_1)); child = node.getChild(Tags.TAG_CTX_1); assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes())); devCapItem = "cdma_1x,1"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_2)); child = node.getChild(Tags.TAG_CTX_2); assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes())); devCapItem = "hrpd,1"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_3)); child = node.getChild(Tags.TAG_CTX_3); assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes())); devCapItem = "ehrpd,12"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_4)); child = node.getChild(Tags.TAG_CTX_4); assertTrue(Arrays.equals(new byte[] {12, 0 , 0}, child.asBytes())); devCapItem = "eutran,11"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_5)); child = node.getChild(Tags.TAG_CTX_5); assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes())); devCapItem = "nfc,0"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_6)); child = node.getChild(Tags.TAG_CTX_6); assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes())); devCapItem = "crl,0"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_7)); child = node.getChild(Tags.TAG_CTX_7); assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes())); // Array length should not be 3. Asn1Node.Builder devCapsBuilder2 = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1); devCapItem = "gsm,1,1"; mEuiccCard.addDeviceCapability(devCapsBuilder2, devCapItem); node = devCapsBuilder2.build(); assertFalse(node.hasChild(Tags.TAG_CTX_0)); } private void verifyStoreData(int channel, String command) { verify(mMockCi, times(1)) .iccTransmitApduLogicalChannel(eq(channel), eq(0x80 | channel), eq(0xE2), eq(0x91), Loading Loading
src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java +85 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.internal.telephony.uicc.euicc; import android.annotation.Nullable; import android.content.Context; import android.content.res.Resources; import android.os.AsyncResult; import android.os.Handler; import android.os.Registrant; Loading Loading @@ -84,6 +85,16 @@ public class EuiccCard extends UiccCard { private static final EuiccSpecVersion SGP_2_0 = new EuiccSpecVersion(2, 0, 0); // Device capabilities. private static final String DEV_CAP_GSM = "gsm"; private static final String DEV_CAP_UTRAN = "utran"; private static final String DEV_CAP_CDMA_1X = "cdma_1x"; private static final String DEV_CAP_HRPD = "hrpd"; private static final String DEV_CAP_EHRPD = "ehrpd"; private static final String DEV_CAP_EUTRAN = "eutran"; private static final String DEV_CAP_NFC = "nfc"; private static final String DEV_CAP_CRL = "crl"; // These interfaces are used for simplifying the code by leveraging lambdas. private interface ApduRequestBuilder { void build(RequestBuilder requestBuilder) Loading Loading @@ -599,8 +610,16 @@ public class EuiccCard extends UiccCard { byte[] tacBytes = new byte[4]; System.arraycopy(imeiBytes, 0, tacBytes, 0, 4); // TODO: Get device capabilities. Asn1Node.Builder devCapsBuilder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1); String[] devCapsStrings = getResources().getStringArray( com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities); if (devCapsStrings != null) { for (String devCapItem : devCapsStrings) { addDeviceCapability(devCapsBuilder, devCapItem); } } else { if (DBG) logd("No device capabilities set."); } Asn1Node.Builder ctxParams1Builder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0) .addChildAsString(Tags.TAG_CTX_0, matchingId) Loading Loading @@ -875,6 +894,62 @@ public class EuiccCard extends UiccCard { callback, handler); } /** * Sets a device capability version as the child of the given device capability ASN1 node * builder. * * @param devCapBuilder The ASN1 node builder to modify. * @param devCapItem The device capability and its supported version in pair. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) public void addDeviceCapability(Asn1Node.Builder devCapBuilder, String devCapItem) { String[] split = devCapItem.split(","); if (split.length != 2) { loge("Invalid device capability item: " + Arrays.toString(split)); return; } String devCap = split[0].trim(); Integer version; try { version = Integer.parseInt(split[1].trim()); } catch (NumberFormatException e) { loge("Invalid device capability version number.", e); return; } byte[] versionBytes = new byte[] { version.byteValue(), 0, 0 }; switch (devCap) { case DEV_CAP_GSM: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_0, versionBytes); break; case DEV_CAP_UTRAN: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_1, versionBytes); break; case DEV_CAP_CDMA_1X: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_2, versionBytes); break; case DEV_CAP_HRPD: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_3, versionBytes); break; case DEV_CAP_EHRPD: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_4, versionBytes); break; case DEV_CAP_EUTRAN: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_5, versionBytes); break; case DEV_CAP_NFC: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_6, versionBytes); break; case DEV_CAP_CRL: devCapBuilder.addChildAsBytes(Tags.TAG_CTX_7, versionBytes); break; default: loge("Invalid device capability name: " + devCap); break; } } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected byte[] getDeviceId() { byte[] imeiBytes = new byte[8]; Loading @@ -885,6 +960,11 @@ public class EuiccCard extends UiccCard { return imeiBytes; } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected Resources getResources() { return Resources.getSystem(); } private RequestProvider newRequestProvider(ApduRequestBuilder builder) { return (selectResponse, requestBuilder) -> { EuiccSpecVersion ver = getOrExtractSpecVersion(selectResponse); Loading Loading @@ -1150,6 +1230,10 @@ public class EuiccCard extends UiccCard { Rlog.e(LOG_TAG, message); } private static void loge(String message, Throwable tr) { Rlog.e(LOG_TAG, message, tr); } private static void logi(String message) { Rlog.i(LOG_TAG, message); } Loading
tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java +132 −0 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.res.Resources; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; Loading @@ -44,6 +46,8 @@ import com.android.internal.telephony.uicc.IccCardApplicationStatus; import com.android.internal.telephony.uicc.IccCardStatus; import com.android.internal.telephony.uicc.IccUtils; import com.android.internal.telephony.uicc.asn1.Asn1Node; import com.android.internal.telephony.uicc.asn1.InvalidAsn1DataException; import com.android.internal.telephony.uicc.asn1.TagNotFoundException; import com.android.internal.telephony.uicc.euicc.apdu.LogicalChannelMocker; import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback; Loading @@ -52,6 +56,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -106,6 +111,12 @@ public class EuiccCardTest extends TelephonyTest { @Override protected void loadEidAndNotifyRegistrants() {} @Override protected Resources getResources() { return mMockResources; } }; mHandler = new Handler(mTestHandlerThread.getLooper()); setReady(true); Loading @@ -122,6 +133,9 @@ public class EuiccCardTest extends TelephonyTest { private EuiccCard mEuiccCard; @Mock private Resources mMockResources; @Before public void setUp() throws Exception { super.setUp(getClass().getSimpleName()); Loading Loading @@ -520,6 +534,10 @@ public class EuiccCardTest extends TelephonyTest { @Test public void testAuthenticateServer() { when(mMockResources.getStringArray( com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities)) .thenReturn(new String[] {}); int channel = mockLogicalChannelResponses("BF3802A0009000"); ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); Loading @@ -542,6 +560,10 @@ public class EuiccCardTest extends TelephonyTest { @Test public void testAuthenticateServer_Error() { when(mMockResources.getStringArray( com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities)) .thenReturn(new String[] {}); int channel = mockLogicalChannelResponses("BF38038101039000"); ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); Loading @@ -561,6 +583,39 @@ public class EuiccCardTest extends TelephonyTest { + "82088967452301214305"); // IMEI } @Test public void testAuthenticateService_devCap() { when(mMockResources.getStringArray( com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities)) .thenReturn(new String[] { "gsm,11", "utran,11", "cdma1x,1", "hrpd,3", "ehrpd,12", "eutran,11"}); int channel = mockLogicalChannelResponses("BF3802A0009000"); ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id Asn1Node.newBuilder(0xA0).build().toBytes(), Asn1Node.newBuilder(0xA1).build().toBytes(), Asn1Node.newBuilder(0xA2).build().toBytes(), Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler); resultCaptor.await(); assertUnexpectedException(resultCaptor.exception); assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result)); verifyStoreData(channel, "BF3846" + "A000" + "A100" + "A200" + "A300" + "A03C" + "800D4131423243332D583459355A36" // Matching id + "A12B800489674523" // TAC // Device capabilities + "A11980030B000081030B0000830303000084030C000085030B0000" + "82088967452301214305"); // IMEI } @Test public void testPrepareDownload() { int channel = mockLogicalChannelResponses("BF2102A0009000"); Loading Loading @@ -852,6 +907,83 @@ public class EuiccCardTest extends TelephonyTest { verifyStoreData(channel, "BF3003800105"); } @Test public void testAddDeviceCapability() throws InvalidAsn1DataException, TagNotFoundException { Asn1Node.Builder devCapsBuilder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1); String devCapItem = "gsm,11"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); Asn1Node node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_0)); Asn1Node child = node.getChild(Tags.TAG_CTX_0); assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes())); devCapItem = "utran,11"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_1)); child = node.getChild(Tags.TAG_CTX_1); assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes())); devCapItem = "cdma_1x,1"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_2)); child = node.getChild(Tags.TAG_CTX_2); assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes())); devCapItem = "hrpd,1"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_3)); child = node.getChild(Tags.TAG_CTX_3); assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes())); devCapItem = "ehrpd,12"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_4)); child = node.getChild(Tags.TAG_CTX_4); assertTrue(Arrays.equals(new byte[] {12, 0 , 0}, child.asBytes())); devCapItem = "eutran,11"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_5)); child = node.getChild(Tags.TAG_CTX_5); assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes())); devCapItem = "nfc,0"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_6)); child = node.getChild(Tags.TAG_CTX_6); assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes())); devCapItem = "crl,0"; mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); node = devCapsBuilder.build(); assertTrue(node.hasChild(Tags.TAG_CTX_7)); child = node.getChild(Tags.TAG_CTX_7); assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes())); // Array length should not be 3. Asn1Node.Builder devCapsBuilder2 = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1); devCapItem = "gsm,1,1"; mEuiccCard.addDeviceCapability(devCapsBuilder2, devCapItem); node = devCapsBuilder2.build(); assertFalse(node.hasChild(Tags.TAG_CTX_0)); } private void verifyStoreData(int channel, String command) { verify(mMockCi, times(1)) .iccTransmitApduLogicalChannel(eq(channel), eq(0x80 | channel), eq(0xE2), eq(0x91), Loading