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

Commit f53750fc authored by Kiwon Park's avatar Kiwon Park
Browse files

Collect sim voltage class and pin1 metrics

Test: statsd_testdrive
Bug: 204818866
Bug: 204817937
Change-Id: I7af01b5f3a05cacc0a596f1ade2a86981970f6ce
parent e05076a3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -666,8 +666,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                    perSimStatus.dataRoamingEnabled, // dataRoamingEnabled
                    perSimStatus.preferredNetworkType, // allowedNetworksByUser
                    perSimStatus.disabled2g, // is2gDisabled
                    false, // TODO(b/215758472): isPin1Enabled
                    0); // TODO(b/215758472): simVoltageClass
                    perSimStatus.pin1Enabled, // isPin1Enabled
                    perSimStatus.minimumVoltageClass); // simVoltageClass
            data.add(statsEvent);
            result = StatsManager.PULL_SUCCESS;
        }
+36 −2
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@ import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER;
import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_IMS;
import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_UICC;

import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_B;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_C;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__CELLULAR_PREFERRED;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__UNKNOWN;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__WIFI_ONLY;
@@ -33,8 +37,11 @@ import android.telephony.ims.ImsManager;
import android.telephony.ims.ImsMmTelManager;
import android.text.TextUtils;

import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccSlot;

import java.util.Optional;

@@ -59,6 +66,8 @@ public class PerSimStatus {
    public final boolean dataRoamingEnabled;
    public final long preferredNetworkType;
    public final boolean disabled2g;
    public final boolean pin1Enabled;
    public final int minimumVoltageClass;

    /** Returns the current sim status of the given {@link Phone}. */
    @Nullable
@@ -66,6 +75,7 @@ public class PerSimStatus {
        int[] numberState = getNumberState(phone);
        if (numberState == null) return null;
        ImsMmTelManager imsMmTelManager = getImsMmTelManager(phone);
        IccCard iccCard = phone.getIccCard();
        return new PerSimStatus(
                phone.getCarrierId(),
                numberState[0],
@@ -82,7 +92,9 @@ public class PerSimStatus {
                imsMmTelManager == null ? false : imsMmTelManager.isVtSettingEnabled(),
                phone.getDataRoamingEnabled(),
                phone.getAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER),
                is2gDisabled(phone));
                is2gDisabled(phone),
                iccCard == null ? false : iccCard.getIccLockEnabled(),
                getMinimumVoltageClass(phone));
    }

    private PerSimStatus(
@@ -97,7 +109,9 @@ public class PerSimStatus {
            boolean vtSettingEnabled,
            boolean dataRoamingEnabled,
            long preferredNetworkType,
            boolean disabled2g) {
            boolean disabled2g,
            boolean pin1Enabled,
            int minimumVoltageClass) {
        this.carrierId = carrierId;
        this.phoneNumberSourceUicc = phoneNumberSourceUicc;
        this.phoneNumberSourceCarrier = phoneNumberSourceCarrier;
@@ -110,6 +124,8 @@ public class PerSimStatus {
        this.dataRoamingEnabled = dataRoamingEnabled;
        this.preferredNetworkType = preferredNetworkType;
        this.disabled2g = disabled2g;
        this.pin1Enabled = pin1Enabled;
        this.minimumVoltageClass = minimumVoltageClass;
    }

    @Nullable
@@ -196,4 +212,22 @@ public class PerSimStatus {
                return PER_SIM_STATUS__WFC_MODE__UNKNOWN;
        }
    }

    /** Returns the minimum voltage class supported by the UICC. */
    private static int getMinimumVoltageClass(Phone phone) {
        UiccSlot uiccSlot = UiccController.getInstance().getUiccSlotForPhone(phone.getPhoneId());
        if (uiccSlot == null) {
            return PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN;
        }
        switch (uiccSlot.getMinimumVoltageClass()) {
            case UiccSlot.VOLTAGE_CLASS_A:
                return PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A;
            case UiccSlot.VOLTAGE_CLASS_B:
                return PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_B;
            case UiccSlot.VOLTAGE_CLASS_C:
                return PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_C;
            default:
                return PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN;
        }
    }
}
+52 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.telephony.uicc;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
@@ -43,9 +44,12 @@ import com.android.internal.telephony.uicc.IccCardStatus.CardState;
import com.android.internal.telephony.uicc.euicc.EuiccCard;
import com.android.telephony.Rlog;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@@ -60,6 +64,17 @@ public class UiccSlot extends Handler {
            "com.android.internal.telephony.uicc.ICC_CARD_ADDED";
    public static final int INVALID_PHONE_ID = -1;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(
            prefix = {"VOLTAGE_CLASS_"},
            value = {VOLTAGE_CLASS_UNKNOWN, VOLTAGE_CLASS_A, VOLTAGE_CLASS_B, VOLTAGE_CLASS_C})
    public @interface VoltageClass {}

    public static final int VOLTAGE_CLASS_UNKNOWN = 0;
    public static final int VOLTAGE_CLASS_A = 1;
    public static final int VOLTAGE_CLASS_B = 2;
    public static final int VOLTAGE_CLASS_C = 3;

    private final Object mLock = new Object();
    private boolean mActive;
    private boolean mStateIsUnknown = true;
@@ -67,6 +82,7 @@ public class UiccSlot extends Handler {
    private Context mContext;
    private UiccCard mUiccCard;
    private boolean mIsEuicc;
    private @VoltageClass int mMinimumVoltageClass;
    private String mEid;
    private AnswerToReset mAtr;
    private boolean mIsRemovable;
@@ -357,15 +373,51 @@ public class UiccSlot extends Handler {
        log(" checkIsEuiccSupported : " + mIsEuicc);
    }

    private void checkMinimumVoltageClass() {
        mMinimumVoltageClass = VOLTAGE_CLASS_UNKNOWN;
        if (mAtr == null) {
            return;
        }
        // Supported voltage classes are stored in the 5 least significant bits of the TA byte for
        // global interface.
        List<AnswerToReset.InterfaceByte> interfaceBytes = mAtr.getInterfaceBytes();
        for (int i = 0; i < interfaceBytes.size() - 1; i++) {
            if (interfaceBytes.get(i).getTD() != null
                    && (interfaceBytes.get(i).getTD() & AnswerToReset.T_MASK)
                            == AnswerToReset.T_VALUE_FOR_GLOBAL_INTERFACE
                    && interfaceBytes.get(i + 1).getTA() != null) {
                byte ta = interfaceBytes.get(i + 1).getTA();
                if ((ta & 0x01) != 0) {
                    mMinimumVoltageClass = VOLTAGE_CLASS_A;
                }
                if ((ta & 0x02) != 0) {
                    mMinimumVoltageClass = VOLTAGE_CLASS_B;
                }
                if ((ta & 0x04) != 0) {
                    mMinimumVoltageClass = VOLTAGE_CLASS_C;
                }
                return;
            }
        }
        // Use default value - only class A
        mMinimumVoltageClass = VOLTAGE_CLASS_A;
    }

    private void parseAtr(String atr) {
        mAtr = AnswerToReset.parseAtr(atr);
        checkIsEuiccSupported();
        checkMinimumVoltageClass();
    }

    public boolean isEuicc() {
        return mIsEuicc;
    }

    @VoltageClass
    public int getMinimumVoltageClass() {
        return mMinimumVoltageClass;
    }

    public boolean isActive() {
        return mActive;
    }
+94 −2
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER;
import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_IMS;
import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_UICC;

import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_B;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__CELLULAR_PREFERRED;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__UNKNOWN;
import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__WIFI_ONLY;
@@ -36,10 +39,12 @@ import android.telephony.ims.ImsManager;
import android.telephony.ims.ImsMmTelManager;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.uicc.UiccSlot;

import org.junit.After;
import org.junit.Before;
@@ -103,7 +108,12 @@ public class PerSimStatusTest extends TelephonyTest {
                .when(mPhone)
                .getAllowedNetworkTypes(
                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G & ENABLED_2G);

        IccCard iccCard1 = mock(IccCard.class);
        doReturn(true).when(iccCard1).getIccLockEnabled();
        doReturn(iccCard1).when(mPhone).getIccCard();
        UiccSlot uiccSlot1 = mock(UiccSlot.class);
        doReturn(UiccSlot.VOLTAGE_CLASS_A).when(uiccSlot1).getMinimumVoltageClass();
        doReturn(uiccSlot1).when(mUiccController).getUiccSlotForPhone(0);
        // phone 1 setup
        doReturn(mContext).when(mSecondPhone).getContext();
        doReturn(1).when(mSecondPhone).getPhoneId();
@@ -136,6 +146,12 @@ public class PerSimStatusTest extends TelephonyTest {
                .when(mSecondPhone)
                .getAllowedNetworkTypes(
                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G & ENABLED_2G);
        IccCard iccCard2 = mock(IccCard.class);
        doReturn(false).when(iccCard2).getIccLockEnabled();
        doReturn(iccCard2).when(mSecondPhone).getIccCard();
        UiccSlot uiccSlot2 = mock(UiccSlot.class);
        doReturn(UiccSlot.VOLTAGE_CLASS_B).when(uiccSlot2).getMinimumVoltageClass();
        doReturn(uiccSlot2).when(mUiccController).getUiccSlotForPhone(1);

        PerSimStatus perSimStatus1 = PerSimStatus.getCurrentState(mPhone);
        PerSimStatus perSimStatus2 = PerSimStatus.getCurrentState(mSecondPhone);
@@ -154,6 +170,10 @@ public class PerSimStatusTest extends TelephonyTest {
        assertEquals(false, perSimStatus1.dataRoamingEnabled);
        assertEquals(1L, perSimStatus1.preferredNetworkType);
        assertEquals(true, perSimStatus1.disabled2g);
        assertEquals(true, perSimStatus1.pin1Enabled);
        assertEquals(
                PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A,
                perSimStatus1.minimumVoltageClass);
        assertEquals(101, perSimStatus2.carrierId);
        assertEquals(1, perSimStatus2.phoneNumberSourceUicc);
        assertEquals(2, perSimStatus2.phoneNumberSourceCarrier);
@@ -167,6 +187,10 @@ public class PerSimStatusTest extends TelephonyTest {
        assertEquals(false, perSimStatus2.dataRoamingEnabled);
        assertEquals(1L, perSimStatus2.preferredNetworkType);
        assertEquals(false, perSimStatus2.disabled2g);
        assertEquals(false, perSimStatus2.pin1Enabled);
        assertEquals(
                PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_B,
                perSimStatus2.minimumVoltageClass);
    }

    @Test
@@ -203,7 +227,12 @@ public class PerSimStatusTest extends TelephonyTest {
                .when(mPhone)
                .getAllowedNetworkTypes(
                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G & ENABLED_2G);

        IccCard iccCard = mock(IccCard.class);
        doReturn(true).when(iccCard).getIccLockEnabled();
        doReturn(iccCard).when(mPhone).getIccCard();
        UiccSlot uiccSlot1 = mock(UiccSlot.class);
        doReturn(UiccSlot.VOLTAGE_CLASS_A).when(uiccSlot1).getMinimumVoltageClass();
        doReturn(uiccSlot1).when(mUiccController).getUiccSlotForPhone(0);

        PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);

@@ -219,6 +248,10 @@ public class PerSimStatusTest extends TelephonyTest {
        assertEquals(false, perSimStatus.dataRoamingEnabled);
        assertEquals(1L, perSimStatus.preferredNetworkType);
        assertEquals(true, perSimStatus.disabled2g);
        assertEquals(true, perSimStatus.pin1Enabled);
        assertEquals(
                PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A,
                perSimStatus.minimumVoltageClass);
    }

    @Test
@@ -247,6 +280,12 @@ public class PerSimStatusTest extends TelephonyTest {
                .when(mPhone)
                .getAllowedNetworkTypes(
                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G & ENABLED_2G);
        IccCard iccCard = mock(IccCard.class);
        doReturn(true).when(iccCard).getIccLockEnabled();
        doReturn(iccCard).when(mPhone).getIccCard();
        UiccSlot uiccSlot1 = mock(UiccSlot.class);
        doReturn(UiccSlot.VOLTAGE_CLASS_A).when(uiccSlot1).getMinimumVoltageClass();
        doReturn(uiccSlot1).when(mUiccController).getUiccSlotForPhone(0);

        PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);

@@ -262,5 +301,58 @@ public class PerSimStatusTest extends TelephonyTest {
        assertEquals(false, perSimStatus.dataRoamingEnabled);
        assertEquals(1L, perSimStatus.preferredNetworkType);
        assertEquals(true, perSimStatus.disabled2g);
        assertEquals(true, perSimStatus.pin1Enabled);
        assertEquals(
                PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A,
                perSimStatus.minimumVoltageClass);
    }

    @Test
    @SmallTest
    public void onPullAtom_perSimStatus_noUiccSlot() throws Exception {
        doReturn(0).when(mPhone).getPhoneId();
        doReturn(1).when(mPhone).getSubId();
        doReturn(100).when(mPhone).getCarrierId();
        doReturn("6506953210")
                .when(mSubscriptionController)
                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC);
        doReturn("").when(mSubscriptionController).getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER);
        doReturn("+16506953210")
                .when(mSubscriptionController)
                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_IMS);
        SubscriptionInfo subscriptionInfo = mock(SubscriptionInfo.class);
        doReturn("us").when(subscriptionInfo).getCountryIso();
        doReturn(subscriptionInfo).when(mSubscriptionController).getSubscriptionInfo(1);
        doReturn(null).when(mContext).getSystemService(ImsManager.class);
        doReturn(1L)
                .when(mPhone)
                .getAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
        doReturn(0L)
                .when(mPhone)
                .getAllowedNetworkTypes(
                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G & ENABLED_2G);
        IccCard iccCard = mock(IccCard.class);
        doReturn(true).when(iccCard).getIccLockEnabled();
        doReturn(iccCard).when(mPhone).getIccCard();
        doReturn(null).when(mUiccController).getUiccSlotForPhone(0);

        PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);

        assertEquals(100, perSimStatus.carrierId);
        assertEquals(1, perSimStatus.phoneNumberSourceUicc);
        assertEquals(0, perSimStatus.phoneNumberSourceCarrier);
        assertEquals(1, perSimStatus.phoneNumberSourceIms);
        assertEquals(false, perSimStatus.advancedCallingSettingEnabled);
        assertEquals(false, perSimStatus.voWiFiSettingEnabled);
        assertEquals(PER_SIM_STATUS__WFC_MODE__UNKNOWN, perSimStatus.voWiFiModeSetting);
        assertEquals(PER_SIM_STATUS__WFC_MODE__UNKNOWN, perSimStatus.voWiFiRoamingModeSetting);
        assertEquals(false, perSimStatus.vtSettingEnabled);
        assertEquals(false, perSimStatus.dataRoamingEnabled);
        assertEquals(1L, perSimStatus.preferredNetworkType);
        assertEquals(true, perSimStatus.disabled2g);
        assertEquals(true, perSimStatus.pin1Enabled);
        assertEquals(
                PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN,
                perSimStatus.minimumVoltageClass);
    }
}
+140 −0
Original line number Diff line number Diff line
@@ -232,6 +232,146 @@ public class UiccSlotTest extends TelephonyTest {
        assertFalse(mUiccSlot.isEuicc());
    }

    @Test
    @SmallTest
    public void testUpdateSlotStatusVoltageClassA() {
        IccSlotStatus iss = new IccSlotStatus();
        IccSimPortInfo simPortInfo = new IccSimPortInfo();
        simPortInfo.mPortActive = false;
        simPortInfo.mLogicalSlotIndex = 0;
        simPortInfo.mIccId = "fake-iccid";
        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
        iss.atr = "3b9795801F018031A073BE211500";

        // initial state
        assertTrue(mUiccSlot.isActive());
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());

        // update slot to inactive
        mUiccSlot.update(null, iss, 0 /* slotIndex */);

        // assert on updated values
        assertFalse(mUiccSlot.isActive());
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());

        iss.mSimPortInfos[0].mPortActive = true;

        // update slot to active
        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);

        // assert on updated values
        assertTrue(mUiccSlot.isActive());
        assertEquals(mUiccSlot.getMinimumVoltageClass(), UiccSlot.VOLTAGE_CLASS_A);
    }

    @Test
    @SmallTest
    public void testUpdateSlotStatusVoltageClassANoTa() {
        IccSlotStatus iss = new IccSlotStatus();
        IccSimPortInfo simPortInfo = new IccSimPortInfo();
        simPortInfo.mPortActive = false;
        simPortInfo.mLogicalSlotIndex = 0;
        simPortInfo.mIccId = "fake-iccid";
        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
        iss.atr = "3b9795800F048031A073BE2115";

        // initial state
        assertTrue(mUiccSlot.isActive());
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());

        // update slot to inactive
        mUiccSlot.update(null, iss, 0 /* slotIndex */);

        // assert on updated values
        assertFalse(mUiccSlot.isActive());
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());

        iss.mSimPortInfos[0].mPortActive = true;

        // update slot to active
        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);

        // assert on updated values
        assertTrue(mUiccSlot.isActive());
        assertEquals(UiccSlot.VOLTAGE_CLASS_A, mUiccSlot.getMinimumVoltageClass());
    }

    @Test
    @SmallTest
    public void testUpdateSlotStatusVoltageClassB() {
        IccSlotStatus iss = new IccSlotStatus();
        IccSimPortInfo simPortInfo = new IccSimPortInfo();
        simPortInfo.mPortActive = false;
        simPortInfo.mLogicalSlotIndex = 0;
        simPortInfo.mIccId = "fake-iccid";
        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
        iss.atr = "3b9795801F428031A073BE211500";

        // initial state
        assertTrue(mUiccSlot.isActive());
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());

        // update slot to inactive
        mUiccSlot.update(null, iss, 0 /* slotIndex */);

        // assert on updated values
        assertFalse(mUiccSlot.isActive());
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());

        iss.mSimPortInfos[0].mPortActive = true;

        // update slot to active
        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);

        // assert on updated values
        assertTrue(mUiccSlot.isActive());
        assertEquals(UiccSlot.VOLTAGE_CLASS_B, mUiccSlot.getMinimumVoltageClass());
    }

    @Test
    @SmallTest
    public void testUpdateSlotStatusVoltageClassC() {
        IccSlotStatus iss = new IccSlotStatus();
        IccSimPortInfo simPortInfo = new IccSimPortInfo();
        simPortInfo.mPortActive = false;
        simPortInfo.mLogicalSlotIndex = 0;
        simPortInfo.mIccId = "fake-iccid";
        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
        iss.atr = "3b9795801F048031A073BE211500";

        // initial state
        assertTrue(mUiccSlot.isActive());
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());

        // update slot to inactive
        mUiccSlot.update(null, iss, 0 /* slotIndex */);

        // assert on updated values
        assertFalse(mUiccSlot.isActive());
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());

        iss.mSimPortInfos[0].mPortActive = true;

        // update slot to active
        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);

        // assert on updated values
        assertTrue(mUiccSlot.isActive());
        assertEquals(UiccSlot.VOLTAGE_CLASS_C, mUiccSlot.getMinimumVoltageClass());
    }

    @Test
    @SmallTest
    public void testUpdateAbsentState() {