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

Commit b0196613 authored by Chris Desir's avatar Chris Desir
Browse files

Add unit test for Remote SIM functionality

Currently there are no unit tests to verify the behavior of the Remote SIM with no FEATURE_TELEPHONY_SUBSCRIPTION and the config_force_phone_globals_creation in place.

These tests would be essential for making sure that 1) the config that was put in place stays in place for the time being and that 2) when mocking these values, the APIs function correctly even with no FEATURE_TELEPHONY_SUBSCRIPTION support.

Additionally, this change reconfigures other functions used for Remote SIM functionality (addSubInfo, removeSubInfo, and getActiveSubscriptionInfoForIccId) within packages/modules/Bluetooth/android/app/src/com/android/bluetooth/mapclient/MapClientContent.java.

See go/remote-sim-testing for additional context.

Flag: TEST_ONLY
Bug: 394918135
Test: atest SubscriptionManagerServiceTest
Change-Id: I22e349f9c62e3af5b70bcf6cb2b27613b8e4e260
parent c537808d
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -2010,7 +2010,11 @@ public class SubscriptionManagerService extends ISub.Stub {
        enforcePermissions("getActiveSubscriptionInfoForIccId",
                Manifest.permission.READ_PRIVILEGED_PHONE_STATE);

        enforceTelephonyFeatureWithException(callingPackage, "getActiveSubscriptionInfoForIccId");
        if (!mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_force_phone_globals_creation)) {
            enforceTelephonyFeatureWithException(callingPackage,
                    "getActiveSubscriptionInfoForIccId");
        }

        final long identity = Binder.clearCallingIdentity();
        try {
@@ -2322,7 +2326,10 @@ public class SubscriptionManagerService extends ISub.Stub {
                + SubscriptionManager.subscriptionTypeToString(subscriptionType) + ", "
                + getCallingPackage());

        if (!mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_force_phone_globals_creation)) {
            enforceTelephonyFeatureWithException(getCurrentPackageName(), "addSubInfo");
        }

        if (subscriptionType == SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM) {
            if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
@@ -2393,7 +2400,10 @@ public class SubscriptionManagerService extends ISub.Stub {
                + SubscriptionManager.subscriptionTypeToString(subscriptionType) + ", "
                + getCallingPackage());

        if (!mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_force_phone_globals_creation)) {
            enforceTelephonyFeatureWithException(getCurrentPackageName(), "removeSubInfo");
        }

        final long identity = Binder.clearCallingIdentity();
        try {
@@ -3125,7 +3135,7 @@ public class SubscriptionManagerService extends ISub.Stub {
    @Override
    public int getDefaultSubIdAsUser(@UserIdInt int userId) {
        enforceTelephonyFeatureWithException(getCurrentPackageName(),
                "getDefaultVoiceSubIdAsUser");
                "getDefaultSubIdAsUser");

        return getDefaultAsUser(userId, mDefaultSubId.get());
    }
+143 −1
Original line number Diff line number Diff line
@@ -107,7 +107,6 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.ArraySet;
import android.util.Base64;
import android.util.Log;

import com.android.internal.R;
import com.android.internal.telephony.ContextFixture;
@@ -3600,4 +3599,147 @@ public class SubscriptionManagerServiceTest extends TelephonyTest {
    public void testIsSatelliteProvisionedForNonIpDatagram() {
        assertFalse(mSubscriptionManagerServiceUT.isSatelliteProvisionedForNonIpDatagram(-1));
    }

    /**
     * Simulates a device environment where the
     * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION} feature is unavailable.
     *
     * This is necessary for testing scenarios specific to automotive devices, which
     * may not always have the telephony subscription feature enabled. It allows us to
     * verify the behavior of certain APIs when this feature is not available, even if the
     * test device technically supports it. These APIs should function regardless for
     * Remote SIM.
     */
    private void simulateNoTelephonySubscriptionSupport() throws Exception {
        doReturn(false).when(mPackageManager).hasSystemFeature(
                eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION));
        int vendorApiLevel = Build.VERSION_CODES.BAKLAVA;
        replaceInstance(SubscriptionManagerService.class, "mVendorApiLevel",
                mSubscriptionManagerServiceUT, vendorApiLevel);
        mContextFixture.putBooleanResource(
                com.android.internal.R.bool.config_force_phone_globals_creation, true);
    }

    @Test
    @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
    public void testRemoteSimNoTelephonySubscription() throws Exception {
        simulateNoTelephonySubscriptionSupport();

        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);

        mSubscriptionManagerServiceUT.addSubInfo(FAKE_MAC_ADDRESS1, FAKE_CARRIER_NAME1,
                0, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
        processAllMessages();

        verify(mMockedSubscriptionManagerServiceCallback).onSubscriptionChanged(eq(1));

        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
                .getSubscriptionInfoInternal(1);
        assertThat(subInfo.getIccId()).isEqualTo(FAKE_MAC_ADDRESS1);
        assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME1);
        assertThat(subInfo.getSimSlotIndex()).isEqualTo(
                SubscriptionManager.INVALID_SIM_SLOT_INDEX);
        assertThat(subInfo.getSubscriptionType()).isEqualTo(
                SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);

        assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_MAC_ADDRESS1,
                SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)).isEqualTo(true);
        assertThat(mSubscriptionManagerServiceUT.getAllSubInfoList(
                CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
        assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty();
        assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
                CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty();

        setIdentifierAccess(true);
        mSubscriptionManagerServiceUT.addSubInfo(FAKE_MAC_ADDRESS2, FAKE_CARRIER_NAME2,
                0, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
        assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isNotEmpty();
        assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
                CALLING_PACKAGE, CALLING_FEATURE, true)).isNotEmpty();
        assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
                CALLING_PACKAGE, CALLING_FEATURE, true).get(0).getIccId())
                .isEqualTo(FAKE_MAC_ADDRESS2);
    }

    @Test
    @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
    public void testGetActiveSubscriptionInfoListNoTelephonySubscription() throws Exception {
        simulateNoTelephonySubscriptionSupport();

        // Grant MODIFY_PHONE_STATE permission for insertion.
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
        insertSubscription(FAKE_SUBSCRIPTION_INFO1);
        insertSubscription(new SubscriptionInfoInternal.Builder(FAKE_SUBSCRIPTION_INFO2)
                .setSimSlotIndex(SubscriptionManager.INVALID_SIM_SLOT_INDEX).build());
        // Remove MODIFY_PHONE_STATE
        mContextFixture.removeCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);

        // Should get an empty list without READ_PHONE_STATE.
        assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
                CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty();

        // Grant READ_PHONE_STATE permission for insertion.
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        // Allow the application to perform.
        doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
                .noteOpNoThrow(eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(),
                        nullable(String.class), nullable(String.class), nullable(String.class));

        List<SubscriptionInfo> subInfos = mSubscriptionManagerServiceUT
                .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE, true);
        // Identifying information removed
        assertThat(subInfos).hasSize(1);
        assertThat(subInfos.get(0).getIccId()).isEmpty();
        assertThat(subInfos.get(0).getCardString()).isEmpty();
        assertThat(subInfos.get(0).getNumber()).isEmpty();
        assertThat(subInfos.get(0).getGroupUuid()).isNull();

        // Grant carrier privilege
        setCarrierPrivilegesForSubId(true, 1);

        subInfos = mSubscriptionManagerServiceUT
                .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE, true);
        assertThat(subInfos).hasSize(1);
        assertThat(subInfos.get(0)).isEqualTo(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo());
    }

    @Test
    @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
    public void testGetActiveSubscriptionInfoForIccIdNoTelephonySubscription() throws Exception {
        simulateNoTelephonySubscriptionSupport();

        insertSubscription(FAKE_SUBSCRIPTION_INFO1);

        // Should fail without READ_PRIVILEGED_PHONE_STATE
        assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
                .getActiveSubscriptionInfoForIccId(FAKE_ICCID1, CALLING_PACKAGE, CALLING_FEATURE));

        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
        SubscriptionInfo subInfo = mSubscriptionManagerServiceUT.getActiveSubscriptionInfoForIccId(
                FAKE_ICCID1, CALLING_PACKAGE, CALLING_FEATURE);
        assertThat(subInfo).isEqualTo(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo());
    }

    @Test
    @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
    public void testRemoveSubInfoNoTelephonySubscription() throws Exception {
        simulateNoTelephonySubscriptionSupport();

        insertSubscription(FAKE_SUBSCRIPTION_INFO1);
        insertSubscription(FAKE_SUBSCRIPTION_INFO2);

        assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
                .removeSubInfo(FAKE_ICCID1, SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM));

        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
        assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_ICCID1,
                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)).isEqualTo(true);
        assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_ICCID2,
                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)).isEqualTo(true);

        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
        assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
                CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty();
    }
}