resolve merge conflicts of 875a3fc05ff6dac1797b44cb6d0f814e9e723dc4 to stage-aosp-master

Bug: None
Test: None
Change-Id: I32fb80dbaad6ace6a989270e14e32284c5b7201e
Merged-In: I5464e4049e8f4e293cca4a9255a99051238101c5
diff --git a/src/java/com/android/internal/telephony/PhoneSubInfoController.java b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
index a371191..297dc84 100644
--- a/src/java/com/android/internal/telephony/PhoneSubInfoController.java
+++ b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
@@ -25,6 +25,7 @@
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.os.Binder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.ImsiEncryptionInfo;
@@ -60,76 +61,35 @@
     }
 
     public String getDeviceIdForPhone(int phoneId, String callingPackage) {
-        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
-            phoneId = 0;
-        }
-        final Phone phone = mPhone[phoneId];
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, phone.getSubId(), callingPackage, "getDeviceId")) {
-                return null;
-            }
-            return phone.getDeviceId();
-        } else {
-            loge("getDeviceIdForPhone phone " + phoneId + " is null");
-            return null;
-        }
+        return callPhoneMethodForPhoneIdWithReadCheck(phoneId, callingPackage,
+                "getDeviceId", (phone)-> phone.getDeviceId());
     }
 
     public String getNaiForSubscriber(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, "getNai")) {
-                return null;
-            }
-            return phone.getNai();
-        } else {
-            loge("getNai phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getNai",
+                (phone)-> phone.getNai());
     }
 
     public String getImeiForSubscriber(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, "getImei")) {
-                return null;
-            }
-            return phone.getImei();
-        } else {
-            loge("getDeviceId phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getImei",
+                (phone)-> phone.getImei());
     }
 
     public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType,
                                                               String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage,
-                    "getCarrierInfoForImsiEncryption")) {
-                return null;
-            }
-            return phone.getCarrierInfoForImsiEncryption(keyType);
-        } else {
-            loge("getCarrierInfoForImsiEncryption phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+                "getCarrierInfoForImsiEncryption",
+                (phone)-> phone.getCarrierInfoForImsiEncryption(keyType));
     }
 
     public void setCarrierInfoForImsiEncryption(int subId, String callingPackage,
                                                 ImsiEncryptionInfo imsiEncryptionInfo) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            enforceModifyPermission();
-            phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo);
-        } else {
-            loge("setCarrierInfoForImsiEncryption phone is null for Subscription:" + subId);
-            return;
-        }
+        callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage,
+                "setCarrierInfoForImsiEncryption",
+                (phone)-> {
+                    phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo);
+                    return null;
+                });
     }
 
     /**
@@ -140,15 +100,12 @@
      *  @param callingPackage
      */
     public void resetCarrierKeysForImsiEncryption(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            enforceModifyPermission();
-            phone.resetCarrierKeysForImsiEncryption();
-            return;
-        } else {
-            loge("resetCarrierKeysForImsiEncryption phone is null for Subscription:" + subId);
-            return;
-        }
+        callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage,
+                "setCarrierInfoForImsiEncryption",
+                (phone)-> {
+                    phone.resetCarrierKeysForImsiEncryption();
+                    return null;
+                });
     }
 
 
@@ -157,17 +114,8 @@
     }
 
     public String getDeviceSvnUsingSubId(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, "getDeviceSvn")) {
-                return null;
-            }
-            return phone.getDeviceSvn();
-        } else {
-            loge("getDeviceSvn phone is null");
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getDeviceSvn",
+                (phone)-> phone.getDeviceSvn());
     }
 
     public String getSubscriberId(String callingPackage) {
@@ -175,17 +123,8 @@
     }
 
     public String getSubscriberIdForSubscriber(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, "getSubscriberId")) {
-                return null;
-            }
-            return phone.getSubscriberId();
-        } else {
-            loge("getSubscriberId phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getSubscriberId",
+                (phone)-> phone.getSubscriberId());
     }
 
     /**
@@ -196,17 +135,8 @@
     }
 
     public String getIccSerialNumberForSubscriber(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, "getIccSerialNumber")) {
-                return null;
-            }
-            return phone.getIccSerialNumber();
-        } else {
-            loge("getIccSerialNumber phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getIccSerialNumber",
+                (phone)-> phone.getIccSerialNumber());
     }
 
     public String getLine1Number(String callingPackage) {
@@ -214,18 +144,9 @@
     }
 
     public String getLine1NumberForSubscriber(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            // This is open to apps with WRITE_SMS.
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
-                    mContext, subId, callingPackage, "getLine1Number")) {
-                return null;
-            }
-            return phone.getLine1Number();
-        } else {
-            loge("getLine1Number phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadPhoneNumberCheck(
+                subId, callingPackage, "getLine1Number",
+                (phone)-> phone.getLine1Number());
     }
 
     public String getLine1AlphaTag(String callingPackage) {
@@ -233,17 +154,8 @@
     }
 
     public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, "getLine1AlphaTag")) {
-                return null;
-            }
-            return phone.getLine1AlphaTag();
-        } else {
-            loge("getLine1AlphaTag phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getLine1AlphaTag",
+                (phone)-> phone.getLine1AlphaTag());
     }
 
     public String getMsisdn(String callingPackage) {
@@ -251,17 +163,8 @@
     }
 
     public String getMsisdnForSubscriber(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, "getMsisdn")) {
-                return null;
-            }
-            return phone.getMsisdn();
-        } else {
-            loge("getMsisdn phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getMsisdn",
+                (phone)-> phone.getMsisdn());
     }
 
     public String getVoiceMailNumber(String callingPackage) {
@@ -269,19 +172,13 @@
     }
 
     public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, "getVoiceMailNumber")) {
-                return null;
-            }
-            String number = PhoneNumberUtils.extractNetworkPortion(phone.getVoiceMailNumber());
-            if (VDBG) log("VM: getVoiceMailNUmber: " + number);
-            return number;
-        } else {
-            loge("getVoiceMailNumber phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+                "getVoiceMailNumber", (phone)-> {
+                    String number = PhoneNumberUtils.extractNetworkPortion(
+                            phone.getVoiceMailNumber());
+                    if (VDBG) log("VM: getVoiceMailNUmber: " + number);
+                    return number;
+                });
     }
 
     // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE
@@ -307,17 +204,8 @@
     }
 
     public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, "getVoiceMailAlphaTag")) {
-                return null;
-            }
-            return phone.getVoiceMailAlphaTag();
-        } else {
-            loge("getVoiceMailAlphaTag phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+                "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag());
     }
 
     /**
@@ -337,6 +225,9 @@
      * @throws SecurityException if the caller does not have the required permission/privilege
      */
     private void enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message) {
+        // TODO(b/73660190): Migrate to
+        // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete
+        // this helper method.
         int permissionResult = mContext.checkCallingOrSelfPermission(
                 READ_PRIVILEGED_PHONE_STATE);
         if (permissionResult == PackageManager.PERMISSION_GRANTED) {
@@ -358,151 +249,216 @@
         return  PhoneFactory.getDefaultSubscription();
     }
 
-
     /**
     * get the Isim Impi based on subId
     */
     public String getIsimImpi(int subId) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
-                    "Requires READ_PRIVILEGED_PHONE_STATE");
-            IsimRecords isim = phone.getIsimRecords();
-            if (isim != null) {
-                return isim.getIsimImpi();
-            } else {
-                return null;
-            }
-        } else {
-            loge("getIsimImpi phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpi",
+                (phone) -> {
+                    IsimRecords isim = phone.getIsimRecords();
+                    if (isim != null) {
+                        return isim.getIsimImpi();
+                    } else {
+                        return null;
+                    }
+                });
     }
 
     /**
     * get the Isim Domain based on subId
     */
     public String getIsimDomain(int subId) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
-                    "Requires READ_PRIVILEGED_PHONE_STATE");
-            IsimRecords isim = phone.getIsimRecords();
-            if (isim != null) {
-                return isim.getIsimDomain();
-            } else {
-                return null;
-            }
-        } else {
-            loge("getIsimDomain phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimDomain",
+                (phone) -> {
+                    IsimRecords isim = phone.getIsimRecords();
+                    if (isim != null) {
+                        return isim.getIsimDomain();
+                    } else {
+                        return null;
+                    }
+                });
     }
 
     /**
     * get the Isim Impu based on subId
     */
     public String[] getIsimImpu(int subId) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
-                    "Requires READ_PRIVILEGED_PHONE_STATE");
-            IsimRecords isim = phone.getIsimRecords();
-            if (isim != null) {
-                return isim.getIsimImpu();
-            } else {
-                return null;
-            }
-        } else {
-            loge("getIsimImpu phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpu",
+                (phone) -> {
+                    IsimRecords isim = phone.getIsimRecords();
+                    if (isim != null) {
+                        return isim.getIsimImpu();
+                    } else {
+                        return null;
+                    }
+                });
     }
 
     /**
     * get the Isim Ist based on subId
     */
     public String getIsimIst(int subId) throws RemoteException {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
-                    "Requires READ_PRIVILEGED_PHONE_STATE");
-            IsimRecords isim = phone.getIsimRecords();
-            if (isim != null) {
-                return isim.getIsimIst();
-            } else {
-                return null;
-            }
-        } else {
-            loge("getIsimIst phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimIst",
+                (phone) -> {
+                    IsimRecords isim = phone.getIsimRecords();
+                    if (isim != null) {
+                        return isim.getIsimIst();
+                    } else {
+                        return null;
+                    }
+                });
     }
 
     /**
     * get the Isim Pcscf based on subId
     */
     public String[] getIsimPcscf(int subId) throws RemoteException {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
-                    "Requires READ_PRIVILEGED_PHONE_STATE");
-            IsimRecords isim = phone.getIsimRecords();
-            if (isim != null) {
-                return isim.getIsimPcscf();
-            } else {
-                return null;
-            }
-        } else {
-            loge("getIsimPcscf phone is null for Subscription:" + subId);
-            return null;
-        }
+        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimPcscf",
+                (phone) -> {
+                    IsimRecords isim = phone.getIsimRecords();
+                    if (isim != null) {
+                        return isim.getIsimPcscf();
+                    } else {
+                        return null;
+                    }
+                });
     }
 
     public String getIccSimChallengeResponse(int subId, int appType, int authType, String data)
             throws RemoteException {
-        // TODO(b/73660190): Migrate to
-        // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete
-        // this helper method.
-        enforcePrivilegedPermissionOrCarrierPrivilege(subId, "getIccSimChallengeResponse");
-        Phone phone = getPhone(subId);
-        UiccCard uiccCard = phone.getUiccCard();
-        if (uiccCard == null) {
-            loge("getIccSimChallengeResponse() UiccCard is null");
-            return null;
-        }
+        CallPhoneMethodHelper<String> toExecute = (phone)-> {
+            UiccCard uiccCard = phone.getUiccCard();
+            if (uiccCard == null) {
+                loge("getIccSimChallengeResponse() UiccCard is null");
+                return null;
+            }
 
-        UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
-        if (uiccApp == null) {
-            loge("getIccSimChallengeResponse() no app with specified type -- " +
-                    appType);
-            return null;
-        } else {
-            loge("getIccSimChallengeResponse() found app " + uiccApp.getAid()
-                    + " specified type -- " + appType);
-        }
+            UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
+            if (uiccApp == null) {
+                loge("getIccSimChallengeResponse() no app with specified type -- " + appType);
+                return null;
+            } else {
+                loge("getIccSimChallengeResponse() found app " + uiccApp.getAid()
+                        + " specified type -- " + appType);
+            }
 
-        if(authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM &&
-                authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) {
-            loge("getIccSimChallengeResponse() unsupported authType: " + authType);
-            return null;
-        }
+            if (authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM
+                    && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) {
+                loge("getIccSimChallengeResponse() unsupported authType: " + authType);
+                return null;
+            }
+            return uiccApp.getIccRecords().getIccSimChallengeResponse(authType, data);
+        };
 
-        return uiccApp.getIccRecords().getIccSimChallengeResponse(authType, data);
+        return callPhoneMethodWithPermissionCheck(
+                subId, null, "getIccSimChallengeResponse", toExecute,
+                (aContext, aSubId, aCallingPackage, aMessage)-> {
+                    enforcePrivilegedPermissionOrCarrierPrivilege(aSubId, aMessage);
+                    return true;
+                });
     }
 
     public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage) {
-        Phone phone = getPhone(subId);
-        if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mContext, subId, callingPackage, "getGroupIdLevel1")) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+                "getGroupIdLevel1", (phone)-> phone.getGroupIdLevel1());
+    }
+
+    /** Below are utility methods that abstracts the flow that many public methods use:
+     *  1. Check permission: pass, throw exception, or fails (returns false).
+     *  2. clearCallingIdentity.
+     *  3. Call a specified phone method and get return value.
+     *  4. restoreCallingIdentity and return.
+     */
+    private interface CallPhoneMethodHelper<T> {
+        T callMethod(Phone phone);
+    }
+
+    private interface PermissionCheckHelper {
+        // Implemented to do whatever permission check it wants.
+        // If passes, it should return true.
+        // If permission is not granted, throws SecurityException.
+        // If permission is revoked by AppOps, return false.
+        boolean checkPermission(Context context, int subId, String callingPackage, String message);
+    }
+
+    // Base utility method that others use.
+    private <T> T callPhoneMethodWithPermissionCheck(int subId, String callingPackage,
+            String message, CallPhoneMethodHelper<T> callMethodHelper,
+            PermissionCheckHelper permissionCheckHelper) {
+        if (!permissionCheckHelper.checkPermission(mContext, subId, callingPackage, message)) {
+            return null;
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            Phone phone = getPhone(subId);
+            if (phone != null) {
+                return callMethodHelper.callMethod(phone);
+            } else {
+                loge(message + " phone is null for Subscription:" + subId);
                 return null;
             }
-            return phone.getGroupIdLevel1();
-        } else {
-            loge("getGroupIdLevel1 phone is null for Subscription:" + subId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private <T> T callPhoneMethodForSubIdWithReadCheck(int subId, String callingPackage,
+            String message, CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aMessage)->
+                        TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                                aContext, aSubId, aCallingPackage, aMessage));
+    }
+
+    private <T> T callPhoneMethodForSubIdWithPrivilegedCheck(
+            int subId, String message, CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aMessage)-> {
+                    mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message);
+                    return true;
+                });
+    }
+
+    private <T> T callPhoneMethodForSubIdWithModifyCheck(int subId, String callingPackage,
+            String message, CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aMessage)-> {
+                    enforceModifyPermission();
+                    return true;
+                });
+    }
+
+    private <T> T callPhoneMethodForSubIdWithReadPhoneNumberCheck(int subId, String callingPackage,
+            String message, CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aMessage)->
+                        TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
+                                aContext, aSubId, aCallingPackage, aMessage));
+    }
+
+    private <T> T callPhoneMethodForPhoneIdWithReadCheck(int phoneId, String callingPackage,
+            String message, CallPhoneMethodHelper<T> callMethodHelper) {
+        // Getting subId before doing permission check.
+        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
+            phoneId = 0;
+        }
+        final Phone phone = mPhone[phoneId];
+        if (phone == null) {
             return null;
         }
+
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mContext, phone.getSubId(), callingPackage, message)) {
+            return null;
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return callMethodHelper.callMethod(phone);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
     }
 
     private void log(String s) {