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

Commit b466b75c authored by Michael Groover's avatar Michael Groover Committed by Automerger Merge Worker
Browse files

Merge "Sanitize number from SubInfo if caller does not have...

Merge "Sanitize number from SubInfo if caller does not have READ_PHONE_NUMBERS" into rvc-dev am: 6996818d am: 7daa0e0d

Change-Id: Idccccdb0e02abac491b9c9d1d01fede1acfeb513
parents a93ab7e3 7daa0e0d
Loading
Loading
Loading
Loading
+27 −4
Original line number Diff line number Diff line
@@ -283,6 +283,20 @@ public class SubscriptionController extends ISub.Stub {
        }
    }

    /**
     * Returns whether the {@code callingPackage} has access to the phone number on the specified
     * {@code subId} using the provided {@code message} in any resulting SecurityException.
     */
    private boolean hasPhoneNumberAccess(int subId, String callingPackage, String callingFeatureId,
            String message) {
        try {
            return TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(mContext, subId,
                    callingPackage, callingFeatureId, message);
        } catch (SecurityException e) {
            return false;
        }
    }

    /**
     * Broadcast when SubscriptionInfo has changed
     * FIXME: Hopefully removed if the API council accepts SubscriptionInfoListener
@@ -3746,12 +3760,21 @@ public class SubscriptionController extends ISub.Stub {
    private SubscriptionInfo conditionallyRemoveIdentifiers(SubscriptionInfo subInfo,
            String callingPackage, String callingFeatureId, String message) {
        SubscriptionInfo result = subInfo;
        if (!hasSubscriberIdentifierAccess(subInfo.getSubscriptionId(), callingPackage,
                callingFeatureId, message)) {
        int subId = subInfo.getSubscriptionId();
        boolean hasIdentifierAccess = hasSubscriberIdentifierAccess(subId, callingPackage,
                callingFeatureId, message);
        boolean hasPhoneNumberAccess = hasPhoneNumberAccess(subId, callingPackage, callingFeatureId,
                message);
        if (!hasIdentifierAccess || !hasPhoneNumberAccess) {
            result = new SubscriptionInfo(subInfo);
            if (!hasIdentifierAccess) {
                result.clearIccId();
                result.clearCardString();
            }
            if (!hasPhoneNumberAccess) {
                result.clearNumber();
            }
        }
        return result;
    }

+99 −12
Original line number Diff line number Diff line
@@ -26,7 +26,9 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
@@ -34,9 +36,11 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.Manifest;
import android.app.AppOpsManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.ParcelUuid;
import android.os.UserHandle;
@@ -87,6 +91,8 @@ public class SubscriptionControllerTest extends TelephonyTest {
    private static final String DISPLAY_NAME_PREFIX = "my_phone_";

    private static final String UNAVAILABLE_ICCID = "";
    private static final String UNAVAILABLE_NUMBER = "";
    private static final String DISPLAY_NUMBER = "123456";

    @Before
    public void setUp() throws Exception {
@@ -1044,17 +1050,33 @@ public class SubscriptionControllerTest extends TelephonyTest {
        // getActiveSubscriptionInfo should still return a result but the ICC ID should not be
        // available via getIccId or getCardString.
        testInsertSim();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        setupMocksForTelephonyPermissions();
        setupReadPhoneNumbersTest();
        setIdentifierAccess(false);
        int subId = getFirstSubId();

        SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
                subId, mCallingPackage, mCallingFeature);

        assertNotNull(subscriptionInfo);
        assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getIccId());
        assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getCardString());
        assertEquals(UNAVAILABLE_NUMBER, subscriptionInfo.getNumber());
    }

    @Test
    public void testGetActiveSubscriptionWithReadPhoneNumbers() throws Exception {
        // If the calling package has the READ_PHONE_NUMBERS permission the number should be
        // available in the SubscriptionInfo.
        testInsertSim();
        setupReadPhoneNumbersTest();
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_NUMBERS);
        int subId = getFirstSubId();

        SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
                subId, mCallingPackage, mCallingFeature);

        assertNotNull(subscriptionInfo);
        assertEquals(DISPLAY_NUMBER, subscriptionInfo.getNumber());
    }

    @Test
@@ -1066,6 +1088,7 @@ public class SubscriptionControllerTest extends TelephonyTest {

        SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
                subId, mCallingPackage, mCallingFeature);

        assertNotNull(subscriptionInfo);
        assertTrue(subscriptionInfo.getIccId().length() > 0);
        assertTrue(subscriptionInfo.getCardString().length() > 0);
@@ -1094,17 +1117,34 @@ public class SubscriptionControllerTest extends TelephonyTest {
        // getActiveSubscriptionInfoForSimlSlotIndex should still return the SubscriptionInfo but
        // the ICC ID should not be available via getIccId or getCardString.
        testInsertSim();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        setupMocksForTelephonyPermissions();
        setupReadPhoneNumbersTest();
        setIdentifierAccess(false);

        SubscriptionInfo subscriptionInfo =
                mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
                        mCallingPackage, mCallingFeature);

        assertNotNull(subscriptionInfo);
        assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getIccId());
        assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getCardString());
        assertEquals(UNAVAILABLE_NUMBER, subscriptionInfo.getNumber());
    }

    @Test
    public void testGetActiveSubscriptionInfoForSimSlotIndexWithReadPhoneNumbers()
            throws Exception {
        // If the calling package has the READ_PHONE_NUMBERS permission the number should be
        // available in the SubscriptionInfo.
        testInsertSim();
        setupReadPhoneNumbersTest();
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_NUMBERS);

        SubscriptionInfo subscriptionInfo =
                mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
                        mCallingPackage, mCallingFeature);

        assertNotNull(subscriptionInfo);
        assertEquals(DISPLAY_NUMBER, subscriptionInfo.getNumber());
    }

    @Test
@@ -1117,6 +1157,7 @@ public class SubscriptionControllerTest extends TelephonyTest {
        SubscriptionInfo subscriptionInfo =
                mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
                        mCallingPackage, mCallingFeature);

        assertNotNull(subscriptionInfo);
        assertTrue(subscriptionInfo.getIccId().length() > 0);
        assertTrue(subscriptionInfo.getCardString().length() > 0);
@@ -1132,6 +1173,7 @@ public class SubscriptionControllerTest extends TelephonyTest {
        List<SubscriptionInfo> subInfoList =
                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
                        mCallingFeature);

        assertNotNull(subInfoList);
        assertTrue(subInfoList.size() == 0);
    }
@@ -1142,21 +1184,38 @@ public class SubscriptionControllerTest extends TelephonyTest {
        // getActiveSubscriptionInfoList should still return the list of SubscriptionInfo objects
        // but the ICC ID should not be available via getIccId or getCardString.
        testInsertSim();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        setupMocksForTelephonyPermissions();
        setupReadPhoneNumbersTest();
        setIdentifierAccess(false);

        List<SubscriptionInfo> subInfoList =
                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
                        mCallingFeature);

        assertTrue(subInfoList.size() > 0);
        for (SubscriptionInfo info : subInfoList) {
            assertEquals(UNAVAILABLE_ICCID, info.getIccId());
            assertEquals(UNAVAILABLE_ICCID, info.getCardString());
            assertEquals(UNAVAILABLE_NUMBER, info.getNumber());
        }
    }

    @Test
    public void testGetActiveSubscriptionInfoListWithReadPhoneNumbers() throws Exception {
        // If the calling package has the READ_PHONE_NUMBERS permission the number should be
        // available in the SubscriptionInfo.
        testInsertSim();
        setupReadPhoneNumbersTest();
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_NUMBERS);

        List<SubscriptionInfo> subInfoList =
                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
                        mCallingFeature);

        assertTrue(subInfoList.size() > 0);
        SubscriptionInfo subInfo = subInfoList.get(0);
        assertEquals(DISPLAY_NUMBER, subInfo.getNumber());
    }

    @Test
    public void testGetActiveSubscriptionInfoListWithPrivilegedPermission() throws Exception {
        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
@@ -1166,6 +1225,7 @@ public class SubscriptionControllerTest extends TelephonyTest {
        List<SubscriptionInfo> subInfoList =
                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
                        mCallingFeature);

        assertTrue(subInfoList.size() > 0);
        for (SubscriptionInfo info : subInfoList) {
            assertTrue(info.getIccId().length() > 0);
@@ -1195,20 +1255,36 @@ public class SubscriptionControllerTest extends TelephonyTest {
        // getSubscriptionsInGroup should still return the list of SubscriptionInfo objects
        // but the ICC ID should not be available via getIccId or getCardString.
        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        setupMocksForTelephonyPermissions();
        setupReadPhoneNumbersTest();
        setIdentifierAccess(false);

        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
                groupUuid, mCallingPackage, mCallingFeature);

        assertTrue(subInfoList.size() > 0);
        for (SubscriptionInfo info : subInfoList) {
            assertEquals(UNAVAILABLE_ICCID, info.getIccId());
            assertEquals(UNAVAILABLE_ICCID, info.getCardString());
            assertEquals(UNAVAILABLE_NUMBER, info.getNumber());
        }
    }

    @Test
    public void testGetSubscriptionInGroupWithReadPhoneNumbers() throws Exception {
        // If the calling package has the READ_PHONE_NUMBERS permission the number should be
        // available in the SubscriptionInfo.
        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
        setupReadPhoneNumbersTest();
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_NUMBERS);

        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
                groupUuid, mCallingPackage, mCallingFeature);

        assertTrue(subInfoList.size() > 0);
        SubscriptionInfo subInfo = subInfoList.get(0);
        assertEquals(DISPLAY_NUMBER, subInfo.getNumber());
    }

    @Test
    public void testGetSubscriptionsInGroupWithPrivilegedPermission() throws Exception {
        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
@@ -1217,6 +1293,7 @@ public class SubscriptionControllerTest extends TelephonyTest {

        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
                groupUuid, mCallingPackage, mCallingFeature);

        assertTrue(subInfoList.size() > 0);
        for (SubscriptionInfo info : subInfoList) {
            assertTrue(info.getIccId().length() > 0);
@@ -1233,6 +1310,16 @@ public class SubscriptionControllerTest extends TelephonyTest {
        return groupUuid;
    }

    private void setupReadPhoneNumbersTest() throws Exception {
        mSubscriptionControllerUT.setDisplayNumber(DISPLAY_NUMBER, getFirstSubId());
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        setupMocksForTelephonyPermissions(mCallingPackage, Build.VERSION_CODES.R);
        doReturn(AppOpsManager.MODE_DEFAULT).when(mAppOpsManager).noteOp(
                eq(AppOpsManager.OPSTR_WRITE_SMS), anyInt(), anyString(),
                nullable(String.class), nullable(String.class));
    }

    private int getFirstSubId() throws Exception {
        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
        assertTrue(subIds != null && subIds.length != 0);
+8 −3
Original line number Diff line number Diff line
@@ -734,13 +734,18 @@ public abstract class TelephonyTest {
    }

    protected void setupMocksForTelephonyPermissions() throws Exception {
        setupMocksForTelephonyPermissions(TAG, Build.VERSION_CODES.Q);
    }

    protected void setupMocksForTelephonyPermissions(String packageName, int targetSdkVersion)
            throws Exception {
        // If the calling package does not meet the new requirements for device identifier access
        // TelephonyPermissions will query the PackageManager for the ApplicationInfo of the package
        // to determine the target SDK. For apps targeting Q a SecurityException is thrown
        // regardless of if the package satisfies the previous requirements for device ID access.
        mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
        doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfoAsUser(eq(TAG), anyInt(),
                any());
        mApplicationInfo.targetSdkVersion = targetSdkVersion;
        doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfoAsUser(eq(packageName),
                anyInt(), any());

        // TelephonyPermissions uses a SystemAPI to check if the calling package meets any of the
        // generic requirements for device identifier access (currently READ_PRIVILEGED_PHONE_STATE,