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

Commit 4bdad561 authored by Julian Thomassie's avatar Julian Thomassie
Browse files

Add metrics for Multiple Enabled Profiles

Fixes: 231240934
Test: atest SimSlotStateTest MetricsCollectorTest VoiceCallSessionStatsTest
Change-Id: I1c6ccce5125d716f70e2776a018daa2dec231948
parent 58a27a20
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -82,6 +82,8 @@ import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportSession
import com.android.internal.telephony.nano.PersistAtomsProto.UceEventStats;
import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallRatUsage;
import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallSession;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccSlot;
import com.android.internal.util.ConcurrentUtils;
import com.android.telephony.Rlog;

@@ -337,7 +339,9 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                        SIM_SLOT_STATE,
                        state.numActiveSlots,
                        state.numActiveSims,
                        state.numActiveEsims));
                        state.numActiveEsims,
                        state.numActiveEsimSlots,
                        state.numActiveMepSlots));
        return StatsManager.PULL_SUCCESS;
    }

@@ -526,9 +530,14 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
        boolean hasDedicatedManagedProfileSub = Arrays.stream(phones)
                .anyMatch(Phone::isManagedProfile);

        UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
        int mepSupportedSlotCount = (int) Arrays.stream(slots)
                .filter(UiccSlot::isMultipleEnabledProfileSupported)
                .count();

        data.add(TelephonyStatsLog.buildStatsEvent(DEVICE_TELEPHONY_PROPERTIES, true,
                isAutoDataSwitchOn, mStorage.getAutoDataSwitchToggleCount(),
                hasDedicatedManagedProfileSub));
                hasDedicatedManagedProfileSub, mepSupportedSlotCount));
        return StatsManager.PULL_SUCCESS;
    }

+34 −9
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ import com.android.internal.telephony.uicc.UiccPort;
import com.android.internal.telephony.uicc.UiccSlot;
import com.android.telephony.Rlog;

import java.util.Arrays;
import java.util.Objects;

/** Snapshots and stores the current SIM state. */
public class SimSlotState {
    private static final String TAG = SimSlotState.class.getSimpleName();
@@ -30,31 +33,41 @@ public class SimSlotState {
    public final int numActiveSlots;
    public final int numActiveSims;
    public final int numActiveEsims;
    public final int numActiveEsimSlots;
    public final int numActiveMepSlots;

    /** Returns the current SIM state. */
    public static SimSlotState getCurrentState() {
        int numActiveSlots = 0;
        int numActiveSims = 0;
        int numActiveEsims = 0;
        int numActiveEsimSlots = 0;
        int numActiveMepSlots = 0;
        UiccController uiccController = UiccController.getInstance();
        // since we cannot hold lock insider UiccController, using getUiccSlots() for length only
        for (int i = 0; i < uiccController.getUiccSlots().length; i++) {
            UiccSlot slot = uiccController.getUiccSlot(i);
            if (slot != null && slot.isActive()) {
                numActiveSlots++;
                if (slot.isEuicc()) {
                    numActiveEsimSlots++;
                }
                // avoid CardState.isCardPresent() since this should not include restricted cards
                if (slot.getCardState() == CardState.CARDSTATE_PRESENT) {
                    if (slot.isEuicc()) {
                        // need to check active profiles besides the presence of eSIM cards
                        UiccCard card = slot.getUiccCard();
                        if (card != null) {
                            // Check each port on the EuiccCard
                            UiccPort[] uiccPorts = card.getUiccPortList();
                            for (UiccPort port : uiccPorts) {
                                if (port != null && port.getNumApplications() > 0) {
                                    numActiveSims++;
                                    numActiveEsims++;
                                }
                            int numActiveProfiles = (int) Arrays.stream(card.getUiccPortList())
                                    .filter(Objects::nonNull)
                                    .map(UiccPort::getUiccProfile)
                                    .filter(Objects::nonNull)
                                    .filter(profile -> profile.getNumApplications() > 0)
                                    .count();
                            numActiveSims += numActiveProfiles;
                            numActiveEsims += numActiveProfiles;
                            if (numActiveProfiles > 1) {
                                numActiveMepSlots++;
                            }
                        }
                    } else {
@@ -64,13 +77,25 @@ public class SimSlotState {
                }
            }
        }
        return new SimSlotState(numActiveSlots, numActiveSims, numActiveEsims);
        return new SimSlotState(
                numActiveSlots,
                numActiveSims,
                numActiveEsims,
                numActiveEsimSlots,
                numActiveMepSlots);
    }

    private SimSlotState(int numActiveSlots, int numActiveSims, int numActiveEsims) {
    private SimSlotState(
            int numActiveSlots,
            int numActiveSims,
            int numActiveEsims,
            int numActiveEsimSlots,
            int numActiveMepSlots) {
        this.numActiveSlots = numActiveSlots;
        this.numActiveSims = numActiveSims;
        this.numActiveEsims = numActiveEsims;
        this.numActiveEsimSlots = numActiveEsimSlots;
        this.numActiveMepSlots = numActiveMepSlots;
    }

    /** Returns whether the given phone is using a eSIM. */
+4 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import com.android.internal.telephony.uicc.IccCardStatus.CardState;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccPort;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.uicc.UiccSlot;

import org.junit.After;
@@ -119,6 +120,9 @@ public class MetricsCollectorTest extends TelephonyTest {
    @SmallTest
    public void onPullAtom_simSlotState_bothSimPresent() {
        // these have been tested extensively in SimSlotStateTest, here we verify atom generation
        UiccProfile activeProfile = mock(UiccProfile.class);
        doReturn(4).when(activeProfile).getNumApplications();
        doReturn(activeProfile).when(mActivePort).getUiccProfile();
        doReturn(true).when(mPhysicalSlot).isActive();
        doReturn(CardState.CARDSTATE_PRESENT).when(mPhysicalSlot).getCardState();
        doReturn(false).when(mPhysicalSlot).isEuicc();
@@ -126,7 +130,6 @@ public class MetricsCollectorTest extends TelephonyTest {
        doReturn(CardState.CARDSTATE_PRESENT).when(mEsimSlot).getCardState();
        doReturn(true).when(mEsimSlot).isEuicc();
        doReturn(mActiveCard).when(mEsimSlot).getUiccCard();
        doReturn(4).when(mActivePort).getNumApplications();
        doReturn(new UiccPort[] {mActivePort}).when(mActiveCard).getUiccPortList();
        doReturn(new UiccSlot[] {mPhysicalSlot, mEsimSlot}).when(mUiccController).getUiccSlots();
        doReturn(mPhysicalSlot).when(mUiccController).getUiccSlot(eq(0));
+83 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.uicc.IccCardStatus.CardState;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccPort;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.uicc.UiccSlot;

import org.junit.After;
@@ -71,8 +72,12 @@ public class SimSlotStateTest extends TelephonyTest {
        doReturn(CardState.CARDSTATE_PRESENT).when(mEsimSlot).getCardState();
        doReturn(true).when(mEsimSlot).isEuicc();

        doReturn(0).when(mInactivePort).getNumApplications();
        doReturn(4).when(mActivePort).getNumApplications();
        UiccProfile inactiveProfile = mock(UiccProfile.class);
        UiccProfile activeProfile = mock(UiccProfile.class);
        doReturn(0).when(inactiveProfile).getNumApplications();
        doReturn(4).when(activeProfile).getNumApplications();
        doReturn(inactiveProfile).when(mInactivePort).getUiccProfile();
        doReturn(activeProfile).when(mActivePort).getUiccProfile();

        doReturn(new UiccPort[]{mInactivePort}).when(mInactiveCard).getUiccPortList();
        doReturn(new UiccPort[]{mActivePort}).when(mActiveCard).getUiccPortList();
@@ -94,6 +99,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(0, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(0, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -108,6 +115,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(0, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(0, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -122,6 +131,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(0, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(0, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -136,6 +147,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(0, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -151,6 +164,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(1, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(0, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -166,6 +181,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(0, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -182,6 +199,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(0, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -197,6 +216,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -212,6 +233,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -227,9 +250,29 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(1, state.numActiveSims);
        assertEquals(1, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

    @Test
    @SmallTest
    public void testSingleSim_esimCardWithMultipleProfiles() {
        doReturn(mActiveCard).when(mEsimSlot).getUiccCard();
        doReturn(new UiccPort[]{mActivePort, mActivePort}).when(mActiveCard).getUiccPortList();
        setupSingleSim(mEsimSlot);

        SimSlotState state = SimSlotState.getCurrentState();
        boolean isMultiSim = SimSlotState.isMultiSim();

        assertEquals(1, state.numActiveSlots);
        assertEquals(2, state.numActiveSims);
        assertEquals(2, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(1, state.numActiveMepSlots);
        assertTrue(isMultiSim);
    }

    @Test
    @SmallTest
    public void testDsdsSingleSimMode_noSimCard() {
@@ -241,6 +284,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(0, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -255,6 +300,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(1, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(0, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -270,6 +317,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -285,6 +334,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(1, state.numActiveSlots);
        assertEquals(1, state.numActiveSims);
        assertEquals(1, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -300,6 +351,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(2, state.numActiveSlots);
        assertEquals(0, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -315,6 +368,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(2, state.numActiveSlots);
        assertEquals(1, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

@@ -330,9 +385,29 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(2, state.numActiveSlots);
        assertEquals(1, state.numActiveSims);
        assertEquals(1, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim);
    }

    @Test
    @SmallTest
    public void testDsds_esimCardWithMultipleProfiles() {
        doReturn(mActiveCard).when(mEsimSlot).getUiccCard();
        doReturn(new UiccPort[]{mActivePort, mActivePort}).when(mActiveCard).getUiccPortList();
        setupDualSim(mEmptySlot, mEsimSlot);

        SimSlotState state = SimSlotState.getCurrentState();
        boolean isMultiSim = SimSlotState.isMultiSim();

        assertEquals(2, state.numActiveSlots);
        assertEquals(2, state.numActiveSims);
        assertEquals(2, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(1, state.numActiveMepSlots);
        assertTrue(isMultiSim);
    }

    @Test
    @SmallTest
    public void testDsds_physicalAndEsimCardWithProfile() {
@@ -345,6 +420,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(2, state.numActiveSlots);
        assertEquals(2, state.numActiveSims);
        assertEquals(1, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertTrue(isMultiSim);
    }

@@ -359,6 +436,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(2, state.numActiveSlots);
        assertEquals(2, state.numActiveSims);
        assertEquals(0, state.numActiveEsims);
        assertEquals(0, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertTrue(isMultiSim);
    }

@@ -382,6 +461,8 @@ public class SimSlotStateTest extends TelephonyTest {
        assertEquals(2, state.numActiveSlots);
        assertEquals(1, state.numActiveSims);
        assertEquals(1, state.numActiveEsims);
        assertEquals(1, state.numActiveEsimSlots);
        assertEquals(0, state.numActiveMepSlots);
        assertFalse(isMultiSim); // one Uicc Port does not have active sim profile
    }

+8 −2
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ import com.android.internal.telephony.protobuf.nano.MessageNano;
import com.android.internal.telephony.uicc.IccCardStatus.CardState;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccPort;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.uicc.UiccSlot;

import org.junit.After;
@@ -177,8 +178,13 @@ public class VoiceCallSessionStatsTest extends TelephonyTest {
        doReturn(true).when(mEsimSlot).isActive();
        doReturn(CardState.CARDSTATE_PRESENT).when(mEsimSlot).getCardState();
        doReturn(true).when(mEsimSlot).isEuicc();
        doReturn(0).when(mInactivePort).getNumApplications();
        doReturn(4).when(mActivePort).getNumApplications();

        UiccProfile inactiveProfile = mock(UiccProfile.class);
        UiccProfile activeProfile = mock(UiccProfile.class);
        doReturn(0).when(inactiveProfile).getNumApplications();
        doReturn(4).when(activeProfile).getNumApplications();
        doReturn(inactiveProfile).when(mInactivePort).getUiccProfile();
        doReturn(activeProfile).when(mActivePort).getUiccProfile();

        doReturn(new UiccSlot[] {mPhysicalSlot}).when(mUiccController).getUiccSlots();
        doReturn(mPhysicalSlot).when(mUiccController).getUiccSlot(eq(0));