Merge "Handle 5G meteredness in telephony framework"
diff --git a/OWNERS b/OWNERS
index 8f494b2..0f8fc34 100644
--- a/OWNERS
+++ b/OWNERS
@@ -11,4 +11,5 @@
 refuhoo@google.com
 paulye@google.com
 nazaninb@google.com
-sarahchin@google.com
\ No newline at end of file
+sarahchin@google.com
+dbright@google.com
diff --git a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
index 4cdfd26..56f0eea 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
@@ -272,9 +272,11 @@
 
             String error;
             try {
-                if (mContext.bindServiceAsUser(carrierService, connection,
-                        Context.BIND_AUTO_CREATE |  Context.BIND_FOREGROUND_SERVICE,
-                        mHandler, Process.myUserHandle())) {
+                if (mContext.createContextAsUser(Process.myUserHandle(), 0)
+                        .bindService(carrierService,
+                                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+                                (r) -> mHandler.post(r),
+                                connection)) {
                     return;
                 }
 
diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index 3610be8..7ad0de4 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -407,7 +407,7 @@
         if (DBG) log("onSubscriptionGroupChanged");
 
         List<SubscriptionInfo> infoList = mSubController.getSubscriptionsInGroup(
-                groupUuid, mContext.getOpPackageName());
+                groupUuid, mContext.getOpPackageName(), null);
         if (infoList == null || infoList.isEmpty()) return;
 
         // Get a reference subscription to copy settings from.
@@ -470,7 +470,8 @@
         if (!isReadyToReevaluate()) return;
 
         List<SubscriptionInfo> activeSubInfos = mSubController
-                .getActiveSubscriptionInfoList(mContext.getOpPackageName());
+                .getActiveSubscriptionInfoList(mContext.getOpPackageName(),
+                        null);
 
         if (ArrayUtils.isEmpty(activeSubInfos)) {
             mPrimarySubList.clear();
@@ -644,7 +645,8 @@
             if (phone != null && phone.isCdmaSubscriptionAppPresent()) {
                 cdmaPhoneCount++;
                 String simName = mSubController.getActiveSubscriptionInfo(
-                        subId, mContext.getOpPackageName()).getDisplayName().toString();
+                        subId, mContext.getOpPackageName(), null)
+                        .getDisplayName().toString();
                 if (TextUtils.isEmpty(simName)) {
                     // Fall back to carrier name.
                     simName = phone.getCarrierName();
@@ -700,7 +702,8 @@
     private void setUserDataEnabledForGroup(int subId, boolean enable) {
         log("setUserDataEnabledForGroup subId " + subId + " enable " + enable);
         List<SubscriptionInfo> infoList = mSubController.getSubscriptionsInGroup(
-                mSubController.getGroupUuid(subId), mContext.getOpPackageName());
+                mSubController.getGroupUuid(subId), mContext.getOpPackageName(),
+                null);
 
         if (infoList == null) return;
 
@@ -730,7 +733,8 @@
     private void setRoamingDataEnabledForGroup(int subId, boolean enable) {
         SubscriptionController subController = SubscriptionController.getInstance();
         List<SubscriptionInfo> infoList = subController.getSubscriptionsInGroup(
-                mSubController.getGroupUuid(subId), mContext.getOpPackageName());
+                mSubController.getGroupUuid(subId), mContext.getOpPackageName(),
+                null);
 
         if (infoList == null) return;
 
@@ -778,7 +782,7 @@
         if (!SubscriptionInfoUpdater.isSubInfoInitialized()) return;
 
         List<SubscriptionInfo> opptSubList = mSubController.getOpportunisticSubscriptions(
-                mContext.getOpPackageName());
+                mContext.getOpPackageName(), null);
 
         if (ArrayUtils.isEmpty(opptSubList)) return;
 
diff --git a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
index 895170d..f8ef3b2 100644
--- a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
+++ b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
@@ -189,7 +189,7 @@
      */
     public static Set<String> getAllowedMccMncsForLocationRestrictedScan(Context context) {
         return withCleanCallingIdentity(() -> SubscriptionController.getInstance()
-            .getAvailableSubscriptionInfoList(context.getOpPackageName()).stream()
+            .getAvailableSubscriptionInfoList(context.getOpPackageName(), null).stream()
             .flatMap(NetworkScanRequestTracker::getAllowableMccMncsFromSubscriptionInfo)
             .collect(Collectors.toSet()));
     }
diff --git a/src/java/com/android/internal/telephony/PhoneSubInfoController.java b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
index 384a7c9..51d9595 100644
--- a/src/java/com/android/internal/telephony/PhoneSubInfoController.java
+++ b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
@@ -21,6 +21,8 @@
 import static android.Manifest.permission.MODIFY_PHONE_STATE;
 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.app.AppOpsManager;
 import android.content.Context;
@@ -54,24 +56,31 @@
         mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
     }
 
+    @Deprecated
     public String getDeviceId(String callingPackage) {
+        return getDeviceIdWithFeature(callingPackage, null);
+    }
+
+    public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
         return getDeviceIdForPhone(SubscriptionManager.getPhoneId(getDefaultSubscription()),
-                callingPackage);
+                callingPackage, callingFeatureId);
     }
 
-    public String getDeviceIdForPhone(int phoneId, String callingPackage) {
+    public String getDeviceIdForPhone(int phoneId, String callingPackage,
+            String callingFeatureId) {
         return callPhoneMethodForPhoneIdWithReadDeviceIdentifiersCheck(phoneId, callingPackage,
-                "getDeviceId", (phone)-> phone.getDeviceId());
+                callingFeatureId, "getDeviceId", (phone) -> phone.getDeviceId());
     }
 
-    public String getNaiForSubscriber(int subId, String callingPackage) {
+    public String getNaiForSubscriber(int subId, String callingPackage, String callingFeatureId) {
         return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage,
-                "getNai", (phone)-> phone.getNai());
+                callingFeatureId, "getNai", (phone)-> phone.getNai());
     }
 
-    public String getImeiForSubscriber(int subId, String callingPackage) {
+    public String getImeiForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         return callPhoneMethodForSubIdWithReadDeviceIdentifiersCheck(subId, callingPackage,
-                "getImei", (phone)-> phone.getImei());
+                callingFeatureId, "getImei", (phone) -> phone.getImei());
     }
 
     public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType,
@@ -107,34 +116,43 @@
                 });
     }
 
-    public String getDeviceSvn(String callingPackage) {
-        return getDeviceSvnUsingSubId(getDefaultSubscription(), callingPackage);
+    public String getDeviceSvn(String callingPackage, String callingFeatureId) {
+        return getDeviceSvnUsingSubId(getDefaultSubscription(), callingPackage, callingFeatureId);
     }
 
-    public String getDeviceSvnUsingSubId(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getDeviceSvn",
-                (phone)-> phone.getDeviceSvn());
+    public String getDeviceSvnUsingSubId(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
+                "getDeviceSvn", (phone)-> phone.getDeviceSvn());
     }
 
+    @Deprecated
     public String getSubscriberId(String callingPackage) {
-        return getSubscriberIdForSubscriber(getDefaultSubscription(), callingPackage);
+        return getSubscriberIdWithFeature(callingPackage, null);
     }
 
-    public String getSubscriberIdForSubscriber(int subId, String callingPackage) {
+    public String getSubscriberIdWithFeature(String callingPackage, String callingFeatureId) {
+        return getSubscriberIdForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
+    }
+
+    public String getSubscriberIdForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         String message = "getSubscriberId";
         long identity = Binder.clearCallingIdentity();
         boolean isActive;
         try {
-            isActive = SubscriptionController.getInstance().isActiveSubId(subId, callingPackage);
+            isActive = SubscriptionController.getInstance().isActiveSubId(subId, callingPackage,
+                    callingFeatureId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
         if (isActive) {
             return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage,
-                    message, (phone) -> phone.getSubscriberId());
+                    callingFeatureId, message, (phone) -> phone.getSubscriberId());
         } else {
             if (!TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(
-                    mContext, subId, callingPackage, message)) {
+                    mContext, subId, callingPackage, callingFeatureId, message)) {
                 return null;
             }
             identity = Binder.clearCallingIdentity();
@@ -146,52 +164,66 @@
         }
     }
 
+    @Deprecated
+    public String getIccSerialNumber(String callingPackage) {
+        return getIccSerialNumberWithFeature(callingPackage, null);
+    }
+
     /**
      * Retrieves the serial number of the ICC, if applicable.
      */
-    public String getIccSerialNumber(String callingPackage) {
-        return getIccSerialNumberForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getIccSerialNumberWithFeature(String callingPackage, String callingFeatureId) {
+        return getIccSerialNumberForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
-    public String getIccSerialNumberForSubscriber(int subId, String callingPackage) {
+    public String getIccSerialNumberForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage,
-                "getIccSerialNumber", (phone) -> phone.getIccSerialNumber());
+                callingFeatureId, "getIccSerialNumber", (phone) -> phone.getIccSerialNumber());
     }
 
-    public String getLine1Number(String callingPackage) {
-        return getLine1NumberForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getLine1Number(String callingPackage, String callingFeatureId) {
+        return getLine1NumberForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
-    public String getLine1NumberForSubscriber(int subId, String callingPackage) {
+    public String getLine1NumberForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         return callPhoneMethodForSubIdWithReadPhoneNumberCheck(
-                subId, callingPackage, "getLine1Number",
+                subId, callingPackage, callingFeatureId, "getLine1Number",
                 (phone)-> phone.getLine1Number());
     }
 
-    public String getLine1AlphaTag(String callingPackage) {
-        return getLine1AlphaTagForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getLine1AlphaTag(String callingPackage, String callingFeatureId) {
+        return getLine1AlphaTagForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
-    public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getLine1AlphaTag",
-                (phone)-> phone.getLine1AlphaTag());
+    public String getLine1AlphaTagForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
+                "getLine1AlphaTag", (phone)-> phone.getLine1AlphaTag());
     }
 
-    public String getMsisdn(String callingPackage) {
-        return getMsisdnForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getMsisdn(String callingPackage, String callingFeatureId) {
+        return getMsisdnForSubscriber(getDefaultSubscription(), callingPackage, callingFeatureId);
     }
 
-    public String getMsisdnForSubscriber(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getMsisdn",
-                (phone)-> phone.getMsisdn());
+    public String getMsisdnForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
+                "getMsisdn", (phone)-> phone.getMsisdn());
     }
 
-    public String getVoiceMailNumber(String callingPackage) {
-        return getVoiceMailNumberForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getVoiceMailNumber(String callingPackage, String callingFeatureId) {
+        return getVoiceMailNumberForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
-    public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+    public String getVoiceMailNumberForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
                 "getVoiceMailNumber", (phone)-> {
                     String number = PhoneNumberUtils.extractNetworkPortion(
                             phone.getVoiceMailNumber());
@@ -200,12 +232,14 @@
                 });
     }
 
-    public String getVoiceMailAlphaTag(String callingPackage) {
-        return getVoiceMailAlphaTagForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getVoiceMailAlphaTag(String callingPackage, String callingFeatureId) {
+        return getVoiceMailAlphaTagForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
-    public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+    public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
                 "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag());
     }
 
@@ -353,16 +387,17 @@
             return uiccApp.getIccRecords().getIccSimChallengeResponse(authType, data);
         };
 
-        return callPhoneMethodWithPermissionCheck(
-                subId, null, "getIccSimChallengeResponse", toExecute,
-                (aContext, aSubId, aCallingPackage, aMessage)-> {
+        return callPhoneMethodWithPermissionCheck(subId, null, null, "getIccSimChallengeResponse",
+                toExecute,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage) -> {
                     enforcePrivilegedPermissionOrCarrierPrivilege(aSubId, aMessage);
                     return true;
                 });
     }
 
-    public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+    public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
                 "getGroupIdLevel1", (phone)-> phone.getGroupIdLevel1());
     }
 
@@ -381,14 +416,17 @@
         // 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);
+        boolean checkPermission(Context context, int subId, String callingPackage,
+                @Nullable String callingFeatureId, String message);
     }
 
     // Base utility method that others use.
     private <T> T callPhoneMethodWithPermissionCheck(int subId, String callingPackage,
-            String message, CallPhoneMethodHelper<T> callMethodHelper,
+            @Nullable String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper,
             PermissionCheckHelper permissionCheckHelper) {
-        if (!permissionCheckHelper.checkPermission(mContext, subId, callingPackage, message)) {
+        if (!permissionCheckHelper.checkPermission(mContext, subId, callingPackage,
+                callingFeatureId, message)) {
             return null;
         }
 
@@ -407,33 +445,39 @@
     }
 
     private <T> T callPhoneMethodForSubIdWithReadCheck(int subId, String callingPackage,
-            String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)->
+            @Nullable String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId,
+                message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)->
                         TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                                aContext, aSubId, aCallingPackage, aMessage));
+                                aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage));
     }
 
     private <T> T callPhoneMethodForSubIdWithReadDeviceIdentifiersCheck(int subId,
-            String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)->
+            String callingPackage, @Nullable String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId,
+                message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)->
                         TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(
-                                aContext, aSubId, aCallingPackage, aMessage));
+                                aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage));
     }
 
     private <T> T callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(int subId,
-            String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)->
+            String callingPackage, @Nullable String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId,
+                message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)->
                         TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(
-                                aContext, aSubId, aCallingPackage, aMessage));
+                                aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage));
     }
 
     private <T> T callPhoneMethodForSubIdWithPrivilegedCheck(
             int subId, String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)-> {
+        return callPhoneMethodWithPermissionCheck(subId, null, null, message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage) -> {
                     mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message);
                     return true;
                 });
@@ -441,23 +485,26 @@
 
     private <T> T callPhoneMethodForSubIdWithModifyCheck(int subId, String callingPackage,
             String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)-> {
+        return callPhoneMethodWithPermissionCheck(subId, null, null, message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, 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)->
+            @NonNull String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId,
+                message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage) ->
                         TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
-                                aContext, aSubId, aCallingPackage, aMessage));
+                                aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage));
     }
 
     private <T> T callPhoneMethodForPhoneIdWithReadDeviceIdentifiersCheck(int phoneId,
-            String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) {
+            String callingPackage, @Nullable String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper) {
         // Getting subId before doing permission check.
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
             phoneId = 0;
@@ -467,7 +514,7 @@
             return null;
         }
         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mContext,
-                phone.getSubId(), callingPackage, message)) {
+                phone.getSubId(), callingPackage, callingFeatureId, message)) {
             return null;
         }
 
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 4b32c72..a261b42 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -1239,15 +1239,15 @@
             }
 
             if (error == RESULT_ERROR_NONE) {
-                PackageManager pm = mContext.getPackageManager();
+                UserHandle userHandle = UserHandle.of(trackers[0].mUserId);
+                PackageManager pm = mContext.createContextAsUser(userHandle, 0).getPackageManager();
 
                 try {
                     // Get package info via packagemanager
                     appInfo =
-                            pm.getPackageInfoAsUser(
+                            pm.getPackageInfo(
                                     trackers[0].getAppPackageName(),
-                                    PackageManager.GET_SIGNATURES,
-                                    trackers[0].mUserId);
+                                    PackageManager.GET_SIGNATURES);
                 } catch (PackageManager.NameNotFoundException e) {
                     Rlog.e(TAG, "Can't get calling app package info: refusing to send SMS");
                     error = RESULT_ERROR_GENERIC_FAILURE;
@@ -1840,15 +1840,14 @@
             AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
             SmsHeader smsHeader, boolean expectMore, String fullMessageText, boolean isText,
             boolean persistMessage, int priority, int validityPeriod, boolean isForVvm) {
-        // Get calling app package name via UID from Binder call
-        PackageManager pm = mContext.getPackageManager();
 
         // Get package info via packagemanager
-        final int userId = UserHandle.getUserHandleForUid(Binder.getCallingUid()).getIdentifier();
+        UserHandle callingUser = UserHandle.getUserHandleForUid(Binder.getCallingUid());
+        final int userId = callingUser.getIdentifier();
+        PackageManager pm = mContext.createContextAsUser(callingUser, 0).getPackageManager();
         PackageInfo appInfo = null;
         try {
-            appInfo = pm.getPackageInfoAsUser(
-                    callingPackage, PackageManager.GET_SIGNATURES, userId);
+            appInfo = pm.getPackageInfo(callingPackage, PackageManager.GET_SIGNATURES);
         } catch (PackageManager.NameNotFoundException e) {
             // error will be logged in sendRawPdu
         }
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 8dd7e44..047ea52 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -4116,7 +4116,8 @@
         Context context = mPhone.getContext();
 
         SubscriptionInfo info = mSubscriptionController
-                .getActiveSubscriptionInfo(mPhone.getSubId(), context.getOpPackageName());
+                .getActiveSubscriptionInfo(mPhone.getSubId(), context.getOpPackageName(),
+                        null);
 
         //if subscription is part of a group and non-primary, suppress all notifications
         if (info == null || (info.isOpportunistic() && info.getGroupUuid() != null)) {
@@ -4960,7 +4961,8 @@
         if (!isStale) return false;
 
         List<SubscriptionInfo> subInfoList = SubscriptionController.getInstance()
-                .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName());
+                .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName(),
+                        null);
         for (SubscriptionInfo info : subInfoList) {
             // If we have an active opportunistic subscription whose data is IN_SERVICE, we needs
             // to get signal strength to decide data switching threshold. In this case, we poll
diff --git a/src/java/com/android/internal/telephony/SmsController.java b/src/java/com/android/internal/telephony/SmsController.java
index b1f49a7..1c14271 100644
--- a/src/java/com/android/internal/telephony/SmsController.java
+++ b/src/java/com/android/internal/telephony/SmsController.java
@@ -638,10 +638,10 @@
     }
 
     @Override
-    public int checkSmsShortCodeDestination(
-            int subId, String callingPackage, String destAddress, String countryIso) {
+    public int checkSmsShortCodeDestination(int subId, String callingPackage,
+            String callingFeatureId, String destAddress, String countryIso) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(getPhone(subId).getContext(),
-                subId, callingPackage, "checkSmsShortCodeDestination")) {
+                subId, callingPackage, callingFeatureId, "checkSmsShortCodeDestination")) {
             return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
         }
         final long identity = Binder.clearCallingIdentity();
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index a866f9e..967a807 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -459,10 +459,12 @@
     /**
      * Find unused color to be set for new SubInfoRecord
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return RGB integer value of color
      */
-    private int getUnusedColor(String callingPackage) {
-        List<SubscriptionInfo> availableSubInfos = getActiveSubscriptionInfoList(callingPackage);
+    private int getUnusedColor(String callingPackage, String callingFeatureId) {
+        List<SubscriptionInfo> availableSubInfos = getActiveSubscriptionInfoList(callingPackage,
+                callingFeatureId);
         colorArr = mContext.getResources().getIntArray(com.android.internal.R.array.sim_colors);
         int colorIdx = 0;
 
@@ -483,17 +485,24 @@
         return colorArr[colorIdx];
     }
 
+    @Deprecated
+    @UnsupportedAppUsage
+    public SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage) {
+        return getActiveSubscriptionInfo(subId, callingPackage, null);
+    }
+
     /**
      * Get the active SubscriptionInfo with the subId key
      * @param subId The unique SubscriptionInfo key in database
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return SubscriptionInfo, maybe null if its not active
      */
-    @UnsupportedAppUsage
     @Override
-    public SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, subId, callingPackage, "getActiveSubscriptionInfo")) {
+    public SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage,
+            String callingFeatureId) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
+                callingFeatureId, "getActiveSubscriptionInfo")) {
             return null;
         }
 
@@ -501,7 +510,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             List<SubscriptionInfo> subList = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), null);
             if (subList != null) {
                 for (SubscriptionInfo si : subList) {
                     if (si.getSubscriptionId() == subId) {
@@ -545,19 +554,10 @@
      * @return SubscriptionInfo, maybe null if its not active
      */
     @Override
-    public SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage) {
-        // Query the subscriptions unconditionally, and then check whether the caller has access to
-        // the given subscription.
-        final SubscriptionInfo si = getActiveSubscriptionInfoForIccIdInternal(iccId);
-
-        final int subId = si != null
-                ? si.getSubscriptionId() : SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, subId, callingPackage, "getActiveSubscriptionInfoForIccId")) {
-            return null;
-        }
-
-        return si;
+    public SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage,
+            String callingFeatureId) {
+        enforceReadPrivilegedPhoneState("getActiveSubscriptionInfoForIccId");
+        return getActiveSubscriptionInfoForIccIdInternal(iccId);
     }
 
     /**
@@ -572,7 +572,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             List<SubscriptionInfo> subList = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), null);
             if (subList != null) {
                 for (SubscriptionInfo si : subList) {
                     if (iccId.equals(si.getIccId())) {
@@ -598,11 +598,12 @@
      * This API does not return details on Remote-SIM subscriptions.
      * @param slotIndex the slot which the subscription is inserted
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return SubscriptionInfo, null for Remote-SIMs or non-active slotIndex.
      */
     @Override
     public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex,
-            String callingPackage) {
+            String callingPackage, String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone == null) {
             if (DBG) {
@@ -611,7 +612,7 @@
             return null;
         }
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, phone.getSubId(), callingPackage,
+                mContext, phone.getSubId(), callingPackage, callingFeatureId,
                 "getActiveSubscriptionInfoForSimSlotIndex")) {
             return null;
         }
@@ -620,7 +621,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             List<SubscriptionInfo> subList = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), null);
             if (subList != null) {
                 for (SubscriptionInfo si : subList) {
                     if (si.getSimSlotIndex() == slotIndex) {
@@ -649,19 +650,21 @@
 
     /**
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return List of all SubscriptionInfo records in database,
      * include those that were inserted before, maybe empty but not null.
      * @hide
      */
     @Override
-    public List<SubscriptionInfo> getAllSubInfoList(String callingPackage) {
+    public List<SubscriptionInfo> getAllSubInfoList(String callingPackage,
+            String callingFeatureId) {
         if (VDBG) logd("[getAllSubInfoList]+");
 
         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
         // about carrier-privileged callers not having access.
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                 mContext, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                "getAllSubInfoList")) {
+                callingFeatureId, "getAllSubInfoList")) {
             return null;
         }
 
@@ -681,16 +684,25 @@
         }
     }
 
+    @Deprecated
+    @UnsupportedAppUsage
+    public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage) {
+        return getSubscriptionInfoListFromCacheHelper(callingPackage, null,
+                mCacheActiveSubInfoList);
+    }
+
     /**
      * Get the SubInfoRecord(s) of the currently active SIM(s) - which include both local
      * and remote SIMs.
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return Array list of currently inserted SubInfoRecord(s)
      */
-    @UnsupportedAppUsage
     @Override
-    public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage) {
-        return getSubscriptionInfoListFromCacheHelper(callingPackage, mCacheActiveSubInfoList);
+    public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage,
+            String callingFeatureId) {
+        return getSubscriptionInfoListFromCacheHelper(callingPackage, callingFeatureId,
+                mCacheActiveSubInfoList);
     }
 
     /**
@@ -739,16 +751,23 @@
         }
     }
 
+    @Deprecated
+    @UnsupportedAppUsage
+    public int getActiveSubInfoCount(String callingPackage) {
+        return getActiveSubInfoCount(callingPackage, null);
+    }
+
     /**
      * Get the SUB count of active SUB(s)
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package.
      * @return active SIM count
      */
-    @UnsupportedAppUsage
     @Override
-    public int getActiveSubInfoCount(String callingPackage) {
+    public int getActiveSubInfoCount(String callingPackage, String callingFeatureId) {
         // Let getActiveSubscriptionInfoList perform permission checks / filtering.
-        List<SubscriptionInfo> records = getActiveSubscriptionInfoList(callingPackage);
+        List<SubscriptionInfo> records = getActiveSubscriptionInfoList(callingPackage,
+                callingFeatureId);
         if (records == null) {
             if (VDBG) logd("[getActiveSubInfoCount] records null");
             return 0;
@@ -760,17 +779,18 @@
     /**
      * Get the SUB count of all SUB(s) in SubscriptoinInfo database
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return all SIM count in database, include what was inserted before
      */
     @Override
-    public int getAllSubInfoCount(String callingPackage) {
+    public int getAllSubInfoCount(String callingPackage, String callingFeatureId) {
         if (DBG) logd("[getAllSubInfoCount]+");
 
         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
         // about carrier-privileged callers not having access.
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                 mContext, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                "getAllSubInfoCount")) {
+                callingFeatureId, "getAllSubInfoCount")) {
             return 0;
         }
 
@@ -808,12 +828,13 @@
     }
 
     @Override
-    public List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage) {
+    public List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage,
+            String callingFeatureId) {
         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
         // about carrier-privileged callers not having access.
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                 mContext, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                "getAvailableSubscriptionInfoList")) {
+                callingFeatureId, "getAvailableSubscriptionInfoList")) {
             throw new SecurityException("Need READ_PHONE_STATE to call "
                     + " getAvailableSubscriptionInfoList");
         }
@@ -1325,7 +1346,7 @@
             int newDefault = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
             SubscriptionInfo info = null;
             final List<SubscriptionInfo> records = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), null);
             if (!records.isEmpty()) {
                 // yes, we have more subscriptions. pick the first one.
                 // FIXME do we need a policy to figure out which one is to be next default
@@ -1379,7 +1400,7 @@
         ContentResolver resolver = mContext.getContentResolver();
         ContentValues value = new ContentValues();
         value.put(SubscriptionManager.ICC_ID, uniqueId);
-        int color = getUnusedColor(mContext.getOpPackageName());
+        int color = getUnusedColor(mContext.getOpPackageName(), null);
         // default SIM color differs between slots
         value.put(SubscriptionManager.COLOR, color);
         value.put(SubscriptionManager.SIM_SLOT_INDEX, slotIndex);
@@ -1779,7 +1800,7 @@
     // TODO: replace all updates with this helper method.
     private int updateDatabase(ContentValues value, int subId, boolean updateEntireGroup) {
         List<SubscriptionInfo> infoList = getSubscriptionsInGroup(getGroupUuid(subId),
-                mContext.getOpPackageName());
+                mContext.getOpPackageName(), null);
         if (!updateEntireGroup || infoList == null || infoList.size() == 0) {
             // Only update specified subscriptions.
             return mContext.getContentResolver().update(
@@ -2413,7 +2434,8 @@
      * Whether a subscription is opportunistic or not.
      */
     public boolean isOpportunistic(int subId) {
-        SubscriptionInfo info = getActiveSubscriptionInfo(subId, mContext.getOpPackageName());
+        SubscriptionInfo info = getActiveSubscriptionInfo(subId, mContext.getOpPackageName(),
+                null);
         return (info != null) && info.isOpportunistic();
     }
 
@@ -2532,9 +2554,9 @@
     }
 
     @Override
-    public boolean isActiveSubId(int subId, String callingPackage) {
+    public boolean isActiveSubId(int subId, String callingPackage, String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
-              "isActiveSubId")) {
+                callingFeatureId, "isActiveSubId")) {
             throw new SecurityException("Requires READ_PHONE_STATE permission.");
         }
         final long identity = Binder.clearCallingIdentity();
@@ -2665,9 +2687,10 @@
      * @return Value associated with subId and propKey column in database
      */
     @Override
-    public String getSubscriptionProperty(int subId, String propKey, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, subId, callingPackage, "getSubscriptionProperty")) {
+    public String getSubscriptionProperty(int subId, String propKey, String callingPackage,
+            String callingFeatureId) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
+                callingFeatureId, "getSubscriptionProperty")) {
             return null;
         }
 
@@ -2779,7 +2802,7 @@
             pw.println("++++++++++++++++++++++++++++++++");
 
             List<SubscriptionInfo> sirl = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), null);
             if (sirl != null) {
                 pw.println(" ActiveSubInfoList:");
                 for (SubscriptionInfo entry : sirl) {
@@ -2791,7 +2814,7 @@
             pw.flush();
             pw.println("++++++++++++++++++++++++++++++++");
 
-            sirl = getAllSubInfoList(mContext.getOpPackageName());
+            sirl = getAllSubInfoList(mContext.getOpPackageName(), null);
             if (sirl != null) {
                 pw.println(" AllSubInfoList:");
                 for (SubscriptionInfo entry : sirl) {
@@ -2947,9 +2970,10 @@
     }
 
     @Override
-    public List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage) {
+    public List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage,
+            String callingFeatureId) {
         return getSubscriptionInfoListFromCacheHelper(
-                callingPackage, mCacheOpportunisticSubInfoList);
+                callingPackage, callingFeatureId, mCacheOpportunisticSubInfoList);
     }
 
     /**
@@ -3292,12 +3316,12 @@
      */
     @Override
     public List<SubscriptionInfo> getSubscriptionsInGroup(ParcelUuid groupUuid,
-            String callingPackage) {
+            String callingPackage, String callingFeatureId) {
         long identity = Binder.clearCallingIdentity();
         List<SubscriptionInfo> subInfoList;
 
         try {
-            subInfoList = getAllSubInfoList(mContext.getOpPackageName());
+            subInfoList = getAllSubInfoList(mContext.getOpPackageName(), null);
             if (groupUuid == null || subInfoList == null || subInfoList.isEmpty()) {
                 return new ArrayList<>();
             }
@@ -3309,7 +3333,7 @@
             if (!groupUuid.equals(info.getGroupUuid())) return false;
             int subId = info.getSubscriptionId();
             return TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId,
-                    callingPackage, "getSubscriptionsInGroup")
+                    callingPackage, callingFeatureId, "getSubscriptionsInGroup")
                     || info.canManageSubscription(mContext, callingPackage);
         }).collect(Collectors.toList());
     }
@@ -3355,7 +3379,7 @@
             if (enable == isActiveSubscriptionId(subId)) return true;
 
             SubscriptionInfo info = SubscriptionController.getInstance()
-                    .getAllSubInfoList(mContext.getOpPackageName())
+                    .getAllSubInfoList(mContext.getOpPackageName(), null)
                     .stream()
                     .filter(subInfo -> subInfo.getSubscriptionId() == subId)
                     .findFirst()
@@ -3577,12 +3601,13 @@
     // Helper function of getOpportunisticSubscriptions and getActiveSubscriptionInfoList.
     // They are doing similar things except operating on different cache.
     private List<SubscriptionInfo> getSubscriptionInfoListFromCacheHelper(
-            String callingPackage, List<SubscriptionInfo> cacheSubList) {
+            String callingPackage, String callingFeatureId, List<SubscriptionInfo> cacheSubList) {
         boolean canReadAllPhoneState;
         try {
             canReadAllPhoneState = TelephonyPermissions.checkReadPhoneState(mContext,
                     SubscriptionManager.INVALID_SUBSCRIPTION_ID, Binder.getCallingPid(),
-                    Binder.getCallingUid(), callingPackage, "getSubscriptionInfoList");
+                    Binder.getCallingUid(), callingPackage, callingFeatureId,
+                    "getSubscriptionInfoList");
         } catch (SecurityException e) {
             canReadAllPhoneState = false;
         }
@@ -3599,7 +3624,7 @@
                         try {
                             return TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext,
                                     subscriptionInfo.getSubscriptionId(), callingPackage,
-                                    "getSubscriptionInfoList");
+                                    callingFeatureId, "getSubscriptionInfoList");
                         } catch (SecurityException e) {
                             return false;
                         }
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index 793f846..3416a23 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -425,11 +425,15 @@
 
     private void handleSimNotReady(int phoneId) {
         logd("handleSimNotReady: phoneId: " + phoneId);
+        boolean isFinalState = false;
 
         IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
-        if (iccCard.isEmptyProfile()) {
-            // ICC_NOT_READY is a terminal state for an eSIM on the boot profile. At this
-            // phase, the subscription list is accessible. Treating NOT_READY
+        if (iccCard.isEmptyProfile() || areUiccAppsDisabledOnCard(phoneId)) {
+            isFinalState = true;
+            // ICC_NOT_READY is a terminal state for
+            // 1) It's an empty profile as there's no uicc applications. Or
+            // 2) Its uicc applications are set to be disabled.
+            // At this phase, the subscription list is accessible. Treating NOT_READY
             // as equivalent to ABSENT, once the rest of the system can handle it.
             sIccId[phoneId] = ICCID_STRING_FOR_NO_SIM;
             updateSubscriptionInfoByIccId(phoneId, false /* updateEmbeddedSubs */);
@@ -439,6 +443,20 @@
                 null);
         broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_PRESENT);
         broadcastSimApplicationStateChanged(phoneId, TelephonyManager.SIM_STATE_NOT_READY);
+        if (isFinalState) {
+            updateCarrierServices(phoneId, IccCardConstants.INTENT_VALUE_ICC_NOT_READY);
+        }
+    }
+
+    private boolean areUiccAppsDisabledOnCard(int phoneId) {
+        // When uicc apps are disabled(supported in IRadio 1.5), we will still get IccId from
+        // cardStatus (since IRadio 1.2). Amd upon cardStatus change we'll receive another
+        // handleSimNotReady so this will be evaluated again.
+        UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(phoneId);
+        if (slot == null || slot.getIccId() == null) return false;
+        SubscriptionInfo info = SubscriptionController.getInstance()
+                .getSubInfoForIccId(slot.getIccId());
+        return info != null && !info.areUiccApplicationsEnabled();
     }
 
     private void handleSimLoaded(int phoneId) {
diff --git a/src/java/com/android/internal/telephony/WapPushOverSms.java b/src/java/com/android/internal/telephony/WapPushOverSms.java
index 069178d..a33b6ef 100755
--- a/src/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/src/java/com/android/internal/telephony/WapPushOverSms.java
@@ -20,6 +20,8 @@
 import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND;
 import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_READ_ORIG_IND;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.AppOpsManager;
@@ -31,6 +33,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteException;
@@ -61,6 +65,7 @@
 import com.google.android.mms.pdu.ReadOrigInd;
 
 import java.util.HashMap;
+import java.util.List;
 
 /**
  * WAP push handler class.
@@ -110,7 +115,7 @@
 
     private void bindWapPushManagerService(Context context) {
         Intent intent = new Intent(IWapPushManager.class.getName());
-        ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0);
+        ComponentName comp = resolveSystemService(context.getPackageManager(), intent);
         intent.setComponent(comp);
         if (comp == null || !context.bindService(intent, this, Context.BIND_AUTO_CREATE)) {
             Rlog.e(TAG, "bindService() for wappush manager failed");
@@ -122,6 +127,33 @@
         }
     }
 
+    /**
+     * Special function for use by the system to resolve service
+     * intents to system apps.  Throws an exception if there are
+     * multiple potential matches to the Intent.  Returns null if
+     * there are no matches.
+     */
+    private static @Nullable ComponentName resolveSystemService(@NonNull PackageManager pm,
+            @NonNull Intent intent) {
+        List<ResolveInfo> results = pm.queryIntentServices(
+                intent, PackageManager.MATCH_SYSTEM_ONLY);
+        if (results == null) {
+            return null;
+        }
+        ComponentName comp = null;
+        for (int i = 0; i < results.size(); i++) {
+            ResolveInfo ri = results.get(i);
+            ComponentName foundComp = new ComponentName(ri.serviceInfo.applicationInfo.packageName,
+                    ri.serviceInfo.name);
+            if (comp != null) {
+                throw new IllegalStateException("Multiple system services handle " + intent
+                    + ": " + comp + ", " + foundComp);
+            }
+            comp = foundComp;
+        }
+        return comp;
+    }
+
     @Override
     public void onServiceConnected(ComponentName name, IBinder service) {
         mWapPushManager = IWapPushManager.Stub.asInterface(service);
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
index ee3bfcc..16ec3d6 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
@@ -448,7 +448,7 @@
 
     private static boolean isStandAloneOpportunistic(int subId, Context context) {
         SubscriptionInfo info = SubscriptionController.getInstance().getActiveSubscriptionInfo(
-                subId, context.getOpPackageName());
+                subId, context.getOpPackageName(), null);
         return (info != null) && info.isOpportunistic() && info.getGroupUuid() == null;
     }
 
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
index 87152f2..0a3a84c 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
@@ -194,7 +194,10 @@
             if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
                 // only log metrics for DataConnection with NET_CAPABILITY_INTERNET
                 if (mNetworkCapabilities == null
-                        || networkCapabilities.isMetered() != mNetworkCapabilities.isMetered()) {
+                        || networkCapabilities.hasCapability(
+                                NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+                                        != mNetworkCapabilities.hasCapability(
+                                                NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
                     TelephonyMetrics.getInstance().writeNetworkCapabilitiesChangedEvent(
                             mPhone.getPhoneId(), networkCapabilities);
                 }
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 36cf9e5..517bd08 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -2067,7 +2067,7 @@
             // Search for Initial APN setting and the first apn that can handle default
             for (ApnSetting apn : mAllApnSettings) {
                 if (firstNonEmergencyApnSetting == null
-                        && !apn.canHandleType(ApnSetting.TYPE_EMERGENCY)) {
+                        && !apn.isEmergencyApn()) {
                     firstNonEmergencyApnSetting = apn;
                     log("setInitialApn: firstNonEmergencyApnSetting="
                             + firstNonEmergencyApnSetting);
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index 376977e..6354ab1 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -444,7 +444,7 @@
             int nameSource) {
         /* update display name with carrier override */
         SubscriptionInfo subInfo = subCon.getActiveSubscriptionInfo(
-                subId, mContext.getOpPackageName());
+                subId, mContext.getOpPackageName(), null);
 
         if (subInfo == null) {
             return;
@@ -590,6 +590,12 @@
                 }
                 setExternalState(IccCardConstants.State.NOT_READY);
                 break;
+            case APPSTATE_DETECTED:
+                if (VDBG) {
+                    log("updateExternalState: app state is detected; setting state to NOT_READY");
+                }
+                setExternalState(IccCardConstants.State.NOT_READY);
+                break;
             case APPSTATE_READY:
                 checkAndUpdateIfAnyAppToBeIgnored();
                 if (areAllApplicationsReady()) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index 40cec03..1e7ef4d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doAnswer;
@@ -315,18 +316,16 @@
 
         @Override
         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
-            return registerReceiver(receiver, filter, null, null);
+            return registerReceiverFakeImpl(receiver, filter);
         }
 
         @Override
         public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
                 String broadcastPermission, Handler scheduler) {
-            return registerReceiverAsUser(receiver, null, filter, broadcastPermission, scheduler);
+            return registerReceiverFakeImpl(receiver, filter);
         }
 
-        @Override
-        public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
-                IntentFilter filter, String broadcastPermission, Handler scheduler) {
+        private Intent registerReceiverFakeImpl(BroadcastReceiver receiver, IntentFilter filter) {
             Intent result = null;
             synchronized (mBroadcastReceiversByAction) {
                 for (int i = 0 ; i < filter.countActions() ; i++) {
@@ -410,6 +409,11 @@
         }
 
         @Override
+        public Context createContextAsUser(UserHandle user, int flags) {
+            return this;
+        }
+
+        @Override
         public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
                 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
                 int initialCode, String initialData, Bundle initialExtras) {
@@ -619,7 +623,7 @@
         }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), any());
 
         try {
-            doReturn(mPackageInfo).when(mPackageManager).getPackageInfoAsUser(any(), anyInt(),
+            doReturn(mPackageInfo).when(mPackageManager).getPackageInfo(nullable(String.class),
                     anyInt());
         } catch (NameNotFoundException e) {
         }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
index 194b377..d6db30e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
@@ -121,7 +122,7 @@
         doReturn(2).when(mPhoneMock2).getSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo2);
         doReturn(infoList).when(mSubControllerMock)
-                .getActiveSubscriptionInfoList(anyString());
+                .getActiveSubscriptionInfoList(anyString(), nullable(String.class));
         doReturn(new int[]{1, 2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mPhones = new Phone[] {mPhoneMock1, mPhoneMock2};
@@ -163,7 +164,8 @@
         doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
         doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         // Mark subscription ready as false. The below sub info change should be ignored.
@@ -200,7 +202,8 @@
         doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
         doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
@@ -215,7 +218,8 @@
         doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(1);
         doReturn(2).when(mPhoneMock1).getSubId();
         infoList = Arrays.asList(mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
@@ -238,7 +242,8 @@
         doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
         doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
@@ -258,7 +263,8 @@
         doReturn(1).when(mSubControllerMock).getPhoneId(2);
         doReturn(2).when(mPhoneMock2).getSubId();
         infoList = Arrays.asList(mSubInfo1, mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1, 2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
@@ -280,7 +286,8 @@
         doReturn(1).when(mSubControllerMock).getPhoneId(3);
         doReturn(3).when(mPhoneMock2).getSubId();
         infoList = Arrays.asList(mSubInfo1, mSubInfo3);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1, 3}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
@@ -325,7 +332,8 @@
         clearInvocations(mSubControllerMock);
         doReturn(false).when(mSubControllerMock).isActiveSubId(1);
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
         mMultiSimSettingControllerUT.notifyCarrierConfigChanged(
@@ -361,7 +369,7 @@
         doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(3);
         doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(4);
         doReturn(Arrays.asList(mSubInfo2, mSubInfo3, mSubInfo4)).when(mSubControllerMock)
-                .getSubscriptionsInGroup(any(), anyString());
+                .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
         // This should result in setting sync.
@@ -398,7 +406,8 @@
         doReturn(2).when(mSubControllerMock).getDefaultSmsSubId();
         doReturn(1).when(mSubControllerMock).getDefaultVoiceSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo3);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1, 3}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
@@ -475,7 +484,7 @@
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 2, false);
         // Group sub 1 with sub 2.
         doReturn(Arrays.asList(mSubInfo1, mSubInfo2)).when(mSubControllerMock)
-                .getSubscriptionsInGroup(any(), anyString());
+                .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
         // This should result in setting sync.
@@ -515,7 +524,7 @@
         // Create subscription grouping.
         replaceInstance(SubscriptionInfo.class, "mGroupUUID", mSubInfo1, mGroupUuid1);
         doReturn(Arrays.asList(mSubInfo1, mSubInfo2)).when(mSubControllerMock)
-                .getSubscriptionsInGroup(any(), anyString());
+                .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
         // This should result in setting sync.
@@ -556,7 +565,8 @@
         doReturn(1).when(mSubControllerMock).getPhoneId(3);
         doReturn(3).when(mPhoneMock2).getSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo3);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1, 3}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         // Nothing should happen until carrier config change is notified on sub 3.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
index 66d676c..a642818 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.anyString;
@@ -39,6 +40,8 @@
 import org.mockito.Mock;
 
 public class PhoneSubInfoControllerTest extends TelephonyTest {
+    private static final String FEATURE_ID = null;
+
     private PhoneSubInfoController mPhoneSubInfoControllerUT;
     private AppOpsManager mAppOsMgr;
 
@@ -54,8 +57,8 @@
         doReturn(1).when(mSubscriptionController).getPhoneId(eq(1));
         doReturn(2).when(mTelephonyManager).getPhoneCount();
         doReturn(2).when(mTelephonyManager).getActiveModemCount();
-        doReturn(true).when(mSubscriptionController).isActiveSubId(0, TAG);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(1, TAG);
+        doReturn(true).when(mSubscriptionController).isActiveSubId(0, TAG, FEATURE_ID);
+        doReturn(true).when(mSubscriptionController).isActiveSubId(1, TAG, FEATURE_ID);
         doReturn(new int[]{0, 1}).when(mSubscriptionManager)
                 .getActiveSubscriptionIdList(anyBoolean());
 
@@ -89,8 +92,10 @@
         doReturn("353626073736741").when(mPhone).getDeviceId();
         doReturn("353626073736742").when(mSecondPhone).getDeviceId();
 
-        assertEquals("353626073736741", mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG));
-        assertEquals("353626073736742", mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG));
+        assertEquals("353626073736741",
+                mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG, FEATURE_ID));
+        assertEquals("353626073736742",
+                mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -105,7 +110,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -113,7 +118,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -125,7 +130,7 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -133,7 +138,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -146,7 +151,7 @@
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -154,7 +159,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -166,10 +171,12 @@
     @SmallTest
     public void testGetNai() {
         doReturn("aaa@example.com").when(mPhone).getNai();
-        assertEquals("aaa@example.com", mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG));
+        assertEquals("aaa@example.com",
+                mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("bbb@example.com").when(mSecondPhone).getNai();
-        assertEquals("bbb@example.com", mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG));
+        assertEquals("bbb@example.com",
+                mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -184,7 +191,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -192,7 +199,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -204,7 +211,7 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -212,7 +219,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -224,7 +231,7 @@
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -232,7 +239,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -244,10 +251,12 @@
     @SmallTest
     public void testGetImei() {
         doReturn("990000862471854").when(mPhone).getImei();
-        assertEquals("990000862471854", mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG));
+        assertEquals("990000862471854",
+                mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("990000862471855").when(mSecondPhone).getImei();
-        assertEquals("990000862471855", mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG));
+        assertEquals("990000862471855",
+                mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -262,7 +271,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -270,7 +279,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -282,7 +291,7 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -290,7 +299,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -302,7 +311,7 @@
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -310,7 +319,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -322,10 +331,10 @@
     @SmallTest
     public void testGetDeviceSvn() {
         doReturn("00").when(mPhone).getDeviceSvn();
-        assertEquals("00", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG));
+        assertEquals("00", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG, FEATURE_ID));
 
         doReturn("01").when(mSecondPhone).getDeviceSvn();
-        assertEquals("01", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG));
+        assertEquals("01", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -337,7 +346,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG);
+            mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -345,7 +354,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG);
+            mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -357,15 +366,15 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
 
-        assertNull(mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG, FEATURE_ID));
 
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
-        assertEquals("00", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG));
-        assertEquals("01", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG));
+        assertEquals("00", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG, FEATURE_ID));
+        assertEquals("01", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -374,18 +383,18 @@
         //IMSI
         doReturn("310260426283121").when(mPhone).getSubscriberId();
         assertEquals("310260426283121", mPhoneSubInfoControllerUT
-                .getSubscriberIdForSubscriber(0, TAG));
+                .getSubscriberIdForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("310260426283122").when(mSecondPhone).getSubscriberId();
         assertEquals("310260426283122", mPhoneSubInfoControllerUT
-                .getSubscriberIdForSubscriber(1, TAG));
+                .getSubscriberIdForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
     @SmallTest
     public void testGetSubscriberIdWithInactiveSubId() {
         //IMSI
-        assertNull(mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(2, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(2, TAG, FEATURE_ID));
     }
 
     @Test
@@ -400,7 +409,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -408,7 +417,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -420,7 +429,7 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -428,7 +437,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -441,7 +450,7 @@
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -449,7 +458,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -463,11 +472,11 @@
         //IccId
         doReturn("8991101200003204510").when(mPhone).getIccSerialNumber();
         assertEquals("8991101200003204510", mPhoneSubInfoControllerUT
-                .getIccSerialNumberForSubscriber(0, TAG));
+                .getIccSerialNumberForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("8991101200003204511").when(mSecondPhone).getIccSerialNumber();
         assertEquals("8991101200003204511", mPhoneSubInfoControllerUT
-                .getIccSerialNumberForSubscriber(1, TAG));
+                .getIccSerialNumberForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -482,7 +491,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -490,7 +499,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -502,7 +511,7 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -510,7 +519,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -522,7 +531,7 @@
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -530,7 +539,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -542,10 +551,12 @@
     @SmallTest
     public void testLine1Number() {
         doReturn("+18051234567").when(mPhone).getLine1Number();
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("+18052345678").when(mSecondPhone).getLine1Number();
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -564,14 +575,14 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         try {
-            mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
         }
 
         try {
-            mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -580,41 +591,49 @@
         /* case 2: only enable WRITE_SMS permission */
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_WRITE_SMS), anyInt(), eq(TAG));
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
 
         /* case 3: only enable READ_PRIVILEGED_PHONE_STATE */
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_WRITE_SMS), anyInt(), eq(TAG));
         mContextFixture.addCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE);
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
 
         /* case 4: only enable READ_PHONE_STATE permission */
         mContextFixture.removeCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE);
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
-        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
 
         /* case 5: enable appOsMgr READ_PHONE_PERMISSION & READ_PHONE_STATE */
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
 
         /* case 6: only enable READ_SMS */
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         mContextFixture.removeCallingOrSelfPermission(READ_PHONE_STATE);
         mContextFixture.addCallingOrSelfPermission(READ_SMS);
-        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
 
         /* case 7: enable READ_SMS and OP_READ_SMS */
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_SMS), anyInt(), eq(TAG));
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -622,11 +641,11 @@
     public void testLine1AlphaTag() {
         doReturn("LINE1_SIM_0").when(mPhone).getLine1AlphaTag();
         assertEquals("LINE1_SIM_0", mPhoneSubInfoControllerUT
-                .getLine1AlphaTagForSubscriber(0, TAG));
+                .getLine1AlphaTagForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("LINE1_SIM_1").when(mSecondPhone).getLine1AlphaTag();
         assertEquals("LINE1_SIM_1", mPhoneSubInfoControllerUT
-                .getLine1AlphaTagForSubscriber(1, TAG));
+                .getLine1AlphaTagForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -638,7 +657,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -646,7 +665,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -658,27 +677,29 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
 
-        assertNull(mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(1, TAG, FEATURE_ID));
 
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         assertEquals("LINE1_SIM_0", mPhoneSubInfoControllerUT
-                .getLine1AlphaTagForSubscriber(0, TAG));
+                .getLine1AlphaTagForSubscriber(0, TAG, FEATURE_ID));
         assertEquals("LINE1_SIM_1", mPhoneSubInfoControllerUT
-                .getLine1AlphaTagForSubscriber(1, TAG));
+                .getLine1AlphaTagForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
     @SmallTest
     public void testMsisdn() {
         doReturn("+18051234567").when(mPhone).getMsisdn();
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("+18052345678").when(mSecondPhone).getMsisdn();
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -690,7 +711,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -698,7 +719,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -710,15 +731,17 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
 
-        assertNull(mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG, FEATURE_ID));
 
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG));
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG, FEATURE_ID));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -726,11 +749,11 @@
     public void testGetVoiceMailNumber() {
         doReturn("+18051234567").when(mPhone).getVoiceMailNumber();
         assertEquals("+18051234567", mPhoneSubInfoControllerUT
-                .getVoiceMailNumberForSubscriber(0, TAG));
+                .getVoiceMailNumberForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("+18052345678").when(mSecondPhone).getVoiceMailNumber();
         assertEquals("+18052345678", mPhoneSubInfoControllerUT
-                .getVoiceMailNumberForSubscriber(1, TAG));
+                .getVoiceMailNumberForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -742,7 +765,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -750,7 +773,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -762,17 +785,17 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
 
-        assertNull(mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(1, TAG, FEATURE_ID));
 
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         assertEquals("+18051234567", mPhoneSubInfoControllerUT
-                .getVoiceMailNumberForSubscriber(0, TAG));
+                .getVoiceMailNumberForSubscriber(0, TAG, FEATURE_ID));
         assertEquals("+18052345678", mPhoneSubInfoControllerUT
-                .getVoiceMailNumberForSubscriber(1, TAG));
+                .getVoiceMailNumberForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -780,11 +803,11 @@
     public void testGetVoiceMailAlphaTag() {
         doReturn("VM_SIM_0").when(mPhone).getVoiceMailAlphaTag();
         assertEquals("VM_SIM_0", mPhoneSubInfoControllerUT
-                .getVoiceMailAlphaTagForSubscriber(0, TAG));
+                .getVoiceMailAlphaTagForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("VM_SIM_1").when(mSecondPhone).getVoiceMailAlphaTag();
         assertEquals("VM_SIM_1", mPhoneSubInfoControllerUT
-                .getVoiceMailAlphaTagForSubscriber(1, TAG));
+                .getVoiceMailAlphaTagForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -796,7 +819,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -804,7 +827,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -816,16 +839,16 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
 
-        assertNull(mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(1, TAG, FEATURE_ID));
 
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
                 eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
         assertEquals("VM_SIM_0", mPhoneSubInfoControllerUT
-                .getVoiceMailAlphaTagForSubscriber(0, TAG));
+                .getVoiceMailAlphaTagForSubscriber(0, TAG, FEATURE_ID));
         assertEquals("VM_SIM_1", mPhoneSubInfoControllerUT
-                .getVoiceMailAlphaTagForSubscriber(1, TAG));
+                .getVoiceMailAlphaTagForSubscriber(1, TAG, FEATURE_ID));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 36850a7..d75a727 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -1509,7 +1509,7 @@
         doReturn(subId).when(mSubInfo).getSubscriptionId();
 
         doReturn(mSubInfo).when(mSubscriptionController).getActiveSubscriptionInfo(
-                anyInt(), anyString());
+                anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1541,7 +1541,7 @@
         sst.mSubId = subId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
         doReturn(mSubInfo).when(mSubscriptionController)
-                .getActiveSubscriptionInfo(anyInt(), anyString());
+                .getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1574,7 +1574,7 @@
         sst.mSubId = subId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
         doReturn(mSubInfo).when(mSubscriptionController)
-                .getActiveSubscriptionInfo(anyInt(), anyString());
+                .getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1606,7 +1606,7 @@
         sst.mSubId = subId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
         doReturn(mSubInfo).when(mSubscriptionController)
-                .getActiveSubscriptionInfo(anyInt(), anyString());
+                .getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index 899ffc8..0529b24 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -66,6 +66,7 @@
     private static final int SINGLE_SIM = 1;
     private static final int DUAL_SIM = 2;
     private String mCallingPackage;
+    private String mCallingFeature;
     private SubscriptionController mSubscriptionControllerUT;
     private MockContentResolver mMockContentResolver;
     private FakeTelephonyProvider mFakeTelephonyProvider;
@@ -95,6 +96,7 @@
 
         mSubscriptionControllerUT = SubscriptionController.init(mContext);
         mCallingPackage = mContext.getOpPackageName();
+        mCallingFeature = null;
 
         doReturn(1).when(mProxyController).getMaxRafSupported();
         mContextFixture.putIntArrayResource(com.android.internal.R.array.sim_colors, new int[]{5});
@@ -129,18 +131,20 @@
     @Test @SmallTest
     public void testInsertSim() {
         //verify there is no sim inserted in the SubscriptionManager
-        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
+                mCallingFeature));
 
         int slotID = 0;
         //insert one Subscription Info
         mSubscriptionControllerUT.addSubInfoRecord("test", slotID);
 
         //verify there is one sim
-        assertEquals(1, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+        assertEquals(1, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
+                mCallingFeature));
 
         //sanity for slot id and sub id
         List<SubscriptionInfo> mSubList = mSubscriptionControllerUT
-                .getActiveSubscriptionInfoList(mCallingPackage);
+                .getActiveSubscriptionInfoList(mCallingPackage, mCallingFeature);
         assertTrue(mSubList != null && mSubList.size() > 0);
         for (int i = 0; i < mSubList.size(); i++) {
             assertTrue(SubscriptionManager.isValidSubscriptionId(
@@ -165,7 +169,7 @@
 
         /* Getting, there is no direct getter function for each fields of property */
         SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subID, mCallingPackage);
+                .getActiveSubscriptionInfo(subID, mCallingPackage, mCallingFeature);
 
         /* Setting */
         mSubscriptionControllerUT.setDisplayNameUsingSrc(disName, subID,
@@ -176,7 +180,7 @@
         mSubscriptionControllerUT.setOpportunistic(isOpportunistic, subID, mCallingPackage);
 
         subInfo = mSubscriptionControllerUT
-            .getActiveSubscriptionInfo(subID, mCallingPackage);
+            .getActiveSubscriptionInfo(subID, mCallingPackage, mCallingFeature);
 
         assertNotNull(subInfo);
         assertEquals(dataRoaming, subInfo.getDataRoaming());
@@ -206,7 +210,7 @@
         int nameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;
         mSubscriptionControllerUT.setDisplayNameUsingSrc(disName, subID, nameSource);
         SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subID, mCallingPackage);
+                .getActiveSubscriptionInfo(subID, mCallingPackage, mCallingFeature);
         assertNotNull(subInfo);
         assertEquals(disName, subInfo.getDisplayName());
         assertEquals(nameSource, subInfo.getNameSource());
@@ -253,7 +257,7 @@
         mSubscriptionControllerUT.setMccMnc(mCcMncVERIZON, 1);
 
         SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(1, mCallingPackage);
+                .getActiveSubscriptionInfo(1, mCallingPackage, mCallingFeature);
         assertNotNull(subInfo);
         assertEquals(Integer.parseInt(mCcMncVERIZON.substring(0, 3)), subInfo.getMcc());
         assertEquals(Integer.parseInt(mCcMncVERIZON.substring(3)), subInfo.getMnc());
@@ -272,7 +276,7 @@
         mSubscriptionControllerUT.setCarrierId(carrierId, 1);
 
         SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(1, mCallingPackage);
+                .getActiveSubscriptionInfo(1, mCallingPackage, mCallingFeature);
         assertNotNull(subInfo);
         assertEquals(carrierId, subInfo.getCarrierId());
 
@@ -359,27 +363,32 @@
         assertEquals("1", mSubscriptionControllerUT.getSubscriptionProperty(
                 subID,
                 SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
-                mCallingPackage));
+                mCallingPackage,
+                mCallingFeature));
 
         assertEquals("0", mSubscriptionControllerUT.getSubscriptionProperty(
                 subID,
                 SubscriptionManager.VT_IMS_ENABLED,
-                mCallingPackage));
+                mCallingPackage,
+                mCallingFeature));
 
         assertEquals("1", mSubscriptionControllerUT.getSubscriptionProperty(
                 subID,
                 SubscriptionManager.WFC_IMS_ENABLED,
-                mCallingPackage));
+                mCallingPackage,
+                mCallingFeature));
 
         assertEquals("2", mSubscriptionControllerUT.getSubscriptionProperty(
                 subID,
                 SubscriptionManager.WFC_IMS_MODE,
-                mCallingPackage));
+                mCallingPackage,
+                mCallingFeature));
 
         assertEquals("3", mSubscriptionControllerUT.getSubscriptionProperty(
                 subID,
                 SubscriptionManager.WFC_IMS_ROAMING_MODE,
-                mCallingPackage));
+                mCallingPackage,
+                mCallingFeature));
     }
 
     @Test
@@ -448,7 +457,7 @@
         // Neither sub1 or sub2 are opportunistic. So getOpportunisticSubscriptions
         // should return empty list and no callback triggered.
         List<SubscriptionInfo> opptSubList = mSubscriptionControllerUT
-                .getOpportunisticSubscriptions(mCallingPackage);
+                .getOpportunisticSubscriptions(mCallingPackage, mCallingFeature);
 
         assertTrue(opptSubList.isEmpty());
         verify(mTelephonyRegisteryMock, times(0))
@@ -460,7 +469,7 @@
         verify(mTelephonyRegisteryMock, times(1))
                 .notifyOpportunisticSubscriptionInfoChanged();
         opptSubList = mSubscriptionControllerUT
-                .getOpportunisticSubscriptions(mCallingPackage);
+                .getOpportunisticSubscriptions(mCallingPackage, mCallingFeature);
         assertEquals(1, opptSubList.size());
         assertEquals("test2", opptSubList.get(0).getIccId());
 
@@ -481,7 +490,8 @@
         makeThisDeviceMultiSimCapable();
 
         // verify there are no sim's in the system.
-        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
+                mCallingFeature));
 
         addAndVerifyRemoteSimAddition(1, 0);
     }
@@ -489,14 +499,15 @@
     private void addAndVerifyRemoteSimAddition(int num, int numOfCurrentSubs) {
         // Verify the number of current subs in the system
         assertEquals(numOfCurrentSubs,
-                mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+                mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage, mCallingFeature));
 
         // if there are current subs in the system, get that info
         List<SubscriptionInfo> mSubList;
         ArrayList<String> macAddresses = new ArrayList<>();
         ArrayList<String> displayNames = new ArrayList<>();
         if (numOfCurrentSubs > 0) {
-            mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
+            mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
+                    mCallingFeature);
             assertNotNull(mSubList);
             assertEquals(numOfCurrentSubs, mSubList.size());
             for (SubscriptionInfo info : mSubList) {
@@ -536,7 +547,8 @@
             assertEquals(expectedNumOfSubs, subIdsList.size());
 
             // validate slot index, sub id etc
-            mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
+            mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
+                    mCallingFeature);
             assertNotNull(mSubList);
             assertEquals(expectedNumOfSubs, mSubList.size());
 
@@ -566,7 +578,8 @@
         makeThisDeviceMultiSimCapable();
 
         // verify that there are no subscription info records
-        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
+                mCallingFeature));
         Map<Integer, ArrayList<Integer>> slotIndexToSubsMap =
                 mSubscriptionControllerUT.getSlotIndexToSubIdsMap();
         assertNotNull(slotIndexToSubsMap);
@@ -708,8 +721,9 @@
                 subIdList, mContext.getOpPackageName());
         assertNotEquals(null, groupId);
 
-        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT
-                .getActiveSubscriptionInfoList(mContext.getOpPackageName());
+        List<SubscriptionInfo> subInfoList =
+                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
+                        null);
 
         // Put sub3 into slot 1 to make sub2 inactive.
         mContextFixture.addCallingOrSelfPermission(
@@ -775,7 +789,7 @@
         doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
         mSubscriptionControllerUT.addSubscriptionsIntoGroup(new int[] {2}, groupId, "packageName2");
         List<SubscriptionInfo> infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupId, "packageName2");
+                .getSubscriptionsInGroup(groupId, "packageName2", null);
         assertEquals(2, infoList.size());
     }
 
@@ -807,7 +821,7 @@
         mSubscriptionControllerUT.addSubscriptionsIntoGroup(
                 new int[] {2}, groupId, "packageName1");
         List<SubscriptionInfo> infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1");
+                groupId, "packageName1", null);
         assertEquals(2, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
         assertEquals(2, infoList.get(1).getSubscriptionId());
@@ -815,7 +829,7 @@
         mSubscriptionControllerUT.removeSubscriptionsFromGroup(
                 new int[] {2}, groupId, "packageName1");
         infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1");
+                groupId, "packageName1", null);
         assertEquals(1, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
 
@@ -835,7 +849,7 @@
         mSubscriptionControllerUT.addSubscriptionsIntoGroup(
                 new int[] {2}, groupId, "packageName1");
         infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1");
+                groupId, "packageName1", null);
         assertEquals(2, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
         assertEquals(2, infoList.get(1).getSubscriptionId());
@@ -843,7 +857,7 @@
         mSubscriptionControllerUT.removeSubscriptionsFromGroup(
                 new int[] {2}, groupId, "packageName1");
         infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1");
+                groupId, "packageName1", null);
         assertEquals(1, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
     }
@@ -878,7 +892,7 @@
         verify(mTelephonyRegisteryMock, times(2))
                 .notifyOpportunisticSubscriptionInfoChanged();
         List<SubscriptionInfo> opptSubList = mSubscriptionControllerUT
-                .getOpportunisticSubscriptions(mCallingPackage);
+                .getOpportunisticSubscriptions(mCallingPackage, mCallingFeature);
         assertEquals(1, opptSubList.size());
         assertEquals(2, opptSubList.get(0).getSubscriptionId());
         assertEquals(false, opptSubList.get(0).isGroupDisabled());
@@ -893,7 +907,8 @@
 
         verify(mTelephonyRegisteryMock, times(3))
                 .notifyOpportunisticSubscriptionInfoChanged();
-        opptSubList = mSubscriptionControllerUT.getOpportunisticSubscriptions(mCallingPackage);
+        opptSubList = mSubscriptionControllerUT.getOpportunisticSubscriptions(mCallingPackage,
+                mCallingFeature);
         assertEquals(1, opptSubList.size());
         assertEquals(2, opptSubList.get(0).getSubscriptionId());
         assertEquals(true, opptSubList.get(0).isGroupDisabled());
@@ -914,7 +929,7 @@
         assertTrue(mSubscriptionControllerUT.isActiveSubId(1));
         assertTrue(mSubscriptionControllerUT.isActiveSubId(2));
         assertTrue(TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, 1,
-                mContext.getOpPackageName(), "getSubscriptionsInGroup"));
+                mContext.getOpPackageName(), null, "getSubscriptionsInGroup"));
 
         int[] subIdList = new int[] {1};
         ParcelUuid groupUuid = mSubscriptionControllerUT.createSubscriptionGroup(
@@ -922,8 +937,8 @@
         assertNotEquals(null, groupUuid);
 
         // Sub 1 and sub 2 should be in same group.
-        List<SubscriptionInfo> infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
+        List<SubscriptionInfo> infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
+                groupUuid, mContext.getOpPackageName(), null);
         assertNotEquals(null, infoList);
         assertEquals(1, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
@@ -932,8 +947,8 @@
 
         mSubscriptionControllerUT.addSubscriptionsIntoGroup(
                 subIdList, groupUuid, mContext.getOpPackageName());
-        infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
+        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid,
+                mContext.getOpPackageName(), null);
         assertEquals(2, infoList.size());
         assertEquals(2, infoList.get(1).getSubscriptionId());
 
@@ -941,8 +956,8 @@
         subIdList = new int[] {1};
         mSubscriptionControllerUT.removeSubscriptionsFromGroup(
                 subIdList, groupUuid, mContext.getOpPackageName());
-        infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
+        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid,
+                mContext.getOpPackageName(), null);
         assertEquals(1, infoList.size());
         assertEquals(2, infoList.get(0).getSubscriptionId());
 
@@ -950,8 +965,8 @@
         groupUuid = new ParcelUuid(UUID.randomUUID());
         mSubscriptionControllerUT.addSubscriptionsIntoGroup(
                 subIdList, groupUuid, mContext.getOpPackageName());
-        infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
+        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid,
+                mContext.getOpPackageName(), null);
         assertEquals(1, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
index 6c34903..e7a5303 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
@@ -232,6 +232,46 @@
 
     @Test
     @SmallTest
+    public void testSimNotReady() throws Exception {
+        mUpdater.updateInternalIccState(
+                IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_SUB_ID_1, false);
+
+        processAllMessages();
+        assertFalse(mUpdater.isSubInfoInitialized());
+        verify(mSubscriptionContent, never()).put(anyString(), any());
+        CarrierConfigManager mConfigManager = (CarrierConfigManager)
+                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        verify(mConfigManager, never()).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
+                eq(IccCardConstants.INTENT_VALUE_ICC_NOT_READY));
+        verify(mSubscriptionController, never()).clearSubInfo();
+        verify(mSubscriptionController, never()).notifySubscriptionInfoChanged();
+    }
+
+    @Test
+    @SmallTest
+    public void testSimNotReadyEmptyProfile() throws Exception {
+        doReturn(mIccCard).when(mPhone).getIccCard();
+        doReturn(true).when(mIccCard).isEmptyProfile();
+
+        mUpdater.updateInternalIccState(
+                IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_SUB_ID_1, false);
+
+        processAllMessages();
+        assertTrue(mUpdater.isSubInfoInitialized());
+        // Sub info should be cleared and change should be notified.
+        verify(mSubscriptionController).clearSubInfoRecord(eq(FAKE_SUB_ID_1));
+        verify(mSubscriptionController).notifySubscriptionInfoChanged();
+        // No new sub should be added.
+        verify(mSubscriptionManager, never()).addSubscriptionInfoRecord(any(), anyInt());
+        verify(mSubscriptionContent, never()).put(anyString(), any());
+        CarrierConfigManager mConfigManager = (CarrierConfigManager)
+                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
+                eq(IccCardConstants.INTENT_VALUE_ICC_NOT_READY));
+    }
+
+    @Test
+    @SmallTest
     public void testSimError() throws Exception {
         mUpdater.updateInternalIccState(
                 IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, null, FAKE_SUB_ID_1, false);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
index 08defe3..10cdff9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
@@ -18,11 +18,12 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.when;
@@ -63,6 +64,7 @@
     private static final int PID = Binder.getCallingPid();
     private static final int UID = Binder.getCallingUid();
     private static final String PACKAGE = "com.example";
+    private static final String FEATURE = null;
     private static final String MSG = "message";
 
     @Mock
@@ -120,7 +122,7 @@
     public void testCheckReadPhoneState_noPermissions() {
         try {
             TelephonyPermissions.checkReadPhoneState(
-                    mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG);
+                    mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -132,7 +134,7 @@
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, PID, UID, MSG);
         assertTrue(TelephonyPermissions.checkReadPhoneState(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -142,7 +144,7 @@
         when(mMockAppOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, UID, PACKAGE))
                 .thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(TelephonyPermissions.checkReadPhoneState(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -150,7 +152,7 @@
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PHONE_STATE, PID, UID, MSG);
         assertFalse(TelephonyPermissions.checkReadPhoneState(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -158,13 +160,13 @@
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(TelephonyPermissions.checkReadPhoneState(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadPhoneStateOnAnyActiveSub_noPermissions() {
         assertFalse(TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
-                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -172,7 +174,7 @@
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, PID, UID, MSG);
         assertTrue(TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
-                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -182,7 +184,7 @@
         when(mMockAppOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, UID, PACKAGE))
                 .thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
-                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -190,7 +192,7 @@
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PHONE_STATE, PID, UID, MSG);
         assertFalse(TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
-                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -198,14 +200,14 @@
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
-                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadPhoneNumber_noPermissions() {
         try {
             TelephonyPermissions.checkReadPhoneNumber(
-                    mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG);
+                    mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -217,7 +219,7 @@
         when(mMockAppOps.noteOp(AppOpsManager.OPSTR_WRITE_SMS, UID, PACKAGE))
                 .thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(TelephonyPermissions.checkReadPhoneNumber(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -225,7 +227,7 @@
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, PID, UID, MSG);
         assertTrue(TelephonyPermissions.checkReadPhoneNumber(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -235,7 +237,7 @@
         when(mMockAppOps.noteOp(AppOpsManager.OPSTR_READ_SMS, UID, PACKAGE))
                 .thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(TelephonyPermissions.checkReadPhoneNumber(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -245,7 +247,7 @@
         when(mMockAppOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, UID, PACKAGE))
                 .thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(TelephonyPermissions.checkReadPhoneNumber(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -253,7 +255,7 @@
         setupMocksForDeviceIdentifiersErrorPath();
         try {
             TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                    SUB_ID, PACKAGE, MSG);
+                    SUB_ID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -266,7 +268,7 @@
                 PID, UID)).thenReturn(PackageManager.PERMISSION_GRANTED);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -275,7 +277,7 @@
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -284,7 +286,7 @@
                 PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -293,7 +295,7 @@
                 eq(UID))).thenReturn(true);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -306,7 +308,7 @@
         setupMocksForDeviceIdentifiersErrorPath();
         try {
             TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                    SUB_ID, PACKAGE, MSG);
+                    SUB_ID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -324,7 +326,7 @@
         mMockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
         assertFalse(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -336,7 +338,7 @@
                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -350,7 +352,7 @@
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -364,7 +366,7 @@
                 PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -375,7 +377,7 @@
         setupMocksForDeviceIdentifiersErrorPath();
         try {
             TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                    SUB_ID, null, MSG);
+                    SUB_ID, null, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -395,7 +397,7 @@
                 anyInt())).thenReturn(false);
         try {
             TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
-                    SUB_ID, PACKAGE, MSG);
+                    SUB_ID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -413,7 +415,7 @@
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -431,7 +433,7 @@
         // Carrier privilege on the other active sub shouldn't allow access to this sub.
         try {
             TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
-                    SUB_ID, PACKAGE, MSG);
+                    SUB_ID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 4671e51..9967b2b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -38,6 +38,7 @@
 import android.telephony.PhoneCapability;
 import android.telephony.PhoneStateListener;
 import android.telephony.PreciseDataConnectionState;
+import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -57,7 +58,7 @@
 @TestableLooper.RunWithLooper
 public class TelephonyRegistryTest extends TelephonyTest {
     @Mock
-    private ISub.Stub mISubStub;
+    private SubscriptionInfo mMockSubInfo;
     private PhoneStateListenerWrapper mPhoneStateListener;
     private TelephonyRegistry mTelephonyRegistry;
     private PhoneCapability mPhoneCapability;
@@ -105,9 +106,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp("TelephonyRegistryTest");
-        // ServiceManager.getService("isub") will return this stub for any call to
-        // SubscriptionManager.
-        mServiceManagerMockedServices.put("isub", mISubStub);
         mTelephonyRegistry = new TelephonyRegistry(mContext);
         addTelephonyRegistryService();
         mPhoneStateListener = new PhoneStateListenerWrapper();
@@ -124,10 +122,12 @@
 
     @Test @SmallTest
     public void testPhoneCapabilityChanged() {
+        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
         // mTelephonyRegistry.listen with notifyNow = true should trigger callback immediately.
         PhoneCapability phoneCapability = new PhoneCapability(1, 2, 3, null, false);
         mTelephonyRegistry.notifyPhoneCapabilityChanged(phoneCapability);
-        mTelephonyRegistry.listen(mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithFeature(mContext.getOpPackageName(), null,
                 mPhoneStateListener.callback,
                 LISTEN_PHONE_CAPABILITY_CHANGE, true);
         processAllMessages();
@@ -148,7 +148,7 @@
         when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(activeSubs);
         int activeSubId = 0;
         mTelephonyRegistry.notifyActiveDataSubIdChanged(activeSubId);
-        mTelephonyRegistry.listen(mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithFeature(mContext.getOpPackageName(), null,
                 mPhoneStateListener.callback,
                 LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE, true);
         processAllMessages();
@@ -169,20 +169,21 @@
     @Test
     @SmallTest
     public void testSrvccStateChanged() throws Exception {
-        // Return a phone ID of 0 for all sub ids given.
-        doReturn(0/*phoneId*/).when(mISubStub).getPhoneId(anyInt());
+        // Return a slotIndex / phoneId of 0 for all sub ids given.
+        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
         int srvccState = TelephonyManager.SRVCC_STATE_HANDOVER_STARTED;
-        mTelephonyRegistry.notifySrvccStateChanged(0 /*subId*/, srvccState);
+        mTelephonyRegistry.notifySrvccStateChanged(1 /*subId*/, srvccState);
         // Should receive callback when listen is called that contains the latest notify result.
-        mTelephonyRegistry.listenForSubscriber(0 /*subId*/, mContext.getOpPackageName(),
-                mPhoneStateListener.callback,
+        mTelephonyRegistry.listenForSubscriber(1 /*subId*/, mContext.getOpPackageName(),
+                null, mPhoneStateListener.callback,
                 LISTEN_SRVCC_STATE_CHANGED, true);
         processAllMessages();
         assertEquals(srvccState, mSrvccState);
 
         // trigger callback
         srvccState = TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED;
-        mTelephonyRegistry.notifySrvccStateChanged(0 /*subId*/, srvccState);
+        mTelephonyRegistry.notifySrvccStateChanged(1 /*subId*/, srvccState);
         processAllMessages();
         assertEquals(srvccState, mSrvccState);
     }
@@ -200,7 +201,7 @@
         mTelephonyRegistry.notifySrvccStateChanged(0 /*subId*/, srvccState);
         try {
             mTelephonyRegistry.listenForSubscriber(0 /*subId*/, mContext.getOpPackageName(),
-                    mPhoneStateListener.callback,
+                    null, mPhoneStateListener.callback,
                     LISTEN_SRVCC_STATE_CHANGED, true);
             fail();
         } catch (SecurityException e) {
@@ -214,7 +215,7 @@
     @Test
     public void testMultiSimConfigChange() {
         mTelephonyRegistry.listenForSubscriber(1, mContext.getOpPackageName(),
-                mPhoneStateListener.callback,
+                null, mPhoneStateListener.callback,
                 LISTEN_RADIO_POWER_STATE_CHANGED, true);
         processAllMessages();
         assertEquals(RADIO_POWER_UNAVAILABLE, mRadioPowerState);
@@ -244,14 +245,16 @@
      */
     @Test
     public void testPreciseDataConnectionStateChanged() {
-        final int subId = 0;
+        final int subId = 1;
+        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
         // Initialize the PSL with a PreciseDataConnection
         mTelephonyRegistry.notifyDataConnectionForSubscriber(
                 /*phoneId*/ 0, subId, "default",
                 new PreciseDataConnectionState(
                     0, 0, 0, "default", new LinkProperties(), 0, null));
         mTelephonyRegistry.listenForSubscriber(subId, mContext.getOpPackageName(),
-                mPhoneStateListener.callback,
+                null, mPhoneStateListener.callback,
                 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE, true);
         processAllMessages();
         // Verify that the PDCS is reported for the only APN
@@ -268,13 +271,13 @@
 
         // Unregister the listener
         mTelephonyRegistry.listenForSubscriber(subId, mContext.getOpPackageName(),
-                mPhoneStateListener.callback,
+                null, mPhoneStateListener.callback,
                 PhoneStateListener.LISTEN_NONE, true);
         processAllMessages();
 
         // Re-register the listener and ensure that both APN types are reported
         mTelephonyRegistry.listenForSubscriber(subId, mContext.getOpPackageName(),
-                mPhoneStateListener.callback,
+                null, mPhoneStateListener.callback,
                 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE, true);
         processAllMessages();
         assertEquals(mPhoneStateListener.invocationCount.get(), 4);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 743fcaf..d3115fe 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -268,6 +268,8 @@
     protected UiccCard mUiccCard;
     @Mock
     protected MultiSimSettingController mMultiSimSettingController;
+    @Mock
+    protected IccCard mIccCard;
 
     protected ImsCallProfile mImsCallProfile;
     protected TelephonyManager mTelephonyManager;
@@ -711,8 +713,6 @@
     protected void setupMockPackagePermissionChecks() throws Exception {
         doReturn(new String[]{TAG}).when(mPackageManager).getPackagesForUid(anyInt());
         doReturn(mPackageInfo).when(mPackageManager).getPackageInfo(eq(TAG), anyInt());
-        doReturn(mPackageInfo).when(mPackageManager).getPackageInfoAsUser(
-                eq(TAG), anyInt(), anyInt());
     }
 
     protected void setupMocksForTelephonyPermissions() throws Exception {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
index 2dce712..b99749c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -29,7 +29,6 @@
 import static org.mockito.Matchers.nullable;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -43,7 +42,6 @@
 import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -809,8 +807,8 @@
         // verify that a broadcast receiver is registered for current user (user == null) based on
         // implementation in ContextFixture. registerReceiver may be called more than once (for
         // example by GsmInboundSmsHandler if TEST_MODE is true)
-        verify(mContext, atLeastOnce()).registerReceiverAsUser(any(BroadcastReceiver.class),
-                eq((UserHandle)null), any(IntentFilter.class), eq((String)null), eq((Handler)null));
+        verify(mContext, atLeastOnce()).registerReceiver(any(BroadcastReceiver.class),
+                any(IntentFilter.class));
 
         // wait for ScanRawTableThread
         waitForMs(100);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
index 38218c4..84c9cb3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doReturn;
@@ -95,8 +96,8 @@
         doReturn(mSubscriptionController).when(mBinder).queryLocalInterface(anyString());
         mServiceManagerMockedServices.put("isub", mBinder);
         // Stick to the CarrierConfig defaults unless explicitly overwritten.
-        doReturn("-1").when(mSubscriptionController)
-                .getSubscriptionProperty(anyInt(), anyString(), anyString());
+        doReturn("-1").when(mSubscriptionController).getSubscriptionProperty(anyInt(), anyString(),
+                anyString(), nullable(String.class));
 
 
         doReturn(true).when(mMmTelFeatureConnection).isBinderAlive();
@@ -143,38 +144,44 @@
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         assertEquals(WFC_IMS_ROAMING_ENABLE_DEFAULT_VAL, imsManager.isWfcRoamingEnabledByUser());
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         assertEquals(ENHANCED_4G_MODE_DEFAULT_VAL,
                 imsManager.isEnhanced4gLteModeSettingEnabledByUser());
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.ENHANCED_4G_MODE_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         assertEquals(WFC_IMS_MODE_DEFAULT_VAL, imsManager.getWfcMode(false));
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         assertEquals(WFC_IMS_ROAMING_MODE_DEFAULT_VAL, imsManager.getWfcMode(true));
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         assertEquals(VT_IMS_ENABLE_DEFAULT_VAL, imsManager.isVtEnabledByUser());
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.VT_IMS_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
     }
 
     @Test @SmallTest
@@ -285,12 +292,14 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                         anyInt(),
                         eq(SubscriptionManager.WFC_IMS_MODE),
-                        anyString());
+                        anyString(),
+                        nullable(String.class));
         doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
                 .when(mSubscriptionController).getSubscriptionProperty(
                         anyInt(),
                         eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                        anyString());
+                        anyString(),
+                        nullable(String.class));
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
         // Roaming
@@ -345,7 +354,8 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
@@ -380,7 +390,8 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
@@ -454,7 +465,8 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         // The device is roaming
         doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
@@ -500,7 +512,8 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         // The device is roaming
         doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
@@ -534,13 +547,15 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
         // The user has enabled the "WFC while roaming" setting in the UI while WFC was enabled
         doReturn(String.valueOf(1 /*true*/))
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
@@ -574,7 +589,8 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
@@ -609,12 +625,14 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
         doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY))
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
         // Roaming
@@ -687,12 +705,14 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
         doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
@@ -702,7 +722,8 @@
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         // Set WFC roaming network mode to not editable.
         mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL,
@@ -713,7 +734,8 @@
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
     }
 
     /**
@@ -730,12 +752,14 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
         doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         // Set to use WFC home network mode in roaming network.
         mBundle.putBoolean(
@@ -749,7 +773,8 @@
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         // Set WFC home network mode to not editable.
         mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL,
@@ -760,7 +785,8 @@
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
     }
 
     /**