Merge "Fixed leak of cross user data in multiple settings." into sc-dev
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index ba797a3..2ac3d2c 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -103,6 +103,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyScanManager;
 import android.telephony.ThermalMitigationRequest;
+import android.telephony.UiccAccessRule;
 import android.telephony.UiccCardInfo;
 import android.telephony.UiccSlotInfo;
 import android.telephony.UssdResponse;
@@ -6663,6 +6664,9 @@
 
         PackageManager pkgMgr = phone.getContext().getPackageManager();
         String[] packages = pkgMgr.getPackagesForUid(uid);
+        if (packages == null) {
+            return privilegeFromSim;
+        }
 
         final long identity = Binder.clearCallingIdentity();
         try {
@@ -6673,10 +6677,10 @@
                 return privilegeFromSim;
             }
             SubscriptionInfo subInfo = subController.getSubscriptionInfo(subId);
-            SubscriptionManager subManager = (SubscriptionManager)
-                    phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+            List<UiccAccessRule> carrierConfigAccessRules = subInfo.getCarrierConfigAccessRules();
+
             for (String pkg : packages) {
-                if (subManager.canManageSubscription(subInfo, pkg)) {
+                if (hasCarrierConfigAccess(pkg, pkgMgr, carrierConfigAccessRules)) {
                     return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
                 }
             }
@@ -6702,15 +6706,49 @@
                 return privilegeFromSim;
             }
             SubscriptionInfo subInfo = subController.getSubscriptionInfo(subId);
-            SubscriptionManager subManager = (SubscriptionManager)
-                    phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
-            return subManager.canManageSubscription(subInfo, pkgName)
+            List<UiccAccessRule> carrierConfigAccessRules = subInfo.getCarrierConfigAccessRules();
+
+            return hasCarrierConfigAccess(pkgName, phone.getContext().getPackageManager(),
+                carrierConfigAccessRules)
                 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS : privilegeFromSim;
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
+    /**
+     * Check whether carrier privilege status can be granted to the provided app for this
+     * subscription based on the carrier config access rules of the subscription.
+     *
+     * @param packageName package name of the app to check
+     * @param packageManager package manager
+     * @param carrierConfigAccessRules carrier config access rules of the subscription
+     * @return true if the app is included in the mCarrierConfigAccessRules of this subscription.
+     */
+    private boolean hasCarrierConfigAccess(String packageName, PackageManager packageManager,
+        @NonNull List<UiccAccessRule> carrierConfigAccessRules) {
+        if ((packageName == null) || (carrierConfigAccessRules.isEmpty())) {
+            return false;
+        }
+
+        PackageInfo packageInfo;
+        try {
+            packageInfo = packageManager.getPackageInfo(packageName,
+                PackageManager.GET_SIGNING_CERTIFICATES);
+        } catch (PackageManager.NameNotFoundException e) {
+            logv("Unknown package: " + packageName);
+            return false;
+        }
+
+        for (UiccAccessRule rule : carrierConfigAccessRules) {
+            if (rule.getCarrierPrivilegeStatus(packageInfo)
+                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @Override
     public int getCarrierPrivilegeStatus(int subId) {
         final Phone phone = getPhone(subId);