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

Commit 6996818d authored by Michael Groover's avatar Michael Groover Committed by Android (Google) Code Review
Browse files

Merge "Sanitize number from SubInfo if caller does not have READ_PHONE_NUMBERS" into rvc-dev

parents 6345280a 13fd7d95
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,