Factor out telephony permission checks into a helper class.

The aim is to cut down on duplicate code (for a particularly high-risk
area) and make it easier to expand READ_PHONE_STATE access to
carrier-privileged apps in a follow-up CL.

No major functional changes are intended, although some logging will
change slightly (different tag / less verbose carrier privilege
logging without DBG flag).

Bug: 70041899
Test: bit FrameworksTelephonyTests:*, nothing visibly broken on boot
Change-Id: Ide2aec8302898906b23125e4e1fca0992b6e4a4a
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 5db535f..cfd33cc 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -101,6 +101,7 @@
 import com.android.internal.telephony.RIL;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.SubscriptionController;
+import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.euicc.EuiccConnector;
 import com.android.internal.telephony.uicc.IccIoResult;
@@ -109,6 +110,7 @@
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccCardApplication;
 import com.android.internal.telephony.uicc.UiccController;
+import com.android.internal.telephony.uicc.UiccProfile;
 import com.android.internal.telephony.uicc.UiccSlot;
 import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
 import com.android.internal.util.HexDump;
@@ -1253,7 +1255,8 @@
 
     @Override
     public boolean isOffhookForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "isOffhookForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "isOffhookForSubscriber")) {
             return false;
         }
 
@@ -1272,7 +1275,8 @@
 
     @Override
     public boolean isRingingForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "isRingingForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "isRingingForSubscriber")) {
             return false;
         }
 
@@ -1291,7 +1295,8 @@
 
     @Override
     public boolean isIdleForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "isIdleForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "isIdleForSubscriber")) {
             return false;
         }
 
@@ -1466,7 +1471,8 @@
 
     @Override
     public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "isRadioOnForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "isRadioOnForSubscriber")) {
             return false;
         }
         return isRadioOnForSubscriber(subId);
@@ -1773,16 +1779,18 @@
 
     @Override
     public String getImeiForSlot(int slotIndex, String callingPackage) {
-      if (!canReadPhoneState(callingPackage, "getImeiForSlot")) {
-          return null;
-      }
-      Phone phone = PhoneFactory.getPhone(slotIndex);
-      return phone == null ? null : phone.getImei();
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getImeiForSlot")) {
+            return null;
+        }
+        Phone phone = PhoneFactory.getPhone(slotIndex);
+        return phone == null ? null : phone.getImei();
     }
 
     @Override
     public String getMeidForSlot(int slotIndex, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getMeidForSlot")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getMeidForSlot")) {
             return null;
         }
         Phone phone = PhoneFactory.getPhone(slotIndex);
@@ -1791,11 +1799,12 @@
 
     @Override
     public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
-      if (!canReadPhoneState(callingPackage, "getDeviceSoftwareVersionForSlot")) {
-          return null;
-      }
-      Phone phone = PhoneFactory.getPhone(slotIndex);
-      return phone == null ? null : phone.getDeviceSvn();
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getDeviceSoftwareVersionForSlot")) {
+            return null;
+        }
+        Phone phone = PhoneFactory.getPhone(slotIndex);
+        return phone == null ? null : phone.getDeviceSvn();
     }
 
     @Override
@@ -1824,35 +1833,6 @@
     }
 
     /**
-     * Make sure either system app or the caller has carrier privilege.
-     *
-     * @throws SecurityException if the caller does not have the required permission/privilege
-     */
-    private void enforceModifyPermissionOrCarrierPrivilege(int subId) {
-        int permission = mApp.checkCallingOrSelfPermission(
-                android.Manifest.permission.MODIFY_PHONE_STATE);
-        if (permission == PackageManager.PERMISSION_GRANTED) {
-            return;
-        }
-
-        log("No modify permission, check carrier privilege next.");
-        enforceCarrierPrivilege(subId);
-    }
-
-    /**
-     * Make sure the caller has carrier privilege.
-     *
-     * @throws SecurityException if the caller does not have the required permission
-     */
-    private void enforceCarrierPrivilege(int subId) {
-        if (getCarrierPrivilegeStatus(subId) !=
-                    TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
-            loge("No Carrier Privilege.");
-            throw new SecurityException("No Carrier Privilege.");
-        }
-    }
-
-    /**
      * Make sure the caller has the CALL_PHONE permission.
      *
      * @throws SecurityException if the caller does not have the required permission
@@ -1912,7 +1892,8 @@
 
     @Override
     public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getCdmaEriIconIndexForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
             return -1;
         }
         final Phone phone = getPhone(subId);
@@ -1935,7 +1916,8 @@
 
     @Override
     public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getCdmaEriIconModeForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getCdmaEriIconModeForSubscriber")) {
             return -1;
         }
         final Phone phone = getPhone(subId);
@@ -1956,7 +1938,8 @@
 
     @Override
     public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getCdmaEriIconTextForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getCdmaEriIconTextForSubscriber")) {
             return null;
         }
         final Phone phone = getPhone(subId);
@@ -1972,7 +1955,8 @@
      */
     @Override
     public String getCdmaMdn(int subId) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "getCdmaMdn");
         final Phone phone = getPhone(subId);
         if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) {
             return phone.getLine1Number();
@@ -1986,7 +1970,8 @@
      */
     @Override
     public String getCdmaMin(int subId) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "getCdmaMin");
         final Phone phone = getPhone(subId);
         if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
             return phone.getCdmaMin();
@@ -2007,7 +1992,7 @@
      */
     @Override
     public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
-        enforceCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
         Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
                 new Pair<String, String>(alphaTag, number), new Integer(subId));
         return success;
@@ -2030,7 +2015,8 @@
     @Override
     public String getVisualVoicemailPackageName(String callingPackage, int subId) {
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
-        if (!canReadPhoneState(callingPackage, "getVisualVoicemailPackageName")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getVisualVoicemailPackageName")) {
             return null;
         }
         return RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId).getPackageName();
@@ -2094,7 +2080,8 @@
      */
     @Override
     public void setVoiceActivationState(int subId, int activationState) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setVoiceActivationState");
         final Phone phone = getPhone(subId);
         if (phone != null) {
             phone.setVoiceActivationState(activationState);
@@ -2108,7 +2095,8 @@
      */
     @Override
     public void setDataActivationState(int subId, int activationState) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setDataActivationState");
         final Phone phone = getPhone(subId);
         if (phone != null) {
             phone.setDataActivationState(activationState);
@@ -2185,7 +2173,8 @@
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         String defaultDialer = TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage();
         if (!TextUtils.equals(callingPackage, defaultDialer)) {
-            enforceCarrierPrivilege(getDefaultSubscription());
+            TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+                    getDefaultSubscription(), "sendDialerSpecialCode");
         }
         mPhone.sendDialerSpecialCode(inputCode);
     }
@@ -2211,7 +2200,8 @@
      */
     @Override
     public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getNetworkTypeForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -2236,7 +2226,8 @@
      */
     @Override
     public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getDataNetworkTypeForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getDataNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -2253,7 +2244,8 @@
      */
     @Override
     public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getDataNetworkTypeForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getDataNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -2303,7 +2295,8 @@
 
     @Override
     public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getLteOnCdmaModeForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getLteOnCdmaModeForSubscriber")) {
             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
         }
 
@@ -2360,7 +2353,8 @@
     @Override
     public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
             int subId, String callingPackage, String aid, int p2) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "iccOpenLogicalChannel");
 
         if (TextUtils.equals(ISDR_AID, aid)) {
             // Only allows LPA to open logical channel to ISD-R.
@@ -2383,7 +2377,8 @@
 
     @Override
     public boolean iccCloseLogicalChannel(int subId, int channel) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "iccCloseLogicalChannel");
 
         if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
         if (channel < 0) {
@@ -2397,7 +2392,8 @@
     @Override
     public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
             int command, int p1, int p2, int p3, String data) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "iccTransmitApduLogicalChannel");
 
         if (DBG) {
             log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel +
@@ -2425,7 +2421,8 @@
     @Override
     public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
             int command, int p1, int p2, int p3, String data) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "iccTransmitApduBasicChannel");
 
         if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
                 && TextUtils.equals(ISDR_AID, data)) {
@@ -2461,7 +2458,8 @@
     @Override
     public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
             String filePath) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "iccExchangeSimIO");
 
         if (DBG) {
             log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " " +
@@ -2514,7 +2512,8 @@
 
     @Override
     public String sendEnvelopeWithStatus(int subId, String content) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "sendEnvelopeWithStatus");
 
         IccIoResult response = (IccIoResult)sendRequest(CMD_SEND_ENVELOPE, content, subId);
         if (response.payload == null) {
@@ -2537,7 +2536,8 @@
      */
     @Override
     public String nvReadItem(int itemID) {
-        enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription());
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, getDefaultSubscription(), "nvReadItem");
         if (DBG) log("nvReadItem: item " + itemID);
         String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID);
         if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
@@ -2554,7 +2554,8 @@
      */
     @Override
     public boolean nvWriteItem(int itemID, String itemValue) {
-        enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription());
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, getDefaultSubscription(), "nvWriteItem");
         if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
         Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
                 new Pair<Integer, String>(itemID, itemValue));
@@ -2571,7 +2572,8 @@
      */
     @Override
     public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
-        enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription());
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
         if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
         Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
         if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
@@ -2587,7 +2589,8 @@
      */
     @Override
     public boolean nvResetConfig(int resetType) {
-        enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription());
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, getDefaultSubscription(), "nvResetConfig");
         if (DBG) log("nvResetConfig: type " + resetType);
         Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType);
         if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail"));
@@ -2604,7 +2607,8 @@
     }
 
     public String[] getPcscfAddress(String apnType, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getPcscfAddress")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getPcscfAddress")) {
             return new String[0];
         }
 
@@ -2681,7 +2685,8 @@
      */
     @Override
     public void setNetworkSelectionModeAutomatic(int subId) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setNetworkSelectionModeAutomatic");
         if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
         sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
     }
@@ -2692,7 +2697,8 @@
     @Override
     public boolean setNetworkSelectionModeManual(int subId, String operatorNumeric,
             boolean persistSelection) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setNetworkSelectionModeManual");
         OperatorInfo operator = new OperatorInfo(
                 /* operatorAlphaLong */ "",
                 /* operatorAlphaShort */ "",
@@ -2708,7 +2714,8 @@
      */
     @Override
     public CellNetworkScanResult getCellNetworkScanResults(int subId) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "getCellNetworkScanResults");
         if (DBG) log("getCellNetworkScanResults: subId " + subId);
         CellNetworkScanResult result = (CellNetworkScanResult) sendRequest(
                 CMD_PERFORM_NETWORK_SCAN, null, subId);
@@ -2727,7 +2734,8 @@
     @Override
     public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
             IBinder binder) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "requestNetworkScan");
         return mNetworkScanRequestTracker.startNetworkScan(
                 request, messenger, binder, getPhone(subId));
     }
@@ -2740,7 +2748,8 @@
      */
     @Override
     public void stopNetworkScan(int subId, int scanId) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "stopNetworkScan");
         mNetworkScanRequestTracker.stopNetworkScan(scanId);
     }
 
@@ -2752,7 +2761,8 @@
      */
     @Override
     public int getCalculatedPreferredNetworkType(String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getCalculatedPreferredNetworkType")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getCalculatedPreferredNetworkType")) {
             return RILConstants.PREFERRED_NETWORK_MODE;
         }
 
@@ -2767,7 +2777,8 @@
      */
     @Override
     public int getPreferredNetworkType(int subId) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "getPreferredNetworkType");
         if (DBG) log("getPreferredNetworkType");
         int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
         int networkType = (result != null ? result[0] : -1);
@@ -2784,7 +2795,8 @@
      */
     @Override
     public boolean setPreferredNetworkType(int subId, int networkType) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setPreferredNetworkType");
         if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
         Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
         if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
@@ -2824,7 +2836,8 @@
      */
     @Override
     public void setUserDataEnabled(int subId, boolean enable) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setUserDataEnabled");
         int phoneId = mSubscriptionController.getPhoneId(subId);
         if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
         Phone phone = PhoneFactory.getPhone(phoneId);
@@ -2867,7 +2880,8 @@
             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
                     null);
         } catch (Exception e) {
-            enforceModifyPermissionOrCarrierPrivilege(subId);
+            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                    mApp, subId, "isUserDataEnabled");
         }
         int phoneId = mSubscriptionController.getPhoneId(subId);
         if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
@@ -2898,7 +2912,8 @@
             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
                     null);
         } catch (Exception e) {
-            enforceModifyPermissionOrCarrierPrivilege(subId);
+            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                    mApp, subId, "isDataEnabled");
         }
         int phoneId = mSubscriptionController.getPhoneId(subId);
         if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
@@ -2930,6 +2945,22 @@
     }
 
     @Override
+    public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
+        final Phone phone = getPhone(subId);
+        if (phone == null) {
+            loge("getCarrierPrivilegeStatus: Invalid subId");
+            return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
+        }
+        UiccProfile profile =
+                UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
+        if (profile == null) {
+            loge("getCarrierPrivilegeStatus: No UICC");
+            return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
+        }
+        return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
+    }
+
+    @Override
     public int checkCarrierPrivilegesForPackage(String pkgName) {
         if (TextUtils.isEmpty(pkgName))
             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
@@ -3028,7 +3059,8 @@
     @Override
     public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
             String number) {
-        enforceCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+                subId, "setLine1NumberForDisplayForSubscriber");
 
         final String iccId = getIccId(subId);
         final Phone phone = getPhone(subId);
@@ -3074,7 +3106,8 @@
     @Override
     public String getLine1NumberForDisplay(int subId, String callingPackage) {
         // This is open to apps with WRITE_SMS.
-        if (!canReadPhoneNumber(callingPackage, "getLine1NumberForDisplay")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
+                mApp, callingPackage, "getLine1NumberForDisplay")) {
             if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
             return null;
         }
@@ -3094,7 +3127,8 @@
 
     @Override
     public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getLine1AlphaTagForDisplay")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getLine1AlphaTagForDisplay")) {
             return null;
         }
 
@@ -3108,7 +3142,8 @@
 
     @Override
     public String[] getMergedSubscriberIds(String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getMergedSubscriberIds")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getMergedSubscriberIds")) {
             return null;
         }
         final Context context = mPhone.getContext();
@@ -3181,7 +3216,8 @@
 
     @Override
     public boolean setOperatorBrandOverride(int subId, String brand) {
-        enforceCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+                subId, "setOperatorBrandOverride");
         final Phone phone = getPhone(subId);
         return phone == null ? false : phone.setOperatorBrandOverride(brand);
     }
@@ -3190,7 +3226,7 @@
     public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
             List<String> cdmaNonRoamingList) {
-        enforceCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
         final Phone phone = getPhone(subId);
         if (phone == null) {
             return false;
@@ -3210,7 +3246,8 @@
 
     @Override
     public int getRadioAccessFamily(int phoneId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getRadioAccessFamily")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getRadioAccessFamily")) {
             return RadioAccessFamily.RAF_UNKNOWN;
         }
 
@@ -3225,7 +3262,8 @@
 
     @Override
     public boolean isVideoCallingEnabled(String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "isVideoCallingEnabled")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "isVideoCallingEnabled")) {
             return false;
         }
 
@@ -3279,7 +3317,8 @@
      */
     @Override
     public String getDeviceId(String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getDeviceId")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getDeviceId")) {
             return null;
         }
 
@@ -3343,72 +3382,6 @@
         return mPhone.isVideoEnabled();
     }
 
-    private boolean canReadPhoneState(String callingPackage, String message) {
-        try {
-            mApp.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);
-
-            // SKIP checking for run-time permission since caller or self has PRIVILEDGED permission
-            return true;
-        } catch (SecurityException e) {
-            mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
-                    message);
-        }
-
-        if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
-                callingPackage) != AppOpsManager.MODE_ALLOWED) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Besides READ_PHONE_STATE, WRITE_SMS and READ_SMS also allow apps to get phone numbers.
-     */
-    private boolean canReadPhoneNumber(String callingPackage, String message) {
-        // Default SMS app can always read it.
-        if (mAppOps.noteOp(AppOpsManager.OP_WRITE_SMS,
-                Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED) {
-            return true;
-        }
-
-        try {
-            return canReadPhoneState(callingPackage, message);
-        } catch (SecurityException readPhoneStateSecurityException) {
-        }
-        // Can be read with READ_SMS too.
-        try {
-            mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_SMS, message);
-            int opCode = mAppOps.permissionToOpCode(android.Manifest.permission.READ_SMS);
-            if (opCode != AppOpsManager.OP_NONE) {
-                return mAppOps.noteOp(opCode, Binder.getCallingUid(), callingPackage)
-                        == AppOpsManager.MODE_ALLOWED;
-            } else {
-                return true;
-            }
-        } catch (SecurityException readSmsSecurityException) {
-        }
-        // Can be read with READ_PHONE_NUMBERS too.
-        try {
-            mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_NUMBERS,
-                    message);
-            int opCode = mAppOps.permissionToOpCode(android.Manifest.permission.READ_PHONE_NUMBERS);
-            if (opCode != AppOpsManager.OP_NONE) {
-                return mAppOps.noteOp(opCode, Binder.getCallingUid(), callingPackage)
-                        == AppOpsManager.MODE_ALLOWED;
-            } else {
-                return true;
-            }
-        } catch (SecurityException readPhoneNumberSecurityException) {
-        }
-
-        throw new SecurityException(message + ": Neither user " + Binder.getCallingUid() +
-                " nor current process has" + android.Manifest.permission.READ_PHONE_STATE +
-                ", " + android.Manifest.permission.READ_SMS + ", or " +
-                android.Manifest.permission.READ_PHONE_NUMBERS);
-    }
-
     @Override
     public void factoryReset(int subId) {
         enforceConnectivityInternalPermission();
@@ -3571,7 +3544,8 @@
     @Override
     public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
 
-        if (!canReadPhoneState(callingPackage, "getServiceStateForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getServiceStateForSubscriber")) {
             return null;
         }
 
@@ -3618,8 +3592,9 @@
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         if (!TextUtils.equals(callingPackage,
                 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
-            enforceModifyPermissionOrCarrierPrivilege(
-                    PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle));
+            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                    mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
+                    "setVoicemailRingtoneUri");
         }
         Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
         if (phone == null){
@@ -3662,8 +3637,9 @@
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         if (!TextUtils.equals(callingPackage,
                 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
-            enforceModifyPermissionOrCarrierPrivilege(
-                    PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle));
+            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                    mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
+                    "setVoicemailVibrationEnabled");
         }
 
         Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
@@ -3786,7 +3762,8 @@
      */
     @Override
     public List<TelephonyHistogram> getTelephonyHistograms() {
-        enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription());
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, getDefaultSubscription(), "getTelephonyHistograms");
         return RIL.getTelephonyRILTimingHistograms();
     }
 
@@ -3953,7 +3930,8 @@
      */
     @Override
     public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
-        if (!canReadPhoneState(callingPackage, "getClientRequestStats")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getClientRequestStats")) {
             return null;
         }