Merge "Add PhoneStateListener#onPreferredDataSubIdChanged"
diff --git a/proto/src/carrierId.proto b/proto/src/carrierId.proto
index f67e9f6..ca8b69b 100644
--- a/proto/src/carrierId.proto
+++ b/proto/src/carrierId.proto
@@ -79,5 +79,9 @@
   // [Optional] Prefix of Integrated Circuit Card Identifier. Read from subscription EF_ICCID.
   // Sample values: 894430, 894410
   repeated string iccid_prefix = 8;
+
+  // [Optional] Carrier Privilege Access Rule in hex string.
+  // Sample values: 61ed377e85d386a8dfee6b864bd85b0bfaa5af88
+  repeated string privilege_access_rule = 9;
 };
 
diff --git a/src/java/com/android/internal/telephony/CarrierIdentifier.java b/src/java/com/android/internal/telephony/CarrierResolver.java
similarity index 76%
rename from src/java/com/android/internal/telephony/CarrierIdentifier.java
rename to src/java/com/android/internal/telephony/CarrierResolver.java
index 1ff8971..8da6718 100644
--- a/src/java/com/android/internal/telephony/CarrierIdentifier.java
+++ b/src/java/com/android/internal/telephony/CarrierResolver.java
@@ -26,6 +26,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.provider.Telephony;
+import android.service.carrier.CarrierIdentifier;
 import android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -46,32 +47,34 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
- * CarrierIdentifier identifies the subscription carrier and returns a canonical carrier Id
- * and a user friendly carrier name. CarrierIdentifier reads subscription info and check against
+ * CarrierResolver identifies the subscription carrier and returns a canonical carrier Id
+ * and a user friendly carrier name. CarrierResolver reads subscription info and check against
  * all carrier matching rules stored in CarrierIdProvider. It is msim aware, each phone has a
- * dedicated CarrierIdentifier.
+ * dedicated CarrierResolver.
  */
-public class CarrierIdentifier extends Handler {
-    private static final String LOG_TAG = CarrierIdentifier.class.getSimpleName();
+public class CarrierResolver extends Handler {
+    private static final String LOG_TAG = CarrierResolver.class.getSimpleName();
     private static final boolean DBG = true;
     private static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE);
 
     // events to trigger carrier identification
     private static final int SIM_LOAD_EVENT             = 1;
     private static final int SIM_ABSENT_EVENT           = 2;
-    private static final int SPN_OVERRIDE_EVENT         = 3;
-    private static final int ICC_CHANGED_EVENT          = 4;
-    private static final int PREFER_APN_UPDATE_EVENT    = 5;
-    private static final int CARRIER_ID_DB_UPDATE_EVENT = 6;
+    private static final int ICC_CHANGED_EVENT          = 3;
+    private static final int PREFER_APN_UPDATE_EVENT    = 4;
+    private static final int CARRIER_ID_DB_UPDATE_EVENT = 5;
 
     private static final Uri CONTENT_URL_PREFER_APN = Uri.withAppendedPath(
             Telephony.Carriers.CONTENT_URI, "preferapn");
-    private static final String OPERATOR_BRAND_OVERRIDE_PREFIX = "operator_branding_";
 
     // cached matching rules based mccmnc to speed up resolution
     private List<CarrierMatchingRule> mCarrierMatchingRulesOnMccMnc = new ArrayList<>();
     // cached carrier Id
     private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+    // cached MNO carrier Id. mno carrier shares the same mccmnc as cid and can be solely
+    // identified by mccmnc only. If there is no such mno carrier, mno carrier id equals to
+    // the cid.
+    private int mMnoCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
     // cached carrier name
     private String mCarrierName;
     // cached preferapn name
@@ -128,8 +131,8 @@
         }
     }
 
-    public CarrierIdentifier(Phone phone) {
-        logd("Creating CarrierIdentifier[" + phone.getPhoneId() + "]");
+    public CarrierResolver(Phone phone) {
+        logd("Creating CarrierResolver[" + phone.getPhoneId() + "]");
         mContext = phone.getContext();
         mPhone = phone;
         mTelephonyMgr = TelephonyManager.from(mContext);
@@ -150,7 +153,7 @@
      *    1. SIM_LOAD_EVENT
      *        This indicates that all SIM records has been loaded and its first entry point for the
      *        carrier identification. Note, there are other attributes could be changed on the fly
-     *        like APN and SPN. We cached all carrier matching rules based on MCCMNC to speed
+     *        like APN. We cached all carrier matching rules based on MCCMNC to speed
      *        up carrier resolution on following trigger events.
      *
      *    2. PREFER_APN_UPDATE_EVENT
@@ -159,48 +162,37 @@
      *        We follow up on this by querying prefer apn sqlite and re-issue carrier identification
      *        with the updated prefer apn name.
      *
-     *    3. SPN_OVERRIDE_EVENT
-     *        This indicates that SPN value as been changed. It could be triggered from EF_SPN
-     *        record loading, carrier config override
-     *        {@link android.telephony.CarrierConfigManager#KEY_CARRIER_NAME_STRING}
-     *        or carrier app override {@link TelephonyManager#setOperatorBrandOverride(String)}.
-     *        we follow up this by checking the cached mSPN against the latest value and issue
-     *        carrier identification only if spn changes.
-     *
-     *    4. CARRIER_ID_DB_UPDATE_EVENT
+     *    3. CARRIER_ID_DB_UPDATE_EVENT
      *        This indicates that carrierIdentification database which stores all matching rules
      *        has been updated. It could be triggered from OTA or assets update.
      */
     @Override
     public void handleMessage(Message msg) {
-        if (VDBG) logd("handleMessage: " + msg.what);
+        if (DBG) logd("handleMessage: " + msg.what);
         switch (msg.what) {
             case SIM_LOAD_EVENT:
-            case CARRIER_ID_DB_UPDATE_EVENT:
-                mSpn = mTelephonyMgr.getSimOperatorNameForPhone(mPhone.getPhoneId());
+                if (mIccRecords != null) {
+                    mSpn = mIccRecords.getServiceProviderName();
+                } else {
+                    loge("mIccRecords is null on SIM_LOAD_EVENT, could not get SPN");
+                }
                 mPreferApn = getPreferApn();
+            case CARRIER_ID_DB_UPDATE_EVENT:
                 loadCarrierMatchingRulesOnMccMnc();
                 break;
             case SIM_ABSENT_EVENT:
                 mCarrierMatchingRulesOnMccMnc.clear();
                 mSpn = null;
                 mPreferApn = null;
-                updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null);
+                updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID,
+                        TelephonyManager.UNKNOWN_CARRIER_ID, null);
                 break;
             case PREFER_APN_UPDATE_EVENT:
                 String preferApn = getPreferApn();
                 if (!equals(mPreferApn, preferApn, true)) {
                     logd("[updatePreferApn] from:" + mPreferApn + " to:" + preferApn);
                     mPreferApn = preferApn;
-                    matchCarrier();
-                }
-                break;
-            case SPN_OVERRIDE_EVENT:
-                String spn = mTelephonyMgr.getSimOperatorNameForPhone(mPhone.getPhoneId());
-                if (!equals(mSpn, spn, true)) {
-                    logd("[updateSpn] from:" + mSpn + " to:" + spn);
-                    mSpn = spn;
-                    matchCarrier();
+                    matchCarrier(getSubscriptionMatchingRule(), true);
                 }
                 break;
             case ICC_CHANGED_EVENT:
@@ -222,20 +214,8 @@
                     }
                 }
                 // check UICC profile
-                final UiccProfile uiccProfile = UiccController.getInstance()
+                mUiccProfile = UiccController.getInstance()
                         .getUiccProfileForPhone(mPhone.getPhoneId());
-                if (mUiccProfile != uiccProfile) {
-                    if (mUiccProfile != null) {
-                        logd("unregister operatorBrandOverride");
-                        mUiccProfile.unregisterForOperatorBrandOverride(this);
-                        mUiccProfile = null;
-                    }
-                    if (uiccProfile != null) {
-                        logd("register operatorBrandOverride");
-                        uiccProfile.registerForOpertorBrandOverride(this, SPN_OVERRIDE_EVENT, null);
-                        mUiccProfile = uiccProfile;
-                    }
-                }
                 break;
             default:
                 loge("invalid msg: " + msg.what);
@@ -261,7 +241,7 @@
                     while (cursor.moveToNext()) {
                         mCarrierMatchingRulesOnMccMnc.add(makeCarrierMatchingRule(cursor));
                     }
-                    matchCarrier();
+                    matchCarrier(getSubscriptionMatchingRule(), true);
                 }
             } finally {
                 if (cursor != null) {
@@ -300,7 +280,7 @@
         return null;
     }
 
-    private void updateCarrierIdAndName(int cid, String name) {
+    private void updateCarrierIdAndName(int cid, int mnoCid, String name) {
         boolean update = false;
         if (!equals(name, mCarrierName, true)) {
             logd("[updateCarrierName] from:" + mCarrierName + " to:" + name);
@@ -312,13 +292,20 @@
             mCarrierId = cid;
             update = true;
         }
+        if (mnoCid != mMnoCarrierId) {
+            logd("[updateMnoCarrierId] from:" + mMnoCarrierId + " to:" + mnoCid);
+            mMnoCarrierId = mnoCid;
+            update = true;
+        }
+
         if (update) {
             mCarrierIdLocalLog.log("[updateCarrierIdAndName] cid:" + mCarrierId + " name:"
-                    + mCarrierName);
+                    + mCarrierName + " mnoCid:" + mMnoCarrierId);
             final Intent intent = new Intent(TelephonyManager
                     .ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED);
             intent.putExtra(TelephonyManager.EXTRA_CARRIER_ID, mCarrierId);
             intent.putExtra(TelephonyManager.EXTRA_CARRIER_NAME, mCarrierName);
+            intent.putExtra(TelephonyManager.EXTRA_MNO_CARRIER_ID, mMnoCarrierId);
             intent.putExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID, mPhone.getSubId());
             mContext.sendBroadcast(intent);
 
@@ -326,6 +313,7 @@
             ContentValues cv = new ContentValues();
             cv.put(CarrierId.CARRIER_ID, mCarrierId);
             cv.put(CarrierId.CARRIER_NAME, mCarrierName);
+            cv.put(CarrierId.MNO_CARRIER_ID, mMnoCarrierId);
             mContext.getContentResolver().update(
                     Uri.withAppendedPath(CarrierId.CONTENT_URI,
                     Integer.toString(mPhone.getSubId())), cv, null, null);
@@ -344,6 +332,7 @@
                 cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.PLMN)),
                 cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.SPN)),
                 cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.APN)),
+                cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.PRIVILEGE_ACCESS_RULE)),
                 cursor.getInt(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_ID)),
                 cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_NAME)));
     }
@@ -351,7 +340,7 @@
     /**
      * carrier matching attributes with corresponding cid
      */
-    private static class CarrierMatchingRule {
+    private class CarrierMatchingRule {
         /**
          * These scores provide the hierarchical relationship between the attributes, intended to
          * resolve conflicts in a deterministic way. The scores are constructed such that a match
@@ -361,26 +350,28 @@
          * rule 1 {mccmnc, imsi} rule 2 {mccmnc, imsi, gid1} and rule 3 {mccmnc, imsi, gid2} all
          * matches with subscription data. rule 2 wins with the highest matching score.
          */
-        private static final int SCORE_MCCMNC          = 1 << 7;
-        private static final int SCORE_IMSI_PREFIX     = 1 << 6;
-        private static final int SCORE_ICCID_PREFIX    = 1 << 5;
-        private static final int SCORE_GID1            = 1 << 4;
-        private static final int SCORE_GID2            = 1 << 3;
-        private static final int SCORE_PLMN            = 1 << 2;
-        private static final int SCORE_SPN             = 1 << 1;
-        private static final int SCORE_APN             = 1 << 0;
+        private static final int SCORE_MCCMNC                   = 1 << 8;
+        private static final int SCORE_IMSI_PREFIX              = 1 << 7;
+        private static final int SCORE_ICCID_PREFIX             = 1 << 6;
+        private static final int SCORE_GID1                     = 1 << 5;
+        private static final int SCORE_GID2                     = 1 << 4;
+        private static final int SCORE_PLMN                     = 1 << 3;
+        private static final int SCORE_PRIVILEGE_ACCESS_RULE    = 1 << 2;
+        private static final int SCORE_SPN                      = 1 << 1;
+        private static final int SCORE_APN                      = 1 << 0;
 
-        private static final int SCORE_INVALID         = -1;
+        private static final int SCORE_INVALID                  = -1;
 
         // carrier matching attributes
-        private String mMccMnc;
-        private String mImsiPrefixPattern;
-        private String mIccidPrefix;
-        private String mGid1;
-        private String mGid2;
-        private String mPlmn;
-        private String mSpn;
-        private String mApn;
+        private final String mMccMnc;
+        private final String mImsiPrefixPattern;
+        private final String mIccidPrefix;
+        private final String mGid1;
+        private final String mGid2;
+        private final String mPlmn;
+        private final String mSpn;
+        private final String mApn;
+        private final String mPrivilegeAccessRule;
 
         // user-facing carrier name
         private String mName;
@@ -390,8 +381,8 @@
         private int mScore = 0;
 
         CarrierMatchingRule(String mccmnc, String imsiPrefixPattern, String iccidPrefix,
-                String gid1, String gid2, String plmn, String spn, String apn, int cid,
-                String name) {
+                String gid1, String gid2, String plmn, String spn, String apn,
+                String privilegeAccessRule, int cid, String name) {
             mMccMnc = mccmnc;
             mImsiPrefixPattern = imsiPrefixPattern;
             mIccidPrefix = iccidPrefix;
@@ -400,6 +391,7 @@
             mPlmn = plmn;
             mSpn = spn;
             mApn = apn;
+            mPrivilegeAccessRule = privilegeAccessRule;
             mCid = cid;
             mName = name;
         }
@@ -412,7 +404,7 @@
         public void match(CarrierMatchingRule subscriptionRule) {
             mScore = 0;
             if (mMccMnc != null) {
-                if (!CarrierIdentifier.equals(subscriptionRule.mMccMnc, mMccMnc, false)) {
+                if (!CarrierResolver.equals(subscriptionRule.mMccMnc, mMccMnc, false)) {
                     mScore = SCORE_INVALID;
                     return;
                 }
@@ -435,7 +427,7 @@
             if (mGid1 != null) {
                 // full string match. carrier matching should cover the corner case that gid1
                 // with garbage tail due to SIM manufacture issues.
-                if (!CarrierIdentifier.equals(subscriptionRule.mGid1, mGid1, true)) {
+                if (!CarrierResolver.equals(subscriptionRule.mGid1, mGid1, true)) {
                     mScore = SCORE_INVALID;
                     return;
                 }
@@ -444,28 +436,38 @@
             if (mGid2 != null) {
                 // full string match. carrier matching should cover the corner case that gid2
                 // with garbage tail due to SIM manufacture issues.
-                if (!CarrierIdentifier.equals(subscriptionRule.mGid2, mGid2, true)) {
+                if (!CarrierResolver.equals(subscriptionRule.mGid2, mGid2, true)) {
                     mScore = SCORE_INVALID;
                     return;
                 }
                 mScore += SCORE_GID2;
             }
             if (mPlmn != null) {
-                if (!CarrierIdentifier.equals(subscriptionRule.mPlmn, mPlmn, true)) {
+                if (!CarrierResolver.equals(subscriptionRule.mPlmn, mPlmn, true)) {
                     mScore = SCORE_INVALID;
                     return;
                 }
                 mScore += SCORE_PLMN;
             }
             if (mSpn != null) {
-                if (!CarrierIdentifier.equals(subscriptionRule.mSpn, mSpn, true)) {
+                if (!CarrierResolver.equals(subscriptionRule.mSpn, mSpn, true)) {
                     mScore = SCORE_INVALID;
                     return;
                 }
                 mScore += SCORE_SPN;
             }
+
+            if (mPrivilegeAccessRule != null) {
+                if (mUiccProfile == null || !mUiccProfile.hasCarrierPrivilegeRulesLoadedForCertHex(
+                        mPrivilegeAccessRule)) {
+                    mScore = SCORE_INVALID;
+                    return;
+                }
+                mScore += SCORE_PRIVILEGE_ACCESS_RULE;
+            }
+
             if (mApn != null) {
-                if (!CarrierIdentifier.equals(subscriptionRule.mApn, mApn, true)) {
+                if (!CarrierResolver.equals(subscriptionRule.mApn, mApn, true)) {
                     mScore = SCORE_INVALID;
                     return;
                 }
@@ -504,6 +506,7 @@
                     + " imsi_prefix: " + mImsiPrefixPattern
                     + " iccid_prefix" + mIccidPrefix
                     + " spn: " + mSpn
+                    + " privilege_access_rule: " + mPrivilegeAccessRule
                     + " apn: " + mApn
                     + " name: " + mName
                     + " cid: " + mCid
@@ -511,15 +514,7 @@
         }
     }
 
-    /**
-     * find the best matching carrier from candidates with matched MCCMNC and notify
-     * all interested parties on carrier id change.
-     */
-    private void matchCarrier() {
-        if (!SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
-            logd("[matchCarrier]" + "skip before sim records loaded");
-            return;
-        }
+    private CarrierMatchingRule getSubscriptionMatchingRule() {
         final String mccmnc = mTelephonyMgr.getSimOperatorNumericForPhone(mPhone.getPhoneId());
         final String iccid = mPhone.getIccSerialNumber();
         final String gid1 = mPhone.getGroupIdLevel1();
@@ -540,29 +535,55 @@
                     + " spn: " + spn
                     + " apn: " + apn);
         }
-
-        CarrierMatchingRule subscriptionRule = new CarrierMatchingRule(
-                mccmnc, imsi, iccid, gid1, gid2, plmn,  spn, apn,
+        return new CarrierMatchingRule(
+                mccmnc, imsi, iccid, gid1, gid2, plmn, spn, apn, null
+                /** fetching privilege access rule is handled by CarrierMatchingRule#match **/,
                 TelephonyManager.UNKNOWN_CARRIER_ID, null);
+    }
 
+    /**
+     * find the best matching carrier from candidates with matched MCCMNC.
+     * @param update if true, update cached mCarrierId and notify registrants on carrier id change.
+     * @return the best matching carrier id.
+     */
+    private int matchCarrier(CarrierMatchingRule subscriptionRule, boolean update) {
+        int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+        if (update && !SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
+            logd("[matchCarrier]" + "skip before sim records loaded");
+            return carrierId;
+        }
         int maxScore = CarrierMatchingRule.SCORE_INVALID;
         CarrierMatchingRule maxRule = null;
+        /**
+         * matching rule with mccmnc only. If mnoRule is found, then mno carrier id equals to the
+         * cid from mnoRule. otherwise, mno carrier id is same as cid.
+         */
+        CarrierMatchingRule mnoRule = null;
 
         for (CarrierMatchingRule rule : mCarrierMatchingRulesOnMccMnc) {
             rule.match(subscriptionRule);
             if (rule.mScore > maxScore) {
                 maxScore = rule.mScore;
                 maxRule = rule;
+                carrierId = rule.mCid;
+            }
+            if (rule.mScore == CarrierMatchingRule.SCORE_MCCMNC) {
+                mnoRule = rule;
             }
         }
-
+        // skip updating the cached carrierId
+        if (!update) {
+            return carrierId;
+        }
         if (maxScore == CarrierMatchingRule.SCORE_INVALID) {
             logd("[matchCarrier - no match] cid: " + TelephonyManager.UNKNOWN_CARRIER_ID
                     + " name: " + null);
-            updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null);
+            updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID,
+                    TelephonyManager.UNKNOWN_CARRIER_ID, null);
         } else {
             logd("[matchCarrier] cid: " + maxRule.mCid + " name: " + maxRule.mName);
-            updateCarrierIdAndName(maxRule.mCid, maxRule.mName);
+            updateCarrierIdAndName(maxRule.mCid,
+                    (mnoRule == null) ? maxRule.mCid : mnoRule.mCid, maxRule.mName);
         }
 
         /*
@@ -583,6 +604,7 @@
         TelephonyMetrics.getInstance().writeCarrierIdMatchingEvent(
                 mPhone.getPhoneId(), getCarrierListVersion(), mCarrierId,
                 unknownMccmncToLog, unknownGid1ToLog);
+        return carrierId;
     }
 
     public int getCarrierListVersion() {
@@ -597,10 +619,39 @@
         return mCarrierId;
     }
 
+    public int getMnoCarrierId() {
+        return mMnoCarrierId;
+    }
+
     public String getCarrierName() {
         return mCarrierName;
     }
 
+    /**
+     * a util function to convert carrierIdentifier to the best matching carrier id.
+     * If there is no exact match for MVNO, will fallback to match its MNO.
+     */
+    public int getCarrierIdFromIdentifier(CarrierIdentifier carrierIdentifier) {
+        final String mccmnc = carrierIdentifier.getMcc() + carrierIdentifier.getMnc();
+        final String gid1 = carrierIdentifier.getGid1();
+        final String gid2 = carrierIdentifier.getGid2();
+        final String imsi = carrierIdentifier.getImsi();
+        final String spn = carrierIdentifier.getSpn();
+
+        if (VDBG) {
+            logd("[matchCarrier]"
+                    + " mnnmnc:" + mccmnc
+                    + " gid1: " + gid1
+                    + " gid2: " + gid2
+                    + " imsi: " + Rlog.pii(LOG_TAG, imsi)
+                    + " spn: " + spn);
+        }
+        CarrierMatchingRule rule = new CarrierMatchingRule(mccmnc, imsi, null, gid1, gid2, null,
+                spn, null, null, -1, null);
+        // not trigger the updating logic for internal conversion.
+        return matchCarrier(rule, false);
+    }
+
     private static boolean equals(String a, String b, boolean ignoreCase) {
         if (a == null && b == null) return true;
         if (a != null && b != null) {
@@ -617,12 +668,13 @@
     }
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
-        ipw.println("mCarrierIdLocalLogs:");
+        ipw.println("mCarrierResolverLocalLogs:");
         ipw.increaseIndent();
         mCarrierIdLocalLog.dump(fd, pw, args);
         ipw.decreaseIndent();
 
         ipw.println("mCarrierId: " + mCarrierId);
+        ipw.println("mMnoCarrierId: " + mMnoCarrierId);
         ipw.println("mCarrierName: " + mCarrierName);
         ipw.println("version: " + getCarrierListVersion());
 
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
index abd09a5..07d70b1 100755
--- a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
@@ -476,7 +476,7 @@
             // Some networks need an empty flash before sending the normal one
             CarrierConfigManager configManager = (CarrierConfigManager)
                     mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
-            PersistableBundle bundle = configManager.getConfig();
+            PersistableBundle bundle = configManager.getConfigForSubId(mPhone.getSubId());
             if (bundle != null) {
                 m3WayCallFlashDelay =
                         bundle.getInt(CarrierConfigManager.KEY_CDMA_3WAYCALL_FLASH_DELAY_INT);
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index f8edbcf..960a6a3 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -169,7 +169,7 @@
     private ArrayList <MmiCode> mPendingMMIs = new ArrayList<MmiCode>();
     private IccPhoneBookInterfaceManager mIccPhoneBookIntManager;
     // Used for identify the carrier of current subscription
-    private CarrierIdentifier mCarrerIdentifier;
+    private CarrierResolver mCarrerResolver;
 
     private int mPrecisePhoneType;
 
@@ -226,7 +226,7 @@
         mSST = mTelephonyComponentFactory.makeServiceStateTracker(this, this.mCi);
         // DcTracker uses SST so needs to be created after it is instantiated
         mDcTracker = mTelephonyComponentFactory.makeDcTracker(this);
-        mCarrerIdentifier = mTelephonyComponentFactory.makeCarrierIdentifier(this);
+        mCarrerResolver = mTelephonyComponentFactory.makeCarrierResolver(this);
 
         mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
         mDeviceStateMonitor = mTelephonyComponentFactory.makeDeviceStateMonitor(this);
@@ -1402,7 +1402,7 @@
         if (TextUtils.isEmpty(number)) {
             CarrierConfigManager configManager = (CarrierConfigManager)
                     getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
-            PersistableBundle b = configManager.getConfig();
+            PersistableBundle b = configManager.getConfigForSubId(getSubId());
             if (b != null) {
                 String defaultVmNumber =
                         b.getString(CarrierConfigManager.KEY_DEFAULT_VM_NUMBER_STRING);
@@ -1420,7 +1420,7 @@
             // Read platform settings for dynamic voicemail number
             CarrierConfigManager configManager = (CarrierConfigManager)
                     getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
-            PersistableBundle b = configManager.getConfig();
+            PersistableBundle b = configManager.getConfigForSubId(getSubId());
             if (b != null && b.getBoolean(
                     CarrierConfigManager.KEY_CONFIG_TELEPHONY_USE_OWN_NUMBER_FOR_VOICEMAIL_BOOL)) {
                 number = getLine1Number();
@@ -1555,17 +1555,17 @@
 
     @Override
     public int getCarrierId() {
-        return mCarrerIdentifier.getCarrierId();
+        return mCarrerResolver.getCarrierId();
     }
 
     @Override
     public String getCarrierName() {
-        return mCarrerIdentifier.getCarrierName();
+        return mCarrerResolver.getCarrierName();
     }
 
     @Override
     public int getCarrierIdListVersion() {
-        return mCarrerIdentifier.getCarrierListVersion();
+        return mCarrerResolver.getCarrierListVersion();
     }
 
     @Override
@@ -2102,7 +2102,7 @@
     public boolean supports3gppCallForwardingWhileRoaming() {
         CarrierConfigManager configManager = (CarrierConfigManager)
                 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        PersistableBundle b = configManager.getConfig();
+        PersistableBundle b = configManager.getConfigForSubId(getSubId());
         if (b != null) {
             return b.getBoolean(
                     CarrierConfigManager.KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL, true);
diff --git a/src/java/com/android/internal/telephony/IccProvider.java b/src/java/com/android/internal/telephony/IccProvider.java
index 8feec94..76af170 100644
--- a/src/java/com/android/internal/telephony/IccProvider.java
+++ b/src/java/com/android/internal/telephony/IccProvider.java
@@ -294,7 +294,7 @@
         String[] emails = null;
         String pin2 = null;
 
-        String[] tokens = where.split("AND");
+        String[] tokens = where.split(" AND ");
         int n = tokens.length;
 
         while (--n >= 0) {
diff --git a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
index 91c0040..60715d9 100644
--- a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
+++ b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
@@ -26,7 +26,6 @@
 import android.telephony.ServiceState;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.aidl.IImsSmsListener;
-import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.telephony.ims.stub.ImsSmsImplBase;
@@ -66,8 +65,8 @@
      * Listen to the IMS service state change
      *
      */
-    private ImsRegistrationImplBase.Callback mRegistrationCallback =
-            new ImsRegistrationImplBase.Callback() {
+    private android.telephony.ims.ImsMmTelManager.RegistrationCallback mRegistrationCallback =
+            new android.telephony.ims.ImsMmTelManager.RegistrationCallback() {
                 @Override
                 public void onRegistered(
                         @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
@@ -95,12 +94,13 @@
                 }
             };
 
-    private ImsFeature.CapabilityCallback mCapabilityCallback =
-            new ImsFeature.CapabilityCallback() {
+    private android.telephony.ims.ImsMmTelManager.CapabilityCallback mCapabilityCallback =
+            new android.telephony.ims.ImsMmTelManager.CapabilityCallback() {
                 @Override
-                public void onCapabilitiesStatusChanged(ImsFeature.Capabilities config) {
+                public void onCapabilitiesStatusChanged(
+                        MmTelFeature.MmTelCapabilities capabilities) {
                     synchronized (mLock) {
-                        mIsSmsCapable = config.isCapable(
+                        mIsSmsCapable = capabilities.isCapable(
                                 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS);
                     }
                 }
diff --git a/src/java/com/android/internal/telephony/LocaleTracker.java b/src/java/com/android/internal/telephony/LocaleTracker.java
index b69bae2..cc1993f 100755
--- a/src/java/com/android/internal/telephony/LocaleTracker.java
+++ b/src/java/com/android/internal/telephony/LocaleTracker.java
@@ -138,7 +138,7 @@
     public void handleMessage(Message msg) {
         switch (msg.what) {
             case EVENT_REQUEST_CELL_INFO:
-                mPhone.getAllCellInfo(null, obtainMessage(EVENT_RESPONSE_CELL_INFO));
+                mPhone.requestCellInfoUpdate(null, obtainMessage(EVENT_RESPONSE_CELL_INFO));
                 break;
 
             case EVENT_UNSOL_CELL_INFO:
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 048fd5d..d9792f2 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -605,7 +605,7 @@
     public boolean supportsConversionOfCdmaCallerIdMmiCodesWhileRoaming() {
         CarrierConfigManager configManager = (CarrierConfigManager)
                 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        PersistableBundle b = configManager.getConfig();
+        PersistableBundle b = configManager.getConfigForSubId(getSubId());
         if (b != null) {
             return b.getBoolean(
                     CarrierConfigManager
@@ -1723,7 +1723,7 @@
      * @param workSource calling WorkSource
      * @param rspMsg the response message containing the cell info
      */
-    public void getAllCellInfo(WorkSource workSource, Message rspMsg) {
+    public void requestCellInfoUpdate(WorkSource workSource, Message rspMsg) {
         getServiceStateTracker().requestAllCellInfo(workSource, rspMsg);
     }
 
@@ -3278,6 +3278,20 @@
     }
 
     /**
+     * @return true if the IMS capability for the registration technology specified is available,
+     * false otherwise.
+     */
+    public boolean isImsCapabilityAvailable(int capability, int regTech) {
+        Phone imsPhone = mImsPhone;
+        boolean isAvailable = false;
+        if (imsPhone != null) {
+            isAvailable = imsPhone.isImsCapabilityAvailable(capability, regTech);
+        }
+        Rlog.d(LOG_TAG, "isImsRegistered =" + isAvailable);
+        return isAvailable;
+    }
+
+    /**
      * Get Volte Feature Availability
      */
     public boolean isVolteEnabled() {
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index cc3e207..2230d33 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -3646,7 +3646,7 @@
         CarrierConfigManager configManager = (CarrierConfigManager)
                 context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         if (configManager != null) {
-            PersistableBundle bundle = configManager.getConfig();
+            PersistableBundle bundle = configManager.getConfigForSubId(mPhone.getSubId());
             if (bundle != null) {
                 boolean disableVoiceBarringNotification = bundle.getBoolean(
                         CarrierConfigManager.KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL, false);
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index 1ee96a8..1287aa7 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -122,6 +122,13 @@
 
     public SubscriptionInfoUpdater(
             Looper looper, Context context, Phone[] phone, CommandsInterface[] ci) {
+        this(looper, context, phone, ci,
+                IPackageManager.Stub.asInterface(ServiceManager.getService("package")));
+    }
+
+    @VisibleForTesting public SubscriptionInfoUpdater(
+            Looper looper, Context context, Phone[] phone,
+            CommandsInterface[] ci, IPackageManager packageMgr) {
         super(looper);
         logd("Constructor invoked");
 
@@ -129,7 +136,7 @@
         mPhone = phone;
         mSubscriptionManager = SubscriptionManager.from(mContext);
         mEuiccManager = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE);
-        mPackageManager = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+        mPackageManager = packageMgr;
 
         mCarrierServiceBindHelper = new CarrierServiceBindHelper(mContext);
         initializeCarrierApps();
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index 31abc53..6641008 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -97,8 +97,8 @@
         return new CarrierActionAgent(phone);
     }
 
-    public CarrierIdentifier makeCarrierIdentifier(Phone phone) {
-        return new CarrierIdentifier(phone);
+    public CarrierResolver makeCarrierResolver(Phone phone) {
+        return new CarrierResolver(phone);
     }
 
     public IccPhoneBookInterfaceManager makeIccPhoneBookInterfaceManager(Phone phone) {
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 25dcb6a..621b8bb 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -2132,7 +2132,7 @@
         CarrierConfigManager configManager = (CarrierConfigManager)
                 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
         if (configManager != null) {
-            PersistableBundle bundle = configManager.getConfig();
+            PersistableBundle bundle = configManager.getConfigForSubId(mPhone.getSubId());
             if (bundle != null) {
                 singleDcRats = bundle.getIntArray(
                         CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY);
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index dc8c126..ea5f671 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -1620,6 +1620,11 @@
     }
 
     @Override
+    public boolean isImsCapabilityAvailable(int capability, int regTech) {
+        return mCT.isImsCapabilityAvailable(capability, regTech);
+    }
+
+    @Override
     public boolean isVolteEnabled() {
         return mCT.isVolteEnabled();
     }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 99847ad..9039629 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -55,6 +55,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsMmTelManager;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.telephony.ims.ImsSuppServiceNotification;
@@ -302,6 +303,8 @@
         HOLDING_TO_ANSWER_INCOMING,
         // Pending resuming the foreground call after some kind of failure
         PENDING_RESUME_FOREGROUND_AFTER_FAILURE,
+        // Pending holding a call to dial another outgoing call
+        HOLDING_TO_DIAL_OUTGOING,
     }
 
     //***** Instance Variables
@@ -966,7 +969,7 @@
             // Cache the video state for pending MO call.
             mPendingCallVideoState = videoState;
             mPendingIntentExtras = dialArgs.intentExtras;
-            holdActiveCall();
+            holdActiveCallForPendingMo();
         }
 
         ImsPhoneCall.State fgState = ImsPhoneCall.State.IDLE;
@@ -1334,6 +1337,28 @@
         }
     }
 
+    private void holdActiveCallForPendingMo() throws CallStateException {
+        if (mHoldSwitchingState == HoldSwapState.PENDING_SINGLE_CALL_HOLD
+                || mHoldSwitchingState == HoldSwapState.SWAPPING_ACTIVE_AND_HELD) {
+            logi("Ignoring hold request while already holding or swapping");
+            return;
+        }
+        ImsCall callToHold = mForegroundCall.getImsCall();
+
+        mHoldSwitchingState = HoldSwapState.HOLDING_TO_DIAL_OUTGOING;
+        logHoldSwapState("holdActiveCallForPendingMo");
+
+        mForegroundCall.switchWith(mBackgroundCall);
+        try {
+            callToHold.hold();
+            mMetrics.writeOnImsCommand(mPhone.getPhoneId(), callToHold.getSession(),
+                    ImsCommand.IMS_CMD_HOLD);
+        } catch (ImsException e) {
+            mForegroundCall.switchWith(mBackgroundCall);
+            throw new CallStateException(e.getMessage());
+        }
+    }
+
     /**
      * Holds the active call, possibly resuming the already-held background call if it exists.
      */
@@ -2390,9 +2415,6 @@
                 if (mRingingCall.getState().isRinging()) {
                     // Drop pending MO. We should address incoming call first
                     mPendingMO = null;
-                } else if (mPendingMO != null
-                        && mPendingMO.getDisconnectCause() == DisconnectCause.NOT_DISCONNECTED) {
-                    sendEmptyMessage(EVENT_DIAL_PENDINGMO);
                 }
             }
 
@@ -2437,6 +2459,19 @@
                     logHoldSwapState("onCallTerminated hold to answer case");
                     sendEmptyMessage(EVENT_RESUME_NOW_FOREGROUND_CALL);
                 }
+            } else if (mHoldSwitchingState == HoldSwapState.HOLDING_TO_DIAL_OUTGOING) {
+                // The call that we were gonna hold might've gotten terminated. If that's the case,
+                // dial mPendingMo if present.
+                if (mPendingMO == null
+                        || mPendingMO.getDisconnectCause() != DisconnectCause.NOT_DISCONNECTED) {
+                    mHoldSwitchingState = HoldSwapState.INACTIVE;
+                    logHoldSwapState("onCallTerminated hold to dial but no pendingMo");
+                }
+                if (imsCall != mPendingMO.getImsCall()) {
+                    sendEmptyMessage(EVENT_DIAL_PENDINGMO);
+                    mHoldSwitchingState = HoldSwapState.INACTIVE;
+                    logHoldSwapState("onCallTerminated hold to dial, dial pendingMo");
+                }
             }
 
             if (mShouldUpdateImsConfigOnDisconnect) {
@@ -2477,14 +2512,12 @@
                     } else if (mRingingCall.getState() == ImsPhoneCall.State.WAITING
                             && mHoldSwitchingState == HoldSwapState.HOLDING_TO_ANSWER_INCOMING) {
                         sendEmptyMessage(EVENT_ANSWER_WAITING_CALL);
+                    } else if (mPendingMO != null
+                            && mHoldSwitchingState == HoldSwapState.HOLDING_TO_DIAL_OUTGOING) {
+                        dialPendingMO();
+                        mHoldSwitchingState = HoldSwapState.INACTIVE;
+                        logHoldSwapState("onCallHeld hold to dial");
                     } else {
-                        //when multiple connections belong to background call,
-                        //only the first callback reaches here
-                        //otherwise the oldState is already HOLDING
-                        if (mPendingMO != null) {
-                            dialPendingMO();
-                        }
-
                         // In this case there will be no call resumed, so we can assume that we
                         // are done switching fg and bg calls now.
                         // This may happen if there is no BG call and we are holding a call so that
@@ -2531,6 +2564,7 @@
                         mCallExpectedToResume = null;
                     }
                 }
+                mHoldSwitchingState = HoldSwapState.INACTIVE;
                 mPhone.notifySuppServiceFailed(Phone.SuppService.HOLD);
             }
             mMetrics.writeOnImsCallHoldFailed(mPhone.getPhoneId(), imsCall.getCallSession(),
@@ -2979,8 +3013,8 @@
         }
     };
 
-    private final ImsRegistrationImplBase.Callback mImsRegistrationCallback =
-            new ImsRegistrationImplBase.Callback() {
+    private final ImsMmTelManager.RegistrationCallback mImsRegistrationCallback =
+            new ImsMmTelManager.RegistrationCallback() {
 
                 @Override
                 public void onRegistered(
@@ -3019,13 +3053,14 @@
                 }
             };
 
-    private final ImsFeature.CapabilityCallback mImsCapabilityCallback =
-            new ImsFeature.CapabilityCallback() {
+    private final ImsMmTelManager.CapabilityCallback mImsCapabilityCallback =
+            new ImsMmTelManager.CapabilityCallback() {
                 @Override
-                public void onCapabilitiesStatusChanged(ImsFeature.Capabilities config) {
-                    if (DBG) log("onCapabilitiesStatusChanged: " + config);
+                public void onCapabilitiesStatusChanged(
+                        MmTelFeature.MmTelCapabilities capabilities) {
+                    if (DBG) log("onCapabilitiesStatusChanged: " + capabilities);
                     SomeArgs args = SomeArgs.obtain();
-                    args.arg1 = config;
+                    args.arg1 = capabilities;
                     // Remove any pending updates; they're already stale, so no need to process
                     // them.
                     removeMessages(EVENT_ON_FEATURE_CAPABILITY_CHANGED);
@@ -3399,6 +3434,9 @@
             case PENDING_RESUME_FOREGROUND_AFTER_FAILURE:
                 holdSwapState = "PENDING_RESUME_FOREGROUND_AFTER_FAILURE";
                 break;
+            case HOLDING_TO_DIAL_OUTGOING:
+                holdSwapState = "HOLDING_TO_DIAL_OUTGOING";
+                break;
         }
         logi("holdSwapState set to " + holdSwapState + " at " + loc);
     }
@@ -3505,6 +3543,14 @@
         return mIsInEmergencyCall;
     }
 
+    /**
+     * @return true if the IMS capability for the specified registration technology is currently
+     * available.
+     */
+    public boolean isImsCapabilityAvailable(int capability, int regTech) {
+        return (getImsRegistrationTech() == regTech) && mMmTelCapabilities.isCapable(capability);
+    }
+
     public boolean isVolteEnabled() {
         boolean isRadioTechLte = getImsRegistrationTech()
                 == ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index b707761..85fd719 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -458,6 +458,9 @@
                 Rlog.d(LOG_TAG, "onDisconnect: no parent");
             }
             synchronized (this) {
+                if (mRttTextHandler != null) {
+                    mRttTextHandler.tearDown();
+                }
                 if (mImsCall != null) mImsCall.close();
                 mImsCall = null;
             }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsRttTextHandler.java b/src/java/com/android/internal/telephony/imsphone/ImsRttTextHandler.java
index 3f9e8a8..eff2499 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsRttTextHandler.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsRttTextHandler.java
@@ -25,6 +25,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.IOException;
+import java.nio.channels.ClosedByInterruptException;
 import java.util.concurrent.CountDownLatch;
 
 public class ImsRttTextHandler extends Handler {
@@ -79,17 +80,16 @@
                 String charsReceived;
                 try {
                     charsReceived = mReaderThreadRttTextStream.read();
+                } catch (ClosedByInterruptException e) {
+                    Rlog.i(LOG_TAG, "RttReaderThread - Thread interrupted. Finishing.");
+                    break;
                 } catch (IOException e) {
                     Rlog.e(LOG_TAG, "RttReaderThread - IOException encountered " +
-                            "reading from in-call: %s", e);
+                            "reading from in-call: ", e);
                     obtainMessage(TEARDOWN).sendToTarget();
                     break;
                 }
                 if (charsReceived == null) {
-                    if (Thread.currentThread().isInterrupted()) {
-                        Rlog.i(LOG_TAG, "RttReaderThread - Thread interrupted. Finishing.");
-                        break;
-                    }
                     Rlog.e(LOG_TAG, "RttReaderThread - Stream closed unexpectedly. Attempt to " +
                             "reinitialize.");
                     obtainMessage(TEARDOWN).sendToTarget();
@@ -145,7 +145,7 @@
                 int numCodepointsBuffered = mBufferedTextToNetwork
                         .codePointCount(0, mBufferedTextToNetwork.length());
                 if (numCodepointsBuffered >= MAX_BUFFERED_CHARACTER_COUNT) {
-                    sendMessageAtFrontOfQueue(obtainMessage(ATTEMPT_SEND_TO_NETWORK));
+                    sendMessage(obtainMessage(ATTEMPT_SEND_TO_NETWORK));
                 } else {
                     sendEmptyMessageDelayed(
                             ATTEMPT_SEND_TO_NETWORK, MAX_BUFFERING_DELAY_MILLIS);
@@ -175,12 +175,13 @@
             case EXPIRE_SENT_CODEPOINT_COUNT:
                 mCodepointsAvailableForTransmission += msg.arg1;
                 if (mCodepointsAvailableForTransmission > 0) {
-                    sendMessageAtFrontOfQueue(obtainMessage(ATTEMPT_SEND_TO_NETWORK));
+                    sendMessage(obtainMessage(ATTEMPT_SEND_TO_NETWORK));
                 }
                 break;
             case TEARDOWN:
                 try {
                     if (mReaderThread != null) {
+                        mReaderThread.interrupt();
                         mReaderThread.join(1000);
                     }
                 } catch (InterruptedException e) {
@@ -202,6 +203,7 @@
     }
 
     public void initialize(Connection.RttTextStream rttTextStream) {
+        Rlog.i(LOG_TAG, "Initializing: " + this);
         obtainMessage(INITIALIZE, rttTextStream).sendToTarget();
     }
 
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index 4f44f15..d1574c7 100755
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -1028,16 +1028,20 @@
                                         onCphsCompleted));
                     } else {
                         if (ar.userObj != null) {
-                            CarrierConfigManager configLoader = (CarrierConfigManager)
+                            CarrierConfigManager configManager = (CarrierConfigManager)
                                     mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-                            if (ar.exception != null && configLoader != null
-                                    && configLoader.getConfig().getBoolean(
-                                    CarrierConfigManager.KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL)) {
-                                // GsmCdmaPhone will store vm number on device
-                                // when IccVmNotSupportedException occurred
-                                AsyncResult.forMessage(((Message) ar.userObj)).exception =
-                                        new IccVmNotSupportedException(
-                                            "Update SIM voice mailbox error");
+                            if (ar.exception != null && configManager != null) {
+                                PersistableBundle b = configManager.getConfigForSubId(
+                                        SubscriptionController.getInstance().getSubIdUsingPhoneId(
+                                                mParentApp.getPhoneId()));
+                                if (b != null && b.getBoolean(
+                                        CarrierConfigManager.KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL)) {
+                                    // GsmCdmaPhone will store vm number on device
+                                    // when IccVmNotSupportedException occurred
+                                    AsyncResult.forMessage(((Message) ar.userObj)).exception =
+                                            new IccVmNotSupportedException(
+                                                    "Update SIM voice mailbox error");
+                                }
                             } else {
                                 AsyncResult.forMessage(((Message) ar.userObj))
                                     .exception = ar.exception;
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index d9abe13..76a0227 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -312,7 +312,8 @@
             // gained carrier privileges (as an indication that a matching SIM has been inserted).
             PackageInfo pInfo = packageManager.getPackageInfo(packageName,
                     PackageManager.GET_SIGNATURES
-                            | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS);
+                            | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                            | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS);
             return getCarrierPrivilegeStatus(pInfo);
         } catch (PackageManager.NameNotFoundException ex) {
             log("Package " + packageName + " not found for carrier privilege status check");
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index 94af660..da69708 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -1464,6 +1464,26 @@
     }
 
     /**
+     * Match the input certificate to any loaded carrier privileges access rules.
+     *
+     * @param cert certificate in hex string
+     * @return true if matching certificate is found. false otherwise.
+     */
+    public boolean hasCarrierPrivilegeRulesLoadedForCertHex(String cert) {
+        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
+        if (carrierPrivilegeRules != null) {
+            List<UiccAccessRule> accessRules = carrierPrivilegeRules.getAccessRules();
+            for (UiccAccessRule accessRule : accessRules) {
+                String certHexString = accessRule.getCertificateHexString();
+                if (!TextUtils.isEmpty(certHexString) && certHexString.equalsIgnoreCase(cert)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
      * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPackageNamesForIntent}.
      */
     public List<String> getCarrierPackageNamesForIntent(
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java b/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
index 07d3223..8fc6d4d 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
@@ -23,7 +23,9 @@
 import static org.mockito.Mockito.verify;
 
 import android.os.Parcel;
+import android.os.RemoteException;
 import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.feature.CapabilityChangeRequest;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
@@ -42,9 +44,29 @@
 
 @RunWith(AndroidJUnit4.class)
 public class ImsFeatureTest {
+    // Public for Mockito testing
+    public class CapabilityCallback extends IImsCapabilityCallback.Stub {
+
+        @Override
+        public void onQueryCapabilityConfiguration(int capability, int radioTech, boolean enabled)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public void onChangeCapabilityConfigurationError(int capability, int radioTech, int reason)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public void onCapabilitiesStatusChanged(int config) throws RemoteException {
+
+        }
+    }
 
     private TestImsFeature mTestImsFeature;
-    private ImsFeature.CapabilityCallback mCapabilityCallback;
+    private CapabilityCallback mCapabilityCallback;
 
     @Mock
     private IImsFeatureStatusCallback mTestStatusCallback;
@@ -55,7 +77,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mTestImsFeature = new TestImsFeature();
-        mCapabilityCallback = Mockito.spy(new ImsFeature.CapabilityCallback());
+        mCapabilityCallback = Mockito.spy(new CapabilityCallback());
         mTestImsFeature.addCapabilityCallback(mCapabilityCallback);
     }
 
@@ -183,7 +205,8 @@
         mTestImsFeature.capabilitiesStatusChanged(status);
 
         assertEquals(status.getMask(), mTestImsFeature.queryCapabilityStatus().getMask());
-        verify(mCapabilityCallback).onCapabilitiesStatusChanged(eq(status));
+        verify(mCapabilityCallback).onCapabilitiesStatusChanged(
+                eq(TestImsFeature.CAPABILITY_TEST_1 | TestImsFeature.CAPABILITY_TEST_2));
     }
 
     @SmallTest
diff --git a/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
index 6be2fb0..79b9d60 100644
--- a/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
@@ -30,8 +30,8 @@
 import android.os.Messenger;
 import android.support.test.runner.AndroidJUnit4;
 import android.telecom.TelecomManager;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsMmTelFeature;
-import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsCallSessionImplBase;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -49,6 +49,26 @@
 @RunWith(AndroidJUnit4.class)
 public class MmTelFeatureTests extends ImsTestBase {
 
+    // Public for Mockito testing
+    public class CapabilityCallback extends IImsCapabilityCallback.Stub {
+
+        @Override
+        public void onQueryCapabilityConfiguration(int capability, int radioTech, boolean enabled) {
+
+        }
+
+        @Override
+        public void onChangeCapabilityConfigurationError(int capability, int radioTech,
+                int reason) {
+
+        }
+
+        @Override
+        public void onCapabilitiesStatusChanged(int config) {
+
+        }
+    }
+
     private static final int TEST_CAPABILITY = 1;
     private static final int TEST_RADIO_TECH = 0;
 
@@ -60,7 +80,7 @@
 
     private android.telephony.ims.TestMmTelFeature mFeature;
     private IImsMmTelFeature mFeatureBinder;
-    private ImsFeature.CapabilityCallback mCapabilityCallback;
+    private CapabilityCallback mCapabilityCallback;
     private MmTelFeature.Listener mListener;
 
     // set to true when the handler receives a message back from the Feature.
@@ -92,7 +112,7 @@
         super.setUp();
         mFeature = new TestMmTelFeature();
         mFeatureBinder = mFeature.getBinder();
-        mCapabilityCallback = spy(new ImsFeature.CapabilityCallback());
+        mCapabilityCallback = spy(new CapabilityCallback());
         mListener = spy(new MmTelFeature.Listener());
         mFeatureBinder.setListener(mListener);
         mHandlerResults = new boolean[TEST_RESULT_MAX];
diff --git a/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java b/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
index 6414403..fc1d670 100644
--- a/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
+++ b/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
@@ -16,6 +16,7 @@
 
 package android.telephony.ims;
 
+import android.os.Bundle;
 import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.ims.feature.CapabilityChangeRequest;
@@ -50,8 +51,8 @@
         }
     }
 
-    public void incomingCall(ImsCallSessionImplBase c) throws RemoteException {
-        notifyIncomingCall(c, null);
+    public void incomingCall(ImsCallSessionImplBase c) {
+        notifyIncomingCall(c, new Bundle());
     }
 
     @Override
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
index 54a56df..59c36bb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
@@ -87,15 +87,18 @@
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_MissingApp() throws Exception {
         Mockito.when(mPackageManager.getApplicationInfo("com.example.missing.app",
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(null);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(null);
         ArraySet<String> systemCarrierAppsDisabledUntilUsed = new ArraySet<>();
         systemCarrierAppsDisabledUntilUsed.add("com.example.missing.app");
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID,
                 systemCarrierAppsDisabledUntilUsed, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppHiddenUntilInstalled(
+                Mockito.anyString(), Mockito.anyBoolean());
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(Mockito.any(String[].class),
                         Mockito.anyInt());
@@ -107,12 +110,15 @@
     public void testDisableCarrierAppsUntilPrivileged_NonSystemApp() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppHiddenUntilInstalled(
+                Mockito.anyString(), Mockito.anyBoolean());
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
@@ -128,17 +134,20 @@
             throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
@@ -148,37 +157,43 @@
     public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_Disabled() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
-    /** Configured app has privileges, and is already enabled - should only grant permissions. */
+    /** Configured app has privileges, and is already installed - should only grant permissions. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_Enabled() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
@@ -188,23 +203,27 @@
     public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_UpdatedApp() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP
+                | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
     /**
-     * Configured app has privileges, and is in the default state - should enable. Associated app
+     * Configured app has privileges, and is in the default state - should install. Associated app
      * is missing and should not be touched.
      */
     @Test @SmallTest
@@ -212,28 +231,29 @@
             throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, USER_ID))
                 .thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
-                PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
-                PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                CARRIER_APP, true, USER_ID);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                ASSOCIATED_APP, true, USER_ID);
         Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
     /**
      * Configured app has privileges, and is in the default state along with associated app - should
-     * enable both.
+     * install both.
      */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_Associated_Default()
@@ -243,34 +263,38 @@
                 mContentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 1, USER_ID);
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, USER_ID))
                 .thenReturn(appInfo);
         ApplicationInfo associatedAppInfo = new ApplicationInfo();
         associatedAppInfo.packageName = ASSOCIATED_APP;
         associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
         associatedAppInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, USER_ID))
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
-                PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
-                PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                ASSOCIATED_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                CARRIER_APP, true, USER_ID);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                ASSOCIATED_APP, true, USER_ID);
         Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
     /**
-     * Configured app has privileges, and is disabled until used - should enable. Associated app has
+     * Configured app has privileges, and is uninstalled - should install. Associated app has
      * been updated and should not be touched.
      */
     @Test @SmallTest
@@ -278,10 +302,12 @@
             throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         ApplicationInfo associatedAppInfo = new ApplicationInfo();
         associatedAppInfo.packageName = ASSOCIATED_APP;
         associatedAppInfo.flags |=
@@ -289,53 +315,61 @@
         associatedAppInfo.enabledSetting =
                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
         Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, USER_ID))
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
-                PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
-                PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppHiddenUntilInstalled(
+                ASSOCIATED_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                CARRIER_APP, true, USER_ID);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                ASSOCIATED_APP, true, USER_ID);
         Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
     /**
-     * Configured app has privileges, and is disabled until used along with associated app - should
-     * enable both.
+     * Configured app has privileges, and is uninstalled until used along with associated app -
+     * should install both.
      */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_Associated_DisabledUntilUsed()
             throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         ApplicationInfo associatedAppInfo = new ApplicationInfo();
         associatedAppInfo.packageName = ASSOCIATED_APP;
         associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
         associatedAppInfo.enabledSetting =
                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
         Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, USER_ID))
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
-                PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
-                PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                ASSOCIATED_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                CARRIER_APP, true, USER_ID);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                ASSOCIATED_APP, true, USER_ID);
         Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
@@ -345,17 +379,20 @@
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_DisabledUser() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
@@ -367,98 +404,113 @@
             throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
 
-    /** Configured app has no privileges, and was disabled - should do nothing. */
+    /** Configured app has no privileges, and was uninstalled - should do nothing. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Disabled() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
 
-    /** Telephony is not initialized, and app was disabled - should do nothing. */
+    /** Telephony is not initialized, and app was uninstalled - should do nothing. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NullPrivileges_Disabled() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
 
-    /** Configured app has no privileges, and is explicitly enabled - should do nothing. */
+    /** Configured app has no privileges, and is explicitly installed - should do nothing. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Enabled() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
 
-    /** Telephony is not initialized, and app is explicitly enabled - should do nothing. */
+    /** Telephony is not initialized, and app is explicitly installed - should do nothing. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NullPrivileges_Enabled() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
@@ -469,17 +521,21 @@
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_UpdatedApp() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP
+                | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
@@ -490,51 +546,60 @@
     public void testDisableCarrierAppsUntilPrivileged_NullPrivileges_UpdatedApp() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+        appInfo.flags |= (ApplicationInfo.FLAG_SYSTEM
+                | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP | ApplicationInfo.FLAG_INSTALLED);
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
 
     /**
-     * Configured app has no privileges, and is in the default state - should disable until use.
-     * Associated app is enabled and should not be touched.
+     * Configured app has no privileges, and is in the default state - should uninstalled.
+     * Associated app is installed and should not be touched.
      */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_EnabledAssociated_Default()
             throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         ApplicationInfo associatedAppInfo = new ApplicationInfo();
         associatedAppInfo.packageName = ASSOCIATED_APP;
         associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
         associatedAppInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
         Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, USER_ID))
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0, USER_ID,
-                CALLING_PACKAGE);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0,
-                USER_ID, CALLING_PACKAGE);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                ASSOCIATED_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                CARRIER_APP, false, USER_ID);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                ASSOCIATED_APP, false, USER_ID);
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
@@ -542,34 +607,39 @@
 
     /**
      * Configured app has no privileges, and is in the default state along with associated app -
-     * should disable both.
+     * should uninstall both.
      */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Associated_Default()
             throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         ApplicationInfo associatedAppInfo = new ApplicationInfo();
         associatedAppInfo.packageName = ASSOCIATED_APP;
-        associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         associatedAppInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, USER_ID))
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0, USER_ID,
-                CALLING_PACKAGE);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0,
-                USER_ID, CALLING_PACKAGE);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                ASSOCIATED_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                CARRIER_APP, false, USER_ID);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                ASSOCIATED_APP, false, USER_ID);
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
@@ -577,7 +647,7 @@
 
     /**
      * Configured app has no privileges, and is in the default state along with associated app, and
-     * disabling has already occurred - should only disable configured app.
+     * disabling has already occurred - should only uninstall configured app.
      */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Associated_Default_AlreadyRun()
@@ -586,90 +656,108 @@
                 mContentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 1, USER_ID);
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         ApplicationInfo associatedAppInfo = new ApplicationInfo();
         associatedAppInfo.packageName = ASSOCIATED_APP;
         associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
         associatedAppInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, USER_ID))
                 .thenReturn(associatedAppInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0, USER_ID,
-                CALLING_PACKAGE);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.eq(ASSOCIATED_APP), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                ASSOCIATED_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                CARRIER_APP, false, USER_ID);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.eq(ASSOCIATED_APP), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
 
-    /** Telephony is not initialized, and app is in the default state - should disable until use. */
+    /** Telephony is not initialized, and app is in the default state - should uninstall it. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NullPrivileges_Default() throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager).setApplicationEnabledSetting(
-                CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0, USER_ID,
-                CALLING_PACKAGE);
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager).setSystemAppInstallState(
+                CARRIER_APP, false, USER_ID);
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
 
-    /** Configured app has no privileges, and is disabled until used - should do nothing. */
+    /** Configured app has no privileges, and is disabled until used or not installed - should do
+     *  nothing.
+     **/
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_DisabledUntilUsed()
             throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
 
-    /** Telephony is not initialized, and app is disabled until used - should do nothing. */
+    /** Telephony is not initialized, and app is disabled until used or not installed - should do
+     *  nothing.
+     **/
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_NullPrivileges_DisabledUntilUsed()
             throws Exception {
         ApplicationInfo appInfo = new ApplicationInfo();
         appInfo.packageName = CARRIER_APP;
-        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
         Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
-                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
+                USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
                 null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
                 ASSOCIATED_APPS);
-        Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
-                Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
-                Mockito.anyString());
+        Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
+                CARRIER_APP, true);
+        Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
+                Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
         Mockito.verify(mPackageManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierIdentifierTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java
similarity index 62%
rename from tests/telephonytests/src/com/android/internal/telephony/CarrierIdentifierTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java
index 6ce6d20..fb1cb47 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierIdentifierTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java
@@ -28,6 +28,7 @@
 import android.os.HandlerThread;
 import android.provider.Telephony.CarrierId;
 import android.provider.Telephony.Carriers;
+import android.service.carrier.CarrierIdentifier;
 import android.test.mock.MockContentProvider;
 import android.test.mock.MockContentResolver;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -38,11 +39,16 @@
 
 import java.util.Arrays;
 
-public class CarrierIdentifierTest extends TelephonyTest {
+public class CarrierResolverTest extends TelephonyTest {
     private static final String MCCMNC = "311480";
     private static final String NAME = "VZW";
     private static final int CID_VZW = 1;
 
+    private static final String MCCMNC_VODAFONE = "20205";
+    private static final String NAME_VODAFONE = "VODAFONE";
+    private static final String SPN_VODAFONE = "vodafone GR";
+    private static final int CID_VODAFONE = 5;
+
     private static final String SPN_FI = "PROJECT FI";
     private static final String NAME_FI = "FI";
     private static final int CID_FI = 2;
@@ -60,43 +66,44 @@
     // events to trigger carrier identification
     private static final int SIM_LOAD_EVENT       = 1;
     private static final int SIM_ABSENT_EVENT     = 2;
-    private static final int SPN_OVERRIDE_EVENT   = 3;
-    private static final int PREFER_APN_SET_EVENT = 5;
+    private static final int ICC_CHANGED_EVENT    = 3;
+    private static final int PREFER_APN_SET_EVENT = 4;
 
-    private CarrierIdentifier mCarrierIdentifier;
-    private CarrierIdentifierHandler mCarrierIdentifierHandler;
+    private CarrierResolver mCarrierResolver;
+    private CarrierResolverHandler mCarrierCarrierResolverHandler;
 
-    private class CarrierIdentifierHandler extends HandlerThread {
-        private CarrierIdentifierHandler(String name) {
+    private class CarrierResolverHandler extends HandlerThread {
+        private CarrierResolverHandler(String name) {
             super(name);
         }
 
         @Override
         public void onLooperPrepared() {
-            mCarrierIdentifier = new CarrierIdentifier(mPhone);
+            mCarrierResolver = new CarrierResolver(mPhone);
             setReady(true);
         }
     }
 
     @Before
     public void setUp() throws Exception {
-        logd("CarrierIdentifierTest +Setup!");
+        logd("CarrierResolverTest +Setup!");
         super.setUp(getClass().getSimpleName());
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 CarrierId.AUTHORITY, new CarrierIdContentProvider());
         // start handler thread
-        mCarrierIdentifierHandler = new CarrierIdentifierHandler(getClass().getSimpleName());
-        mCarrierIdentifierHandler.start();
+        mCarrierCarrierResolverHandler = new CarrierResolverHandler(getClass().getSimpleName());
+        mCarrierCarrierResolverHandler.start();
         waitUntilReady();
-        logd("CarrierIdentifierTest -Setup!");
+        mCarrierResolver.sendEmptyMessage(ICC_CHANGED_EVENT);
+        logd("CarrierResolverTest -Setup!");
     }
 
     @After
     public void tearDown() throws Exception {
-        logd("CarrierIdentifier -tearDown");
-        mCarrierIdentifier.removeCallbacksAndMessages(null);
-        mCarrierIdentifier = null;
-        mCarrierIdentifierHandler.quit();
+        logd("CarrierResolver -tearDown");
+        mCarrierResolver.removeCallbacksAndMessages(null);
+        mCarrierResolver = null;
+        mCarrierCarrierResolverHandler.quit();
         super.tearDown();
     }
 
@@ -106,40 +113,46 @@
         int phoneId = mPhone.getPhoneId();
         doReturn(MCCMNC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(phoneId));
         // trigger sim loading event
-        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
+        mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
-        assertEquals(CID_VZW, mCarrierIdentifier.getCarrierId());
-        assertEquals(NAME, mCarrierIdentifier.getCarrierName());
+        assertEquals(CID_VZW, mCarrierResolver.getCarrierId());
+        assertEquals(NAME, mCarrierResolver.getCarrierName());
 
-        doReturn(SPN_FI).when(mTelephonyManager).getSimOperatorNameForPhone(eq(phoneId));
-        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
+        doReturn(SPN_FI).when(mSimRecords).getServiceProviderName();
+        mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
-        assertEquals(CID_FI, mCarrierIdentifier.getCarrierId());
-        assertEquals(NAME_FI, mCarrierIdentifier.getCarrierName());
+        assertEquals(CID_FI, mCarrierResolver.getCarrierId());
+        assertEquals(NAME_FI, mCarrierResolver.getCarrierName());
 
         doReturn(GID1).when(mPhone).getGroupIdLevel1();
-        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
+        mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
-        assertEquals(CID_TMO, mCarrierIdentifier.getCarrierId());
-        assertEquals(NAME_TMO, mCarrierIdentifier.getCarrierName());
+        assertEquals(CID_TMO, mCarrierResolver.getCarrierId());
+        assertEquals(NAME_TMO, mCarrierResolver.getCarrierName());
     }
 
     @Test
     @SmallTest
-    public void testCarrierMatchSpnOverride() {
+    public void testMnoCarrierId() {
         int phoneId = mPhone.getPhoneId();
         doReturn(MCCMNC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(phoneId));
-        // trigger sim loading event
-        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
+        doReturn(SPN_FI).when(mSimRecords).getServiceProviderName();
+
+        mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
-        assertEquals(CID_VZW, mCarrierIdentifier.getCarrierId());
-        assertEquals(NAME, mCarrierIdentifier.getCarrierName());
-        // spn override
-        doReturn(SPN_FI).when(mTelephonyManager).getSimOperatorNameForPhone(eq(phoneId));
-        mCarrierIdentifier.sendEmptyMessage(SPN_OVERRIDE_EVENT);
+
+        assertEquals(CID_FI, mCarrierResolver.getCarrierId());
+        assertEquals(NAME_FI, mCarrierResolver.getCarrierName());
+        assertEquals(CID_VZW, mCarrierResolver.getMnoCarrierId());
+
+        doReturn(MCCMNC_VODAFONE).when(mTelephonyManager)
+                .getSimOperatorNumericForPhone(eq(phoneId));
+        doReturn(SPN_VODAFONE).when(mSimRecords).getServiceProviderName();
+        mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
-        assertEquals(CID_FI, mCarrierIdentifier.getCarrierId());
-        assertEquals(NAME_FI, mCarrierIdentifier.getCarrierName());
+        assertEquals(CID_VODAFONE, mCarrierResolver.getCarrierId());
+        assertEquals(NAME_VODAFONE, mCarrierResolver.getCarrierName());
+        assertEquals(CID_VODAFONE, mCarrierResolver.getMnoCarrierId());
     }
 
     @Test
@@ -148,15 +161,15 @@
         int phoneId = mPhone.getPhoneId();
         doReturn(MCCMNC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(phoneId));
         // trigger sim loading event
-        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
+        mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
-        assertEquals(CID_VZW, mCarrierIdentifier.getCarrierId());
-        assertEquals(NAME, mCarrierIdentifier.getCarrierName());
+        assertEquals(CID_VZW, mCarrierResolver.getCarrierId());
+        assertEquals(NAME, mCarrierResolver.getCarrierName());
         // trigger sim absent event
-        mCarrierIdentifier.sendEmptyMessage(SIM_ABSENT_EVENT);
+        mCarrierResolver.sendEmptyMessage(SIM_ABSENT_EVENT);
         waitForMs(200);
-        assertEquals(CID_UNKNOWN, mCarrierIdentifier.getCarrierId());
-        assertNull(mCarrierIdentifier.getCarrierName());
+        assertEquals(CID_UNKNOWN, mCarrierResolver.getCarrierId());
+        assertNull(mCarrierResolver.getCarrierName());
     }
 
     @Test
@@ -166,10 +179,32 @@
         int phoneId = mPhone.getPhoneId();
         doReturn("12345").when(mTelephonyManager).getSimOperatorNumericForPhone(eq(phoneId));
         // trigger sim loading event
-        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
+        mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
-        assertEquals(CID_UNKNOWN, mCarrierIdentifier.getCarrierId());
-        assertNull(mCarrierIdentifier.getCarrierName());
+        assertEquals(CID_UNKNOWN, mCarrierResolver.getCarrierId());
+        assertNull(mCarrierResolver.getCarrierName());
+    }
+
+    @Test
+    @SmallTest
+    public void testGetCarrierIdFromIdentifier() {
+        // trigger sim loading event
+        mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
+        waitForMs(200);
+
+        CarrierIdentifier identifier = new CarrierIdentifier(null, null, null, null, null, null);
+        int carrierid = mCarrierResolver.getCarrierIdFromIdentifier(identifier);
+        assertEquals(CID_UNKNOWN, carrierid);
+
+        identifier = new CarrierIdentifier(MCCMNC.substring(0, 3), MCCMNC.substring(3), null, null,
+                null, null);
+        carrierid = mCarrierResolver.getCarrierIdFromIdentifier(identifier);
+        assertEquals(CID_VZW, carrierid);
+
+        identifier = new CarrierIdentifier(MCCMNC.substring(0, 3), MCCMNC.substring(3),  SPN_FI, null,
+                null, null);
+        carrierid = mCarrierResolver.getCarrierIdFromIdentifier(identifier);
+        assertEquals(CID_FI, carrierid);
     }
 
     @Test
@@ -178,17 +213,17 @@
         int phoneId = mPhone.getPhoneId();
         doReturn(MCCMNC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(phoneId));
         // trigger sim loading event
-        mCarrierIdentifier.sendEmptyMessage(SIM_LOAD_EVENT);
+        mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
-        assertEquals(CID_VZW, mCarrierIdentifier.getCarrierId());
-        assertEquals(NAME, mCarrierIdentifier.getCarrierName());
+        assertEquals(CID_VZW, mCarrierResolver.getCarrierId());
+        assertEquals(NAME, mCarrierResolver.getCarrierName());
         // mock apn
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 Carriers.CONTENT_URI.getAuthority(), new CarrierIdContentProvider());
-        mCarrierIdentifier.sendEmptyMessage(PREFER_APN_SET_EVENT);
+        mCarrierResolver.sendEmptyMessage(PREFER_APN_SET_EVENT);
         waitForMs(200);
-        assertEquals(CID_DOCOMO, mCarrierIdentifier.getCarrierId());
-        assertEquals(NAME_DOCOMO, mCarrierIdentifier.getCarrierName());
+        assertEquals(CID_DOCOMO, mCarrierResolver.getCarrierId());
+        assertEquals(NAME_DOCOMO, mCarrierResolver.getCarrierName());
     }
 
     private class CarrierIdContentProvider extends MockContentProvider {
@@ -212,6 +247,7 @@
                                 CarrierId.All.PLMN,
                                 CarrierId.All.IMSI_PREFIX_XPATTERN,
                                 CarrierId.All.ICCID_PREFIX,
+                                CarrierId.All.PRIVILEGE_ACCESS_RULE,
                                 CarrierId.All.SPN,
                                 CarrierId.All.APN,
                                 CarrierId.CARRIER_NAME,
@@ -225,6 +261,7 @@
                         null,                   // plmn
                         null,                   // imsi_prefix
                         null,                   // iccid_prefix
+                        null,                   // access rule
                         null,                   // spn
                         null,                   // apn
                         NAME,                   // carrier name
@@ -238,6 +275,7 @@
                         null,                   // plmn
                         null,                   // imsi_prefix
                         null,                   // iccid_prefix
+                        null,                   // access_rule
                         null,                   // spn
                         null,                   // apn
                         NAME_TMO,               // carrier name
@@ -251,6 +289,7 @@
                         null,                   // plmn
                         null,                   // imsi_prefix
                         null,                   // iccid_prefix
+                        null,                   // access_rule
                         SPN_FI,                 // spn
                         null,                   // apn
                         NAME_FI,                // carrier name
@@ -264,11 +303,26 @@
                         null,                   // plmn
                         null,                   // imsi_prefix
                         null,                   // iccid_prefix
+                        null,                   // access_rule
                         null,                   // spn
                         APN_DOCOMO,             // apn
                         NAME_DOCOMO,            // carrier name
                         CID_DOCOMO,             // cid
                 });
+                mc.addRow(new Object[] {
+                        4,                      // id
+                        MCCMNC_VODAFONE,        // mccmnc
+                        null,                   // gid1
+                        null,                   // gid2
+                        null,                   // plmn
+                        null,                   // imsi_prefix
+                        null,                   // iccid_prefix
+                        null,                   // access_rule
+                        SPN_VODAFONE,           // spn
+                        null,                   // apn
+                        NAME_VODAFONE,          // carrier name
+                        CID_VODAFONE,           // cid
+                });
                 return mc;
             } else if (Carriers.CONTENT_URI.getAuthority().equals(uri.getAuthority())) {
                 MatrixCursor mc = new MatrixCursor(new String[]{Carriers._ID, Carriers.APN});
diff --git a/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
index f4a3311..23e0450 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
@@ -89,7 +89,7 @@
             Message m = invocation.getArgument(1);
             AsyncResult.forMessage(m, Arrays.asList(mCellInfo), null);
             m.sendToTarget();
-            return null; }).when(mPhone).getAllCellInfo(any(), any());
+            return null; }).when(mPhone).requestCellInfoUpdate(any(), any());
 
         logd("LocaleTrackerTest -Setup!");
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
index 4466378..60bbff9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
@@ -36,6 +36,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.IPackageManager;
 import android.content.pm.UserInfo;
 import android.net.Uri;
 import android.os.HandlerThread;
@@ -90,6 +91,8 @@
     private EuiccController mEuiccController;
     @Mock
     private IntentBroadcaster mIntentBroadcaster;
+    @Mock
+    private IPackageManager mPackageManager;
 
     /*Custom ContentProvider */
     private class FakeSubscriptionContentProvider extends MockContentProvider {
@@ -108,7 +111,7 @@
         @Override
         public void onLooperPrepared() {
             mUpdater = new SubscriptionInfoUpdater(getLooper(), mContext, new Phone[]{mPhone},
-                    new CommandsInterface[]{mSimulatedCommands});
+                    new CommandsInterface[]{mSimulatedCommands}, mPackageManager);
             setReady(true);
         }
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTest.java b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTest.java
index 694d610..5e4cc44 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTest.java
@@ -29,23 +29,26 @@
         EmergencyNumber number = new EmergencyNumber(
                 "911",
                 "us",
-                // EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED
-                0,
-                // EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALLING
-                1);
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
         assertEquals(number.getNumber(), "911");
         assertEquals(number.getCountryIso(), "us");
         assertTrue(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE));
-        assertFalse(number.isInEmergencyServiceCategories(
+        assertTrue(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
+        assertTrue(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE));
+        assertTrue(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE));
+        assertTrue(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD));
-        assertFalse(number.isInEmergencyServiceCategories(
+        assertTrue(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC));
+        assertTrue(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC));
+        assertTrue(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC));
         assertEquals(0, number.getEmergencyServiceCategoryBitmask());
 
         List<Integer> categories = number.getEmergencyServiceCategories();
@@ -57,7 +60,8 @@
         assertFalse(number.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM));
         assertFalse(number.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG));
         assertFalse(number.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT));
-        assertEquals(1, number.getEmergencyNumberSourceBitmask());
+        assertEquals(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                number.getEmergencyNumberSourceBitmask());
 
         List<Integer> sources = number.getEmergencyNumberSources();
         assertEquals(1, sources.size());
@@ -69,24 +73,27 @@
         EmergencyNumber number = new EmergencyNumber(
                 "911",
                 "us",
-                // EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD
-                8,
-                // EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALLING
-                // EMERGENCY_NUMBER_SOURCE_MODEM
-                5);
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING
+                        | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG);
         assertEquals(number.getNumber(), "911");
         assertEquals(number.getCountryIso(), "us");
         assertFalse(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE));
+        assertFalse(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
+        assertFalse(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE));
+        assertFalse(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE));
         assertTrue(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD));
         assertFalse(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC));
+        assertFalse(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC));
+        assertFalse(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC));
         assertEquals(8, number.getEmergencyServiceCategoryBitmask());
 
         List<Integer> categories = number.getEmergencyServiceCategories();
@@ -98,7 +105,9 @@
         assertFalse(number.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM));
         assertTrue(number.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG));
         assertFalse(number.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT));
-        assertEquals(5, number.getEmergencyNumberSourceBitmask());
+        assertEquals(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG,
+                number.getEmergencyNumberSourceBitmask());
 
         List<Integer> sources = number.getEmergencyNumberSources();
         assertEquals(2, sources.size());
@@ -114,28 +123,34 @@
         EmergencyNumber number = new EmergencyNumber(
                 "110",
                 "jp",
-                // EMERGENCY_SERVICE_CATEGORY_POLICE
-                // EMERGENCY_SERVICE_CATEGORY_AMBULANCE
-                // EMERGENCY_SERVICE_CATEGORY_MIEC
-                35,
-                // EMERGENCY_NUMBER_SOURCE_NETWORK_SINGALING
-                // EMERGENCY_NUMBER_SOURCE_SIM
-                // EMERGENCY_NUMBER_SOURCE_DEFAULT
-                11);
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
+                        | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
+                        | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING
+                        | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM
+                        | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT);
         assertEquals(number.getNumber(), "110");
         assertEquals(number.getCountryIso(), "jp");
         assertFalse(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED));
-        assertTrue(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
-        assertTrue(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE));
+        assertTrue(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
+        assertTrue(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE));
+        assertFalse(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE));
         assertFalse(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD));
         assertFalse(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE));
-        assertTrue(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC));
-        assertFalse(number.isInEmergencyServiceCategories(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC));
-        assertEquals(35, number.getEmergencyServiceCategoryBitmask());
+        assertTrue(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC));
+        assertFalse(number.isInEmergencyServiceCategories(
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC));
+        assertEquals(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
+                | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
+                | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC,
+                number.getEmergencyServiceCategoryBitmask());
 
         List<Integer> categories = number.getEmergencyServiceCategories();
         assertEquals(3, categories.size());
@@ -151,7 +166,10 @@
         assertTrue(number.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM));
         assertFalse(number.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG));
         assertTrue(number.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT));
-        assertEquals(11, number.getEmergencyNumberSourceBitmask());
+        assertEquals(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT,
+                number.getEmergencyNumberSourceBitmask());
 
         List<Integer> sources = number.getEmergencyNumberSources();
         assertEquals(3, sources.size());
@@ -163,4 +181,34 @@
         Collections.sort(sourcesToVerify);
         assertTrue(sourcesToVerify.equals(sources));
     }
+
+    public void testEmergencyNumberDisplayPriority() throws Exception {
+        EmergencyNumber numberHighestDisplayPriority = new EmergencyNumber(
+                "911",
+                "us",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
+
+        EmergencyNumber numberHigherDisplayPriority = new EmergencyNumber(
+                "922",
+                "us",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
+                        | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
+                        | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM);
+
+        EmergencyNumber numberLowestDisplayPriority = new EmergencyNumber(
+                "110",
+                "us",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
+                        | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
+                        | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG
+                        | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT);
+
+        assertTrue(numberHighestDisplayPriority.compareTo(
+                numberHigherDisplayPriority) < 0);
+        assertTrue(numberHigherDisplayPriority.compareTo(
+                numberLowestDisplayPriority) < 0);
+    }
 }
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 2bf0094..fbb579e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
@@ -73,7 +73,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp("SubscriptionControllerTest");
+        super.setUp("ImsManagerTest");
         mPhoneId = mPhone.getPhoneId();
         mBundle = mContextFixture.getCarrierConfigBundle();
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java
new file mode 100644
index 0000000..4bb92c9
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.ims;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Looper;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.ims.MmTelFeatureConnection;
+import com.android.internal.telephony.TelephonyTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MmTelFeatureConnectionTest extends TelephonyTest {
+
+    private class TestCallback extends Binder implements IInterface {
+
+        @Override
+        public IBinder asBinder() {
+            return this;
+        }
+    }
+
+    private class CallbackManagerTest extends
+            MmTelFeatureConnection.CallbackAdapterManager<TestCallback> {
+
+        List<TestCallback> mCallbacks = new ArrayList<>();
+
+        CallbackManagerTest(Context context, Object lock) {
+            super(context, lock);
+        }
+
+        // A callback has been registered. Register that callback with the MmTelFeature.
+        @Override
+        public boolean registerCallback(TestCallback localCallback) {
+            return mCallbacks.add(localCallback);
+        }
+
+        // A callback has been removed, unregister that callback with the MmTelFeature.
+        @Override
+        public void unregisterCallback(TestCallback localCallback) {
+            mCallbacks.remove(localCallback);
+        }
+
+        public boolean doesCallbackExist(TestCallback callback) {
+            return mCallbacks.contains(callback);
+        }
+    }
+    private CallbackManagerTest mCallbackManagerUT;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp("MmTelFeatureConnectionTest");
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        mCallbackManagerUT = new CallbackManagerTest(mContext, this);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mCallbackManagerUT = null;
+        super.tearDown();
+    }
+
+    /**
+     * Basic test of deprecated functionality, ensure that adding the callback directly triggers the
+     * appropriate registerCallback and unregisterCallback calls.
+     */
+    @Test
+    @SmallTest
+    public void testCallbackAdapter_addAndRemoveCallback() throws Exception {
+        TestCallback testCallback = new TestCallback();
+        mCallbackManagerUT.addCallback(testCallback);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback));
+        // The subscriptions changed listener should only be added for callbacks that are being
+        // linked to a subscription.
+        verify(mSubscriptionManager, never()).addOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+
+        mCallbackManagerUT.removeCallback(testCallback);
+        assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback));
+        // The subscriptions changed listener should only be removed for callbacks that are
+        // linked to a subscription.
+        verify(mSubscriptionManager, never()).removeOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+    }
+
+    /**
+     * Ensure that adding the callback and linking subId triggers the appropriate registerCallback
+     * and unregisterCallback calls as well as the subscriptionChanged listener.
+     */
+    @Test
+    @SmallTest
+    public void testCallbackAdapter_addAndRemoveCallbackForSub() throws Exception {
+        TestCallback testCallback = new TestCallback();
+        int testSub = 1;
+        mCallbackManagerUT.addCallbackForSubscription(testCallback, testSub);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback));
+        verify(mSubscriptionManager, times(1)).addOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+
+        mCallbackManagerUT.removeCallbackForSubscription(testCallback, testSub);
+        assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback));
+        verify(mSubscriptionManager, times(1)).removeOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+    }
+
+    /**
+     * Ensure that adding the callback and linking multiple subIds trigger the appropriate
+     * registerCallback and unregisterCallback calls as well as the subscriptionChanged listener.
+     * When removing the callbacks, the subscriptionChanged listener shoud only be removed when all
+     * callbacks have been removed.
+     */
+    @Test
+    @SmallTest
+    public void testCallbackAdapter_addAndRemoveCallbackForMultipleSubs() throws Exception {
+        TestCallback testCallback1 = new TestCallback();
+        TestCallback testCallback2 = new TestCallback();
+        int testSub1 = 1;
+        int testSub2 = 2;
+        mCallbackManagerUT.addCallbackForSubscription(testCallback1, testSub1);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback1));
+        mCallbackManagerUT.addCallbackForSubscription(testCallback2, testSub2);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback2));
+        // This should only happen once.
+        verify(mSubscriptionManager, times(1)).addOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+
+        mCallbackManagerUT.removeCallbackForSubscription(testCallback1, testSub1);
+        assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback1));
+        // removing the listener should not happen until the second callback is removed.
+        verify(mSubscriptionManager, never()).removeOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+
+        mCallbackManagerUT.removeCallbackForSubscription(testCallback2, testSub2);
+        assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback2));
+        verify(mSubscriptionManager, times(1)).removeOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+    }
+
+    /**
+     * The subscriptions have changed, ensure that the callbacks registered to the original
+     * subscription testSub1 are removed, while keeping the callbacks for testSub2, since it was not
+     * removed.
+     */
+    @Test
+    @SmallTest
+    public void testCallbackAdapter_onSubscriptionsChangedMultipleSubs() throws Exception {
+        TestCallback testCallback1 = new TestCallback();
+        TestCallback testCallback2 = new TestCallback();
+        int testSub1 = 1;
+        int testSub2 = 2;
+        int testSub3 = 3;
+        mCallbackManagerUT.addCallbackForSubscription(testCallback1, testSub1);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback1));
+        mCallbackManagerUT.addCallbackForSubscription(testCallback2, testSub2);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback2));
+        verify(mSubscriptionManager, times(1)).addOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+
+        // Simulate subscriptions changed, where testSub1 is no longer active
+        doReturn(createSubscriptionInfoList(new int[] {testSub2, testSub3}))
+                .when(mSubscriptionManager).getActiveSubscriptionInfoList();
+        mCallbackManagerUT.mSubChangedListener.onSubscriptionsChanged();
+        assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback1));
+        // verify that the subscription changed listener is not removed, since we still have a
+        // callback on testSub2
+        verify(mSubscriptionManager, never()).removeOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+    }
+
+    /**
+     * The active subscription has changed, ensure that the callback registered to the original
+     * subscription testSub1 are removed as well as the subscription changed listener, since
+     * there are mo more active callbacks.
+     */
+    @Test
+    @SmallTest
+    public void testCallbackAdapter_onSubscriptionsChangedOneSub() throws Exception {
+        TestCallback testCallback1 = new TestCallback();
+        int testSub1 = 1;
+        int testSub2 = 2;
+        mCallbackManagerUT.addCallbackForSubscription(testCallback1, testSub1);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback1));
+        verify(mSubscriptionManager, times(1)).addOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+
+        // Simulate subscriptions changed, where testSub1 is no longer active
+        doReturn(createSubscriptionInfoList(new int[] {testSub2}))
+                .when(mSubscriptionManager).getActiveSubscriptionInfoList();
+        mCallbackManagerUT.mSubChangedListener.onSubscriptionsChanged();
+        assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback1));
+        // verify that the subscription listener is removed, since the only active callback has been
+        // removed.
+        verify(mSubscriptionManager, times(1)).removeOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+    }
+
+    /**
+     * The close() method has been called, so al callbacks should be cleaned up and notified
+     * that they have been removed. The subscriptions changed listener should also be removed.
+     */
+    @Test
+    @SmallTest
+    public void testCallbackAdapter_closeMultipleSubs() throws Exception {
+        TestCallback testCallback1 = new TestCallback();
+        TestCallback testCallback2 = new TestCallback();
+        int testSub1 = 1;
+        int testSub2 = 2;
+        mCallbackManagerUT.addCallbackForSubscription(testCallback1, testSub1);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback1));
+        mCallbackManagerUT.addCallbackForSubscription(testCallback2, testSub2);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback2));
+        verify(mSubscriptionManager, times(1)).addOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+
+        // Close the manager, ensure all subscription callbacks are removed
+        mCallbackManagerUT.close();
+        assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback1));
+        assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback2));
+        // verify that the subscription changed listener is removed.
+        verify(mSubscriptionManager, times(1)).removeOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+    }
+
+    /**
+     * The close() method has been called, so all callbacks should be cleaned up. Since they are
+     * not associated with any subscriptions, no subscription based logic should be called.
+     */
+    @Test
+    @SmallTest
+    public void testCallbackAdapter_closeSlotBasedCallbacks() throws Exception {
+        TestCallback testCallback1 = new TestCallback();
+        TestCallback testCallback2 = new TestCallback();
+        mCallbackManagerUT.addCallback(testCallback1);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback1));
+        mCallbackManagerUT.addCallback(testCallback2);
+        assertTrue(mCallbackManagerUT.doesCallbackExist(testCallback2));
+        // verify that the subscription changed listener is never called for these callbacks
+        // because they are not associated with any subscriptions.
+        verify(mSubscriptionManager, never()).addOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+
+        // Close the manager, ensure all subscription callbacks are removed
+        mCallbackManagerUT.close();
+        assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback1));
+        assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback2));
+        // verify that the subscription changed removed method is never called
+        verify(mSubscriptionManager, never()).removeOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class));
+    }
+
+    private List<SubscriptionInfo> createSubscriptionInfoList(int[] subIds) {
+        List<SubscriptionInfo> infos = new ArrayList<>();
+        for (int i = 0; i < subIds.length; i++) {
+            SubscriptionInfo info = new SubscriptionInfo(subIds[i], null, -1, null, null, -1, -1,
+                    null, -1, null, null, null, null, false, null, null);
+            infos.add(info);
+        }
+        return infos;
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
index 759309c..6ca19a0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -52,6 +52,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsCallSession;
+import android.telephony.ims.ImsMmTelManager;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.telephony.ims.feature.ImsFeature;
@@ -84,8 +85,8 @@
     private ImsPhoneCallTracker mCTUT;
     private ImsCTHandlerThread mImsCTHandlerThread;
     private MmTelFeature.Listener mMmTelListener;
-    private ImsRegistrationImplBase.Callback mRegistrationCallback;
-    private ImsFeature.CapabilityCallback mCapabilityCallback;
+    private ImsMmTelManager.RegistrationCallback mRegistrationCallback;
+    private ImsMmTelManager.CapabilityCallback mCapabilityCallback;
     private ImsCall.Listener mImsCallListener;
     private ImsCall mImsCall;
     private ImsCall mSecondImsCall;
@@ -215,13 +216,14 @@
         doAnswer(invocation -> {
             mRegistrationCallback = invocation.getArgument(0);
             return mRegistrationCallback;
-        }).when(mImsManager).addRegistrationCallback(any(ImsRegistrationImplBase.Callback.class));
+        }).when(mImsManager).addRegistrationCallback(
+                any(android.telephony.ims.ImsMmTelManager.RegistrationCallback.class));
 
         doAnswer(invocation -> {
-            mCapabilityCallback = (ImsFeature.CapabilityCallback) invocation.getArguments()[0];
+            mCapabilityCallback = (ImsMmTelManager.CapabilityCallback) invocation.getArguments()[0];
             return mCapabilityCallback;
 
-        }).when(mImsManager).addCapabilitiesCallback(any(ImsFeature.CapabilityCallback.class));
+        }).when(mImsManager).addCapabilitiesCallback(any(ImsMmTelManager.CapabilityCallback.class));
 
         doReturn(mImsConfig).when(mImsManager).getConfigInterface();
 
@@ -282,7 +284,7 @@
         assertFalse(mCTUT.isVowifiEnabled());
 
         // enable Voice over LTE
-        ImsFeature.Capabilities caps = new ImsFeature.Capabilities();
+        MmTelFeature.MmTelCapabilities caps = new MmTelFeature.MmTelCapabilities();
         caps.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
         mCapabilityCallback.onCapabilitiesStatusChanged(caps);
         waitForHandlerAction(mCTHander, 1000);
@@ -300,7 +302,7 @@
         assertFalse(mCTUT.isVowifiEnabled());
 
         // enable Voice over IWLAN
-        ImsFeature.Capabilities caps = new ImsFeature.Capabilities();
+        MmTelFeature.MmTelCapabilities caps = new MmTelFeature.MmTelCapabilities();
         caps.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
         mCapabilityCallback.onCapabilitiesStatusChanged(caps);
         waitForHandlerAction(mCTHander, 1000);
@@ -318,7 +320,7 @@
         assertFalse(mCTUT.isVideoCallEnabled());
 
         // enable only Voice
-        ImsFeature.Capabilities caps = new ImsFeature.Capabilities();
+        MmTelFeature.MmTelCapabilities caps = new MmTelFeature.MmTelCapabilities();
         caps.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
         mCapabilityCallback.onCapabilitiesStatusChanged(caps);
         waitForHandlerAction(mCTHander, 1000);
@@ -330,7 +332,7 @@
         verify(mImsPhone, times(1)).onFeatureCapabilityChanged();
 
         // enable video call
-        ImsFeature.Capabilities capsVideo = new ImsFeature.Capabilities();
+        MmTelFeature.MmTelCapabilities capsVideo = new MmTelFeature.MmTelCapabilities();
         capsVideo.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
         capsVideo.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
         mCapabilityCallback.onCapabilitiesStatusChanged(capsVideo);