Merge "Factor out telephony permission checks into a helper class."
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index f1eadb2..e8d48b8 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -102,6 +102,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;
@@ -110,6 +111,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;
@@ -1254,7 +1256,8 @@
 
     @Override
     public boolean isOffhookForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "isOffhookForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "isOffhookForSubscriber")) {
             return false;
         }
 
@@ -1273,7 +1276,8 @@
 
     @Override
     public boolean isRingingForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "isRingingForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "isRingingForSubscriber")) {
             return false;
         }
 
@@ -1292,7 +1296,8 @@
 
     @Override
     public boolean isIdleForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "isIdleForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "isIdleForSubscriber")) {
             return false;
         }
 
@@ -1467,7 +1472,8 @@
 
     @Override
     public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "isRadioOnForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "isRadioOnForSubscriber")) {
             return false;
         }
         return isRadioOnForSubscriber(subId);
@@ -1780,16 +1786,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);
@@ -1798,11 +1806,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
@@ -1831,35 +1840,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
@@ -1919,7 +1899,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);
@@ -1942,7 +1923,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);
@@ -1963,7 +1945,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);
@@ -1979,7 +1962,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();
@@ -1993,7 +1977,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();
@@ -2014,7 +1999,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;
@@ -2037,7 +2022,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();
@@ -2101,7 +2087,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);
@@ -2115,7 +2102,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);
@@ -2129,7 +2117,8 @@
      */
     @Override
     public int getVoiceActivationState(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getVoiceActivationStateForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getVoiceActivationStateForSubscriber")) {
             return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
         }
         final Phone phone = getPhone(subId);
@@ -2145,7 +2134,8 @@
      */
     @Override
     public int getDataActivationState(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getDataActivationStateForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getDataActivationStateForSubscriber")) {
             return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
         }
         final Phone phone = getPhone(subId);
@@ -2196,7 +2186,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);
     }
@@ -2222,7 +2213,8 @@
      */
     @Override
     public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getNetworkTypeForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -2247,7 +2239,8 @@
      */
     @Override
     public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getDataNetworkTypeForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getDataNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -2264,7 +2257,8 @@
      */
     @Override
     public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getDataNetworkTypeForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getDataNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -2314,7 +2308,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;
         }
 
@@ -2371,7 +2366,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.
@@ -2394,7 +2390,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) {
@@ -2408,7 +2405,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 +
@@ -2436,7 +2434,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)) {
@@ -2472,7 +2471,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 + " " +
@@ -2525,7 +2525,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) {
@@ -2548,7 +2549,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 + '"');
@@ -2565,7 +2567,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));
@@ -2582,7 +2585,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"));
@@ -2598,7 +2602,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"));
@@ -2615,7 +2620,8 @@
     }
 
     public String[] getPcscfAddress(String apnType, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getPcscfAddress")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getPcscfAddress")) {
             return new String[0];
         }
 
@@ -2692,7 +2698,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);
     }
@@ -2703,7 +2710,8 @@
     @Override
     public boolean setNetworkSelectionModeManual(int subId, String operatorNumeric,
             boolean persistSelection) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setNetworkSelectionModeManual");
         OperatorInfo operator = new OperatorInfo(
                 /* operatorAlphaLong */ "",
                 /* operatorAlphaShort */ "",
@@ -2719,7 +2727,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);
@@ -2738,7 +2747,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));
     }
@@ -2751,7 +2761,8 @@
      */
     @Override
     public void stopNetworkScan(int subId, int scanId) {
-        enforceModifyPermissionOrCarrierPrivilege(subId);
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "stopNetworkScan");
         mNetworkScanRequestTracker.stopNetworkScan(scanId);
     }
 
@@ -2763,7 +2774,8 @@
      */
     @Override
     public int getCalculatedPreferredNetworkType(String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getCalculatedPreferredNetworkType")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getCalculatedPreferredNetworkType")) {
             return RILConstants.PREFERRED_NETWORK_MODE;
         }
 
@@ -2778,7 +2790,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);
@@ -2795,7 +2808,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"));
@@ -2835,7 +2849,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);
@@ -2878,7 +2893,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);
@@ -2909,7 +2925,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);
@@ -2941,6 +2958,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;
@@ -3039,7 +3072,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);
@@ -3085,7 +3119,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;
         }
@@ -3105,7 +3140,8 @@
 
     @Override
     public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getLine1AlphaTagForDisplay")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getLine1AlphaTagForDisplay")) {
             return null;
         }
 
@@ -3119,7 +3155,8 @@
 
     @Override
     public String[] getMergedSubscriberIds(String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getMergedSubscriberIds")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getMergedSubscriberIds")) {
             return null;
         }
         final Context context = mPhone.getContext();
@@ -3192,7 +3229,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);
     }
@@ -3201,7 +3239,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;
@@ -3221,7 +3259,8 @@
 
     @Override
     public int getRadioAccessFamily(int phoneId, String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getRadioAccessFamily")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getRadioAccessFamily")) {
             return RadioAccessFamily.RAF_UNKNOWN;
         }
 
@@ -3236,7 +3275,8 @@
 
     @Override
     public boolean isVideoCallingEnabled(String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "isVideoCallingEnabled")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "isVideoCallingEnabled")) {
             return false;
         }
 
@@ -3290,7 +3330,8 @@
      */
     @Override
     public String getDeviceId(String callingPackage) {
-        if (!canReadPhoneState(callingPackage, "getDeviceId")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getDeviceId")) {
             return null;
         }
 
@@ -3371,72 +3412,6 @@
         }
     }
 
-    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();
@@ -3567,7 +3542,8 @@
     @Override
     public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
 
-        if (!canReadPhoneState(callingPackage, "getServiceStateForSubscriber")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getServiceStateForSubscriber")) {
             return null;
         }
 
@@ -3614,8 +3590,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){
@@ -3658,8 +3635,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);
@@ -3782,7 +3760,8 @@
      */
     @Override
     public List<TelephonyHistogram> getTelephonyHistograms() {
-        enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription());
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, getDefaultSubscription(), "getTelephonyHistograms");
         return RIL.getTelephonyRILTimingHistograms();
     }
 
@@ -3949,7 +3928,8 @@
      */
     @Override
     public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
-        if (!canReadPhoneState(callingPackage, "getClientRequestStats")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, callingPackage, "getClientRequestStats")) {
             return null;
         }