Don't allow reading IMSI of one active sub if only has carrier privilege
on the other.

Bug: 136123413
Test: unittest
Change-Id: I24983ac66092c3571cc0f35ead49259587576492
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
index 185d4a4..d94863c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
@@ -31,8 +31,11 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ServiceManager;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
@@ -49,14 +52,15 @@
 import org.mockito.MockitoAnnotations;
 
 import java.lang.reflect.Field;
+import java.util.Map;
 
 @SmallTest
 public class TelephonyPermissionsTest {
 
     private static final int SUB_ID = 55555;
     private static final int SUB_ID_2 = 22222;
-    private static final int PID = 12345;
-    private static final int UID = 54321;
+    private static final int PID = Binder.getCallingPid();
+    private static final int UID = Binder.getCallingUid();
     private static final String PACKAGE = "com.example";
     private static final String MSG = "message";
 
@@ -69,6 +73,8 @@
     @Mock
     private ITelephony mMockTelephony;
     @Mock
+    private IBinder mMockTelephonyBinder;
+    @Mock
     private PackageManager mMockPackageManager;
     @Mock
     private ApplicationInfo mMockApplicationInfo;
@@ -100,10 +106,13 @@
                 AppOpsManager.MODE_ERRORED);
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID)))
+                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         when(mMockContext.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
                 PID, UID)).thenReturn(PackageManager.PERMISSION_DENIED);
         when(mMockDevicePolicyManager.checkDeviceIdentifierAccess(eq(PACKAGE), eq(PID),
                 eq(UID))).thenReturn(false);
+        setTelephonyMockAsService();
     }
 
     @Test
@@ -242,8 +251,8 @@
     public void testCheckReadDeviceIdentifiers_noPermissions() throws Exception {
         setupMocksForDeviceIdentifiersErrorPath();
         try {
-            TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                    SUB_ID, PID, UID, PACKAGE, MSG);
+            TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                    SUB_ID, PACKAGE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -255,8 +264,8 @@
         when(mMockContext.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
                 PID, UID)).thenReturn(PackageManager.PERMISSION_GRANTED);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -264,8 +273,8 @@
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -273,8 +282,8 @@
         when(mMockAppOps.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, UID,
                 PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -282,8 +291,8 @@
         when(mMockDevicePolicyManager.checkDeviceIdentifierAccess(eq(PACKAGE), eq(PID),
                 eq(UID))).thenReturn(true);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -295,8 +304,8 @@
                 UID)).thenReturn(PackageManager.PERMISSION_GRANTED);
         setupMocksForDeviceIdentifiersErrorPath();
         try {
-            TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                    SUB_ID, PID, UID, PACKAGE, MSG);
+            TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                    SUB_ID, PACKAGE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -313,8 +322,8 @@
         setupMocksForDeviceIdentifiersErrorPath();
         mMockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
         assertFalse(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -325,8 +334,8 @@
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID))).thenReturn(
                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -339,8 +348,8 @@
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID)))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID_2, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -353,8 +362,8 @@
         when(mMockAppOps.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, UID,
                 PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(
-                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                        SUB_ID, PID, UID, PACKAGE, MSG));
+                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
     }
 
     @Test
@@ -364,14 +373,79 @@
         // case.
         setupMocksForDeviceIdentifiersErrorPath();
         try {
-            TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
-                    SUB_ID, PID, UID, null, MSG);
+            TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
+                    SUB_ID, null, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
         }
     }
 
+    @Test
+    public void testCheckCallingOrSelfReadSubscriberIdentifiers_noPermissions() throws Exception {
+        setupMocksForDeviceIdentifiersErrorPath();
+        setTelephonyMockAsService();
+        when(mMockContext.checkPermission(
+                eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
+                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
+        when(mMockAppOps.noteOpNoThrow(anyString(), anyInt(), eq(PACKAGE))).thenReturn(
+                AppOpsManager.MODE_ERRORED);
+        when(mMockDevicePolicyManager.checkDeviceIdentifierAccess(eq(PACKAGE), anyInt(),
+                anyInt())).thenReturn(false);
+        try {
+            TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
+                    SUB_ID, PACKAGE, MSG);
+            fail("Should have thrown SecurityException");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testCheckCallingOrSelfReadSubscriberIdentifiers_carrierPrivileges()
+            throws Exception {
+        setTelephonyMockAsService();
+        when(mMockContext.checkPermission(
+                eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
+                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
+        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), anyInt()))
+                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        assertTrue(
+                TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
+                        SUB_ID, PACKAGE, MSG));
+    }
+
+    @Test
+    public void testCheckCallingOrSelfReadSubscriberIdentifiers_carrierPrivilegesOnOtherSub()
+            throws Exception {
+        setupMocksForDeviceIdentifiersErrorPath();
+        setTelephonyMockAsService();
+        when(mMockContext.checkPermission(
+                eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
+                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
+        when(mMockSubscriptionManager.getActiveSubscriptionIdList(anyBoolean())).thenReturn(
+                new int[]{SUB_ID, SUB_ID_2});
+        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), anyInt())).thenReturn(
+                TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        // Carrier privilege on the other active sub shouldn't allow access to this sub.
+        try {
+            TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
+                    SUB_ID, PACKAGE, MSG);
+            fail("Should have thrown SecurityException");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    // Put mMockTelephony into service cache so that TELEPHONY_SUPPLIER will get it.
+    private void setTelephonyMockAsService() throws Exception {
+        when(mMockTelephonyBinder.queryLocalInterface(anyString())).thenReturn(mMockTelephony);
+        Field field = ServiceManager.class.getDeclaredField("sCache");
+        field.setAccessible(true);
+        ((Map<String, IBinder>) field.get(null)).put(Context.TELEPHONY_SERVICE,
+                mMockTelephonyBinder);
+    }
+
     public static class FakeSettingsConfigProvider extends FakeSettingsProvider {
         private static final String PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED =
                 DeviceConfig.NAMESPACE_PRIVACY + "/"