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

Commit f0a7b0df authored by Michael Groover's avatar Michael Groover
Browse files

resolve merge conflicts of 9c392805 to qt-qpr1-dev

Bug: 173421434

Change-Id: I4e5dcf3b9fe03f3403275bd2ca08ff52d53c2278
Merged-In: Iab02eef23a9b34d3e5eaceaabc8affd3725f5f3c
parents 193b5584 9c392805
Loading
Loading
Loading
Loading
+88 −38
Original line number Diff line number Diff line
@@ -284,6 +284,24 @@ public class SubscriptionController extends ISub.Stub {
                Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);
    }

    /**
     * Returns whether the {@code callingPackage} has access to subscriber identifiers on the
     * specified {@code subId} using the provided {@code message} in any resulting
     * SecurityException.
     */
    private boolean hasSubscriberIdentifierAccess(int subId, String callingPackage,
            String message) {
        try {
            return TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mContext, subId,
                    callingPackage, message);
        } catch (SecurityException e) {
            // A SecurityException indicates that the calling package is targeting at least the
            // minimum level that enforces identifier access restrictions and the new access
            // requirements are not met.
            return false;
        }
    }

    /**
     * Broadcast when SubscriptionInfo has changed
     * FIXME: Hopefully removed if the API council accepts SubscriptionInfoListener
@@ -515,17 +533,20 @@ public class SubscriptionController extends ISub.Stub {

        // Now that all security checks passes, perform the operation as ourselves.
        final long identity = Binder.clearCallingIdentity();
        List<SubscriptionInfo> subList;
        try {
            List<SubscriptionInfo> subList = getActiveSubscriptionInfoList(
                    mContext.getOpPackageName());
            subList = getActiveSubscriptionInfoList(mContext.getOpPackageName());
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
        if (subList != null) {
            for (SubscriptionInfo si : subList) {
                if (si.getSubscriptionId() == subId) {
                        if (DBG) {
                    if (VDBG) {
                        logd("[getActiveSubscriptionInfo]+ subId=" + subId + " subInfo=" + si);
                    }

                        return si;
                    return conditionallyRemoveIdentifiers(si, callingPackage,
                            "getActiveSubscriptionInfo");
                }
            }
        }
@@ -533,9 +554,6 @@ public class SubscriptionController extends ISub.Stub {
            logd("[getActiveSubscriptionInfo]- subId=" + subId
                    + " subList=" + subList + " subInfo=null");
        }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }

        return null;
    }
@@ -634,9 +652,12 @@ public class SubscriptionController extends ISub.Stub {

        // Now that all security checks passes, perform the operation as ourselves.
        final long identity = Binder.clearCallingIdentity();
        List<SubscriptionInfo> subList;
        try {
            List<SubscriptionInfo> subList = getActiveSubscriptionInfoList(
                    mContext.getOpPackageName());
            subList = getActiveSubscriptionInfoList(mContext.getOpPackageName());
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
        if (subList != null) {
            for (SubscriptionInfo si : subList) {
                if (si.getSimSlotIndex() == slotIndex) {
@@ -644,7 +665,8 @@ public class SubscriptionController extends ISub.Stub {
                        logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex="
                                + slotIndex + " subId=" + si);
                    }
                        return si;
                    return conditionallyRemoveIdentifiers(si, callingPackage,
                            "getActiveSubscriptionInfoForSimSlotIndex");
                }
            }
            if (DBG) {
@@ -656,9 +678,7 @@ public class SubscriptionController extends ISub.Stub {
                logd("[getActiveSubscriptionInfoForSimSlotIndex]+ subList=null");
            }
        }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }


        return null;
    }
@@ -3311,7 +3331,9 @@ public class SubscriptionController extends ISub.Stub {
            return TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId,
                    callingPackage, "getSubscriptionsInGroup")
                    || info.canManageSubscription(mContext, callingPackage);
        }).collect(Collectors.toList());
        }).map(subscriptionInfo -> conditionallyRemoveIdentifiers(subscriptionInfo,
                callingPackage, "getSubscriptionInfoList"))
        .collect(Collectors.toList());
    }

    public ParcelUuid getGroupUuid(int subId) {
@@ -3583,6 +3605,14 @@ public class SubscriptionController extends ISub.Stub {
            canReadAllPhoneState = TelephonyPermissions.checkReadPhoneState(mContext,
                    SubscriptionManager.INVALID_SUBSCRIPTION_ID, Binder.getCallingPid(),
                    Binder.getCallingUid(), callingPackage, "getSubscriptionInfoList");
            // If the calling package has the READ_PHONE_STATE permission then check if the caller
            // also has access to subscriber identifiers to ensure that the ICC ID and any other
            // unique identifiers are removed if the caller should not have access.
            if (canReadAllPhoneState) {
                canReadAllPhoneState = hasSubscriberIdentifierAccess(
                        SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
                        "getSubscriptionInfoList");
            }
        } catch (SecurityException e) {
            canReadAllPhoneState = false;
        }
@@ -3603,11 +3633,31 @@ public class SubscriptionController extends ISub.Stub {
                        } catch (SecurityException e) {
                            return false;
                        }
                    })
                    }).map(subscriptionInfo -> conditionallyRemoveIdentifiers(subscriptionInfo,
                            callingPackage, "getSubscriptionInfoList"))
                    .collect(Collectors.toList());
        }
    }

    /**
     * Conditionally removes identifiers from the provided {@code subInfo} if the {@code
     * callingPackage} does not meet the access requirements for identifiers and returns the
     * potentially modified object..
     *
     * <p>If the caller does not meet the access requirements for identifiers a clone of the
     * provided SubscriptionInfo is created and modified to avoid altering SubscriptionInfo objects
     * in a cache.
     */
    private SubscriptionInfo conditionallyRemoveIdentifiers(SubscriptionInfo subInfo,
            String callingPackage,  String message) {
        SubscriptionInfo result = subInfo;
        if (!hasSubscriberIdentifierAccess(subInfo.getSubscriptionId(), callingPackage, message)) {
            result = new SubscriptionInfo(subInfo);
            result.clearIccId();
        }
        return result;
    }

    private synchronized boolean addToSubIdList(int slotIndex, int subId, int subscriptionType) {
        ArrayList<Integer> subIdsList = sSlotIndexToSubIds.get(slotIndex);
        if (subIdsList == null) {
+201 −0
Original line number Diff line number Diff line
@@ -78,6 +78,8 @@ public class SubscriptionControllerTest extends TelephonyTest {
    private static final String MAC_ADDRESS_PREFIX = "mac_";
    private static final String DISPLAY_NAME_PREFIX = "my_phone_";

    private static final String UNAVAILABLE_ICCID = "";

    @Before
    public void setUp() throws Exception {
        super.setUp("SubscriptionControllerTest");
@@ -940,6 +942,205 @@ public class SubscriptionControllerTest extends TelephonyTest {
        assertTrue("active sub ids = " + subIds, Arrays.equals(subIds, new int[]{2, 1}));
    }

    @Test
    public void testGetActiveSubscriptionInfoWithNoPermissions() throws Exception {
        // If the calling package does not have the READ_PHONE_STATE permission or carrier
        // privileges then getActiveSubscriptionInfo should throw a SecurityException;
        testInsertSim();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
        int subId = getFirstSubId();

        try {
            mSubscriptionControllerUT.getActiveSubscriptionInfo(subId, mCallingPackage);
            fail("getActiveSubscriptionInfo should fail when invoked with no permissions");
        } catch (SecurityException expected) {
        }
    }

    @Test
    public void testGetActiveSubscriptionInfoWithReadPhoneState() throws Exception {
        // If the calling package only has the READ_PHONE_STATE permission then
        // getActiveSubscriptionInfo should still return a result but the ICC ID should not be
        // available.
        testInsertSim();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        setupMocksForTelephonyPermissions();
        int subId = getFirstSubId();

        SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
                subId, mCallingPackage);
        assertNotNull(subscriptionInfo);
        assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getIccId());
    }

    @Test
    public void testGetActiveSubscriptionWithPrivilegedPermission() throws Exception {
        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
        // privileges the ICC ID should be available in the SubscriptionInfo.
        testInsertSim();
        int subId = getFirstSubId();

        SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
                subId, mCallingPackage);
        assertNotNull(subscriptionInfo);
        assertTrue(subscriptionInfo.getIccId().length() > 0);
    }

    @Test
    public void testGetActiveSubscriptionInfoForSimSlotIndexWithNoPermission() throws Exception {
        // If the calling package does not have the READ_PHONE_STATE permission or carrier
        // privileges then getActiveSubscriptionInfoForSimSlotIndex should throw a
        // SecurityException.
        testInsertSim();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);

        try {
            mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0, mCallingPackage);
            fail("getActiveSubscriptionInfoForSimSlotIndex should fail when invoked with no "
                    + "permissions");
        } catch (SecurityException expected) {
        }
    }

    @Test
    public void testGetActiveSubscriptionInfoForSimSlotIndexWithReadPhoneState() throws Exception {
        // If the calling package only has the READ_PHONE_STATE permission then
        // getActiveSubscriptionInfoForSimlSlotIndex should still return the SubscriptionInfo but
        // the ICC ID should not be available.
        testInsertSim();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        setupMocksForTelephonyPermissions();

        SubscriptionInfo subscriptionInfo =
                mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
                        mCallingPackage);
        assertNotNull(subscriptionInfo);
        assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getIccId());
    }

    @Test
    public void testGetActiveSubscriptionInfoForSimSlotIndexWithPrivilegedPermission()
            throws Exception {
        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
        // privileges the ICC ID should be available in the SubscriptionInfo.
        testInsertSim();

        SubscriptionInfo subscriptionInfo =
                mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
                        mCallingPackage);
        assertNotNull(subscriptionInfo);
        assertTrue(subscriptionInfo.getIccId().length() > 0);
    }

    @Test
    public void testGetActiveSubscriptionInfoListWithNoPermission() throws Exception {
        // If the calling package does not have the READ_PHONE_STATE permission or carrier
        // privileges then getActiveSubscriptionInfoList should return a list with 0 elements.
        testInsertSim();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);

        List<SubscriptionInfo> subInfoList =
                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
        assertNotNull(subInfoList);
        assertTrue(subInfoList.size() == 0);
    }

    @Test
    public void testGetActiveSubscriptionInfoListWithReadPhoneState() throws Exception {
        // If the calling package only has the READ_PHONE_STATE permission then
        // getActiveSubscriptionInfoList should still return the list of SubscriptionInfo objects
        // but the ICC ID should not be available.
        testInsertSim();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        setupMocksForTelephonyPermissions();

        List<SubscriptionInfo> subInfoList =
                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
        assertTrue(subInfoList.size() > 0);
        for (SubscriptionInfo info : subInfoList) {
            assertEquals(UNAVAILABLE_ICCID, info.getIccId());
        }
    }

    @Test
    public void testGetActiveSubscriptionInfoListWithPrivilegedPermission() throws Exception {
        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
        // privileges the ICC ID should be available in the SubscriptionInfo objects in the List.
        testInsertSim();

        List<SubscriptionInfo> subInfoList =
                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
        assertTrue(subInfoList.size() > 0);
        for (SubscriptionInfo info : subInfoList) {
            assertTrue(info.getIccId().length() > 0);
        }
    }

    @Test
    public void testGetSubscriptionsInGroupWithNoPermission() throws Exception {
        // If the calling package does not have the READ_PHONE_STATE permission or carrier
        // privileges then getSubscriptionsInGroup should throw a SecurityException when the
        // READ_PHONE_STATE permission check is performed.
        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);

        try {
            mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid, mCallingPackage);
            fail("getSubscriptionsInGroup should fail when invoked with no permissions");
        } catch (SecurityException expected) {
        }
    }

    @Test
    public void testGetSubscriptionsInGroupWithReadPhoneState() throws Exception {
        // If the calling package only has the READ_PHONE_STATE permission then
        // getSubscriptionsInGroup should still return the list of SubscriptionInfo objects
        // but the ICC ID should not be available.
        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
        setupMocksForTelephonyPermissions();

        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
                groupUuid, mCallingPackage);
        assertTrue(subInfoList.size() > 0);
        for (SubscriptionInfo info : subInfoList) {
            assertEquals(UNAVAILABLE_ICCID, info.getIccId());
        }
    }

    @Test
    public void testGetSubscriptionsInGroupWithPrivilegedPermission() throws Exception {
        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
        // privileges the ICC ID should be available in the SubscriptionInfo objects in the List.
        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();

        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
                groupUuid, mCallingPackage);
        assertTrue(subInfoList.size() > 0);
        for (SubscriptionInfo info : subInfoList) {
            assertTrue(info.getIccId().length() > 0);
        }
    }

    private ParcelUuid setupGetSubscriptionsInGroupTest() throws Exception {
        testInsertSim();
        int[] subIdList = new int[]{getFirstSubId()};
        ParcelUuid groupUuid = mSubscriptionControllerUT.createSubscriptionGroup(subIdList,
                mCallingPackage);
        assertNotNull(groupUuid);
        return groupUuid;
    }

    private int getFirstSubId() throws Exception {
        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
        assertTrue(subIds != null && subIds.length != 0);
        return subIds[0];
    }

    @Test
    public void testGetEnabledSubscriptionIdSingleSIM() {
        // A single SIM device may have logical slot 0 mapped to physical slot 1
+9 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;

import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -252,6 +253,7 @@ public abstract class TelephonyTest {
    protected EuiccManager mEuiccManager;
    protected PackageManager mPackageManager;
    protected ConnectivityManager mConnectivityManager;
    protected AppOpsManager mAppOpsManager;
    protected SimulatedCommands mSimulatedCommands;
    protected ContextFixture mContextFixture;
    protected Context mContext;
@@ -380,6 +382,7 @@ public abstract class TelephonyTest {
        mConnectivityManager = (ConnectivityManager)
                mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        mPackageManager = mContext.getPackageManager();
        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);

        //mTelephonyComponentFactory
        doReturn(mTelephonyComponentFactory).when(mTelephonyComponentFactory).inject(anyString());
@@ -677,6 +680,12 @@ public abstract class TelephonyTest {
        doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfoAsUser(eq(TAG), anyInt(),
                anyInt());

        // TelephonyPermissions also checks to see if the calling package has been granted
        // identifier access via an appop; ensure this query does not allow identifier access for
        // any packages.
        doReturn(AppOpsManager.MODE_DEFAULT).when(mAppOpsManager).noteOpNoThrow(
                eq(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS), anyInt(), anyString());

        // TelephonyPermissions queries DeviceConfig to determine if the identifier access
        // restrictions should be enabled; this results in a NPE when DeviceConfig uses
        // Activity.currentActivity.getContentResolver as the resolver for Settings.Config.getString