Merge "Strip trailing Fs off raw ICCID"
diff --git a/src/java/com/android/internal/telephony/CarrierResolver.java b/src/java/com/android/internal/telephony/CarrierResolver.java
index 56752e4..20d7be8 100644
--- a/src/java/com/android/internal/telephony/CarrierResolver.java
+++ b/src/java/com/android/internal/telephony/CarrierResolver.java
@@ -384,7 +384,10 @@
             cv.put(CarrierId.CARRIER_NAME, mCarrierName);
             mContext.getContentResolver().update(
                     Telephony.CarrierId.getUriForSubscriptionId(mPhone.getSubId()), cv, null, null);
-            SubscriptionController.getInstance().setCarrierId(mCarrierId, mPhone.getSubId());
+            if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
+                // only persist carrier id to simInfo db when subId is valid.
+                SubscriptionController.getInstance().setCarrierId(mCarrierId, mPhone.getSubId());
+            }
         }
 
         update = false;
diff --git a/src/java/com/android/internal/telephony/CellularNetworkService.java b/src/java/com/android/internal/telephony/CellularNetworkService.java
index a8dcee7..abff240 100644
--- a/src/java/com/android/internal/telephony/CellularNetworkService.java
+++ b/src/java/com/android/internal/telephony/CellularNetworkService.java
@@ -326,9 +326,7 @@
                     if (cellIdentity.cellIdentityGsm.size() == 1) {
                         android.hardware.radio.V1_0.CellIdentityGsm cellIdentityGsm =
                                 cellIdentity.cellIdentityGsm.get(0);
-                        result = new CellIdentityGsm(cellIdentityGsm.lac, cellIdentityGsm.cid,
-                                cellIdentityGsm.arfcn, cellIdentityGsm.bsic, cellIdentityGsm.mcc,
-                                cellIdentityGsm.mnc, null, null);
+                        result = new CellIdentityGsm(cellIdentityGsm);
                     }
                     break;
                 }
@@ -336,9 +334,7 @@
                     if (cellIdentity.cellIdentityWcdma.size() == 1) {
                         android.hardware.radio.V1_0.CellIdentityWcdma cellIdentityWcdma =
                                 cellIdentity.cellIdentityWcdma.get(0);
-                        result = new CellIdentityWcdma(cellIdentityWcdma.lac, cellIdentityWcdma.cid,
-                                cellIdentityWcdma.psc, cellIdentityWcdma.uarfcn,
-                                cellIdentityWcdma.mcc, cellIdentityWcdma.mnc, null, null);
+                        result = new CellIdentityWcdma(cellIdentityWcdma);
                     }
                     break;
                 }
@@ -346,10 +342,7 @@
                     if (cellIdentity.cellIdentityTdscdma.size() == 1) {
                         android.hardware.radio.V1_0.CellIdentityTdscdma cellIdentityTdscdma =
                                 cellIdentity.cellIdentityTdscdma.get(0);
-                        result = new  CellIdentityTdscdma(cellIdentityTdscdma.mcc,
-                                cellIdentityTdscdma.mnc, cellIdentityTdscdma.lac,
-                                cellIdentityTdscdma.cid, cellIdentityTdscdma.cpid,
-                                Integer.MAX_VALUE, null, null);
+                        result = new  CellIdentityTdscdma(cellIdentityTdscdma);
                     }
                     break;
                 }
@@ -357,10 +350,7 @@
                     if (cellIdentity.cellIdentityLte.size() == 1) {
                         android.hardware.radio.V1_0.CellIdentityLte cellIdentityLte =
                                 cellIdentity.cellIdentityLte.get(0);
-
-                        result = new CellIdentityLte(cellIdentityLte.ci, cellIdentityLte.pci,
-                                cellIdentityLte.tac, cellIdentityLte.earfcn, Integer.MAX_VALUE,
-                                cellIdentityLte.mcc, cellIdentityLte.mnc, null, null);
+                        result = new CellIdentityLte(cellIdentityLte);
                     }
                     break;
                 }
@@ -368,10 +358,7 @@
                     if (cellIdentity.cellIdentityCdma.size() == 1) {
                         android.hardware.radio.V1_0.CellIdentityCdma cellIdentityCdma =
                                 cellIdentity.cellIdentityCdma.get(0);
-
-                        result = new CellIdentityCdma(cellIdentityCdma.networkId,
-                                cellIdentityCdma.systemId, cellIdentityCdma.baseStationId,
-                                cellIdentityCdma.longitude, cellIdentityCdma.latitude);
+                        result = new CellIdentityCdma(cellIdentityCdma);
                     }
                     break;
                 }
@@ -395,16 +382,7 @@
                     if (cellIdentity.cellIdentityGsm.size() == 1) {
                         android.hardware.radio.V1_2.CellIdentityGsm cellIdentityGsm =
                                 cellIdentity.cellIdentityGsm.get(0);
-
-                        result = new CellIdentityGsm(
-                                cellIdentityGsm.base.lac,
-                                cellIdentityGsm.base.cid,
-                                cellIdentityGsm.base.arfcn,
-                                cellIdentityGsm.base.bsic,
-                                cellIdentityGsm.base.mcc,
-                                cellIdentityGsm.base.mnc,
-                                cellIdentityGsm.operatorNames.alphaLong,
-                                cellIdentityGsm.operatorNames.alphaShort);
+                        result = new CellIdentityGsm(cellIdentityGsm);
                     }
                     break;
                 }
@@ -412,16 +390,7 @@
                     if (cellIdentity.cellIdentityWcdma.size() == 1) {
                         android.hardware.radio.V1_2.CellIdentityWcdma cellIdentityWcdma =
                                 cellIdentity.cellIdentityWcdma.get(0);
-
-                        result = new CellIdentityWcdma(
-                                cellIdentityWcdma.base.lac,
-                                cellIdentityWcdma.base.cid,
-                                cellIdentityWcdma.base.psc,
-                                cellIdentityWcdma.base.uarfcn,
-                                cellIdentityWcdma.base.mcc,
-                                cellIdentityWcdma.base.mnc,
-                                cellIdentityWcdma.operatorNames.alphaLong,
-                                cellIdentityWcdma.operatorNames.alphaShort);
+                        result = new CellIdentityWcdma(cellIdentityWcdma);
                     }
                     break;
                 }
@@ -429,16 +398,7 @@
                     if (cellIdentity.cellIdentityTdscdma.size() == 1) {
                         android.hardware.radio.V1_2.CellIdentityTdscdma cellIdentityTdscdma =
                                 cellIdentity.cellIdentityTdscdma.get(0);
-
-                        result = new  CellIdentityTdscdma(
-                                cellIdentityTdscdma.base.mcc,
-                                cellIdentityTdscdma.base.mnc,
-                                cellIdentityTdscdma.base.lac,
-                                cellIdentityTdscdma.base.cid,
-                                cellIdentityTdscdma.base.cpid,
-                                cellIdentityTdscdma.uarfcn,
-                                cellIdentityTdscdma.operatorNames.alphaLong,
-                                cellIdentityTdscdma.operatorNames.alphaShort);
+                        result = new  CellIdentityTdscdma(cellIdentityTdscdma);
                     }
                     break;
                 }
@@ -446,17 +406,7 @@
                     if (cellIdentity.cellIdentityLte.size() == 1) {
                         android.hardware.radio.V1_2.CellIdentityLte cellIdentityLte =
                                 cellIdentity.cellIdentityLte.get(0);
-
-                        result = new CellIdentityLte(
-                                cellIdentityLte.base.ci,
-                                cellIdentityLte.base.pci,
-                                cellIdentityLte.base.tac,
-                                cellIdentityLte.base.earfcn,
-                                cellIdentityLte.bandwidth,
-                                cellIdentityLte.base.mcc,
-                                cellIdentityLte.base.mnc,
-                                cellIdentityLte.operatorNames.alphaLong,
-                                cellIdentityLte.operatorNames.alphaShort);
+                        result = new CellIdentityLte(cellIdentityLte);
                     }
                     break;
                 }
@@ -464,15 +414,7 @@
                     if (cellIdentity.cellIdentityCdma.size() == 1) {
                         android.hardware.radio.V1_2.CellIdentityCdma cellIdentityCdma =
                                 cellIdentity.cellIdentityCdma.get(0);
-
-                        result = new CellIdentityCdma(
-                                cellIdentityCdma.base.networkId,
-                                cellIdentityCdma.base.systemId,
-                                cellIdentityCdma.base.baseStationId,
-                                cellIdentityCdma.base.longitude,
-                                cellIdentityCdma.base.latitude,
-                                cellIdentityCdma.operatorNames.alphaLong,
-                                cellIdentityCdma.operatorNames.alphaShort);
+                        result = new CellIdentityCdma(cellIdentityCdma);
                     }
                     break;
                 }
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index cda5cd7..f060520 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -825,7 +825,8 @@
      * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
      * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
      */
-    void dial (String address, int clirMode, Message result);
+    void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+               int clirMode, Message result);
 
     /**
      *  returned message
@@ -838,7 +839,8 @@
      * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
      * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
      */
-    void dial(String address, int clirMode, UUSInfo uusInfo, Message result);
+    void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+              int clirMode, UUSInfo uusInfo, Message result);
 
     /**
      *  returned message
diff --git a/src/java/com/android/internal/telephony/Connection.java b/src/java/com/android/internal/telephony/Connection.java
index 05a0081..a48be1f 100755
--- a/src/java/com/android/internal/telephony/Connection.java
+++ b/src/java/com/android/internal/telephony/Connection.java
@@ -23,6 +23,8 @@
 import android.telephony.DisconnectCause;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
+import android.telephony.emergency.EmergencyNumber;
+import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -226,6 +228,29 @@
     private boolean mAnsweringDisconnectsActiveCall;
     private boolean mAllowAddCallDuringVideoCall;
 
+    private boolean mIsEmergencyCall;
+
+    /**
+     * The emergency service categories, only valid if {@link #isEmergencyCall()} returns
+     * {@code true}
+     *
+     * If valid, the value is the bitwise-OR combination of the following constants:
+     * <ol>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li>
+     * </ol>
+     *
+     * Reference: 3gpp 23.167, Section 6 - Functional description;
+     *            3gpp 22.101, Section 10 - Emergency Calls.
+     */
+    private int mEmergencyServiceCategories;
+
     /**
      * When {@code true}, the network has indicated that this is an emergency call.
      */
@@ -433,6 +458,76 @@
     }
 
     /**
+     * Checks if the connection is for an emergency call.
+     *
+     * @return {@code true} if the call is an emergency call
+     *         or {@code false} otherwise.
+     */
+    public boolean isEmergencyCall() {
+        return mIsEmergencyCall;
+    }
+
+    /**
+     * Sets whether this call is an emergency call or not.
+     *
+     * @param isEmergencyCall {@code true} if the call is an emergency call,
+     *                        or {@code false} otherwise.
+     */
+    public void setEmergencyCall(boolean isEmergencyCall) {
+        mIsEmergencyCall = isEmergencyCall;
+    }
+
+
+    /**
+     * Set the emergency service categories. The set value is valid only if
+     * {@link #getEmergencyServiceCategories()} returns {@code true}
+     *
+     * @return the emergency service categories,
+     *
+     * If valid, the value is the bitwise-OR combination of the following constants:
+     * <ol>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li>
+     * </ol>
+     *
+     * Reference: 3gpp 23.167, Section 6 - Functional description;
+     *            3gpp 22.101, Section 10 - Emergency Calls.
+     */
+    public @EmergencyServiceCategories int getEmergencyServiceCategories() {
+        return mEmergencyServiceCategories;
+    }
+
+    /**
+     * Set the emergency service categories. The set value is valid only if
+     * {@link #getEmergencyServiceCategories()} returns {@code true}
+     *
+     * If valid, the value is the bitwise-OR combination of the following constants:
+     * <ol>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_POLICE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AMBULANCE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li>
+     * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li>
+     * </ol>
+     *
+     * Reference: 3gpp 23.167, Section 6 - Functional description;
+     *            3gpp 22.101, Section 10 - Emergency Calls.
+     */
+    public void setEmergencyServiceCategories(
+            @EmergencyServiceCategories int emergencyServiceCategories) {
+        mEmergencyServiceCategories = emergencyServiceCategories;
+    }
+
+    /**
      * If this Connection is connected, then it is associated with
      * a Call.
      *
diff --git a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index ee2a9bb..0617f56 100644
--- a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -31,7 +31,6 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
-import android.telephony.emergency.EmergencyNumber;
 
 import java.util.List;
 
@@ -154,13 +153,13 @@
     }
 
     @Override
-    public void notifyDataConnection(Phone sender, String reason, String apnType,
-            PhoneConstants.DataState state) {
-        doNotifyDataConnection(sender, reason, apnType, state);
+    public void notifyDataConnection(Phone sender, String apnType,
+                                     PhoneConstants.DataState state) {
+        doNotifyDataConnection(sender, apnType, state);
     }
 
-    private void doNotifyDataConnection(Phone sender, String reason, String apnType,
-            PhoneConstants.DataState state) {
+    private void doNotifyDataConnection(Phone sender, String apnType,
+                                        PhoneConstants.DataState state) {
         int subId = sender.getSubId();
         long dds = SubscriptionManager.getDefaultDataSubscriptionId();
         if (DBG) log("subId = " + subId + ", DDS = " + dds);
@@ -185,7 +184,6 @@
                 mRegistry.notifyDataConnectionForSubscriber(subId,
                     PhoneConstantConversions.convertDataState(state),
                         sender.isDataAllowed(ApnSetting.getApnTypesBitmaskFromString(apnType)),
-                        reason,
                         sender.getActiveApnHost(apnType),
                         apnType,
                         linkProperties,
@@ -199,11 +197,11 @@
     }
 
     @Override
-    public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) {
+    public void notifyDataConnectionFailed(Phone sender, String apnType) {
         int subId = sender.getSubId();
         try {
             if (mRegistry != null) {
-                mRegistry.notifyDataConnectionFailedForSubscriber(subId, reason, apnType);
+                mRegistry.notifyDataConnectionFailedForSubscriber(subId, apnType);
             }
         } catch (RemoteException ex) {
             // system process is dead
@@ -287,11 +285,11 @@
         }
     }
 
-    public void notifyPreciseDataConnectionFailed(Phone sender, String reason, String apnType,
+    public void notifyPreciseDataConnectionFailed(Phone sender, String apnType,
             String apn, String failCause) {
         // FIXME: subId?
         try {
-            mRegistry.notifyPreciseDataConnectionFailed(reason, apnType, apn, failCause);
+            mRegistry.notifyPreciseDataConnectionFailed(apnType, apn, failCause);
         } catch (RemoteException ex) {
             // system process is dead
         }
@@ -364,12 +362,10 @@
     }
 
     @Override
-    public void notifyEmergencyNumberList(Phone sender,
-                                          List<EmergencyNumber> emergencyNumberList) {
-        int subId = sender.getSubId();
+    public void notifyEmergencyNumberList() {
         try {
             if (mRegistry != null) {
-                mRegistry.notifyEmergencyNumberList(emergencyNumberList);
+                mRegistry.notifyEmergencyNumberList();
             }
         } catch (RemoteException ex) {
             // system process is dead
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
index e282392..4b37351 100755
--- a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
@@ -28,7 +28,6 @@
 import android.os.Registrant;
 import android.os.RegistrantList;
 import android.os.SystemProperties;
-import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellLocation;
 import android.telephony.DisconnectCause;
@@ -173,9 +172,8 @@
             mCi.unregisterForCallWaitingInfo(this);
             // Prior to phone switch to GSM, if CDMA has any emergency call
             // data will be in disabled state, after switching to GSM enable data.
-            if (mIsInEmergencyCall && mPhone.getDcTracker(TransportType.WWAN) != null) {
-                mPhone.getDcTracker(TransportType.WWAN).setInternalDataEnabled(true);
-
+            if (mIsInEmergencyCall) {
+                mPhone.getDataEnabledSettings().setInternalDataEnabled(true);
             }
         } else {
             mConnections = new GsmCdmaConnection[MAX_CONNECTIONS_CDMA];
@@ -332,7 +330,9 @@
             // Always unmute when initiating a new call
             setMute(false);
 
-            mCi.dial(mPendingMO.getAddress(), clirMode, uusInfo, obtainCompleteMessage());
+            mCi.dial(mPendingMO.getAddress(), mPendingMO.isEmergencyCall(),
+                    mPendingMO.getEmergencyServiceCategories(), clirMode, uusInfo,
+                    obtainCompleteMessage());
         }
 
         if (mNumberConverted) {
@@ -374,9 +374,7 @@
     //CDMA
     public void setIsInEmergencyCall() {
         mIsInEmergencyCall = true;
-        if (mPhone.getDcTracker(TransportType.WWAN) != null) {
-            mPhone.getDcTracker(TransportType.WWAN).setInternalDataEnabled(false);
-        }
+        mPhone.getDataEnabledSettings().setInternalDataEnabled(false);
         mPhone.notifyEmergencyCallRegistrants(true);
         mPhone.sendEmergencyCallStateChange(true);
     }
@@ -449,7 +447,9 @@
 
             // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
             if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
-                mCi.dial(mPendingMO.getAddress(), clirMode, obtainCompleteMessage());
+                mCi.dial(mPendingMO.getAddress(), mPendingMO.isEmergencyCall(),
+                        mPendingMO.getEmergencyServiceCategories(), clirMode,
+                        obtainCompleteMessage());
             } else {
                 mPhone.exitEmergencyCallbackMode();
                 mPhone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
@@ -1533,7 +1533,9 @@
                 if (!isPhoneTypeGsm()) {
                     // no matter the result, we still do the same here
                     if (mPendingCallInEcm) {
-                        mCi.dial(mPendingMO.getAddress(), mPendingCallClirMode, obtainCompleteMessage());
+                        mCi.dial(mPendingMO.getAddress(), mPendingMO.isEmergencyCall(),
+                                mPendingMO.getEmergencyServiceCategories(), mPendingCallClirMode,
+                                obtainCompleteMessage());
                         mPendingCallInEcm = false;
                     }
                     mPhone.unsetOnEcbModeExitResponse(this);
@@ -1632,9 +1634,7 @@
             }
             if (!inEcm) {
                 // Re-initiate data connection
-                if (mPhone.getDcTracker(TransportType.WWAN) != null) {
-                    mPhone.getDcTracker(TransportType.WWAN).setInternalDataEnabled(true);
-                }
+                mPhone.getDataEnabledSettings().setInternalDataEnabled(true);
                 mPhone.notifyEmergencyCallRegistrants(false);
             }
             mPhone.sendEmergencyCallStateChange(false);
diff --git a/src/java/com/android/internal/telephony/GsmCdmaConnection.java b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
index 84c9e0a..64fd2f7 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaConnection.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
@@ -29,6 +29,9 @@
 import android.telephony.PhoneNumberUtils;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
+import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
@@ -37,6 +40,10 @@
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
 import com.android.internal.telephony.uicc.UiccCardApplication;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * {@hide}
  */
@@ -73,8 +80,6 @@
 
     private PowerManager.WakeLock mPartialWakeLock;
 
-    private boolean mIsEmergencyCall = false;
-
     // The cached delay to be used between DTMF tones fetched from carrier config.
     private int mDtmfToneDelay = 0;
 
@@ -135,7 +140,9 @@
         mHandler = new MyHandler(mOwner.getLooper());
 
         mAddress = dc.number;
-        mIsEmergencyCall = PhoneNumberUtils.isLocalEmergencyNumber(phone.getContext(), mAddress);
+        setEmergencyCall(TelephonyManager.getDefault().isCurrentEmergencyNumber(mAddress));
+        setEmergencyServiceCategories(fetchEmergencyServiceCategories());
+
         mIsIncoming = dc.isMT;
         mCreateTime = System.currentTimeMillis();
         mCnapName = dc.name;
@@ -176,7 +183,9 @@
         }
 
         mAddress = PhoneNumberUtils.extractNetworkPortionAlt(dialString);
-        mIsEmergencyCall = isEmergencyCall;
+        setEmergencyCall(isEmergencyCall);
+        setEmergencyServiceCategories(fetchEmergencyServiceCategories());
+
         mPostDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
 
         mIndex = -1;
@@ -540,7 +549,7 @@
                 if (serviceState == ServiceState.STATE_POWER_OFF) {
                     return DisconnectCause.POWER_OFF;
                 }
-                if (!mIsEmergencyCall) {
+                if (!isEmergencyCall()) {
                     // Only send OUT_OF_SERVICE if it is not an emergency call. We can still
                     // technically be in STATE_OUT_OF_SERVICE or STATE_EMERGENCY_ONLY during
                     // an emergency call and when it ends, we do not want to mistakenly generate
@@ -1122,6 +1131,31 @@
         }
     }
 
+    private @EmergencyServiceCategories int fetchEmergencyServiceCategories() {
+        Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
+        for (Phone phone: PhoneFactory.getPhones()) {
+            if (phone.getEmergencyNumberTracker() != null
+                    && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
+                emergencyNumberListInternal.put(
+                        phone.getSubId(),
+                        phone.getEmergencyNumberTracker().getEmergencyNumberList());
+            }
+        }
+        if (emergencyNumberListInternal != null) {
+            for (List<EmergencyNumber> emergencyNumberList
+                    : emergencyNumberListInternal.values()) {
+                if (emergencyNumberList != null) {
+                    for (EmergencyNumber num : emergencyNumberList) {
+                        if (num.getNumber().equals(mAddress)) {
+                            return num.getEmergencyServiceCategoryBitmask();
+                        }
+                    }
+                }
+            }
+        }
+        return EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
+    }
+
     private boolean isPhoneTypeGsm() {
         return mOwner.getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_GSM;
     }
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 2c41700..d4cbbaa 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -77,6 +77,7 @@
 import com.android.internal.telephony.cdma.CdmaMmiCode;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.cdma.EriManager;
+import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 import com.android.internal.telephony.dataconnection.DcTracker;
 import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
@@ -208,6 +209,8 @@
     private CarrierKeyDownloadManager mCDM;
     private CarrierInfoManager mCIM;
 
+    private final SettingsObserver mSettingsObserver;
+
     // Constructors
 
     public GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, int phoneId,
@@ -238,6 +241,9 @@
         mEmergencyNumberTracker = mTelephonyComponentFactory
                 .inject(EmergencyNumberTracker.class.getName()).makeEmergencyNumberTracker(
                 this, this.mCi);
+        mDataEnabledSettings = mTelephonyComponentFactory
+                .inject(DataEnabledSettings.class.getName()).makeDataEnabledSettings(this);
+
         // DcTracker uses SST so needs to be created after it is instantiated
         for (int transport : mTransportManager.getAvailableTransports()) {
             mDcTrackers.put(transport, mTelephonyComponentFactory.inject(DcTracker.class.getName())
@@ -247,11 +253,23 @@
         mCarrierResolver = mTelephonyComponentFactory.inject(CarrierResolver.class.getName())
                 .makeCarrierResolver(this);
 
+        getCarrierActionAgent().registerForCarrierAction(
+                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
+                EVENT_SET_CARRIER_DATA_ENABLED, null, false);
+
         mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
         mDeviceStateMonitor = mTelephonyComponentFactory.inject(DeviceStateMonitor.class.getName())
                 .makeDeviceStateMonitor(this);
 
         mSST.registerForVoiceRegStateOrRatChanged(this, EVENT_VRS_OR_RAT_CHANGED, null);
+
+        mSettingsObserver = new SettingsObserver(context, this);
+        mSettingsObserver.observe(
+                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+                EVENT_DEVICE_PROVISIONED_CHANGE);
+        mSettingsObserver.observe(
+                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
+                EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE);
         logd("GsmCdmaPhone: constructor: sub = " + mPhoneId);
     }
 
@@ -2119,26 +2137,17 @@
         mCT.unregisterForCallWaiting(h);
     }
 
+    /**
+     * Whether data is enabled by user. Unlike isDataEnabled, this only
+     * checks user setting stored in {@link android.provider.Settings.Global#MOBILE_DATA}
+     * if not provisioning, or isProvisioningDataEnabled if provisioning.
+     */
     @Override
     public boolean isUserDataEnabled() {
-        if (getDcTracker(TransportType.WWAN) != null) {
-            return getDcTracker(TransportType.WWAN).isUserDataEnabled();
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isDataEnabled() {
-        if (getDcTracker(TransportType.WWAN) != null) {
-            return getDcTracker(TransportType.WWAN).isDataEnabled();
-        }
-        return false;
-    }
-
-    @Override
-    public void setUserDataEnabled(boolean enable) {
-        if (getDcTracker(TransportType.WWAN) != null) {
-            getDcTracker(TransportType.WWAN).setUserDataEnabled(enable);
+        if (mDataEnabledSettings.isProvisioning()) {
+            return mDataEnabledSettings.isProvisioningDataEnabled();
+        } else {
+            return mDataEnabledSettings.isUserDataEnabled();
         }
     }
 
@@ -2667,6 +2676,17 @@
                 onVoiceRegStateOrRatChanged(vrsRatPair.first, vrsRatPair.second);
                 break;
 
+            case EVENT_SET_CARRIER_DATA_ENABLED:
+                ar = (AsyncResult) msg.obj;
+                boolean enabled = (boolean) ar.result;
+                mDataEnabledSettings.setCarrierDataEnabled(enabled);
+                break;
+            case EVENT_DEVICE_PROVISIONED_CHANGE:
+                mDataEnabledSettings.updateProvisionedChanged();
+                break;
+            case EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE:
+                mDataEnabledSettings.updateProvisioningDataEnabled();
+                break;
             default:
                 super.handleMessage(msg);
         }
@@ -3108,9 +3128,7 @@
             // send an Intent
             sendEmergencyCallbackModeChange();
             // Re-initiate data connection
-            if (getDcTracker(TransportType.WWAN) != null) {
-                getDcTracker(TransportType.WWAN).setInternalDataEnabled(true);
-            }
+            mDataEnabledSettings.setInternalDataEnabled(true);
             notifyEmergencyCallRegistrants(false);
         }
     }
diff --git a/src/java/com/android/internal/telephony/LocaleTracker.java b/src/java/com/android/internal/telephony/LocaleTracker.java
index b6d2871..9236839 100755
--- a/src/java/com/android/internal/telephony/LocaleTracker.java
+++ b/src/java/com/android/internal/telephony/LocaleTracker.java
@@ -416,6 +416,16 @@
             mLocalLog.log(msg);
             mCurrentCountryIso = countryIso;
 
+            // Inform EmergencyNumberTrack with the change of current Country ISO
+            if (mPhone != null && mPhone.getEmergencyNumberTracker() != null) {
+                mPhone.getEmergencyNumberTracker().updateEmergencyNumberDatabaseCountryChange(
+                        getCurrentCountry());
+                log("Notified EmergencyNumberTracker");
+            } else {
+                loge("Cannot notify EmergencyNumberTracker. Phone is null? "
+                        + Boolean.toString(mPhone == null));
+            }
+
             TelephonyManager.setTelephonyProperty(mPhone.getPhoneId(),
                     TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, mCurrentCountryIso);
 
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index e6ec174..5e08a0c 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -67,6 +67,7 @@
 import com.android.ims.ImsManager;
 import com.android.internal.R;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons;
+import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 import com.android.internal.telephony.dataconnection.DcTracker;
 import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
@@ -209,8 +210,11 @@
     protected static final int EVENT_VRS_OR_RAT_CHANGED             = 46;
     // Radio state change
     protected static final int EVENT_RADIO_STATE_CHANGED            = 47;
+    protected static final int EVENT_SET_CARRIER_DATA_ENABLED       = 48;
+    protected static final int EVENT_DEVICE_PROVISIONED_CHANGE      = 49;
+    protected static final int EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE = 50;
 
-    protected static final int EVENT_LAST                       = EVENT_RADIO_STATE_CHANGED;
+    protected static final int EVENT_LAST = EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE;
 
     // For shared prefs.
     private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_";
@@ -294,6 +298,7 @@
     private final String mActionAttached;
     protected DeviceStateMonitor mDeviceStateMonitor;
     protected TransportManager mTransportManager;
+    protected DataEnabledSettings mDataEnabledSettings;
 
     protected int mPhoneId;
 
@@ -2202,20 +2207,19 @@
         mNotifier.notifyMessageWaitingChanged(this);
     }
 
-    public void notifyDataConnection(String reason, String apnType,
-            PhoneConstants.DataState state) {
-        mNotifier.notifyDataConnection(this, reason, apnType, state);
+    public void notifyDataConnection(String apnType, PhoneConstants.DataState state) {
+        mNotifier.notifyDataConnection(this, apnType, state);
     }
 
-    public void notifyDataConnection(String reason, String apnType) {
-        mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
+    public void notifyDataConnection(String apnType) {
+        mNotifier.notifyDataConnection(this, apnType, getDataConnectionState(apnType));
     }
 
-    public void notifyDataConnection(String reason) {
+    public void notifyDataConnection() {
         String types[] = getActiveApnTypes();
         if (types != null) {
             for (String apnType : types) {
-                mNotifier.notifyDataConnection(this, reason, apnType,
+                mNotifier.notifyDataConnection(this, apnType,
                         getDataConnectionState(apnType));
             }
         }
@@ -2260,9 +2264,9 @@
         mNotifier.notifySrvccStateChanged(this, state);
     }
 
-    /** Notify the list of {@link EmergencyNumber} changes. */
-    public void notifyEmergencyNumberList(List<EmergencyNumber> emergencyNumberList) {
-        mNotifier.notifyEmergencyNumberList(this, emergencyNumberList);
+    /** Notify the {@link EmergencyNumber} changes. */
+    public void notifyEmergencyNumberList() {
+        mNotifier.notifyEmergencyNumberList();
     }
 
     /**
@@ -3087,13 +3091,13 @@
     public void notifyCallForwardingIndicator() {
     }
 
-    public void notifyDataConnectionFailed(String reason, String apnType) {
-        mNotifier.notifyDataConnectionFailed(this, reason, apnType);
+    public void notifyDataConnectionFailed(String apnType) {
+        mNotifier.notifyDataConnectionFailed(this, apnType);
     }
 
-    public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
+    public void notifyPreciseDataConnectionFailed(String apnType, String apn,
             String failCause) {
-        mNotifier.notifyPreciseDataConnectionFailed(this, reason, apnType, apn, failCause);
+        mNotifier.notifyPreciseDataConnectionFailed(this, apnType, apn, failCause);
     }
 
     /**
@@ -3732,16 +3736,8 @@
         mAllDataDisconnectedRegistrants.remove(h);
     }
 
-    public void registerForDataEnabledChanged(Handler h, int what, Object obj) {
-        if (getDcTracker(TransportType.WWAN) != null) {
-            getDcTracker(TransportType.WWAN).registerForDataEnabledChanged(h, what, obj);
-        }
-    }
-
-    public void unregisterForDataEnabledChanged(Handler h) {
-        if (getDcTracker(TransportType.WWAN) != null) {
-            getDcTracker(TransportType.WWAN).unregisterForDataEnabledChanged(h);
-        }
+    public DataEnabledSettings getDataEnabledSettings() {
+        return mDataEnabledSettings;
     }
 
     public IccSmsInterfaceManager getIccSmsInterfaceManager(){
@@ -3815,20 +3811,6 @@
     }
 
     /**
-     * Policy control of data connection. Usually used when we hit data limit.
-     * @param enabled True if enabling the data, otherwise disabling.
-     */
-    public void setPolicyDataEnabled(boolean enabled) {
-        if (mTransportManager != null) {
-            for (int transport : mTransportManager.getAvailableTransports()) {
-                if (getDcTracker(transport) != null) {
-                    getDcTracker(transport).setPolicyDataEnabled(enabled);
-                }
-            }
-        }
-    }
-
-    /**
      * SIP URIs aliased to the current subscriber given by the IMS implementation.
      * Applicable only on IMS; used in absence of line1number.
      * @return array of SIP URIs aliased to the current subscriber
diff --git a/src/java/com/android/internal/telephony/PhoneInternalInterface.java b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
index a304ab6..41d7ae4 100644
--- a/src/java/com/android/internal/telephony/PhoneInternalInterface.java
+++ b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
@@ -123,7 +123,7 @@
      */
     static final String REASON_ROAMING_ON = "roamingOn";
     static final String REASON_ROAMING_OFF = "roamingOff";
-    static final String REASON_DATA_DISABLED = "dataDisabled";
+    static final String REASON_DATA_DISABLED_INTERNAL = "dataDisabledInternal";
     static final String REASON_DATA_ENABLED = "dataEnabled";
     static final String REASON_DATA_ATTACHED = "dataAttached";
     static final String REASON_DATA_DETACHED = "dataDetached";
@@ -740,16 +740,6 @@
     boolean isUserDataEnabled();
 
     /**
-     * @return true if data is enabled considering all factors
-     */
-    boolean isDataEnabled();
-
-    /**
-     * @param @enable set {@code true} if enable data connection
-     */
-    void setUserDataEnabled(boolean enable);
-
-    /**
      * Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones.
      */
     String getDeviceId();
diff --git a/src/java/com/android/internal/telephony/PhoneNotifier.java b/src/java/com/android/internal/telephony/PhoneNotifier.java
index 30b53d7..397aff7 100644
--- a/src/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/PhoneNotifier.java
@@ -21,7 +21,6 @@
 import android.telephony.PhoneCapability;
 import android.telephony.PhysicalChannelConfig;
 import android.telephony.TelephonyManager;
-import android.telephony.emergency.EmergencyNumber;
 
 import java.util.List;
 
@@ -30,40 +29,38 @@
  */
 public interface PhoneNotifier {
 
-    public void notifyPhoneState(Phone sender);
+    void notifyPhoneState(Phone sender);
 
-    public void notifyServiceState(Phone sender);
+    void notifyServiceState(Phone sender);
 
     /** Notify registrants of the current CellLocation */
     void notifyCellLocation(Phone sender, CellLocation cl);
 
-    public void notifySignalStrength(Phone sender);
+    void notifySignalStrength(Phone sender);
 
-    public void notifyMessageWaitingChanged(Phone sender);
+    void notifyMessageWaitingChanged(Phone sender);
 
-    public void notifyCallForwardingChanged(Phone sender);
+    void notifyCallForwardingChanged(Phone sender);
 
-    /** TODO - reason should never be null */
-    public void notifyDataConnection(Phone sender, String reason, String apnType,
-            PhoneConstants.DataState state);
+    void notifyDataConnection(Phone sender, String apnType, PhoneConstants.DataState state);
 
-    public void notifyDataConnectionFailed(Phone sender, String reason, String apnType);
+    void notifyDataConnectionFailed(Phone sender, String apnType);
 
-    public void notifyDataActivity(Phone sender);
+    void notifyDataActivity(Phone sender);
 
-    public void notifyOtaspChanged(Phone sender, int otaspMode);
+    void notifyOtaspChanged(Phone sender, int otaspMode);
 
-    public void notifyCellInfo(Phone sender, List<CellInfo> cellInfo);
+    void notifyCellInfo(Phone sender, List<CellInfo> cellInfo);
 
     /** Notify of change to PhysicalChannelConfiguration. */
     void notifyPhysicalChannelConfiguration(Phone sender, List<PhysicalChannelConfig> configs);
 
-    public void notifyPreciseCallState(Phone sender);
+    void notifyPreciseCallState(Phone sender);
 
-    public void notifyDisconnectCause(int cause, int preciseCause);
+    void notifyDisconnectCause(int cause, int preciseCause);
 
-    public void notifyPreciseDataConnectionFailed(Phone sender, String reason, String apnType,
-            String apn, String failCause);
+    void notifyPreciseDataConnectionFailed(Phone sender, String apnType, String apn,
+                                                  String failCause);
 
     /** send a notification that the SRVCC state has changed.*/
     void notifySrvccStateChanged(Phone sender, @TelephonyManager.SrvccState int state);
@@ -81,5 +78,5 @@
     void notifyRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state);
 
     /** Notify of change to EmergencyNumberList. */
-    void notifyEmergencyNumberList(Phone sender, List<EmergencyNumber> emergencyNumberList);
+    void notifyEmergencyNumberList();
 }
diff --git a/src/java/com/android/internal/telephony/PhoneSwitcher.java b/src/java/com/android/internal/telephony/PhoneSwitcher.java
index 75dd049..74897d2 100644
--- a/src/java/com/android/internal/telephony/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/PhoneSwitcher.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import static android.telephony.PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE;
+import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
 import static android.telephony.SubscriptionManager.INVALID_PHONE_INDEX;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
@@ -137,18 +138,18 @@
     }
 
     @VisibleForTesting
-    public PhoneSwitcher(Looper looper) {
+    public PhoneSwitcher(int numPhones, Looper looper) {
         super(looper);
         mMaxActivePhones = 0;
         mSubscriptionController = null;
-        mPhoneSubscriptions = null;
         mCommandsInterfaces = null;
         mContext = null;
         mPhoneStates = null;
         mPhones = null;
         mLocalLog = null;
         mActivePhoneRegistrants = null;
-        mNumPhones = 0;
+        mNumPhones = numPhones;
+        mPhoneSubscriptions = new int[numPhones];
         mRadioConfig = RadioConfig.getInstance(mContext);
         mPhoneStateListener = new PhoneStateListener(looper) {
             public void onPhoneCapabilityChanged(PhoneCapability capability) {
@@ -385,6 +386,11 @@
         if (diffDetected) {
             log("evaluating due to " + sb.toString());
             if (mHalCommandToUse == HAL_COMMAND_PREFERRED_DATA) {
+                // With HAL_COMMAND_PREFERRED_DATA, all phones are assumed to allow PS attach.
+                // So marking all phone as active.
+                for (int phoneId = 0; phoneId < mNumPhones; phoneId++) {
+                    activate(phoneId);
+                }
                 if (SubscriptionManager.isUsableSubIdValue(mPreferredDataPhoneId)) {
                     mRadioConfig.setPreferredDataModem(mPreferredDataPhoneId, null);
                 }
@@ -485,7 +491,7 @@
         if (mHalCommandToUse == HAL_COMMAND_ALLOW_DATA || mHalCommandToUse == HAL_COMMAND_UNKNOWN) {
             // Skip ALLOW_DATA for single SIM device
             if (mNumPhones > 1) {
-                mCommandsInterfaces[phoneId].setDataAllowed(mPhoneStates[phoneId].active, null);
+                mCommandsInterfaces[phoneId].setDataAllowed(isPhoneActive(phoneId), null);
             }
         } else {
             mRadioConfig.setPreferredDataModem(mPreferredDataPhoneId, null);
@@ -503,9 +509,38 @@
     }
 
     private int phoneIdForRequest(NetworkRequest netRequest) {
-        NetworkSpecifier specifier = netRequest.networkCapabilities.getNetworkSpecifier();
+        int subId = getSubIdFromNetworkRequest(netRequest);
+
+        if (subId == DEFAULT_SUBSCRIPTION_ID) return mPreferredDataPhoneId;
+        if (subId == INVALID_SUBSCRIPTION_ID) return INVALID_PHONE_INDEX;
+
+        int preferredDataSubId = SubscriptionManager.isValidPhoneId(mPreferredDataPhoneId)
+                ? mPhoneSubscriptions[mPreferredDataPhoneId] : INVALID_SUBSCRIPTION_ID;
+        // Currently we assume multi-SIM devices will only support one Internet PDN connection. So
+        // if Internet PDN is established on the non-preferred phone, it will interrupt
+        // Internet connection on the preferred phone. So we only accept Internet request with
+        // preferred data subscription or no specified subscription.
+        if (netRequest.networkCapabilities.hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_INTERNET) && subId != preferredDataSubId) {
+            // Returning INVALID_PHONE_INDEX will result in netRequest not being handled.
+            return INVALID_PHONE_INDEX;
+        }
+
+        // Try to find matching phone ID. If it doesn't exist, we'll end up returning INVALID.
+        int phoneId = INVALID_PHONE_INDEX;
+        for (int i = 0; i < mNumPhones; i++) {
+            if (mPhoneSubscriptions[i] == subId) {
+                phoneId = i;
+                break;
+            }
+        }
+        return phoneId;
+    }
+
+    private int getSubIdFromNetworkRequest(NetworkRequest networkRequest) {
+        NetworkSpecifier specifier = networkRequest.networkCapabilities.getNetworkSpecifier();
         if (specifier == null) {
-            return mPreferredDataPhoneId;
+            return DEFAULT_SUBSCRIPTION_ID;
         }
 
         int subId;
@@ -516,22 +551,13 @@
             } catch (NumberFormatException e) {
                 Rlog.e(LOG_TAG, "NumberFormatException on "
                         + ((StringNetworkSpecifier) specifier).specifier);
-                subId = INVALID_SUBSCRIPTION_ID;
+                return INVALID_SUBSCRIPTION_ID;
             }
         } else {
-            subId = INVALID_SUBSCRIPTION_ID;
+            return INVALID_SUBSCRIPTION_ID;
         }
 
-        int phoneId = INVALID_PHONE_INDEX;
-        if (subId == INVALID_SUBSCRIPTION_ID) return phoneId;
-
-        for (int i = 0 ; i < mNumPhones; i++) {
-            if (mPhoneSubscriptions[i] == subId) {
-                phoneId = i;
-                break;
-            }
-        }
-        return phoneId;
+        return subId;
     }
 
     private int getSubIdForDefaultNetworkRequests() {
@@ -560,28 +586,20 @@
         mPreferredDataPhoneId = phoneId;
     }
 
-    /**
-     * Returns whether phone should handle network requests
-     * that don't specify a subId.
-     */
-    public boolean shouldApplyUnspecifiedRequests(int phoneId) {
+    public boolean shouldApplyNetworkRequest(NetworkRequest networkRequest, int phoneId) {
         validatePhoneId(phoneId);
-        if (mHalCommandToUse == HAL_COMMAND_PREFERRED_DATA) {
-            return phoneId == mPreferredDataPhoneId;
-        } else {
-            return mPhoneStates[phoneId].active && phoneId == mPreferredDataPhoneId;
-        }
+
+        // In any case, if phone state is inactive, don't apply the network request.
+        if (!isPhoneActive(phoneId)) return false;
+
+        int phoneIdToHandle = phoneIdForRequest(networkRequest);
+
+        return phoneId == phoneIdToHandle;
     }
 
-    /**
-     * Returns whether phone should handle network requests
-     * that specify a subId.
-     */
-    public boolean shouldApplySpecifiedRequests(int phoneId) {
-        validatePhoneId(phoneId);
-        // If we use SET_PREFERRED_DATA, always apply specified network requests. Otherwise,
-        // only apply network requests if the phone is active (dataAllowed).
-        return mHalCommandToUse == HAL_COMMAND_PREFERRED_DATA || mPhoneStates[phoneId].active;
+    @VisibleForTesting
+    protected boolean isPhoneActive(int phoneId) {
+        return mPhoneStates[phoneId].active;
     }
 
     /**
@@ -598,7 +616,8 @@
         mActivePhoneRegistrants.remove(h);
     }
 
-    private void validatePhoneId(int phoneId) {
+    @VisibleForTesting
+    protected void validatePhoneId(int phoneId) {
         if (phoneId < 0 || phoneId >= mNumPhones) {
             throw new IllegalArgumentException("Invalid PhoneId");
         }
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 020a1c3..8d84b04 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -26,12 +26,6 @@
 import android.hardware.radio.V1_0.CdmaSmsAck;
 import android.hardware.radio.V1_0.CdmaSmsMessage;
 import android.hardware.radio.V1_0.CdmaSmsWriteArgs;
-import android.hardware.radio.V1_0.CellInfoCdma;
-import android.hardware.radio.V1_0.CellInfoGsm;
-import android.hardware.radio.V1_0.CellInfoLte;
-import android.hardware.radio.V1_0.CellInfoTdscdma;
-import android.hardware.radio.V1_0.CellInfoType;
-import android.hardware.radio.V1_0.CellInfoWcdma;
 import android.hardware.radio.V1_0.DataProfileId;
 import android.hardware.radio.V1_0.Dial;
 import android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo;
@@ -63,7 +57,6 @@
 import android.os.Handler;
 import android.os.HwBinder;
 import android.os.Message;
-import android.os.Parcel;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.os.RemoteException;
@@ -72,9 +65,7 @@
 import android.os.WorkSource;
 import android.service.carrier.CarrierIdentifier;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.CellIdentityCdma;
 import android.telephony.CellInfo;
-import android.telephony.CellSignalStrengthCdma;
 import android.telephony.ClientRequestStats;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.ModemActivityInfo;
@@ -85,7 +76,6 @@
 import android.telephony.RadioAccessSpecifier;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
 import android.telephony.SmsManager;
 import android.telephony.TelephonyHistogram;
 import android.telephony.TelephonyManager;
@@ -136,7 +126,7 @@
     // Have a separate wakelock instance for Ack
     static final String RILJ_ACK_WAKELOCK_NAME = "RILJ_ACK_WL";
     static final boolean RILJ_LOGD = true;
-    static final boolean RILJ_LOGV = false; // STOPSHIP if true
+    static final boolean RILJ_LOGV = true; // STOPSHIP if true
     static final int RIL_HISTOGRAM_BUCKET_COUNT = 5;
 
     /**
@@ -861,12 +851,20 @@
     }
 
     @Override
-    public void dial(String address, int clirMode, Message result) {
-        dial(address, clirMode, null, result);
+    public void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+                     int clirMode, Message result) {
+        dial(address, isEmergencyCall, emergencyServiceCategories, clirMode, null, result);
     }
 
     @Override
-    public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
+    public void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+                     int clirMode, UUSInfo uusInfo, Message result) {
+        if (isEmergencyCall && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+            emergencyDial(address, emergencyServiceCategories, clirMode, uusInfo,
+                    result);
+            return;
+        }
+
         IRadio radioProxy = getRadioProxy(result);
         if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_DIAL, result,
@@ -896,6 +894,39 @@
         }
     }
 
+    private void emergencyDial(String address, int emergencyServiceCategories, int clirMode,
+                              UUSInfo uusInfo, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        // IRadio V1.4
+        android.hardware.radio.V1_4.IRadio radioProxy14 =
+                (android.hardware.radio.V1_4.IRadio) radioProxy;
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_EMERGENCY_DIAL, result,
+                    mRILDefaultWorkSource);
+            Dial dialInfo = new Dial();
+            dialInfo.address = convertNullToEmptyString(address);
+            dialInfo.clir = clirMode;
+            if (uusInfo != null) {
+                UusInfo info = new UusInfo();
+                info.uusType = uusInfo.getType();
+                info.uusDcs = uusInfo.getDcs();
+                info.uusData = new String(uusInfo.getUserData());
+                dialInfo.uusInfo.add(info);
+            }
+
+            if (RILJ_LOGD) {
+                // Do not log function arg for privacy
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+            }
+
+            try {
+                radioProxy14.emergencyDial(rr.mSerial, dialInfo, emergencyServiceCategories);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "emergencyDial", e);
+            }
+        }
+    }
+
     @Override
     public void getIMSI(Message result) {
         getIMSIForApp(null, result);
@@ -5399,101 +5430,6 @@
         return lce;
     }
 
-    // TODO(b/119224773) refactor the converter of CellInfo.
-    private static void writeToParcelForGsm(
-            Parcel p, int lac, int cid, int arfcn, int bsic, String mcc, String mnc,
-            String al, String as, int ss, int ber, int ta) {
-        p.writeInt(CellInfo.TYPE_GSM);
-        p.writeString(mcc);
-        p.writeString(mnc);
-        p.writeString(al);
-        p.writeString(as);
-        p.writeInt(lac);
-        p.writeInt(cid);
-        p.writeInt(arfcn);
-        p.writeInt(bsic);
-        p.writeInt(ss);
-        p.writeInt(ber);
-        p.writeInt(ta);
-    }
-
-    // TODO(b/119224773) refactor the converter of CellInfo.
-    private static void writeToParcelForCdma(
-            Parcel p, int ni, int si, int bsi, int lon, int lat, String al, String as,
-            int dbm, int ecio, int eDbm, int eEcio, int eSnr) {
-        new CellIdentityCdma(ni, si, bsi, lon, lat, al, as).writeToParcel(p, 0);
-        new CellSignalStrengthCdma(dbm, ecio, eDbm, eEcio, eSnr).writeToParcel(p, 0);
-    }
-
-    // TODO(b/119224773) refactor the converter of CellInfo.
-    private static void writeToParcelForLte(
-            Parcel p, int ci, int pci, int tac, int earfcn, int bandwidth, String mcc, String mnc,
-            String al, String as, int ss, int rsrp, int rsrq, int rssnr, int cqi, int ta,
-            boolean isEndcAvailable) {
-
-        // General CellInfo
-        p.writeInt(CellInfo.TYPE_LTE);
-        p.writeString(mcc);
-        p.writeString(mnc);
-        p.writeString(al);
-        p.writeString(as);
-
-        // CellIdentity
-        p.writeInt(ci);
-        p.writeInt(pci);
-        p.writeInt(tac);
-        p.writeInt(earfcn);
-        p.writeInt(bandwidth);
-
-        // CellSignalStrength
-        p.writeInt(ss);
-        p.writeInt(rsrp);
-        p.writeInt(rsrq);
-        p.writeInt(rssnr);
-        p.writeInt(cqi);
-        p.writeInt(ta);
-
-        // CellConfigLte
-        p.writeBoolean(isEndcAvailable);
-    }
-
-    // TODO(b/119224773) refactor the converter of CellInfo.
-    private static void writeToParcelForWcdma(
-            Parcel p, int lac, int cid, int psc, int uarfcn, String mcc, String mnc,
-            String al, String as, int ss, int ber, int rscp, int ecno) {
-        p.writeInt(CellInfo.TYPE_WCDMA);
-        p.writeString(mcc);
-        p.writeString(mnc);
-        p.writeString(al);
-        p.writeString(as);
-        p.writeInt(lac);
-        p.writeInt(cid);
-        p.writeInt(psc);
-        p.writeInt(uarfcn);
-        p.writeInt(ss);
-        p.writeInt(ber);
-        p.writeInt(rscp);
-        p.writeInt(ecno);
-    }
-
-    // TODO(b/119224773) refactor the converter of CellInfo.
-    private static void writeToParcelForTdscdma(
-            Parcel p, int lac, int cid, int cpid, int uarfcn, String mcc, String mnc,
-            String al, String as, int ss, int ber, int rscp) {
-        p.writeInt(CellInfo.TYPE_TDSCDMA);
-        p.writeString(mcc);
-        p.writeString(mnc);
-        p.writeString(al);
-        p.writeString(as);
-        p.writeInt(lac);
-        p.writeInt(cid);
-        p.writeInt(cpid);
-        p.writeInt(uarfcn);
-        p.writeInt(ss);
-        p.writeInt(ber);
-        p.writeInt(rscp);
-    }
-
     /**
      * Convert CellInfo defined in 1.0/types.hal to CellInfo type.
      * @param records List of CellInfo defined in 1.0/types.hal
@@ -5505,117 +5441,7 @@
         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
 
         for (android.hardware.radio.V1_0.CellInfo record : records) {
-            // first convert RIL CellInfo to Parcel
-            Parcel p = Parcel.obtain();
-            p.writeInt(record.cellInfoType);
-            p.writeInt(record.registered ? 1 : 0);
-            p.writeLong(SystemClock.elapsedRealtimeNanos());
-            p.writeInt(CellInfo.CONNECTION_UNKNOWN);
-            switch (record.cellInfoType) {
-                case CellInfoType.GSM: {
-                    CellInfoGsm cellInfoGsm = record.gsm.get(0);
-                    writeToParcelForGsm(
-                            p,
-                            cellInfoGsm.cellIdentityGsm.lac,
-                            cellInfoGsm.cellIdentityGsm.cid,
-                            cellInfoGsm.cellIdentityGsm.arfcn,
-                            Byte.toUnsignedInt(cellInfoGsm.cellIdentityGsm.bsic),
-                            cellInfoGsm.cellIdentityGsm.mcc,
-                            cellInfoGsm.cellIdentityGsm.mnc,
-                            EMPTY_ALPHA_LONG,
-                            EMPTY_ALPHA_SHORT,
-                            cellInfoGsm.signalStrengthGsm.signalStrength,
-                            cellInfoGsm.signalStrengthGsm.bitErrorRate,
-                            cellInfoGsm.signalStrengthGsm.timingAdvance);
-                    break;
-                }
-
-                case CellInfoType.CDMA: {
-                    CellInfoCdma cellInfoCdma = record.cdma.get(0);
-                    writeToParcelForCdma(
-                            p,
-                            cellInfoCdma.cellIdentityCdma.networkId,
-                            cellInfoCdma.cellIdentityCdma.systemId,
-                            cellInfoCdma.cellIdentityCdma.baseStationId,
-                            cellInfoCdma.cellIdentityCdma.longitude,
-                            cellInfoCdma.cellIdentityCdma.latitude,
-                            EMPTY_ALPHA_LONG,
-                            EMPTY_ALPHA_SHORT,
-                            cellInfoCdma.signalStrengthCdma.dbm,
-                            cellInfoCdma.signalStrengthCdma.ecio,
-                            cellInfoCdma.signalStrengthEvdo.dbm,
-                            cellInfoCdma.signalStrengthEvdo.ecio,
-                            cellInfoCdma.signalStrengthEvdo.signalNoiseRatio);
-                    break;
-                }
-
-                case CellInfoType.LTE: {
-                    CellInfoLte cellInfoLte = record.lte.get(0);
-                    writeToParcelForLte(
-                            p,
-                            cellInfoLte.cellIdentityLte.ci,
-                            cellInfoLte.cellIdentityLte.pci,
-                            cellInfoLte.cellIdentityLte.tac,
-                            cellInfoLte.cellIdentityLte.earfcn,
-                            Integer.MAX_VALUE,
-                            cellInfoLte.cellIdentityLte.mcc,
-                            cellInfoLte.cellIdentityLte.mnc,
-                            EMPTY_ALPHA_LONG,
-                            EMPTY_ALPHA_SHORT,
-                            cellInfoLte.signalStrengthLte.signalStrength,
-                            cellInfoLte.signalStrengthLte.rsrp,
-                            cellInfoLte.signalStrengthLte.rsrq,
-                            cellInfoLte.signalStrengthLte.rssnr,
-                            cellInfoLte.signalStrengthLte.cqi,
-                            cellInfoLte.signalStrengthLte.timingAdvance,
-                            false /* isEndcAvailable */);
-                    break;
-                }
-
-                case CellInfoType.WCDMA: {
-                    CellInfoWcdma cellInfoWcdma = record.wcdma.get(0);
-                    writeToParcelForWcdma(
-                            p,
-                            cellInfoWcdma.cellIdentityWcdma.lac,
-                            cellInfoWcdma.cellIdentityWcdma.cid,
-                            cellInfoWcdma.cellIdentityWcdma.psc,
-                            cellInfoWcdma.cellIdentityWcdma.uarfcn,
-                            cellInfoWcdma.cellIdentityWcdma.mcc,
-                            cellInfoWcdma.cellIdentityWcdma.mnc,
-                            EMPTY_ALPHA_LONG,
-                            EMPTY_ALPHA_SHORT,
-                            cellInfoWcdma.signalStrengthWcdma.signalStrength,
-                            cellInfoWcdma.signalStrengthWcdma.bitErrorRate,
-                            Integer.MAX_VALUE,
-                            Integer.MAX_VALUE);
-                    break;
-                }
-
-                case CellInfoType.TD_SCDMA: {
-                    CellInfoTdscdma cellInfoTdscdma = record.tdscdma.get(0);
-                    writeToParcelForTdscdma(
-                            p,
-                            cellInfoTdscdma.cellIdentityTdscdma.lac,
-                            cellInfoTdscdma.cellIdentityTdscdma.cid,
-                            cellInfoTdscdma.cellIdentityTdscdma.cpid,
-                            Integer.MAX_VALUE,
-                            cellInfoTdscdma.cellIdentityTdscdma.mcc,
-                            cellInfoTdscdma.cellIdentityTdscdma.mnc,
-                            EMPTY_ALPHA_LONG,
-                            EMPTY_ALPHA_SHORT,
-                            Integer.MAX_VALUE,
-                            Integer.MAX_VALUE,
-                            convertTdscdmaRscpTo1_2(cellInfoTdscdma.signalStrengthTdscdma.rscp));
-                    break;
-                }
-                default:
-                    throw new RuntimeException("unexpected cellinfotype: " + record.cellInfoType);
-            }
-
-            p.setDataPosition(0);
-            CellInfo InfoRec = CellInfo.CREATOR.createFromParcel(p);
-            p.recycle();
-            response.add(InfoRec);
+            response.add(CellInfo.create(record));
         }
 
         return response;
@@ -5632,178 +5458,11 @@
         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
 
         for (android.hardware.radio.V1_2.CellInfo record : records) {
-            // first convert RIL CellInfo to Parcel
-            Parcel p = Parcel.obtain();
-            p.writeInt(record.cellInfoType);
-            p.writeInt(record.registered ? 1 : 0);
-            p.writeLong(SystemClock.elapsedRealtimeNanos());
-            p.writeInt(record.connectionStatus);
-            switch (record.cellInfoType) {
-                case CellInfoType.GSM: {
-                    android.hardware.radio.V1_2.CellInfoGsm cellInfoGsm = record.gsm.get(0);
-                    writeToParcelForGsm(
-                            p,
-                            cellInfoGsm.cellIdentityGsm.base.lac,
-                            cellInfoGsm.cellIdentityGsm.base.cid,
-                            cellInfoGsm.cellIdentityGsm.base.arfcn,
-                            Byte.toUnsignedInt(cellInfoGsm.cellIdentityGsm.base.bsic),
-                            cellInfoGsm.cellIdentityGsm.base.mcc,
-                            cellInfoGsm.cellIdentityGsm.base.mnc,
-                            cellInfoGsm.cellIdentityGsm.operatorNames.alphaLong,
-                            cellInfoGsm.cellIdentityGsm.operatorNames.alphaShort,
-                            cellInfoGsm.signalStrengthGsm.signalStrength,
-                            cellInfoGsm.signalStrengthGsm.bitErrorRate,
-                            cellInfoGsm.signalStrengthGsm.timingAdvance);
-                    break;
-                }
-
-                case CellInfoType.CDMA: {
-                    android.hardware.radio.V1_2.CellInfoCdma cellInfoCdma = record.cdma.get(0);
-                    writeToParcelForCdma(
-                            p,
-                            cellInfoCdma.cellIdentityCdma.base.networkId,
-                            cellInfoCdma.cellIdentityCdma.base.systemId,
-                            cellInfoCdma.cellIdentityCdma.base.baseStationId,
-                            cellInfoCdma.cellIdentityCdma.base.longitude,
-                            cellInfoCdma.cellIdentityCdma.base.latitude,
-                            cellInfoCdma.cellIdentityCdma.operatorNames.alphaLong,
-                            cellInfoCdma.cellIdentityCdma.operatorNames.alphaShort,
-                            cellInfoCdma.signalStrengthCdma.dbm,
-                            cellInfoCdma.signalStrengthCdma.ecio,
-                            cellInfoCdma.signalStrengthEvdo.dbm,
-                            cellInfoCdma.signalStrengthEvdo.ecio,
-                            cellInfoCdma.signalStrengthEvdo.signalNoiseRatio);
-                    break;
-                }
-
-                case CellInfoType.LTE: {
-                    android.hardware.radio.V1_2.CellInfoLte cellInfoLte = record.lte.get(0);
-                    writeToParcelForLte(
-                            p,
-                            cellInfoLte.cellIdentityLte.base.ci,
-                            cellInfoLte.cellIdentityLte.base.pci,
-                            cellInfoLte.cellIdentityLte.base.tac,
-                            cellInfoLte.cellIdentityLte.base.earfcn,
-                            cellInfoLte.cellIdentityLte.bandwidth,
-                            cellInfoLte.cellIdentityLte.base.mcc,
-                            cellInfoLte.cellIdentityLte.base.mnc,
-                            cellInfoLte.cellIdentityLte.operatorNames.alphaLong,
-                            cellInfoLte.cellIdentityLte.operatorNames.alphaShort,
-                            cellInfoLte.signalStrengthLte.signalStrength,
-                            cellInfoLte.signalStrengthLte.rsrp,
-                            cellInfoLte.signalStrengthLte.rsrq,
-                            cellInfoLte.signalStrengthLte.rssnr,
-                            cellInfoLte.signalStrengthLte.cqi,
-                            cellInfoLte.signalStrengthLte.timingAdvance,
-                            false /* isEndcAvailable */);
-                    break;
-                }
-
-                case CellInfoType.WCDMA: {
-                    android.hardware.radio.V1_2.CellInfoWcdma cellInfoWcdma = record.wcdma.get(0);
-                    writeToParcelForWcdma(
-                            p,
-                            cellInfoWcdma.cellIdentityWcdma.base.lac,
-                            cellInfoWcdma.cellIdentityWcdma.base.cid,
-                            cellInfoWcdma.cellIdentityWcdma.base.psc,
-                            cellInfoWcdma.cellIdentityWcdma.base.uarfcn,
-                            cellInfoWcdma.cellIdentityWcdma.base.mcc,
-                            cellInfoWcdma.cellIdentityWcdma.base.mnc,
-                            cellInfoWcdma.cellIdentityWcdma.operatorNames.alphaLong,
-                            cellInfoWcdma.cellIdentityWcdma.operatorNames.alphaShort,
-                            cellInfoWcdma.signalStrengthWcdma.base.signalStrength,
-                            cellInfoWcdma.signalStrengthWcdma.base.bitErrorRate,
-                            cellInfoWcdma.signalStrengthWcdma.rscp,
-                            cellInfoWcdma.signalStrengthWcdma.ecno);
-                    break;
-                }
-
-                case CellInfoType.TD_SCDMA: {
-                    android.hardware.radio.V1_2.CellInfoTdscdma cellInfoTdscdma =
-                            record.tdscdma.get(0);
-                    writeToParcelForTdscdma(
-                            p,
-                            cellInfoTdscdma.cellIdentityTdscdma.base.lac,
-                            cellInfoTdscdma.cellIdentityTdscdma.base.cid,
-                            cellInfoTdscdma.cellIdentityTdscdma.base.cpid,
-                            cellInfoTdscdma.cellIdentityTdscdma.uarfcn,
-                            cellInfoTdscdma.cellIdentityTdscdma.base.mcc,
-                            cellInfoTdscdma.cellIdentityTdscdma.base.mnc,
-                            cellInfoTdscdma.cellIdentityTdscdma.operatorNames.alphaLong,
-                            cellInfoTdscdma.cellIdentityTdscdma.operatorNames.alphaShort,
-                            cellInfoTdscdma.signalStrengthTdscdma.signalStrength,
-                            cellInfoTdscdma.signalStrengthTdscdma.bitErrorRate,
-                            cellInfoTdscdma.signalStrengthTdscdma.rscp);
-                    break;
-                }
-
-                default:
-                    throw new RuntimeException("unexpected cellinfotype: " + record.cellInfoType);
-            }
-
-            p.setDataPosition(0);
-            CellInfo InfoRec = CellInfo.CREATOR.createFromParcel(p);
-            p.recycle();
-            response.add(InfoRec);
+            response.add(CellInfo.create(record));
         }
-
         return response;
     }
 
-    private static int convertTdscdmaRscpTo1_2(int rscp) {
-        // The HAL 1.0 range is 25..120; the ASU/ HAL 1.2 range is 0..96;
-        // yes, this means the range in 1.0 cannot express -24dBm = 96
-        if (rscp >= 25 && rscp <= 120) {
-            // First we flip the sign to convert from the HALs -rscp to the actual RSCP value.
-            int rscpDbm = -rscp;
-            // Then to convert from RSCP to ASU, we apply the offset which aligns 0 ASU to -120dBm.
-            return rscpDbm + 120;
-        }
-        return Integer.MAX_VALUE;
-    }
-
-    /** Convert HAL 1.0 Signal Strength to android SignalStrength */
-    @VisibleForTesting
-    public static SignalStrength convertHalSignalStrength(
-            android.hardware.radio.V1_0.SignalStrength signalStrength) {
-        return new SignalStrength(
-                signalStrength.gw.signalStrength,
-                signalStrength.gw.bitErrorRate,
-                signalStrength.cdma.dbm,
-                signalStrength.cdma.ecio,
-                signalStrength.evdo.dbm,
-                signalStrength.evdo.ecio,
-                signalStrength.evdo.signalNoiseRatio,
-                signalStrength.lte.signalStrength,
-                signalStrength.lte.rsrp,
-                signalStrength.lte.rsrq,
-                signalStrength.lte.rssnr,
-                signalStrength.lte.cqi,
-                convertTdscdmaRscpTo1_2(signalStrength.tdScdma.rscp));
-    }
-
-    /** Convert HAL 1.2 Signal Strength to android SignalStrength */
-    @VisibleForTesting
-    public static SignalStrength convertHalSignalStrength_1_2(
-            android.hardware.radio.V1_2.SignalStrength signalStrength) {
-        return new SignalStrength(
-                signalStrength.gsm.signalStrength,
-                signalStrength.gsm.bitErrorRate,
-                signalStrength.cdma.dbm,
-                signalStrength.cdma.ecio,
-                signalStrength.evdo.dbm,
-                signalStrength.evdo.ecio,
-                signalStrength.evdo.signalNoiseRatio,
-                signalStrength.lte.signalStrength,
-                signalStrength.lte.rsrp,
-                signalStrength.lte.rsrq,
-                signalStrength.lte.rssnr,
-                signalStrength.lte.cqi,
-                signalStrength.tdScdma.rscp,
-                signalStrength.wcdma.base.signalStrength,
-                signalStrength.wcdma.rscp);
-    }
-
     /**
      * @return The {@link IwlanOperationMode IWLAN operation mode}
      */
diff --git a/src/java/com/android/internal/telephony/RadioConfig.java b/src/java/com/android/internal/telephony/RadioConfig.java
index 3706dc1..b47b4f7 100644
--- a/src/java/com/android/internal/telephony/RadioConfig.java
+++ b/src/java/com/android/internal/telephony/RadioConfig.java
@@ -41,6 +41,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.NoSuchElementException;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -53,8 +54,16 @@
 
     private static final int EVENT_SERVICE_DEAD = 1;
 
+    private static final HalVersion RADIO_CONFIG_HAL_VERSION_UNKNOWN = new HalVersion(-1, -1);
+
+    private static final HalVersion RADIO_CONFIG_HAL_VERSION_1_0 = new HalVersion(1, 0);
+
+    private static final HalVersion RADIO_CONFIG_HAL_VERSION_1_1 = new HalVersion(1, 1);
+
     private final boolean mIsMobileNetworkSupported;
     private volatile IRadioConfig mRadioConfigProxy = null;
+    // IRadioConfig version
+    private HalVersion mRadioConfigVersion = RADIO_CONFIG_HAL_VERSION_UNKNOWN;
     private final ServiceDeathRecipient mServiceDeathRecipient;
     private final AtomicLong mRadioConfigProxyCookie = new AtomicLong(0);
     private final RadioConfigResponse mRadioConfigResponse;
@@ -166,24 +175,9 @@
             return mRadioConfigProxy;
         }
 
-        try {
-            mRadioConfigProxy = IRadioConfig.getService(true);
-            if (mRadioConfigProxy != null) {
-                mRadioConfigProxy.linkToDeath(mServiceDeathRecipient,
-                        mRadioConfigProxyCookie.incrementAndGet());
-                mRadioConfigProxy.setResponseFunctions(mRadioConfigResponse,
-                        mRadioConfigIndication);
-            } else {
-                loge("getRadioConfigProxy: mRadioConfigProxy == null");
-            }
-        } catch (RemoteException | RuntimeException e) {
-            mRadioConfigProxy = null;
-            loge("getRadioConfigProxy: RadioConfigProxy getService/setResponseFunctions: " + e);
-        }
+        updateRadioConfigProxy();
 
         if (mRadioConfigProxy == null) {
-            // getService() is a blocking call, so this should never happen
-            loge("getRadioConfigProxy: mRadioConfigProxy == null");
             if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
@@ -194,6 +188,42 @@
         return mRadioConfigProxy;
     }
 
+    private void updateRadioConfigProxy() {
+        try {
+            // Try to get service from different versions.
+            try {
+                mRadioConfigProxy = android.hardware.radio.config.V1_1.IRadioConfig.getService(
+                        true);
+                mRadioConfigVersion = RADIO_CONFIG_HAL_VERSION_1_1;
+            } catch (NoSuchElementException e) {
+            }
+
+            if (mRadioConfigProxy == null) {
+                try {
+                    mRadioConfigProxy = android.hardware.radio.config.V1_0
+                            .IRadioConfig.getService(true);
+                    mRadioConfigVersion = RADIO_CONFIG_HAL_VERSION_1_0;
+                } catch (NoSuchElementException e) {
+                }
+            }
+
+            if (mRadioConfigProxy == null) {
+                loge("getRadioConfigProxy: mRadioConfigProxy == null");
+                return;
+            }
+
+            // Link to death recipient and set response. If fails, set proxy to null and return.
+            mRadioConfigProxy.linkToDeath(mServiceDeathRecipient,
+                    mRadioConfigProxyCookie.incrementAndGet());
+            mRadioConfigProxy.setResponseFunctions(mRadioConfigResponse,
+                    mRadioConfigIndication);
+        } catch (RemoteException | RuntimeException e) {
+            mRadioConfigProxy = null;
+            loge("getRadioConfigProxy: RadioConfigProxy setResponseFunctions: " + e);
+            return;
+        }
+    }
+
     private RILRequest obtainRequest(int request, Message result, WorkSource workSource) {
         RILRequest rr = RILRequest.obtain(request, result, workSource);
         synchronized (mRequestList) {
diff --git a/src/java/com/android/internal/telephony/RadioIndication.java b/src/java/com/android/internal/telephony/RadioIndication.java
index 1614a27..e097212 100644
--- a/src/java/com/android/internal/telephony/RadioIndication.java
+++ b/src/java/com/android/internal/telephony/RadioIndication.java
@@ -25,6 +25,7 @@
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CELL_INFO_LIST;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_DATA_CALL_LIST_CHANGED;
+import static com.android.internal.telephony.RILConstants.RIL_UNSOL_EMERGENCY_NUMBER_LIST;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_HARDWARE_CONFIG_CHANGED;
@@ -92,6 +93,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.SmsMessage;
 import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
 
 import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
 import com.android.internal.telephony.cdma.CdmaInformationRecords;
@@ -229,7 +231,7 @@
                                       android.hardware.radio.V1_0.SignalStrength signalStrength) {
         mRil.processIndication(indicationType);
 
-        SignalStrength ss = RIL.convertHalSignalStrength(signalStrength);
+        SignalStrength ss = new SignalStrength(signalStrength);
         // Note this is set to "verbose" because it happens frequently
         if (RIL.RILJ_LOGV) mRil.unsljLogvRet(RIL_UNSOL_SIGNAL_STRENGTH, ss);
 
@@ -261,7 +263,7 @@
                                       android.hardware.radio.V1_2.SignalStrength signalStrength) {
         mRil.processIndication(indicationType);
 
-        SignalStrength ss = RIL.convertHalSignalStrength_1_2(signalStrength);
+        SignalStrength ss = new SignalStrength(signalStrength);
         // Note this is set to "verbose" because it happens frequently
         if (RIL.RILJ_LOGV) mRil.unsljLogvRet(RIL_UNSOL_SIGNAL_STRENGTH, ss);
 
@@ -306,6 +308,27 @@
                 new AsyncResult(null, response, null));
     }
 
+    /**
+     * Indicates current emergency number list.
+     */
+    public void currentEmergencyNumberList(int indicationType,
+            ArrayList<android.hardware.radio.V1_4.EmergencyNumber> emergencyNumberList) {
+        List<EmergencyNumber> response = new ArrayList<>(emergencyNumberList.size());
+
+        for (android.hardware.radio.V1_4.EmergencyNumber emergencyNumberHal
+                : emergencyNumberList) {
+            EmergencyNumber emergencyNumber = new EmergencyNumber(emergencyNumberHal.number,
+                    MccTable.countryCodeForMcc(emergencyNumberHal.mcc), emergencyNumberHal.mnc,
+                    emergencyNumberHal.categories, emergencyNumberHal.sources);
+            response.add(emergencyNumber);
+        }
+
+        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_EMERGENCY_NUMBER_LIST, response);
+
+        mRil.mEmergencyNumberListRegistrants.notifyRegistrants(
+                new AsyncResult(null, response, null));
+    }
+
     public void dataCallListChanged(int indicationType, ArrayList<SetupDataCallResult> dcList) {
         mRil.processIndication(indicationType);
 
diff --git a/src/java/com/android/internal/telephony/RadioResponse.java b/src/java/com/android/internal/telephony/RadioResponse.java
index af6dcc3..518b4f9 100644
--- a/src/java/com/android/internal/telephony/RadioResponse.java
+++ b/src/java/com/android/internal/telephony/RadioResponse.java
@@ -1468,6 +1468,13 @@
         }
     }
 
+    /**
+     * @param responseInfo Response info struct containing response type, serial no. and error
+     */
+    public void emergencyDialResponse(RadioResponseInfo responseInfo) {
+        responseVoid(responseInfo);
+    }
+
     private void responseInts(RadioResponseInfo responseInfo, int ...var) {
         final ArrayList<Integer> ints = new ArrayList<>();
         for (int i = 0; i < var.length; i++) {
@@ -1720,7 +1727,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            SignalStrength ret = RIL.convertHalSignalStrength(signalStrength);
+            SignalStrength ret = new SignalStrength(signalStrength);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -1734,7 +1741,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            SignalStrength ret = RIL.convertHalSignalStrength_1_2(signalStrength);
+            SignalStrength ret = new SignalStrength(signalStrength);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
diff --git a/src/java/com/android/internal/telephony/RcsMessageStoreController.java b/src/java/com/android/internal/telephony/RcsMessageStoreController.java
deleted file mode 100644
index c2edd95..0000000
--- a/src/java/com/android/internal/telephony/RcsMessageStoreController.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2017 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;
-
-import android.content.Context;
-import android.os.ServiceManager;
-import android.telephony.Rlog;
-import android.telephony.ims.RcsMessageStore;
-import android.telephony.ims.aidl.IRcs;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-
-/** Backing implementation of {@link RcsMessageStore}. */
-public class RcsMessageStoreController extends IRcs.Stub {
-    private static final String TAG = "RcsMessageStoreController";
-    private static final String RCS_SERVICE_NAME = "ircs";
-
-    private static RcsMessageStoreController sInstance;
-
-    private final Context mContext;
-
-    /** Initialize the instance. Should only be called once. */
-    public static RcsMessageStoreController init(Context context) {
-        synchronized (RcsMessageStoreController.class) {
-            if (sInstance == null) {
-                sInstance = new RcsMessageStoreController(context);
-            } else {
-                Rlog.e(TAG, "init() called multiple times! sInstance = " + sInstance);
-            }
-        }
-        return sInstance;
-    }
-
-    private RcsMessageStoreController(Context context) {
-        mContext = context;
-        if (ServiceManager.getService(RCS_SERVICE_NAME) == null) {
-            ServiceManager.addService(RCS_SERVICE_NAME, this);
-        }
-    }
-
-    @VisibleForTesting
-    public RcsMessageStoreController(Context context, Void unused) {
-        mContext = context;
-    }
-
-    @Override
-    public void deleteThread(int threadId) {
-        // TODO - add implementation
-    }
-
-    @Override
-    public int getMessageCount(int rcsThreadId) {
-        // TODO - add implementation. Return a magic number for now to test the RPC calls
-        return 1018;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 3a5e9ad..f86268a 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -3062,7 +3062,7 @@
             }
 
             if (hasCssIndicatorChanged) {
-                mPhone.notifyDataConnection(Phone.REASON_CSS_INDICATOR_CHANGED);
+                mPhone.notifyDataConnection();
             }
 
             mReasonDataDenied = mNewReasonDataDenied;
@@ -3190,7 +3190,6 @@
         if (hasRilDataRadioTechnologyChanged || hasRilVoiceRadioTechnologyChanged) {
             logRatChange();
 
-            updateRatTypeForSignalStrength();
             notifySignalStrength();
         }
 
@@ -3200,13 +3199,7 @@
 
         if (hasDataRegStateChanged || hasRilDataRadioTechnologyChanged) {
             notifyDataRegStateRilRadioTechnologyChanged();
-
-            if (ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
-                    == mSS.getRilDataRadioTechnology()) {
-                mPhone.notifyDataConnection(Phone.REASON_IWLAN_AVAILABLE);
-            } else {
-                mPhone.notifyDataConnection(null);
-            }
+            mPhone.notifyDataConnection();
         }
 
         if (hasVoiceRoamingOn || hasVoiceRoamingOff || hasDataRoamingOn || hasDataRoamingOff) {
@@ -4344,53 +4337,19 @@
 
         if ((ar.exception == null) && (ar.result != null)) {
             mSignalStrength = (SignalStrength) ar.result;
-            mSignalStrength.validateInput();
-            mSignalStrength.setLteRsrpBoost(mSS.getLteEarfcnRsrpBoost());
 
             PersistableBundle config = getCarrierConfig();
-            mSignalStrength.setUseOnlyRsrpForLteLevel(config.getBoolean(
-                    CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL));
-            mSignalStrength.setLteRsrpThresholds(config.getIntArray(
-                    CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY));
-            mSignalStrength.setWcdmaDefaultSignalMeasurement(config.getString(
-                    CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING));
-            mSignalStrength.setWcdmaRscpThresholds(config.getIntArray(
-                    CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY));
+            mSignalStrength.updateLevel(config, mSS);
         } else {
             log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
-            mSignalStrength = new SignalStrength(true);
+            mSignalStrength = new SignalStrength();
         }
 
-        updateRatTypeForSignalStrength();
         boolean ssChanged = notifySignalStrength();
 
         return ssChanged;
     }
 
-    private void updateRatTypeForSignalStrength() {
-        if (mSignalStrength != null) {
-            boolean isGsm = false;
-            int dataRat = mSS.getRilDataRadioTechnology();
-            int voiceRat = mSS.getRilVoiceRadioTechnology();
-
-            // Override isGsm based on currently camped data and voice RATs
-            // Set isGsm to true if the RAT belongs to GSM family and not IWLAN
-            if ((dataRat != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
-                    && ServiceState.isGsm(dataRat))
-                    || (voiceRat != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
-                    && ServiceState.isGsm(voiceRat))) {
-                isGsm = true;
-            }
-
-            if (dataRat == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN
-                    && voiceRat == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
-                mSignalStrength.fixType();
-            } else {
-                mSignalStrength.setGsm(isGsm);
-            }
-        }
-    }
-
     /**
      * Hang up all voice call and turn off radio. Implemented by derived class.
      */
@@ -4859,7 +4818,7 @@
     }
 
     private void setSignalStrengthDefaultValues() {
-        mSignalStrength = new SignalStrength(true);
+        mSignalStrength = new SignalStrength();
     }
 
     protected String getHomeOperatorNumeric() {
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index bd92672..f6c2d86 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -303,10 +303,13 @@
                 SubscriptionManager.MCC_STRING));
         String mnc = cursor.getString(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.MNC_STRING));
+        // cardId is the private ICCID/EID string, also known as the card string
         String cardId = cursor.getString(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.CARD_ID));
         String countryIso = cursor.getString(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.ISO_COUNTRY_CODE));
+        // publicCardId is the publicly exposed int card ID
+        int publicCardId = UiccController.getInstance().convertToPublicCardId(cardId);
         boolean isEmbedded = cursor.getInt(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.IS_EMBEDDED)) == 1;
         int carrierId = cursor.getInt(cursor.getColumnIndexOrThrow(
@@ -334,8 +337,9 @@
                     + " dataRoaming:" + dataRoaming + " mcc:" + mcc + " mnc:" + mnc
                     + " countIso:" + countryIso + " isEmbedded:"
                     + isEmbedded + " accessRules:" + Arrays.toString(accessRules)
-                    + " cardId:" + cardIdToPrint + " isOpportunistic:" + isOpportunistic
-                    + " groupUUID:" + groupUUID + " isMetered:" + isMetered);
+                    + " cardId:" + cardIdToPrint + " publicCardId:" + publicCardId
+                    + " isOpportunistic:" + isOpportunistic + " groupUUID:" + groupUUID
+                    + " isMetered:" + isMetered);
         }
 
         // If line1number has been set to a different number, use it instead.
@@ -345,7 +349,8 @@
         }
         return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
                 nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
-                isEmbedded, accessRules, cardId, isOpportunistic, groupUUID, isMetered, carrierId);
+                isEmbedded, accessRules, cardId, publicCardId, isOpportunistic, groupUUID,
+                isMetered, false /* isGroupDisabled = false */, carrierId);
     }
 
     /**
@@ -2338,95 +2343,220 @@
      * Being in the same group means they might be activated or deactivated
      * together, some of them may be invisible to the users, etc.
      *
-     * Caller will either have {@link android.Manifest.permission.MODIFY_PHONE_STATE}
-     * permission or can manage all subscriptions in the list, according to their
-     * access rules.
+     * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+     * permission or had carrier privilege permission on the subscriptions:
+     * {@link TelephonyManager#hasCarrierPrivileges(int)} or
+     * {@link SubscriptionManager#canManageSubscription(SubscriptionInfo)}
      *
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
+     *
+     * @param subIdList list of subId that will be in the same group
      * @return groupUUID a UUID assigned to the subscription group. It returns
      * null if fails.
      *
      */
     @Override
     public String setSubscriptionGroup(int[] subIdList, String callingPackage) {
-        boolean hasModifyPermission = mContext.checkCallingOrSelfPermission(
-                android.Manifest.permission.MODIFY_PHONE_STATE) == PERMISSION_GRANTED;
+        if (subIdList == null || subIdList.length == 0) {
+            return null;
+        }
+        // If it doesn't have modify phone state permission, or carrier privilege permission,
+        // a SecurityException will be thrown. If it's due to invalid parameter or internal state,
+        // it will return null.
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+                != PERMISSION_GRANTED && !checkCarrierPrivilegeOnSubList(
+                        subIdList, callingPackage)) {
+            return null;
+        }
 
-        // If caller doesn't have modify permission or carrier privilege permission on certain
-        // subscriptions, maybe because the they are not active. So we keep them in a hashset and
-        // later check access rules in our database to know whether they can manage them.
-        Set<Integer> subIdCheckList = new HashSet<>();
+        long identity = Binder.clearCallingIdentity();
+
+        try {
+            // Generate a UUID.
+            String groupUUID = UUID.randomUUID().toString();
+
+            ContentValues value = new ContentValues();
+            value.put(SubscriptionManager.GROUP_UUID, groupUUID);
+            int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI,
+                    value, getSelectionForSubIdList(subIdList), null);
+
+            if (DBG) logdl("setSubscriptionGroup update DB result: " + result);
+
+            refreshCachedActiveSubscriptionInfoList();
+
+            return groupUUID;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
+     * Remove a list of subscriptions from their subscription group.
+     * See {@link #setSubscriptionGroup(int[], String)} for more details.
+     *
+     * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+     * permission or had carrier privilege permission on the subscriptions:
+     * {@link TelephonyManager#hasCarrierPrivileges(int)} or
+     * {@link SubscriptionManager#canManageSubscription(SubscriptionInfo)}
+     *
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
+     *
+     * @param subIdList list of subId that need removing from their groups.
+     * @return whether the operation succeeds.
+     *
+     */
+    public boolean removeSubscriptionsFromGroup(int[] subIdList, String callingPackage) {
+        if (subIdList == null || subIdList.length == 0) {
+            return false;
+        }
+        // If it doesn't have modify phone state permission, or carrier privilege permission,
+        // a SecurityException will be thrown. If it's due to invalid parameter or internal state,
+        // it will return null.
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+                != PERMISSION_GRANTED && !checkCarrierPrivilegeOnSubList(
+                subIdList, callingPackage)) {
+            return false;
+        }
+
+        long identity = Binder.clearCallingIdentity();
+
+        try {
+            ContentValues value = new ContentValues();
+            value.put(SubscriptionManager.GROUP_UUID, (String) null);
+            int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI,
+                    value, getSelectionForSubIdList(subIdList), null);
+
+            if (DBG) logdl("setSubscriptionGroup update DB result: " + result);
+
+            refreshCachedActiveSubscriptionInfoList();
+
+            return result != 0;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
+     *  Helper function to check if the caller has carrier privilege permissions on a list of subId.
+     *  The check can either be processed against access rules on currently active SIM cards, or
+     *  the access rules we keep in our database for currently inactive eSIMs.
+     *
+     *  Throws {@link SecurityException} if it fails.
+     *
+     *  @return true if checking passes on all subId. false if subId is invalid or doesn't exist,
+     *  or sub controller is not ready yet.
+     */
+    private boolean checkCarrierPrivilegeOnSubList(int[] subIdList, String callingPackage) {
+        mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+        // Check carrier privilege permission on active subscriptions first.
+        // If it fails, they could be inactive. So keep them in a HashSet and later check
+        // access rules in our database.
+        Set<Integer> checkSubList = new HashSet<>();
         for (int subId : subIdList) {
-            if (!mTelephonyManager.hasCarrierPrivileges(subId)) {
-                subIdCheckList.add(subId);
+            if (isActiveSubId(subId)) {
+                if (!mTelephonyManager.hasCarrierPrivileges(subId)) {
+                    throw new SecurityException("Need carrier privilege on subId " + subId);
+                }
+            } else {
+                checkSubList.add(subId);
             }
         }
 
+        if (checkSubList.isEmpty()) {
+            return true;
+        }
+
         long identity = Binder.clearCallingIdentity();
 
         try {
             if (!isSubInfoReady()) {
                 if (DBG) logdl("[getSubscriptionInfoList] Sub Controller not ready");
-                return null;
+                return false;
             }
 
+            // Check access rules for each sub info.
             SubscriptionManager subscriptionManager = (SubscriptionManager)
                     mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
-            List<SubscriptionInfo> subList = getSubInfo(null, null);
-
+            List<SubscriptionInfo> subList = getSubInfo(getSelectionForSubIdList(subIdList), null);
             for (SubscriptionInfo subInfo : subList) {
-                if (subIdCheckList.contains(subInfo.getSubscriptionId())) {
-                    // If caller doesn't have modify permission or privilege access to
-                    // the subscription, operation is invalid and returns null.
-                    if (hasModifyPermission || (subInfo.isEmbedded()
-                            && subscriptionManager.canManageSubscription(
-                                    subInfo, callingPackage))) {
-                        subIdCheckList.remove(subInfo.getSubscriptionId());
+                if (checkSubList.contains(subInfo.getSubscriptionId())) {
+                    if (subInfo.isEmbedded() && subscriptionManager.canManageSubscription(
+                            subInfo, callingPackage)) {
+                        checkSubList.remove(subInfo.getSubscriptionId());
                     } else {
-                        if (DBG) {
-                            logdl("setSubscriptionGroup doesn't have permission on"
-                                    + " subInfo " + subInfo);
-                        }
-                        return null;
+                        throw new SecurityException("Need carrier privilege on subId "
+                                + subInfo.getSubscriptionId());
                     }
                 }
             }
 
-            if (!subIdCheckList.isEmpty()) {
-                // Some SubId not found.
-                StringBuilder subIdNotFound = new StringBuilder();
-                for (int subId : subIdCheckList) {
-                    subIdNotFound.append(subId + " ");
-                }
-                if (DBG) {
-                    logdl("setSubscriptionGroup subId not existed: "
-                            + subIdNotFound.toString());
-                }
+            return checkSubList.isEmpty();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
 
+    /**
+     * Helper function to create selection argument of a list of subId.
+     * The result should be: "in (subId1, subId2, ...)".
+     */
+    private String getSelectionForSubIdList(int[] subId) {
+        StringBuilder selection = new StringBuilder();
+        selection.append(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID);
+        selection.append(" IN (");
+        for (int i = 0; i < subId.length - 1; i++) {
+            selection.append(subId[i] + ", ");
+        }
+        selection.append(subId[subId.length - 1]);
+        selection.append(")");
+
+        return selection.toString();
+    }
+
+    /**
+     * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
+     * See {@link #setSubscriptionGroup(int[], String)} for more details.
+     *
+     * Caller will either have {@link android.Manifest.permission#READ_PHONE_STATE}
+     * permission or had carrier privilege permission on the subscription.
+     * {@link TelephonyManager#hasCarrierPrivileges(int)}
+     *
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
+     *
+     * @param subId of which list of subInfo from the same group will be returned.
+     * @return list of subscriptionInfo that belong to the same group, including the given
+     * subscription itself. It will return null if the subscription doesn't exist or it
+     * doesn't belong to any group.
+     *
+     */
+    public List<SubscriptionInfo> getSubscriptionsInGroup(int subId, String callingPackage) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mContext, subId, callingPackage, "getSubscriptionsInGroup")) {
+            return null;
+        }
+
+        long identity = Binder.clearCallingIdentity();
+
+        try {
+            SubscriptionInfo info = getActiveSubscriptionInfo(subId, callingPackage);
+            if (info == null || TextUtils.isEmpty(info.getGroupUuid())) {
                 return null;
             }
 
-            // Generate a UUID.
-            String groupUUID = UUID.randomUUID().toString();
+            String groupUuid = info.getGroupUuid();
+            List<SubscriptionInfo> infoList = getAvailableSubscriptionInfoList(callingPackage);
 
-            // Selection should be: "in (subId1, subId2, ...)".
-            StringBuilder selection = new StringBuilder();
-            selection.append(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID);
-            selection.append(" IN (");
-            for (int i = 0; i < subIdList.length - 1; i++) {
-                selection.append(subIdList[i] + ", ");
+            // Shouldn't happen because we've verified the subId belongs to an active subscription.
+            if (infoList == null) {
+                return null;
             }
-            selection.append(subIdList[subIdList.length - 1]);
-            selection.append(")");
-            ContentValues value = new ContentValues();
-            value.put(SubscriptionManager.GROUP_UUID, groupUUID);
-            int result = mContext.getContentResolver().update(
-                    SubscriptionManager.CONTENT_URI, value, selection.toString(), null);
 
-            if (DBG) logdl("setSubscriptionGroup update DB result: " + result);
-
-            refreshCachedActiveSubscriptionInfoList();
-
-            return groupUUID;
+            return infoList.stream().filter(
+                    subscriptionInfo -> groupUuid.equals(subscriptionInfo.getGroupUuid()))
+                    .collect(Collectors.toList());
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index a8fa4b8..35b8344 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -28,6 +28,7 @@
 
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.cdma.EriManager;
+import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 import com.android.internal.telephony.dataconnection.DcTracker;
 import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
@@ -371,8 +372,13 @@
         return IDeviceIdleController.Stub.asInterface(
                 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
     }
+
     public LocaleTracker makeLocaleTracker(Phone phone, NitzStateMachine nitzStateMachine,
                                            Looper looper) {
         return new LocaleTracker(phone, nitzStateMachine, looper);
     }
+
+    public DataEnabledSettings makeDataEnabledSettings(Phone phone) {
+        return new DataEnabledSettings(phone);
+    }
 }
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
index fa13dac..0b4da48 100644
--- a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
+++ b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
@@ -344,7 +344,6 @@
      */
     public boolean isConnectable() {
         return isReady() && ((mState == DctConstants.State.IDLE)
-                                || (mState == DctConstants.State.SCANNING)
                                 || (mState == DctConstants.State.RETRYING)
                                 || (mState == DctConstants.State.FAILED));
     }
@@ -364,7 +363,6 @@
     public boolean isConnectedOrConnecting() {
         return isReady() && ((mState == DctConstants.State.CONNECTED)
                                 || (mState == DctConstants.State.CONNECTING)
-                                || (mState == DctConstants.State.SCANNING)
                                 || (mState == DctConstants.State.RETRYING));
     }
 
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 216ebb6..593945d 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -174,14 +174,16 @@
     private ApnSetting mApnSetting;
     private ConnectionParams mConnectionParams;
     private DisconnectParams mDisconnectParams;
-    private DataFailCause mDcFailCause;
+    @DataFailCause.FailCause
+    private int mDcFailCause;
 
     private Phone mPhone;
     private DataServiceManager mDataServiceManager;
     private LinkProperties mLinkProperties = new LinkProperties();
     private long mCreateTime;
     private long mLastFailTime;
-    private DataFailCause mLastFailCause;
+    @DataFailCause.FailCause
+    private int mLastFailCause;
     private static final String NULL_IP = "0.0.0.0";
     private Object mUserData;
     private int mSubscriptionOverride;
@@ -190,6 +192,7 @@
     private NetworkInfo mNetworkInfo;
     private DcNetworkAgent mNetworkAgent;
     private LocalLog mNetCapsLocalLog = new LocalLog(50);
+    private int mDisabledApnTypeBitMask = 0;
 
     int mTag;
     public int mCid;
@@ -350,10 +353,10 @@
         ERROR_STALE,
         ERROR_DATA_SERVICE_SPECIFIC_ERROR;
 
-        public DataFailCause mFailCause;
+        public int mFailCause;
 
         SetupResult() {
-            mFailCause = DataFailCause.fromInt(0);
+            mFailCause = DataFailCause.getFailCause(0);
         }
 
         @Override
@@ -514,7 +517,7 @@
         // Check if we should fake an error.
         if (mDcTesterFailBringUpAll.getDcFailBringUp().mCounter  > 0) {
             DataCallResponse response = new DataCallResponse(
-                    mDcTesterFailBringUpAll.getDcFailBringUp().mFailCause.getErrorCode(),
+                    mDcTesterFailBringUpAll.getDcFailBringUp().mFailCause,
                     mDcTesterFailBringUpAll.getDcFailBringUp().mSuggestedRetryTime, 0, 0, "", "",
                     null, null, null, null, PhoneConstants.UNSET_MTU);
 
@@ -607,11 +610,9 @@
         notifyAllWithEvent(null, DctConstants.EVENT_DATA_SETUP_COMPLETE, reason);
     }
 
-    private void notifyAllOfDisconnectDcRetrying(String reason) {
-        notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DC_RETRYING, reason);
-    }
-    private void notifyAllDisconnectCompleted(DataFailCause cause) {
-        notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DONE, cause.toString());
+    private void notifyAllDisconnectCompleted(@DataFailCause.FailCause int cause) {
+        notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DONE,
+                DataFailCause.toString(cause));
     }
 
 
@@ -622,7 +623,8 @@
      * @param cause and if no error the cause is DataFailCause.NONE
      * @param sendAll is true if all contexts are to be notified
      */
-    private void notifyConnectCompleted(ConnectionParams cp, DataFailCause cause, boolean sendAll) {
+    private void notifyConnectCompleted(ConnectionParams cp, @DataFailCause.FailCause int cause,
+                                        boolean sendAll) {
         ApnContext alreadySent = null;
 
         if (cp != null && cp.mOnCompletedMsg != null) {
@@ -642,9 +644,9 @@
                 mLastFailTime = timeStamp;
 
                 // Return message with a Throwable exception to signify an error.
-                if (cause == null) cause = DataFailCause.UNKNOWN;
+                if (cause == DataFailCause.NONE) cause = DataFailCause.UNKNOWN;
                 AsyncResult.forMessage(connectionCompletedMsg, cause,
-                        new Throwable(cause.toString()));
+                        new Throwable(DataFailCause.toString(cause)));
             }
             if (DBG) {
                 log("notifyConnectCompleted at " + timeStamp + " cause=" + cause
@@ -654,9 +656,9 @@
             connectionCompletedMsg.sendToTarget();
         }
         if (sendAll) {
-            log("Send to all. " + alreadySent + " " + cause.toString());
+            log("Send to all. " + alreadySent + " " + DataFailCause.toString(cause));
             notifyAllWithEvent(alreadySent, DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR,
-                    cause.toString());
+                    DataFailCause.toString(cause));
         }
     }
 
@@ -688,7 +690,7 @@
         }
         if (sendAll) {
             if (reason == null) {
-                reason = DataFailCause.UNKNOWN.toString();
+                reason = DataFailCause.toString(DataFailCause.UNKNOWN);
             }
             notifyAllWithEvent(alreadySent, DctConstants.EVENT_DISCONNECT_DONE, reason);
         }
@@ -738,7 +740,8 @@
         mApnSetting = null;
         mUnmeteredUseOnly = false;
         mRestrictedNetworkOverride = false;
-        mDcFailCause = null;
+        mDcFailCause = DataFailCause.NONE;
+        mDisabledApnTypeBitMask = 0;
     }
 
     /**
@@ -763,12 +766,12 @@
             result = SetupResult.ERROR_RADIO_NOT_AVAILABLE;
             result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE;
         } else if (response.getStatus() != 0) {
-            if (response.getStatus() == DataFailCause.RADIO_NOT_AVAILABLE.getErrorCode()) {
+            if (response.getStatus() == DataFailCause.RADIO_NOT_AVAILABLE) {
                 result = SetupResult.ERROR_RADIO_NOT_AVAILABLE;
                 result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE;
             } else {
                 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
-                result.mFailCause = DataFailCause.fromInt(response.getStatus());
+                result.mFailCause = DataFailCause.getFailCause(response.getStatus());
             }
         } else {
             if (DBG) log("onSetupConnectionCompleted received successful DataCallResponse");
@@ -951,7 +954,7 @@
 
         // If the data is disabled, then we need to restrict the network so only privileged apps can
         // use the restricted network while data is disabled.
-        if (!mDct.isDataEnabled()) {
+        if (!mPhone.getDataEnabledSettings().isDataEnabled()) {
             return true;
         }
 
@@ -991,7 +994,7 @@
 
         if (mApnSetting != null) {
             final String[] types = ApnSetting.getApnTypesStringFromBitmask(
-                mApnSetting.getApnTypeBitmask()).split(",");
+                mApnSetting.getApnTypeBitmask() & ~mDisabledApnTypeBitMask).split(",");
             for (String type : types) {
                 if (!mRestrictedNetworkOverride && mUnmeteredUseOnly
                         && ApnSettingUtils.isMeteredApnType(type, mPhone)) {
@@ -1136,7 +1139,7 @@
         // a failure we'll clear again at the bottom of this code.
         linkProperties.clear();
 
-        if (response.getStatus() == DataFailCause.NONE.getErrorCode()) {
+        if (response.getStatus() == DataFailCause.NONE) {
             try {
                 // set interface name
                 linkProperties.setInterfaceName(response.getIfname());
@@ -1294,7 +1297,7 @@
             mPhone = null;
             mDataServiceManager = null;
             mLinkProperties = null;
-            mLastFailCause = null;
+            mLastFailCause = DataFailCause.NONE;
             mUserData = null;
             mDcController = null;
             mDcTesterFailBringUpAll = null;
@@ -1430,7 +1433,8 @@
      */
     private class DcInactiveState extends State {
         // Inform all contexts we've failed connecting
-        public void setEnterNotificationParams(ConnectionParams cp, DataFailCause cause) {
+        public void setEnterNotificationParams(ConnectionParams cp,
+                                               @DataFailCause.FailCause int cause) {
             if (VDBG) log("DcInactiveState: setEnterNotificationParams cp,cause");
             mConnectionParams = cp;
             mDisconnectParams = null;
@@ -1446,7 +1450,7 @@
         }
 
         // Inform all contexts of the failure cause
-        public void setEnterNotificationParams(DataFailCause cause) {
+        public void setEnterNotificationParams(@DataFailCause.FailCause int cause) {
             mConnectionParams = null;
             mDisconnectParams = null;
             mDcFailCause = cause;
@@ -1477,7 +1481,8 @@
                 }
                 notifyDisconnectCompleted(mDisconnectParams, true);
             }
-            if (mDisconnectParams == null && mConnectionParams == null && mDcFailCause != null) {
+            if (mDisconnectParams == null && mConnectionParams == null
+                    && mDcFailCause != DataFailCause.NONE) {
                 if (DBG) {
                     log("DcInactiveState: enter notifyAllDisconnectCompleted failCause="
                             + mDcFailCause);
@@ -1628,8 +1633,8 @@
                                     + " delay=" + delay
                                     + " result=" + result
                                     + " result.isRadioRestartFailure="
-                                    + result.mFailCause.isRadioRestartFailure(mPhone.getContext(),
-                                            mPhone.getSubId())
+                                    + DataFailCause.isRadioRestartFailure(mPhone.getContext(),
+                                    result.mFailCause, mPhone.getSubId())
                                     + " isPermanentFailure=" +
                                     mDct.isPermanentFailure(result.mFailCause);
                             if (DBG) log(str);
@@ -1731,8 +1736,8 @@
                 reason = Phone.REASON_CARRIER_CHANGE;
             } else if (mDisconnectParams != null && mDisconnectParams.mReason != null) {
                 reason = mDisconnectParams.mReason;
-            } else if (mDcFailCause != null) {
-                reason = mDcFailCause.toString();
+            } else {
+                reason = DataFailCause.toString(mDcFailCause);
             }
             mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler());
             mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler());
@@ -1760,6 +1765,10 @@
                     // either add this new apn context to our set or
                     // update the existing cp with the latest connection generation number
                     mApnContexts.put(cp.mApnContext, cp);
+                    // TODO (b/118347948): evaluate if it's still needed after assigning
+                    // different scores to different Cellular network.
+                    mDisabledApnTypeBitMask &= ~cp.mApnContext.getApnTypeBitmask();
+                    mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities());
                     if (DBG) {
                         log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this);
                     }
@@ -1788,6 +1797,10 @@
                             transitionTo(mDisconnectingState);
                         } else {
                             mApnContexts.remove(dp.mApnContext);
+                            // TODO (b/118347948): evaluate if it's still needed after assigning
+                            // different scores to different Cellular network.
+                            mDisabledApnTypeBitMask |= dp.mApnContext.getApnTypeBitmask();
+                            mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities());
                             notifyDisconnectCompleted(dp, false);
                         }
                     } else {
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
index 87521b1..be6892b 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony.dataconnection;
 
 
+import android.annotation.IntDef;
 import android.content.ContentResolver;
 import android.os.Handler;
 import android.os.RegistrantList;
@@ -32,6 +33,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * The class to hold different data enabled/disabled settings. Also it allows clients to register
@@ -42,6 +45,19 @@
 
     private static final String LOG_TAG = "DataEnabledSettings";
 
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"REASON_"},
+            value = {
+                    REASON_REGISTERED,
+                    REASON_INTERNAL_DATA_ENABLED,
+                    REASON_USER_DATA_ENABLED,
+                    REASON_POLICY_DATA_ENABLED,
+                    REASON_DATA_ENABLED_BY_CARRIER,
+                    REASON_PROVISIONED_CHANGED,
+                    REASON_PROVISIONING_DATA_ENABLED_CHANGED
+            })
+    public @interface DataEnabledChangedReason {}
+
     public static final int REASON_REGISTERED = 0;
 
     public static final int REASON_INTERNAL_DATA_ENABLED = 1;
@@ -75,10 +91,11 @@
 
     private boolean mIsDataEnabled = false;
 
-    private Phone mPhone = null;
+    private final Phone mPhone;
+
     private ContentResolver mResolver = null;
 
-    private final RegistrantList mDataEnabledChangedRegistrants = new RegistrantList();
+    private final RegistrantList mOverallDataEnabledChangedRegistrants = new RegistrantList();
 
     private final LocalLog mSettingChangeLocalLog = new LocalLog(50);
 
@@ -99,9 +116,10 @@
 
     public synchronized void setInternalDataEnabled(boolean enabled) {
         localLog("InternalDataEnabled", enabled);
-        mInternalDataEnabled = enabled;
-
-        updateDataEnabledAndNotify(REASON_INTERNAL_DATA_ENABLED);
+        if (mInternalDataEnabled != enabled) {
+            mInternalDataEnabled = enabled;
+            updateDataEnabledAndNotify(REASON_INTERNAL_DATA_ENABLED);
+        }
     }
     public synchronized boolean isInternalDataEnabled() {
         return mInternalDataEnabled;
@@ -110,7 +128,7 @@
     public synchronized void setUserDataEnabled(boolean enabled) {
         localLog("UserDataEnabled", enabled);
         Settings.Global.putInt(mResolver, getMobileDataSettingName(), enabled ? 1 : 0);
-
+        mPhone.notifyUserMobileDataStateChanged(enabled);
         updateDataEnabledAndNotify(REASON_USER_DATA_ENABLED);
     }
 
@@ -136,9 +154,10 @@
 
     public synchronized void setPolicyDataEnabled(boolean enabled) {
         localLog("PolicyDataEnabled", enabled);
-        mPolicyDataEnabled = enabled;
-
-        updateDataEnabledAndNotify(REASON_POLICY_DATA_ENABLED);
+        if (mPolicyDataEnabled != enabled) {
+            mPolicyDataEnabled = enabled;
+            updateDataEnabledAndNotify(REASON_POLICY_DATA_ENABLED);
+        }
     }
 
     public synchronized boolean isPolicyDataEnabled() {
@@ -147,9 +166,10 @@
 
     public synchronized void setCarrierDataEnabled(boolean enabled) {
         localLog("CarrierDataEnabled", enabled);
-        mCarrierDataEnabled = enabled;
-
-        updateDataEnabledAndNotify(REASON_DATA_ENABLED_BY_CARRIER);
+        if (mCarrierDataEnabled != enabled) {
+            mCarrierDataEnabled = enabled;
+            updateDataEnabledAndNotify(REASON_DATA_ENABLED_BY_CARRIER);
+        }
     }
 
     public synchronized boolean isCarrierDataEnabled() {
@@ -212,16 +232,16 @@
     }
 
     private void notifyDataEnabledChanged(boolean enabled, int reason) {
-        mDataEnabledChangedRegistrants.notifyResult(new Pair<>(enabled, reason));
+        mOverallDataEnabledChangedRegistrants.notifyResult(new Pair<>(enabled, reason));
     }
 
     public void registerForDataEnabledChanged(Handler h, int what, Object obj) {
-        mDataEnabledChangedRegistrants.addUnique(h, what, obj);
+        mOverallDataEnabledChangedRegistrants.addUnique(h, what, obj);
         notifyDataEnabledChanged(isDataEnabled(), REASON_REGISTERED);
     }
 
     public void unregisterForDataEnabledChanged(Handler h) {
-        mDataEnabledChangedRegistrants.remove(h);
+        mOverallDataEnabledChangedRegistrants.remove(h);
     }
 
     private void log(String s) {
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcController.java b/src/java/com/android/internal/telephony/dataconnection/DcController.java
index 8933f8b..d18d552 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcController.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcController.java
@@ -35,7 +35,6 @@
 
 import com.android.internal.telephony.DctConstants;
 import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.dataconnection.DataConnection.UpdateLinkPropertyResult;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
@@ -331,8 +330,8 @@
                             apnsToCleanup.addAll(apnContexts);
                             mDct.isCleanupRequired.set(false);
                         } else {
-                            DataFailCause failCause = DataFailCause.fromInt(newState.getStatus());
-                            if (failCause.isRadioRestartFailure(mPhone.getContext(),
+                            int failCause = DataFailCause.getFailCause(newState.getStatus());
+                            if (DataFailCause.isRadioRestartFailure(mPhone.getContext(), failCause,
                                         mPhone.getSubId())) {
                                 if (DBG) {
                                     log("onDataStateChanged: X restart radio, failCause="
@@ -395,9 +394,7 @@
                                         if (DBG) log("onDataStateChanged: simple change");
 
                                         for (ApnContext apnContext : apnContexts) {
-                                             mPhone.notifyDataConnection(
-                                                 PhoneConstants.REASON_LINK_PROPERTIES_CHANGED,
-                                                 apnContext.getApnType());
+                                            mPhone.notifyDataConnection(apnContext.getApnType());
                                         }
                                     }
                                 } else {
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcFailBringUp.java b/src/java/com/android/internal/telephony/dataconnection/DcFailBringUp.java
index b6a63cf..20e13ff 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcFailBringUp.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcFailBringUp.java
@@ -40,8 +40,9 @@
 
     // failCause with its --ei option name and default value
     static final String FAIL_CAUSE = "fail_cause";
-    static final DataFailCause DEFAULT_FAIL_CAUSE = DataFailCause.ERROR_UNSPECIFIED;
-    DataFailCause mFailCause;
+    static final int DEFAULT_FAIL_CAUSE = DataFailCause.ERROR_UNSPECIFIED;
+    @DataFailCause.FailCause
+    int mFailCause;
 
     // suggestedRetryTime with its --ei option name and default value
     static final String SUGGESTED_RETRY_TIME = "suggested_retry_time";
@@ -52,8 +53,8 @@
     void saveParameters(Intent intent, String s) {
         if (DBG) log(s + ".saveParameters: action=" + intent.getAction());
         mCounter = intent.getIntExtra(COUNTER, DEFAULT_COUNTER);
-        mFailCause = DataFailCause.fromInt(
-                intent.getIntExtra(FAIL_CAUSE, DEFAULT_FAIL_CAUSE.getErrorCode()));
+        mFailCause = DataFailCause.getFailCause(
+                intent.getIntExtra(FAIL_CAUSE, DEFAULT_FAIL_CAUSE));
         mSuggestedRetryTime =
                 intent.getIntExtra(SUGGESTED_RETRY_TIME, DEFAULT_SUGGESTED_RETRY_TIME);
         if (DBG) {
@@ -61,9 +62,10 @@
         }
     }
 
-    public void saveParameters(int counter, int failCause, int suggestedRetryTime) {
+    public void saveParameters(int counter, @DataFailCause.FailCause int failCause,
+                               int suggestedRetryTime) {
         mCounter = counter;
-        mFailCause = DataFailCause.fromInt(failCause);
+        mFailCause = DataFailCause.getFailCause(failCause);
         mSuggestedRetryTime = suggestedRetryTime;
     }
 
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java b/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java
index 25edbe1..4013454 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java
@@ -62,12 +62,12 @@
                 // Counter is MAX, bringUp/retry will always fail
                 log("simulate detaching");
                 mFailBringUp.saveParameters(Integer.MAX_VALUE,
-                        DataFailCause.LOST_CONNECTION.getErrorCode(),
+                        DataFailCause.LOST_CONNECTION,
                         DcFailBringUp.DEFAULT_SUGGESTED_RETRY_TIME);
             } else if (action.equals(mPhone.getActionAttached())) {
                 // Counter is 0 next bringUp/retry will succeed
                 log("simulate attaching");
-                mFailBringUp.saveParameters(0, DataFailCause.NONE.getErrorCode(),
+                mFailBringUp.saveParameters(0, DataFailCause.NONE,
                         DcFailBringUp.DEFAULT_SUGGESTED_RETRY_TIME);
             } else {
                 if (DBG) log("onReceive: unknown action=" + action);
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index f22acc0..185a6bb 100755
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -81,7 +81,6 @@
 import android.view.WindowManager;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.CarrierActionAgent;
 import com.android.internal.telephony.DctConstants;
 import com.android.internal.telephony.EventLogTags;
 import com.android.internal.telephony.GsmCdmaPhone;
@@ -94,6 +93,7 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataAllowedReasonType;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
+import com.android.internal.telephony.dataconnection.DataEnabledSettings.DataEnabledChangedReason;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.uicc.IccRecords;
 import com.android.internal.telephony.uicc.UiccController;
@@ -325,12 +325,6 @@
         mSettingsObserver.observe(
                 Settings.Global.getUriFor(Settings.Global.DATA_ROAMING + simSuffix),
                 DctConstants.EVENT_ROAMING_SETTING_CHANGE);
-        mSettingsObserver.observe(
-                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
-                DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
-        mSettingsObserver.observe(
-                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
-                DctConstants.EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE);
     }
 
     /**
@@ -610,7 +604,10 @@
         filter.addAction(INTENT_PROVISIONING_APN_ALARM);
         filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
 
-        mDataEnabledSettings = new DataEnabledSettings(phone);
+        mDataEnabledSettings = mPhone.getDataEnabledSettings();
+
+        mDataEnabledSettings.registerForDataEnabledChanged(this,
+                DctConstants.EVENT_DATA_ENABLED_CHANGED, null);
 
         mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
 
@@ -710,9 +707,6 @@
         mPhone.getCallTracker().registerForVoiceCallStarted(this,
                 DctConstants.EVENT_VOICE_CALL_STARTED, null);
         registerServiceStateTrackerEvents();
-        mPhone.getCarrierActionAgent().registerForCarrierAction(
-                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
-                DctConstants.EVENT_SET_CARRIER_DATA_ENABLED, null, false);
         mDataServiceManager.registerForServiceBindingChanged(this,
                 DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED, null);
     }
@@ -766,38 +760,10 @@
         mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
         mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
         unregisterServiceStateTrackerEvents();
-        mPhone.getCarrierActionAgent().unregisterForCarrierAction(this,
-                CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED);
         mDataServiceManager.unregisterForServiceBindingChanged(this);
     }
 
     /**
-     * Modify {@link android.provider.Settings.Global#MOBILE_DATA} value.
-     */
-    public void setUserDataEnabled(boolean enable) {
-        Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);
-        msg.arg1 = enable ? 1 : 0;
-        if (DBG) log("setDataEnabled: sendMessage: enable=" + enable);
-        sendMessage(msg);
-    }
-
-    private void onSetUserDataEnabled(boolean enabled) {
-        if (mDataEnabledSettings.isUserDataEnabled() != enabled) {
-            mDataEnabledSettings.setUserDataEnabled(enabled);
-            mPhone.notifyUserMobileDataStateChanged(enabled);
-
-            // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
-            // handle the rest from there.
-            if (enabled) {
-                reevaluateDataConnections();
-                onTrySetupData(Phone.REASON_DATA_ENABLED);
-            } else {
-                cleanUpAllConnectionsInternal(true, Phone.REASON_DATA_SPECIFIC_DISABLED);
-            }
-        }
-    }
-
-    /**
      * Reevaluate existing data connections when conditions change.
      *
      * For example, handle reverting restricted networks back to unrestricted. If we're changing
@@ -815,30 +781,6 @@
         }
     }
 
-    private void onDeviceProvisionedChange() {
-        mDataEnabledSettings.updateProvisionedChanged();
-        // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
-        // handle the rest from there.
-        if (isDataEnabled()) {
-            reevaluateDataConnections();
-            onTrySetupData(Phone.REASON_DATA_ENABLED);
-        } else {
-            cleanUpAllConnectionsInternal(true, Phone.REASON_DATA_SPECIFIC_DISABLED);
-        }
-    }
-
-    private void onDeviceProvisioningDataChange() {
-        mDataEnabledSettings.updateProvisioningDataEnabled();
-        // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
-        // handle the rest from there.
-        if (isDataEnabled()) {
-            reevaluateDataConnections();
-            onTrySetupData(Phone.REASON_DATA_ENABLED);
-        } else {
-            cleanUpAllConnectionsInternal(true, Phone.REASON_DATA_SPECIFIC_DISABLED);
-        }
-    }
-
     public long getSubId() {
         return mPhone.getSubId();
     }
@@ -860,11 +802,15 @@
         if (apnContext != null) apnContext.requestNetwork(networkRequest, log);
     }
 
-    public void releaseNetwork(NetworkRequest networkRequest, LocalLog log) {
+    public void releaseNetwork(NetworkRequest networkRequest, LocalLog log,
+            boolean cleanUpConnection) {
         final int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
         final ApnContext apnContext = mApnContextsByType.get(apnType);
         log.log("DcTracker.releaseNetwork for " + networkRequest + " found " + apnContext);
-        if (apnContext != null) apnContext.releaseNetwork(networkRequest, log);
+        if (apnContext != null) {
+            apnContext.releaseNetwork(networkRequest, log);
+            if (cleanUpConnection) cleanUpConnectionInternal(true, apnContext);
+        }
     }
 
     // Turn telephony radio on or off.
@@ -1093,22 +1039,21 @@
             if (apnContext.isEnabled()) {
                 isAnyEnabled = true;
                 switch (apnContext.getState()) {
-                case CONNECTED:
-                case DISCONNECTING:
-                    if (VDBG) log("overall state is CONNECTED");
-                    return DctConstants.State.CONNECTED;
-                case RETRYING:
-                case CONNECTING:
-                    isConnecting = true;
-                    isFailed = false;
-                    break;
-                case IDLE:
-                case SCANNING:
-                    isFailed = false;
-                    break;
-                default:
-                    isAnyEnabled = true;
-                    break;
+                    case CONNECTED:
+                    case DISCONNECTING:
+                        if (VDBG) log("overall state is CONNECTED");
+                        return DctConstants.State.CONNECTED;
+                    case CONNECTING:
+                        isConnecting = true;
+                        isFailed = false;
+                        break;
+                    case IDLE:
+                    case RETRYING:
+                        isFailed = false;
+                        break;
+                    default:
+                        isAnyEnabled = true;
+                        break;
                 }
             }
         }
@@ -1130,15 +1075,6 @@
         }
     }
 
-    /**
-     * Whether data is enabled. This does not only check isUserDataEnabled(), but also
-     * others like CarrierDataEnabled and internalDataEnabled.
-     */
-    @VisibleForTesting
-    public boolean isDataEnabled() {
-        return mDataEnabledSettings.isDataEnabled();
-    }
-
     //****** Called from ServiceStateTracker
     /**
      * Invoked when ServiceStateTracker observes a transition from GPRS
@@ -1152,7 +1088,7 @@
         if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
         stopNetStatPoll();
         stopDataStallAlarm();
-        notifyDataConnection(Phone.REASON_DATA_DETACHED);
+        notifyDataConnection();
         mAttached.set(false);
     }
 
@@ -1163,15 +1099,15 @@
             if (DBG) log("onDataConnectionAttached: start polling notify attached");
             startNetStatPoll();
             startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
-            notifyDataConnection(Phone.REASON_DATA_ATTACHED);
+            notifyDataConnection();
         } else {
             // update APN availability so that APN can be enabled.
-            notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
+            notifyOffApnsOfAvailability();
         }
         if (mAutoAttachOnCreationConfig) {
             mAutoAttachOnCreation.set(true);
         }
-        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED);
+        setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED, RetryFailures.ALWAYS);
     }
 
     /**
@@ -1351,10 +1287,6 @@
         ONLY_ON_CHANGE
     };
 
-    private void setupDataOnConnectableApns(String reason) {
-        setupDataOnConnectableApns(reason, RetryFailures.ALWAYS);
-    }
-
     private void setupDataOnConnectableApns(String reason, RetryFailures retryFailures) {
         if (VDBG) log("setupDataOnConnectableApns: " + reason);
 
@@ -1375,7 +1307,7 @@
             if (VDBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
 
             if (apnContext.getState() == DctConstants.State.FAILED
-                    || apnContext.getState() == DctConstants.State.SCANNING) {
+                    || apnContext.getState() == DctConstants.State.RETRYING) {
                 if (retryFailures == RetryFailures.ALWAYS) {
                     apnContext.releaseDataConnection(reason);
                 } else if (apnContext.isConcurrentVoiceAndDataAllowed() == false &&
@@ -1404,7 +1336,7 @@
             // Assume data is connected on the simulator
             // FIXME  this can be improved
             apnContext.setState(DctConstants.State.CONNECTED);
-            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
+            mPhone.notifyDataConnection(apnContext.getApnType());
 
             log("trySetupData: X We're on the simulator; assuming connected retValue=true");
             return true;
@@ -1431,7 +1363,7 @@
                         buildWaitingApns(apnContext.getApnType(), radioTech);
                 if (waitingApns.isEmpty()) {
                     notifyNoData(DataFailCause.MISSING_UNKNOWN_APN, apnContext);
-                    notifyOffApnsOfAvailability(apnContext.getReason());
+                    notifyOffApnsOfAvailability();
                     String str = "trySetupData: X No APN found retValue=false";
                     if (DBG) log(str);
                     apnContext.requestLog(str);
@@ -1446,16 +1378,16 @@
             }
 
             boolean retValue = setupData(apnContext, radioTech);
-            notifyOffApnsOfAvailability(apnContext.getReason());
+            notifyOffApnsOfAvailability();
 
             if (DBG) log("trySetupData: X retValue=" + retValue);
             return retValue;
         } else {
             if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
                     && apnContext.isConnectable()) {
-                mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
+                mPhone.notifyDataConnectionFailed(apnContext.getApnType());
             }
-            notifyOffApnsOfAvailability(apnContext.getReason());
+            notifyOffApnsOfAvailability();
 
             StringBuilder str = new StringBuilder();
 
@@ -1469,8 +1401,8 @@
             }
 
             // If this is a data retry, we should set the APN state to FAILED so it won't stay
-            // in SCANNING forever.
-            if (apnContext.getState() == DctConstants.State.SCANNING) {
+            // in RETRYING forever.
+            if (apnContext.getState() == DctConstants.State.RETRYING) {
                 apnContext.setState(DctConstants.State.FAILED);
                 str.append(" Stop retrying.");
             }
@@ -1482,12 +1414,11 @@
     }
 
     // Disabled apn's still need avail/unavail notifications - send them out
-    private void notifyOffApnsOfAvailability(String reason) {
+    private void notifyOffApnsOfAvailability() {
         for (ApnContext apnContext : mApnContexts.values()) {
             if (!mAttached.get() || !apnContext.isReady()) {
-                if (VDBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
-                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
-                                            apnContext.getApnType(),
+                if (DBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
+                mPhone.notifyDataConnection(apnContext.getApnType(),
                                             PhoneConstants.DataState.DISCONNECTED);
             } else {
                 if (VDBG) {
@@ -1664,15 +1595,14 @@
                     // Should not be happen, but reset the state in case.
                     apnContext.setState(DctConstants.State.IDLE);
                     apnContext.requestLog("cleanUpConnectionInternal: connected, bug no dc");
-                    mPhone.notifyDataConnection(apnContext.getReason(),
-                                                apnContext.getApnType());
+                    mPhone.notifyDataConnection(apnContext.getApnType());
                 }
             }
         } else {
             // force clean up the data connection.
             if (dataConnection != null) dataConnection.reset();
             apnContext.setState(DctConstants.State.IDLE);
-            mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
+            mPhone.notifyDataConnection(apnContext.getApnType());
             apnContext.setDataConnection(null);
         }
 
@@ -1800,9 +1730,10 @@
         }
     }
 
-    boolean isPermanentFailure(DataFailCause dcFailCause) {
-        return (dcFailCause.isPermanentFailure(mPhone.getContext(), mPhone.getSubId()) &&
-                (mAttached.get() == false || dcFailCause != DataFailCause.SIGNAL_LOST));
+    boolean isPermanentFailure(@DataFailCause.FailCause int dcFailCause) {
+        return (DataFailCause.isPermanentFailure(mPhone.getContext(), dcFailCause,
+                mPhone.getSubId())
+                && (mAttached.get() == false || dcFailCause != DataFailCause.SIGNAL_LOST));
     }
 
     private DataConnection findFreeDataConnection() {
@@ -1917,7 +1848,7 @@
         apnContext.setDataConnection(dataConnection);
         apnContext.setApnSetting(apnSetting);
         apnContext.setState(DctConstants.State.CONNECTING);
-        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
+        mPhone.notifyDataConnection(apnContext.getApnType());
 
         Message msg = obtainMessage();
         msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
@@ -2012,7 +1943,7 @@
 
         // FIXME: See bug 17426028 maybe no conditional is needed.
         if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId()) {
-            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED);
+            setupDataOnConnectableApns(Phone.REASON_APN_CHANGED, RetryFailures.ALWAYS);
         }
     }
 
@@ -2142,12 +2073,12 @@
                 SystemClock.elapsedRealtime() + delay, alarmIntent);
     }
 
-    private void notifyNoData(DataFailCause lastFailCauseCode,
+    private void notifyNoData(@DataFailCause.FailCause int lastFailCauseCode,
                               ApnContext apnContext) {
         if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
         if (isPermanentFailure(lastFailCauseCode)
             && (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT))) {
-            mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
+            mPhone.notifyDataConnectionFailed(apnContext.getApnType());
         }
     }
 
@@ -2165,37 +2096,9 @@
         setInitialAttachApn();
         if (mPhone.mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) {
             if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
-            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
+            notifyOffApnsOfAvailability();
         }
-        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
-    }
-
-    /**
-     * Action set from carrier signalling broadcast receivers to enable/disable metered apns.
-     */
-    private void onSetCarrierDataEnabled(AsyncResult ar) {
-        if (ar.exception != null) {
-            loge("CarrierDataEnable exception: " + ar.exception);
-            return;
-        }
-        boolean enabled = (boolean) ar.result;
-        if (enabled != mDataEnabledSettings.isCarrierDataEnabled()) {
-            if (DBG) {
-                log("carrier Action: set metered apns enabled: " + enabled);
-            }
-
-            // Disable/enable all metered apns
-            mDataEnabledSettings.setCarrierDataEnabled(enabled);
-
-            if (!enabled) {
-                // Tear down all metered apns
-                cleanUpAllConnectionsInternal(true,
-                        Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
-            } else {
-                reevaluateDataConnections();
-                setupDataOnConnectableApns(Phone.REASON_DATA_ENABLED);
-            }
-        }
+        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED, RetryFailures.ALWAYS);
     }
 
     private void onSimNotReady() {
@@ -2213,30 +2116,6 @@
         setDataProfilesAsNeeded();
     }
 
-    public void setPolicyDataEnabled(boolean enabled) {
-        if (DBG) log("setPolicyDataEnabled: " + enabled);
-        Message msg = obtainMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE);
-        msg.arg1 = (enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
-        sendMessage(msg);
-    }
-
-    private void onSetPolicyDataEnabled(boolean enabled) {
-        final boolean prevEnabled = isDataEnabled();
-        if (mDataEnabledSettings.isPolicyDataEnabled() != enabled) {
-            mDataEnabledSettings.setPolicyDataEnabled(enabled);
-            // TODO: We should register for DataEnabledSetting's data enabled/disabled event and
-            // handle the rest from there.
-            if (prevEnabled != isDataEnabled()) {
-                if (!prevEnabled) {
-                    reevaluateDataConnections();
-                    onTrySetupData(Phone.REASON_DATA_ENABLED);
-                } else {
-                    cleanUpAllConnectionsInternal(true, Phone.REASON_DATA_SPECIFIC_DISABLED);
-                }
-            }
-        }
-    }
-
     private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
         boolean cleanup = false;
         boolean trySetup = false;
@@ -2261,17 +2140,15 @@
                     case IDLE:
                         // fall through: this is unexpected but if it happens cleanup and try setup
                     case FAILED:
-                    case SCANNING:
-                    case RETRYING: {
+                    case RETRYING:
                         // We're "READY" but not active so disconnect (cleanup = true) and
                         // connect (trySetup = true) to be sure we retry the connection.
                         trySetup = true;
                         apnContext.setReason(Phone.REASON_DATA_ENABLED);
                         break;
-                    }
                 }
             } else if (met) {
-                apnContext.setReason(Phone.REASON_DATA_DISABLED);
+                apnContext.setReason(Phone.REASON_DATA_DISABLED_INTERNAL);
                 // If ConnectivityService has disabled this network, stop trying to bring
                 // it up, but do not tear it down - ConnectivityService will do that
                 // directly by talking with the DataConnection.
@@ -2345,7 +2222,6 @@
                                                 + " curApnCtx=" + curApnCtx);
                                     }
                                     return curDc;
-                                case RETRYING:
                                 case CONNECTING:
                                     potentialDc = curDc;
                                     potentialApnCtx = curApnCtx;
@@ -2365,7 +2241,6 @@
                                         + " curApnCtx=" + curApnCtx);
                             }
                             return curDc;
-                        case RETRYING:
                         case CONNECTING:
                             potentialDc = curDc;
                             potentialApnCtx = curApnCtx;
@@ -2417,32 +2292,7 @@
             if(DBG) log("onEnableApn: isOnlySingleDcAllowed true & higher priority APN disabled");
             // If the highest priority APN is disabled and only single
             // data call is allowed, try to setup data call on other connectable APN.
-            setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
-        }
-    }
-
-    // TODO: We shouldnt need this.
-    private boolean onTrySetupData(String reason) {
-        if (DBG) log("onTrySetupData: reason=" + reason);
-        setupDataOnConnectableApns(reason);
-        return true;
-    }
-
-    private boolean onTrySetupData(ApnContext apnContext) {
-        if (DBG) log("onTrySetupData: apnContext=" + apnContext);
-        return trySetupData(apnContext);
-    }
-
-    /**
-     * Whether data is enabled by user. Unlike isDataEnabled, this only
-     * checks user setting stored in {@link android.provider.Settings.Global#MOBILE_DATA}
-     * if not provisioning, or isProvisioningDataEnabled if provisioning.
-     */
-    public boolean isUserDataEnabled() {
-        if (mDataEnabledSettings.isProvisioning()) {
-            return mDataEnabledSettings.isProvisioningDataEnabled();
-        } else {
-            return mDataEnabledSettings.isUserDataEnabled();
+            setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION, RetryFailures.ALWAYS);
         }
     }
 
@@ -2583,10 +2433,10 @@
             // If the user did not enable data roaming, now when we transit from roaming to
             // non-roaming, we should try to reestablish the data connection.
 
-            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
-            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF);
+            notifyOffApnsOfAvailability();
+            setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF, RetryFailures.ALWAYS);
         } else {
-            notifyDataConnection(Phone.REASON_ROAMING_OFF);
+            notifyDataConnection();
         }
     }
 
@@ -2616,15 +2466,15 @@
 
             if (DBG) log("onDataRoamingOnOrSettingsChanged: setup data on roaming");
 
-            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON);
-            notifyDataConnection(Phone.REASON_ROAMING_ON);
+            setupDataOnConnectableApns(Phone.REASON_ROAMING_ON, RetryFailures.ALWAYS);
+            notifyDataConnection();
         } else {
             // If the user does not turn on data roaming, when we transit from non-roaming to
             // roaming, we need to tear down the data connection otherwise the user might be
             // charged for data roaming usage.
             if (DBG) log("onDataRoamingOnOrSettingsChanged: Tear down data connection on roaming.");
             cleanUpAllConnectionsInternal(true, Phone.REASON_ROAMING_ON);
-            notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
+            notifyOffApnsOfAvailability();
         }
     }
 
@@ -2650,14 +2500,14 @@
             // Assume data is connected on the simulator
             // FIXME  this can be improved
             // setState(DctConstants.State.CONNECTED);
-            notifyDataConnection(null);
+            notifyDataConnection();
 
             log("onRadioAvailable: We're on the simulator; assuming data is connected");
         }
 
         IccRecords r = mIccRecords.get();
         if (r != null && r.getRecordsLoaded()) {
-            notifyOffApnsOfAvailability(null);
+            notifyOffApnsOfAvailability();
         }
 
         if (getOverallState() != DctConstants.State.IDLE) {
@@ -2682,7 +2532,7 @@
             if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
             cleanUpAllConnectionsInternal(false, Phone.REASON_RADIO_TURNED_OFF);
         }
-        notifyOffApnsOfAvailability(null);
+        notifyOffApnsOfAvailability();
     }
 
     private void completeConnection(ApnContext apnContext) {
@@ -2712,7 +2562,7 @@
                     mProvisioningSpinner));
         }
 
-        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
+        mPhone.notifyDataConnection(apnContext.getApnType());
         startNetStatPoll();
         startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
     }
@@ -2723,7 +2573,7 @@
      */
     private void onDataSetupComplete(AsyncResult ar) {
 
-        DataFailCause cause = DataFailCause.UNKNOWN;
+        int cause = DataFailCause.UNKNOWN;
         boolean handleError = false;
         ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete");
 
@@ -2864,32 +2714,31 @@
                 }
             }
         } else {
-            cause = (DataFailCause) (ar.result);
+            cause = (int) (ar.result);
             if (DBG) {
                 ApnSetting apn = apnContext.getApnSetting();
                 log(String.format("onDataSetupComplete: error apn=%s cause=%s",
                         (apn == null ? "unknown" : apn.getApnName()), cause));
             }
-            if (cause.isEventLoggable()) {
+            if (DataFailCause.isEventLoggable(cause)) {
                 // Log this failure to the Event Logs.
                 int cid = getCellLocationId();
                 EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
-                        cause.ordinal(), cid, mTelephonyManager.getNetworkType());
+                        cause, cid, mTelephonyManager.getNetworkType());
             }
             ApnSetting apn = apnContext.getApnSetting();
-            mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
-                    apnContext.getApnType(), apn != null ? apn.getApnName()
-                    : "unknown", cause.toString());
+            mPhone.notifyPreciseDataConnectionFailed(apnContext.getApnType(),
+                    apn != null ? apn.getApnName() : "unknown", cause + "");
 
             // Compose broadcast intent send to the specific carrier signaling receivers
             Intent intent = new Intent(TelephonyIntents
                     .ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED);
-            intent.putExtra(TelephonyIntents.EXTRA_ERROR_CODE_KEY, cause.getErrorCode());
+            intent.putExtra(TelephonyIntents.EXTRA_ERROR_CODE_KEY, cause);
             intent.putExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY, apnContext.getApnType());
             mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
 
-            if (cause.isRadioRestartFailure(mPhone.getContext(), mPhone.getSubId())
-                    || apnContext.restartOnError(cause.getErrorCode())) {
+            if (DataFailCause.isRadioRestartFailure(mPhone.getContext(), cause, mPhone.getSubId())
+                    || apnContext.restartOnError(cause)) {
                 if (DBG) log("Modem restarted.");
                 sendRestartRadio();
             }
@@ -2907,14 +2756,6 @@
         if (handleError) {
             onDataSetupCompleteError(ar);
         }
-
-        /* If flag is set to false after SETUP_DATA_CALL is invoked, we need
-         * to clean data connections.
-         */
-        if (!mDataEnabledSettings.isInternalDataEnabled()) {
-            cleanUpAllConnectionsInternal(true, Phone.REASON_DATA_DISABLED);
-        }
-
     }
 
     /**
@@ -2958,7 +2799,7 @@
         // Check if we need to retry or not.
         if (delay >= 0) {
             if (DBG) log("onDataSetupCompleteError: Try next APN. delay = " + delay);
-            apnContext.setState(DctConstants.State.SCANNING);
+            apnContext.setState(DctConstants.State.RETRYING);
             // Wait a bit before trying the next APN, so that
             // we're not tying up the RIL command channel
             startAlarmForReconnect(delay, apnContext);
@@ -2966,7 +2807,7 @@
             // If we are not going to retry any APN, set this APN context to failed state.
             // This would be the final state of a data connection.
             apnContext.setState(DctConstants.State.FAILED);
-            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
+            mPhone.notifyDataConnection(apnContext.getApnType());
             apnContext.setDataConnection(null);
             log("onDataSetupCompleteError: Stop retrying APNs.");
         }
@@ -2994,7 +2835,7 @@
         if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
         apnContext.setState(DctConstants.State.IDLE);
 
-        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
+        mPhone.notifyDataConnection(apnContext.getApnType());
 
         // if all data connection are gone, check whether Airplane mode request was
         // pending.
@@ -3046,7 +2887,8 @@
             apnContext.setDataConnection(null);
             if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
                 if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
-                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION);
+                setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION,
+                        RetryFailures.ALWAYS);
             } else {
                 if(DBG) log("onDisconnectDone: not retrying");
             }
@@ -3063,20 +2905,6 @@
 
     }
 
-    /**
-     * Called when EVENT_DISCONNECT_DC_RETRYING is received.
-     */
-    private void onDisconnectDcRetrying(AsyncResult ar) {
-        // We could just do this in DC!!!
-        ApnContext apnContext = getValidApnContext(ar, "onDisconnectDcRetrying");
-        if (apnContext == null) return;
-
-        apnContext.setState(DctConstants.State.RETRYING);
-        if(DBG) log("onDisconnectDcRetrying: apnContext=" + apnContext);
-
-        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
-    }
-
     private void onVoiceCallStarted() {
         if (DBG) log("onVoiceCallStarted");
         mInVoiceCall = true;
@@ -3084,7 +2912,7 @@
             if (DBG) log("onVoiceCallStarted stop polling");
             stopNetStatPoll();
             stopDataStallAlarm();
-            notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
+            notifyDataConnection();
         }
     }
 
@@ -3095,23 +2923,14 @@
             if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
                 startNetStatPoll();
                 startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
-                notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
+                notifyDataConnection();
             } else {
                 // clean slate after call end.
                 resetPollStats();
             }
         }
         // reset reconnect timer
-        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
-    }
-
-    private void onCleanUpConnection(boolean tearDown, int apnType, String reason) {
-        if (DBG) log("onCleanUpConnection");
-        ApnContext apnContext = mApnContextsByType.get(apnType);
-        if (apnContext != null) {
-            apnContext.setReason(reason);
-            cleanUpConnectionInternal(tearDown, apnContext);
-        }
+        setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED, RetryFailures.ALWAYS);
     }
 
     private boolean isConnected() {
@@ -3136,16 +2955,14 @@
         return true;
     }
 
-    private void notifyDataConnection(String reason) {
-        if (DBG) log("notifyDataConnection: reason=" + reason);
+    private void notifyDataConnection() {
         for (ApnContext apnContext : mApnContexts.values()) {
             if (mAttached.get() && apnContext.isReady()) {
                 if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
-                mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
-                        apnContext.getApnType());
+                mPhone.notifyDataConnection(apnContext.getApnType());
             }
         }
-        notifyOffApnsOfAvailability(reason);
+        notifyOffApnsOfAvailability();
     }
 
     private void setDataProfilesAsNeeded() {
@@ -3182,7 +2999,7 @@
 
         // ORDER BY Telephony.Carriers._ID ("_id")
         Cursor cursor = mPhone.getContext().getContentResolver().query(
-                Uri.withAppendedPath(Telephony.Carriers.SIM_APN_LIST, "filtered/subId/"
+                Uri.withAppendedPath(Telephony.Carriers.SIM_APN_URI, "filtered/subId/"
                         + mPhone.getSubId()), null, null, null, Telephony.Carriers._ID);
 
         if (cursor != null) {
@@ -3578,9 +3395,7 @@
 
             case DctConstants.EVENT_TRY_SETUP_DATA:
                 if (msg.obj instanceof ApnContext) {
-                    onTrySetupData((ApnContext)msg.obj);
-                } else if (msg.obj instanceof String) {
-                    onTrySetupData((String)msg.obj);
+                    trySetupData((ApnContext) msg.obj);
                 } else {
                     loge("EVENT_TRY_SETUP request w/o apnContext or String");
                 }
@@ -3590,11 +3405,6 @@
                 if (DBG) log("EVENT_CLEAN_UP_CONNECTION");
                 cleanUpConnectionInternal(true, (ApnContext) msg.obj);
                 break;
-            case DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE: {
-                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
-                onSetInternalDataEnabled(enabled);
-                break;
-            }
             case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
                 if ((msg.obj != null) && (msg.obj instanceof String == false)) {
                     msg.obj = null;
@@ -3640,15 +3450,6 @@
             case DctConstants.EVENT_ROAMING_SETTING_CHANGE:
                 onDataRoamingOnOrSettingsChanged(msg.what);
                 break;
-
-            case DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE:
-                onDeviceProvisionedChange();
-                break;
-
-            case DctConstants.EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE:
-                onDeviceProvisioningDataChange();
-                break;
-
             case DctConstants.EVENT_REDIRECTION_DETECTED:
                 String url = (String) msg.obj;
                 log("dataConnectionTracker.handleMessage: EVENT_REDIRECTION_DETECTED=" + url);
@@ -3676,11 +3477,6 @@
                 onDisconnectDone((AsyncResult) msg.obj);
                 break;
 
-            case DctConstants.EVENT_DISCONNECT_DC_RETRYING:
-                log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DC_RETRYING msg=" + msg);
-                onDisconnectDcRetrying((AsyncResult) msg.obj);
-                break;
-
             case DctConstants.EVENT_VOICE_CALL_STARTED:
                 onVoiceCallStarted();
                 break;
@@ -3688,17 +3484,6 @@
             case DctConstants.EVENT_VOICE_CALL_ENDED:
                 onVoiceCallEnded();
                 break;
-            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
-                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
-                if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
-                onSetUserDataEnabled(enabled);
-                break;
-            }
-            case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
-                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
-                onSetPolicyDataEnabled(enabled);
-                break;
-            }
             case DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: {
                 sEnableFailFastRefCounter += (msg.arg1 == DctConstants.ENABLED) ? 1 : -1;
                 if (DBG) {
@@ -3823,15 +3608,21 @@
                 handlePcoData((AsyncResult)msg.obj);
                 break;
             }
-            case DctConstants.EVENT_SET_CARRIER_DATA_ENABLED:
-                onSetCarrierDataEnabled((AsyncResult) msg.obj);
-                break;
             case DctConstants.EVENT_DATA_RECONNECT:
                 onDataReconnect(msg.getData());
                 break;
             case DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED:
                 onDataServiceBindingChanged((Boolean) ((AsyncResult) msg.obj).result);
                 break;
+            case DctConstants.EVENT_DATA_ENABLED_CHANGED:
+                AsyncResult ar = (AsyncResult) msg.obj;
+                if (ar.result instanceof Pair) {
+                    Pair<Boolean, Integer> p = (Pair<Boolean, Integer>) ar.result;
+                    boolean enabled = p.first;
+                    int reason = p.second;
+                    onDataEnabledChanged(enabled, reason);
+                }
+                break;
             default:
                 Rlog.e("DcTracker", "Unhandled event=" + msg);
                 break;
@@ -3935,33 +3726,36 @@
         mAllDataDisconnectedRegistrants.remove(h);
     }
 
-    public void registerForDataEnabledChanged(Handler h, int what, Object obj) {
-        mDataEnabledSettings.registerForDataEnabledChanged(h, what, obj);
-    }
-
-    public void unregisterForDataEnabledChanged(Handler h) {
-        mDataEnabledSettings.unregisterForDataEnabledChanged(h);
-    }
-
-    private void onSetInternalDataEnabled(boolean enabled) {
-        if (DBG) log("onSetInternalDataEnabled: enabled=" + enabled);
-        mDataEnabledSettings.setInternalDataEnabled(enabled);
-        if (enabled) {
-            log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
-            onTrySetupData(Phone.REASON_DATA_ENABLED);
-        } else {
-            log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
-            cleanUpAllConnectionsInternal(true, Phone.REASON_DATA_DISABLED);
+    private void onDataEnabledChanged(boolean enable,
+                                      @DataEnabledChangedReason int enabledChangedReason) {
+        if (DBG) {
+            log("onDataEnabledChanged: enable=" + enable + ", enabledChangedReason="
+                    + enabledChangedReason);
         }
-    }
 
-    public boolean setInternalDataEnabled(boolean enable) {
-        if (DBG) log("setInternalDataEnabled(" + enable + ")");
+        if (enable) {
+            reevaluateDataConnections();
+            setupDataOnConnectableApns(Phone.REASON_DATA_ENABLED, RetryFailures.ALWAYS);
+        } else {
+            String cleanupReason;
+            switch (enabledChangedReason) {
+                case DataEnabledSettings.REASON_INTERNAL_DATA_ENABLED:
+                    cleanupReason = Phone.REASON_DATA_DISABLED_INTERNAL;
+                    break;
+                case DataEnabledSettings.REASON_DATA_ENABLED_BY_CARRIER:
+                    cleanupReason = Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN;
+                    break;
+                case DataEnabledSettings.REASON_USER_DATA_ENABLED:
+                case DataEnabledSettings.REASON_POLICY_DATA_ENABLED:
+                case DataEnabledSettings.REASON_PROVISIONED_CHANGED:
+                case DataEnabledSettings.REASON_PROVISIONING_DATA_ENABLED_CHANGED:
+                default:
+                    cleanupReason = Phone.REASON_DATA_SPECIFIC_DISABLED;
+                    break;
 
-        Message msg = obtainMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE);
-        msg.arg1 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
-        sendMessage(msg);
-        return true;
+            }
+            cleanUpAllConnectionsInternal(true, cleanupReason);
+        }
     }
 
     private void log(String s) {
diff --git a/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
index 5c44f37..a606ad6 100644
--- a/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
+++ b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
@@ -43,22 +43,22 @@
     public final String LOG_TAG;
     protected static final boolean DBG = true;
 
+    private static final int REQUEST_LOG_SIZE = 40;
+
+    private static final int ACTION_NO_OP   = 0;
+    private static final int ACTION_REQUEST = 1;
+    private static final int ACTION_RELEASE = 2;
+
     private final PhoneSwitcher mPhoneSwitcher;
     private final SubscriptionController mSubscriptionController;
     private final SubscriptionMonitor mSubscriptionMonitor;
     private final DcTracker mDcTracker;
+    private final LocalLog mLocalLog = new LocalLog(REQUEST_LOG_SIZE);
 
-    private final HashMap<NetworkRequest, LocalLog> mDefaultRequests =
-            new HashMap<NetworkRequest, LocalLog>();
-    private final HashMap<NetworkRequest, LocalLog> mSpecificRequests =
-            new HashMap<NetworkRequest, LocalLog>();
+    // Key: network request. Value: whether it's applied to DcTracker.
+    private final HashMap<NetworkRequest, Boolean> mNetworkRequests = new HashMap();
 
     private final Phone mPhone;
-    // Only when this network factory is active, it will apply any network requests.
-    private boolean mIsActive;
-    // Whether this network factory is active and should handle default network requests.
-    // Default network requests are those that don't specify subscription ID.
-    private boolean mIsActiveForDefault;
     private int mSubscriptionId;
 
     private final static int TELEPHONY_NETWORK_SCORE = 50;
@@ -88,7 +88,6 @@
         // the future. For now we route everything to WWAN.
         mDcTracker = mPhone.getDcTracker(TransportType.WWAN);
 
-        mIsActive = false;
         mPhoneSwitcher.registerForActivePhoneSwitch(mInternalHandler, EVENT_ACTIVE_PHONE_SWITCH,
                 null);
 
@@ -96,8 +95,6 @@
         mSubscriptionMonitor.registerForSubscriptionChanged(mPhone.getPhoneId(), mInternalHandler,
                 EVENT_SUBSCRIPTION_CHANGED, null);
 
-        mIsActiveForDefault = false;
-
         register();
     }
 
@@ -154,24 +151,17 @@
         }
     }
 
-    private static final int REQUEST_LOG_SIZE = 40;
-
-    private static final int ACTION_NO_OP   = 0;
-    private static final int ACTION_REQUEST = 1;
-    private static final int ACTION_RELEASE = 2;
-
-    private void applyRequests(HashMap<NetworkRequest, LocalLog> requestMap,
-            int action, String logStr) {
+    private void applyRequestsOnActivePhoneSwitch(NetworkRequest networkRequest,
+            boolean cleanUpOnRelease, int action) {
         if (action == ACTION_NO_OP) return;
 
-        for (NetworkRequest networkRequest : requestMap.keySet()) {
-            LocalLog localLog = requestMap.get(networkRequest);
-            localLog.log(logStr);
-            if (action == ACTION_REQUEST) {
-                mDcTracker.requestNetwork(networkRequest, localLog);
-            } else if (action == ACTION_RELEASE) {
-                mDcTracker.releaseNetwork(networkRequest, localLog);
-            }
+        String logStr = "onActivePhoneSwitch: " + ((action == ACTION_REQUEST)
+                ? "Requesting" : "Releasing") + " network request " + networkRequest;
+        mLocalLog.log(logStr);
+        if (action == ACTION_REQUEST) {
+            mDcTracker.requestNetwork(networkRequest, mLocalLog);
+        } else if (action == ACTION_RELEASE) {
+            mDcTracker.releaseNetwork(networkRequest, mLocalLog, cleanUpOnRelease);
         }
     }
 
@@ -187,21 +177,17 @@
 
     // apply or revoke requests if our active-ness changes
     private void onActivePhoneSwitch() {
-        final boolean newIsActive = mPhoneSwitcher.shouldApplySpecifiedRequests(
-                mPhone.getPhoneId());
-        final boolean newIsActiveForDefault =
-                mPhoneSwitcher.shouldApplyUnspecifiedRequests(mPhone.getPhoneId());
+        for (HashMap.Entry<NetworkRequest, Boolean> entry : mNetworkRequests.entrySet()) {
+            NetworkRequest networkRequest = entry.getKey();
+            boolean applied = entry.getValue();
 
-        String logString = "onActivePhoneSwitch(newIsActive " + newIsActive + ", "
-                + "newIsActiveForDefault " + newIsActiveForDefault + ")";
-        if (DBG) log(logString);
+            boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest(
+                    networkRequest, mPhone.getPhoneId());
 
-        applyRequests(mSpecificRequests, getAction(mIsActive, newIsActive), logString);
-        applyRequests(mDefaultRequests, getAction(mIsActiveForDefault, newIsActiveForDefault),
-                logString);
-
-        mIsActive = newIsActive;
-        mIsActiveForDefault = newIsActiveForDefault;
+            applyRequestsOnActivePhoneSwitch(networkRequest, true,
+                    getAction(applied, shouldApply));
+            mNetworkRequests.put(networkRequest, shouldApply);
+        }
     }
 
     // watch for phone->subId changes, reapply new filter and let
@@ -225,34 +211,17 @@
 
     private void onNeedNetworkFor(Message msg) {
         NetworkRequest networkRequest = (NetworkRequest)msg.obj;
-        boolean isApplicable = false;
-        LocalLog localLog = null;
-        if (networkRequest.networkCapabilities.getNetworkSpecifier() == null) {
-            // request only for the default network
-            localLog = mDefaultRequests.get(networkRequest);
-            if (localLog == null) {
-                localLog = new LocalLog(REQUEST_LOG_SIZE);
-                localLog.log("created for " + networkRequest);
-                mDefaultRequests.put(networkRequest, localLog);
-                isApplicable = mIsActiveForDefault;
-            }
-        } else {
-            localLog = mSpecificRequests.get(networkRequest);
-            if (localLog == null) {
-                localLog = new LocalLog(REQUEST_LOG_SIZE);
-                mSpecificRequests.put(networkRequest, localLog);
-                isApplicable = mIsActive;
-            }
-        }
-        if (isApplicable) {
-            String s = "onNeedNetworkFor";
-            localLog.log(s);
-            log(s + " " + networkRequest);
-            mDcTracker.requestNetwork(networkRequest, localLog);
-        } else {
-            String s = "not acting - isApplicable=" + isApplicable + ", mIsActive=" + mIsActive;
-            localLog.log(s);
-            log(s + " " + networkRequest);
+        boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest(
+                networkRequest, mPhone.getPhoneId());
+
+        mNetworkRequests.put(networkRequest, shouldApply);
+
+        String s = "onNeedNetworkFor " + networkRequest + " shouldApply " + shouldApply;
+        log(s);
+        mLocalLog.log(s);
+
+        if (shouldApply) {
+            mDcTracker.requestNetwork(networkRequest, mLocalLog);
         }
     }
 
@@ -265,25 +234,17 @@
 
     private void onReleaseNetworkFor(Message msg) {
         NetworkRequest networkRequest = (NetworkRequest)msg.obj;
-        LocalLog localLog = null;
-        boolean isApplicable = false;
-        if (networkRequest.networkCapabilities.getNetworkSpecifier() == null) {
-            // request only for the default network
-            isApplicable = mDefaultRequests.containsKey(networkRequest) && mIsActiveForDefault;
-            localLog = mDefaultRequests.remove(networkRequest);
-        } else {
-            isApplicable = mSpecificRequests.containsKey(networkRequest) && mIsActive;
-            localLog = mSpecificRequests.remove(networkRequest);
-        }
-        if (isApplicable) {
-            String s = "onReleaseNetworkFor";
-            localLog.log(s);
-            log(s + " " + networkRequest);
-            mDcTracker.releaseNetwork(networkRequest, localLog);
-        } else {
-            String s = "not releasing - isApplicable=" + isApplicable + ", mIsActive=" + mIsActive;
-            localLog.log(s);
-            log(s + " " + networkRequest);
+        boolean applied = mNetworkRequests.get(networkRequest);
+
+        mNetworkRequests.remove(networkRequest);
+
+        String s = "onReleaseNetworkFor " + networkRequest + " applied " + applied;
+        log(s);
+        mLocalLog.log(s);
+
+
+        if (applied) {
+            mDcTracker.releaseNetwork(networkRequest, mLocalLog, false);
         }
     }
 
@@ -293,16 +254,14 @@
 
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
-        pw.println(LOG_TAG + " mSubId=" + mSubscriptionId + " mIsActive=" +
-                mIsActive + " mIsActiveForDefault=" + mIsActiveForDefault);
-        pw.println("Default Requests:");
+        pw.println("Network Requests:");
         pw.increaseIndent();
-        for (NetworkRequest nr : mDefaultRequests.keySet()) {
-            pw.println(nr);
-            pw.increaseIndent();
-            mDefaultRequests.get(nr).dump(fd, pw, args);
-            pw.decreaseIndent();
+        for (HashMap.Entry<NetworkRequest, Boolean> entry : mNetworkRequests.entrySet()) {
+            NetworkRequest nr = entry.getKey();
+            boolean applied = entry.getValue();
+            pw.println((applied ? "Applied: " : "Not applied: ") + nr);
         }
+        mLocalLog.dump(fd, pw, args);
         pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
index 5425f2b..64e12d1 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
@@ -19,21 +19,38 @@
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
+import android.os.SystemProperties;
+import android.telephony.PhoneNumberUtils;
 import android.telephony.Rlog;
 import android.telephony.emergency.EmergencyNumber;
+import android.text.TextUtils;
 import android.util.LocalLog;
 
+import com.android.i18n.phonenumbers.ShortNumberInfo;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.LocaleTracker;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.ServiceStateTracker;
+import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.phone.ecc.nano.ProtobufEccData;
+import com.android.phone.ecc.nano.ProtobufEccData.EccInfo;
 
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+import java.util.zip.GZIPInputStream;
+
+import libcore.io.IoUtils;
 
 /**
  * Emergency Number Tracker that handles update of emergency number list from RIL and emergency
@@ -47,6 +64,10 @@
 
     private final CommandsInterface mCi;
     private final Phone mPhone;
+    private String mCountryIso;
+
+    private static final String EMERGENCY_NUMBER_DB_ASSETS_FILE = "eccdata";
+
     private List<EmergencyNumber> mEmergencyNumberListFromDatabase = new ArrayList<>();
     private List<EmergencyNumber> mEmergencyNumberListFromRadio = new ArrayList<>();
     private List<EmergencyNumber> mEmergencyNumberList = new ArrayList<>();
@@ -57,14 +78,16 @@
 
     /** Event indicating the update for the emergency number list from the radio. */
     private static final int EVENT_UNSOL_EMERGENCY_NUMBER_LIST = 1;
-
-    // TODO EVENT_UPDATE_NETWORK_COUNTRY_ISO
+    /**
+     * Event indicating the update for the emergency number list from the database due to the
+     * change of country code.
+     **/
+    private static final int EVENT_UPDATE_DB_COUNTRY_ISO_CHANGED = 2;
 
     public EmergencyNumberTracker(Phone phone, CommandsInterface ci) {
         mPhone = phone;
         mCi = ci;
-        // TODO cache Emergency Number List Database per country ISO;
-        // TODO register for Locale Tracker Country ISO Change
+        initializeDatabaseEmergencyNumberList();
         mCi.registerForEmergencyNumberList(this, EVENT_UNSOL_EMERGENCY_NUMBER_LIST, null);
     }
 
@@ -83,59 +106,369 @@
                 if (ar.result == null) {
                     loge("EVENT_UNSOL_EMERGENCY_NUMBER_LIST: Result from RIL is null.");
                 } else if ((ar.result != null) && (ar.exception == null)) {
-                    updateAndNotifyEmergencyNumberList((List<EmergencyNumber>) ar.result);
+                    updateRadioEmergencyNumberListAndNotify((List<EmergencyNumber>) ar.result);
                 } else {
                     loge("EVENT_UNSOL_EMERGENCY_NUMBER_LIST: Exception from RIL : "
                             + ar.exception);
                 }
                 break;
+            case EVENT_UPDATE_DB_COUNTRY_ISO_CHANGED:
+                if (msg.obj == null) {
+                    loge("EVENT_UPDATE_DB_COUNTRY_ISO_CHANGED: Result from UpdateCountryIso is"
+                            + " null.");
+                } else {
+                    updateEmergencyNumberListDatabaseAndNotify((String) msg.obj);
+                }
+                break;
         }
     }
 
-    private void updateAndNotifyEmergencyNumberList(
+    private void initializeDatabaseEmergencyNumberList() {
+        mCountryIso = getInitialCountryIso().toLowerCase();
+        cacheEmergencyDatabaseByCountry(mCountryIso);
+    }
+
+    private String getInitialCountryIso() {
+        if (mPhone != null) {
+            ServiceStateTracker sst = mPhone.getServiceStateTracker();
+            if (sst != null) {
+                LocaleTracker lt = sst.getLocaleTracker();
+                if (lt != null) {
+                    return lt.getCurrentCountry();
+                }
+            }
+        }
+        return "";
+    }
+
+    /**
+     * Update Emergency Number database based on changed Country ISO.
+     *
+     * @param countryIso
+     *
+     * @hide
+     */
+    public void updateEmergencyNumberDatabaseCountryChange(String countryIso) {
+        this.obtainMessage(EVENT_UPDATE_DB_COUNTRY_ISO_CHANGED, countryIso).sendToTarget();
+    }
+
+    private EmergencyNumber convertEmergencyNumberFromEccInfo(EccInfo eccInfo, String countryIso) {
+        String phoneNumber = eccInfo.phoneNumber.trim();
+        if (phoneNumber.isEmpty()) {
+            loge("EccInfo has empty phone number.");
+            return null;
+        }
+        int emergencyServiceCategoryBitmask = 0;
+        for (int typeData : eccInfo.types) {
+            switch (typeData) {
+                case EccInfo.Type.POLICE:
+                    emergencyServiceCategoryBitmask = emergencyServiceCategoryBitmask == 0
+                            ? EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
+                            : emergencyServiceCategoryBitmask
+                            | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE;
+                    break;
+                case EccInfo.Type.AMBULANCE:
+                    emergencyServiceCategoryBitmask = emergencyServiceCategoryBitmask == 0
+                            ? EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
+                            : emergencyServiceCategoryBitmask
+                            | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE;
+                    break;
+                case EccInfo.Type.FIRE:
+                    emergencyServiceCategoryBitmask = emergencyServiceCategoryBitmask == 0
+                            ? EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE
+                            : emergencyServiceCategoryBitmask
+                            | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE;
+                    break;
+                default:
+                    // Ignores unknown types.
+            }
+        }
+        return new EmergencyNumber(phoneNumber, countryIso, "", emergencyServiceCategoryBitmask,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE);
+    }
+
+    private void cacheEmergencyDatabaseByCountry(String countryIso) {
+        BufferedInputStream inputStream = null;
+        ProtobufEccData.AllInfo allEccMessages = null;
+        List<EmergencyNumber> updatedEmergencyNumberList = new ArrayList<>();
+        try {
+            inputStream = new BufferedInputStream(
+                    mPhone.getContext().getAssets().open(EMERGENCY_NUMBER_DB_ASSETS_FILE));
+            allEccMessages = ProtobufEccData.AllInfo.parseFrom(readInputStreamToByteArray(
+                    new GZIPInputStream(inputStream)));
+            logd("Emergency database is loaded. ");
+            for (ProtobufEccData.CountryInfo countryEccInfo : allEccMessages.countries) {
+                if (countryEccInfo.isoCode.equals(countryIso.toUpperCase())) {
+                    for (ProtobufEccData.EccInfo eccInfo : countryEccInfo.eccs) {
+                        updatedEmergencyNumberList.add(convertEmergencyNumberFromEccInfo(
+                                eccInfo, countryIso));
+                    }
+                }
+            }
+            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(updatedEmergencyNumberList);
+            mEmergencyNumberListFromDatabase = updatedEmergencyNumberList;
+        } catch (IOException ex) {
+            loge("Cache emergency database failure: " + ex);
+        } finally {
+            IoUtils.closeQuietly(inputStream);
+        }
+    }
+
+    /**
+     * Util function to convert inputStream to byte array before parsing proto data.
+     */
+    private static byte[] readInputStreamToByteArray(InputStream inputStream) throws IOException {
+        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        int nRead;
+        int size = 16 * 1024; // Read 16k chunks
+        byte[] data = new byte[size];
+        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
+            buffer.write(data, 0, nRead);
+        }
+        buffer.flush();
+        return buffer.toByteArray();
+    }
+
+    private void updateRadioEmergencyNumberListAndNotify(
             List<EmergencyNumber> emergencyNumberListRadio) {
         Collections.sort(emergencyNumberListRadio);
-        logd("updateAndNotifyEmergencyNumberList(): receiving " + emergencyNumberListRadio);
+        logd("updateRadioEmergencyNumberListAndNotify(): receiving " + emergencyNumberListRadio);
 
         if (!emergencyNumberListRadio.equals(mEmergencyNumberListFromRadio)) {
             try {
+                EmergencyNumber.mergeSameNumbersInEmergencyNumberList(emergencyNumberListRadio);
                 mEmergencyNumberListFromRadio = emergencyNumberListRadio;
                 if (!DBG) {
                     mEmergencyNumberListRadioLocalLog.log("updateRadioEmergencyNumberList:"
                             + emergencyNumberListRadio);
                 }
-                List<EmergencyNumber> emergencyNumberListMergedWithDatabase =
-                        constructEmergencyNumberListWithDatabase();
-                mEmergencyNumberList = emergencyNumberListMergedWithDatabase;
+                mergeRadioAndDatabaseList();
                 if (!DBG) {
-                    mEmergencyNumberListLocalLog.log("updateEmergencyNumberList:"
-                            + emergencyNumberListMergedWithDatabase);
+                    mEmergencyNumberListLocalLog.log("updateRadioEmergencyNumberListAndNotify:"
+                            + mEmergencyNumberList);
                 }
                 notifyEmergencyNumberList();
             } catch (NullPointerException ex) {
-                loge("updateAndNotifyEmergencyNumberList() Phone already destroyed: " + ex
-                        + "EmergencyNumberList not notified");
+                loge("updateRadioEmergencyNumberListAndNotify() Phone already destroyed: " + ex
+                        + " EmergencyNumberList not notified");
             }
         }
     }
 
+    private void updateEmergencyNumberListDatabaseAndNotify(String countryIso) {
+        logd("updateEmergencyNumberListDatabaseAndNotify(): receiving countryIso: "
+                + countryIso);
+
+        mCountryIso = countryIso.toLowerCase();
+        cacheEmergencyDatabaseByCountry(countryIso);
+        if (!DBG) {
+            mEmergencyNumberListDatabaseLocalLog.log(
+                    "updateEmergencyNumberListDatabaseAndNotify:"
+                            + mEmergencyNumberListFromDatabase);
+        }
+        mergeRadioAndDatabaseList();
+        if (!DBG) {
+            mEmergencyNumberListLocalLog.log("updateEmergencyNumberListDatabaseAndNotify:"
+                    + mEmergencyNumberList);
+        }
+        notifyEmergencyNumberList();
+    }
+
     private void notifyEmergencyNumberList() {
-        List<EmergencyNumber> emergencyNumberListToNotify = getEmergencyNumberList();
-        mPhone.notifyEmergencyNumberList(emergencyNumberListToNotify);
-        logd("notifyEmergencyNumberList():" + emergencyNumberListToNotify);
+        try {
+            if (getEmergencyNumberList() != null) {
+                mPhone.notifyEmergencyNumberList();
+                logd("notifyEmergencyNumberList(): notified");
+            }
+        } catch (NullPointerException ex) {
+            loge("notifyEmergencyNumberList(): failure: Phone already destroyed: " + ex);
+        }
     }
 
-    private List<EmergencyNumber> constructEmergencyNumberListWithDatabase() {
-        List<EmergencyNumber> emergencyNumberListRadioAndDatabase = mEmergencyNumberListFromRadio;
-        // TODO integrate with emergency number database
-        // TODO sorting
-        return emergencyNumberListRadioAndDatabase;
+    /**
+     * Merge emergency numbers from the radio and database list, if they are the same emergency
+     * numbers.
+     */
+    private void mergeRadioAndDatabaseList() {
+        List<EmergencyNumber> mergedEmergencyNumberList =
+                new ArrayList<>(mEmergencyNumberListFromDatabase);
+        mergedEmergencyNumberList.addAll(mEmergencyNumberListFromRadio);
+        EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList);
+        Collections.sort(mergedEmergencyNumberList);
+        mEmergencyNumberList = mergedEmergencyNumberList;
     }
 
+    /**
+     * Get the emergency number list.
+     *
+     * @return the emergency number list based on radio indication or ril.ecclist if radio
+     *         indication not support from the HAL.
+     */
     public List<EmergencyNumber> getEmergencyNumberList() {
-        return new ArrayList<>(mEmergencyNumberList);
+        if (!mEmergencyNumberListFromRadio.isEmpty()) {
+            return new ArrayList<>(mEmergencyNumberList);
+        } else {
+            return getEmergencyNumberListFromEccList();
+        }
     }
 
+    /**
+     * Checks if the number is an emergency number in the current Phone.
+     *
+     * @return {@code true} if it is; {@code false} otherwise.
+     */
+    public boolean isEmergencyNumber(String number, boolean exactMatch) {
+        if (!mEmergencyNumberListFromRadio.isEmpty()) {
+            for (EmergencyNumber num : mEmergencyNumberList) {
+                // According to com.android.i18n.phonenumbers.ShortNumberInfo, in
+                // these countries, if extra digits are added to an emergency number,
+                // it no longer connects to the emergency service.
+                Set<String> countriesRequiredForExactMatch = new HashSet<>();
+                countriesRequiredForExactMatch.add("br");
+                countriesRequiredForExactMatch.add("cl");
+                countriesRequiredForExactMatch.add("ni");
+                if (exactMatch || countriesRequiredForExactMatch.contains(mCountryIso)) {
+                    if (num.getNumber().equals(number)) {
+                        return true;
+                    }
+                } else {
+                    if (number.startsWith(num.getNumber())) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        } else {
+            return isEmergencyNumberFromEccList(number, exactMatch);
+        }
+    }
+
+    /**
+     * Get Emergency number list based on EccList. This util is used for solving backward
+     * compatibility if device does not support the 1.4 IRadioIndication HAL that reports
+     * emergency number list.
+     */
+    private List<EmergencyNumber> getEmergencyNumberListFromEccList() {
+        List<EmergencyNumber> emergencyNumberList = new ArrayList<>();
+        int slotId = SubscriptionController.getInstance().getSlotIndex(mPhone.getSubId());
+
+        String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
+        String emergencyNumbers = SystemProperties.get(ecclist, "");
+        if (TextUtils.isEmpty(emergencyNumbers)) {
+            // then read-only ecclist property since old RIL only uses this
+            emergencyNumbers = SystemProperties.get("ro.ril.ecclist");
+        }
+        if (!TextUtils.isEmpty(emergencyNumbers)) {
+            // searches through the comma-separated list for a match,
+            // return true if one is found.
+            for (String emergencyNum : emergencyNumbers.split(",")) {
+                emergencyNumberList.add(new EmergencyNumber(emergencyNum, "", "",
+                        EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 0));
+            }
+        }
+        emergencyNumbers = ((slotId < 0) ? "112,911,000,08,110,118,119,999" : "112,911");
+        for (String emergencyNum : emergencyNumbers.split(",")) {
+            emergencyNumberList.add(new EmergencyNumber(emergencyNum, "", "",
+                    EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 0));
+        }
+        EmergencyNumber.mergeSameNumbersInEmergencyNumberList(emergencyNumberList);
+        return emergencyNumberList;
+    }
+
+    /**
+     * Back-up old logics for {@link PhoneNumberUtils#isEmergencyNumberInternal} for legacy
+     * and deprecate purpose.
+     */
+    private boolean isEmergencyNumberFromEccList(String number, boolean useExactMatch) {
+        // If the number passed in is null, just return false:
+        if (number == null) return false;
+
+        // If the number passed in is a SIP address, return false, since the
+        // concept of "emergency numbers" is only meaningful for calls placed
+        // over the cell network.
+        // (Be sure to do this check *before* calling extractNetworkPortionAlt(),
+        // since the whole point of extractNetworkPortionAlt() is to filter out
+        // any non-dialable characters (which would turn 'abc911def@example.com'
+        // into '911', for example.))
+        if (PhoneNumberUtils.isUriNumber(number)) {
+            return false;
+        }
+
+        // Strip the separators from the number before comparing it
+        // to the list.
+        number = PhoneNumberUtils.extractNetworkPortionAlt(number);
+
+        String emergencyNumbers = "";
+        int slotId = SubscriptionController.getInstance().getSlotIndex(mPhone.getSubId());
+
+        // retrieve the list of emergency numbers
+        // check read-write ecclist property first
+        String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
+
+        emergencyNumbers = SystemProperties.get(ecclist, "");
+
+        logd("slotId:" + slotId + " country:" + mCountryIso + " emergencyNumbers: "
+                +  emergencyNumbers);
+
+        if (TextUtils.isEmpty(emergencyNumbers)) {
+            // then read-only ecclist property since old RIL only uses this
+            emergencyNumbers = SystemProperties.get("ro.ril.ecclist");
+        }
+
+        if (!TextUtils.isEmpty(emergencyNumbers)) {
+            // searches through the comma-separated list for a match,
+            // return true if one is found.
+            for (String emergencyNum : emergencyNumbers.split(",")) {
+                // It is not possible to append additional digits to an emergency number to dial
+                // the number in Brazil - it won't connect.
+                if (useExactMatch || "br".equalsIgnoreCase(mCountryIso)) {
+                    if (number.equals(emergencyNum)) {
+                        return true;
+                    }
+                } else {
+                    if (number.startsWith(emergencyNum)) {
+                        return true;
+                    }
+                }
+            }
+            // no matches found against the list!
+            return false;
+        }
+
+        logd("System property doesn't provide any emergency numbers."
+                + " Use embedded logic for determining ones.");
+
+        // If slot id is invalid, means that there is no sim card.
+        // According spec 3GPP TS22.101, the following numbers should be
+        // ECC numbers when SIM/USIM is not present.
+        emergencyNumbers = ((slotId < 0) ? "112,911,000,08,110,118,119,999" : "112,911");
+
+        for (String emergencyNum : emergencyNumbers.split(",")) {
+            if (useExactMatch) {
+                if (number.equals(emergencyNum)) {
+                    return true;
+                }
+            } else {
+                if (number.startsWith(emergencyNum)) {
+                    return true;
+                }
+            }
+        }
+
+        // No ecclist system property, so use our own list.
+        if (mCountryIso != null) {
+            ShortNumberInfo info = ShortNumberInfo.getInstance();
+            if (useExactMatch) {
+                return info.isEmergencyNumber(number, mCountryIso.toUpperCase());
+            } else {
+                return info.connectsToEmergencyNumber(number, mCountryIso.toUpperCase());
+            }
+        }
+
+        return false;
+    }
+
+
     @VisibleForTesting
     public List<EmergencyNumber> getRadioEmergencyNumberList() {
         return new ArrayList<>(mEmergencyNumberListFromRadio);
diff --git a/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java b/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java
new file mode 100644
index 0000000..862cb63
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2017 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 android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.os.ServiceManager;
+import android.telephony.Rlog;
+import android.telephony.ims.Rcs1To1Thread;
+import android.telephony.ims.RcsMessageStore;
+import android.telephony.ims.RcsParticipant;
+import android.telephony.ims.RcsThread;
+import android.telephony.ims.RcsThreadQueryContinuationToken;
+import android.telephony.ims.RcsThreadQueryParameters;
+import android.telephony.ims.RcsThreadQueryResult;
+import android.telephony.ims.aidl.IRcs;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/** Backing implementation of {@link RcsMessageStore}. */
+public class RcsMessageStoreController extends IRcs.Stub {
+    public static final String PARTICIPANT_ADDRESS_KEY = "participant_address";
+    private static final String TAG = "RcsMessageStoreController";
+    private static final String RCS_SERVICE_NAME = "ircs";
+
+    private static RcsMessageStoreController sInstance;
+
+    private final ContentResolver mContentResolver;
+
+    /** Initialize the instance. Should only be called once. */
+    public static RcsMessageStoreController init(Context context) {
+        synchronized (RcsMessageStoreController.class) {
+            if (sInstance == null) {
+                sInstance = new RcsMessageStoreController(context.getContentResolver());
+            } else {
+                Rlog.e(TAG, "init() called multiple times! sInstance = " + sInstance);
+            }
+        }
+        return sInstance;
+    }
+
+    private RcsMessageStoreController(ContentResolver contentResolver) {
+        mContentResolver = contentResolver;
+        if (ServiceManager.getService(RCS_SERVICE_NAME) == null) {
+            ServiceManager.addService(RCS_SERVICE_NAME, this);
+        }
+    }
+
+    @VisibleForTesting
+    public RcsMessageStoreController(ContentResolver contentResolver, Void unused) {
+        mContentResolver = contentResolver;
+    }
+
+    @Override
+    public void deleteThread(int threadId) {
+        // TODO - add implementation
+    }
+
+    @Override
+    public int getMessageCount(int rcsThreadId) {
+        // TODO - add implementation. Return a magic number for now to test the RPC calls
+        return 1018;
+    }
+
+    @Override
+    public RcsThreadQueryResult getRcsThreads(RcsThreadQueryParameters queryParameters) {
+        // TODO - refine implementation to include tokens for the next query
+        Cursor rcsThreadsCursor = mContentResolver.query(
+                RcsThreadQueryHelper.THREADS_URI,
+                RcsThreadQueryHelper.THREAD_PROJECTION,
+                RcsThreadQueryHelper.buildWhereClause(queryParameters),
+                null,
+                queryParameters.isAscending()
+                        ? RcsThreadQueryHelper.ASCENDING : RcsThreadQueryHelper.DESCENDING);
+
+        List<RcsThread> rcsThreadList = new ArrayList<>();
+
+        // TODO - currently this only creates 1 to 1 threads - fix this
+        while (rcsThreadsCursor != null && rcsThreadsCursor.moveToNext()) {
+            Rcs1To1Thread rcs1To1Thread = new Rcs1To1Thread(rcsThreadsCursor.getInt(0));
+            rcsThreadList.add(rcs1To1Thread);
+        }
+
+        return new RcsThreadQueryResult(null, rcsThreadList);
+    }
+
+    @Override
+    public RcsThreadQueryResult getRcsThreadsWithToken(
+            RcsThreadQueryContinuationToken continuationToken) {
+        // TODO - implement
+        return null;
+    }
+
+    @Override
+    public Rcs1To1Thread createRcs1To1Thread(RcsParticipant recipient) {
+        // TODO - use recipient to add a thread
+
+        ContentValues contentValues = new ContentValues(0);
+        mContentResolver.insert(RcsThreadQueryHelper.THREADS_URI, contentValues);
+
+        return null;
+    }
+
+    @Override
+    public RcsParticipant createRcsParticipant(String canonicalAddress) {
+        // TODO - refine implementation to disallow duplicate participants
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(PARTICIPANT_ADDRESS_KEY, canonicalAddress);
+        mContentResolver.insert(RcsThreadQueryHelper.PARTICIPANTS_URI, contentValues);
+
+        // TODO - return the newly created participant
+        return null;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/ims/RcsThreadQueryHelper.java b/src/java/com/android/internal/telephony/ims/RcsThreadQueryHelper.java
new file mode 100644
index 0000000..9f84f59
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ims/RcsThreadQueryHelper.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 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 android.net.Uri;
+import android.telephony.ims.RcsThreadQueryParameters;
+
+/**
+ * A helper class focused on querying RCS threads from the
+ * {@link com.android.providers.telephony.RcsProvider}
+ */
+class RcsThreadQueryHelper {
+    static final String ASCENDING = "ASCENDING";
+    static final String DESCENDING = "DESCENDING";
+    static final String THREAD_ID = "_id";
+
+    static final Uri THREADS_URI = Uri.parse("content://rcs/thread");
+    static final Uri PARTICIPANTS_URI = Uri.parse("content://rcs/participant");
+    static final String[] THREAD_PROJECTION = new String[]{THREAD_ID};
+
+    static String buildWhereClause(RcsThreadQueryParameters queryParameters) {
+        // TODO - implement
+        return null;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
index c08ce6c..c54643b 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
@@ -207,8 +207,6 @@
 
     public void notifyDisconnect(Connection cn) {
         mDisconnectRegistrants.notifyResult(cn);
-
-        mNotifier.notifyDisconnectCause(cn.getDisconnectCause(), cn.getPreciseDisconnectCause());
     }
 
     void notifyUnknownConnection() {
@@ -460,16 +458,6 @@
         return false;
     }
 
-    @Override
-    public boolean isDataEnabled() {
-        return false;
-    }
-
-    @Override
-    public void setUserDataEnabled(boolean enable) {
-    }
-
-
     public boolean enableDataConnectivity() {
         return false;
     }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 8fea1aa..1021b74 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.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsMmTelManager;
 import android.telephony.ims.ImsReasonInfo;
@@ -68,7 +69,6 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
-import android.util.SparseIntArray;
 
 import com.android.ims.ImsCall;
 import com.android.ims.ImsConfig;
@@ -96,6 +96,7 @@
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
+import com.android.internal.telephony.dataconnection.DataEnabledSettings.DataEnabledChangedReason;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.nano.TelephonyProto.ImsConnectionState;
@@ -406,237 +407,6 @@
     private boolean mSupportDowngradeVtToAudio = false;
 
     /**
-     * Stores the mapping of {@code ImsReasonInfo#CODE_*} to {@code PreciseDisconnectCause#*}
-     */
-    private static final SparseIntArray PRECISE_CAUSE_MAP = new SparseIntArray();
-    static {
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT,
-                PreciseDisconnectCause.LOCAL_ILLEGAL_ARGUMENT);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE,
-                PreciseDisconnectCause.LOCAL_ILLEGAL_STATE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR,
-                PreciseDisconnectCause.LOCAL_INTERNAL_ERROR);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN,
-                PreciseDisconnectCause.LOCAL_IMS_SERVICE_DOWN);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_NO_PENDING_CALL,
-                PreciseDisconnectCause.LOCAL_NO_PENDING_CALL);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE,
-                PreciseDisconnectCause.NORMAL);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_POWER_OFF,
-                PreciseDisconnectCause.LOCAL_POWER_OFF);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_LOW_BATTERY,
-                PreciseDisconnectCause.LOCAL_LOW_BATTERY);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_NETWORK_NO_SERVICE,
-                PreciseDisconnectCause.LOCAL_NETWORK_NO_SERVICE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_NETWORK_NO_LTE_COVERAGE,
-                PreciseDisconnectCause.LOCAL_NETWORK_NO_LTE_COVERAGE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_NETWORK_ROAMING,
-                PreciseDisconnectCause.LOCAL_NETWORK_ROAMING);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_NETWORK_IP_CHANGED,
-                PreciseDisconnectCause.LOCAL_NETWORK_IP_CHANGED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE,
-                PreciseDisconnectCause.LOCAL_SERVICE_UNAVAILABLE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
-                PreciseDisconnectCause.LOCAL_NOT_REGISTERED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_CALL_EXCEEDED,
-                PreciseDisconnectCause.LOCAL_MAX_CALL_EXCEEDED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_CALL_DECLINE,
-                PreciseDisconnectCause.LOCAL_CALL_DECLINE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_CALL_VCC_ON_PROGRESSING,
-                PreciseDisconnectCause.LOCAL_CALL_VCC_ON_PROGRESSING);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED,
-                PreciseDisconnectCause.LOCAL_CALL_RESOURCE_RESERVATION_FAILED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED,
-                PreciseDisconnectCause.LOCAL_CALL_CS_RETRY_REQUIRED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED,
-                PreciseDisconnectCause.LOCAL_CALL_VOLTE_RETRY_REQUIRED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED,
-                PreciseDisconnectCause.LOCAL_CALL_TERMINATED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
-                PreciseDisconnectCause.LOCAL_HO_NOT_FEASIBLE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_TIMEOUT_1XX_WAITING,
-                PreciseDisconnectCause.TIMEOUT_1XX_WAITING);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_TIMEOUT_NO_ANSWER,
-                PreciseDisconnectCause.TIMEOUT_NO_ANSWER);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE,
-                PreciseDisconnectCause.TIMEOUT_NO_ANSWER_CALL_UPDATE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_FDN_BLOCKED,
-                PreciseDisconnectCause.FDN_BLOCKED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_REDIRECTED,
-                PreciseDisconnectCause.SIP_REDIRECTED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_BAD_REQUEST,
-                PreciseDisconnectCause.SIP_BAD_REQUEST);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_FORBIDDEN,
-                PreciseDisconnectCause.SIP_FORBIDDEN);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_NOT_FOUND,
-                PreciseDisconnectCause.SIP_NOT_FOUND);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_NOT_SUPPORTED,
-                PreciseDisconnectCause.SIP_NOT_SUPPORTED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_REQUEST_TIMEOUT,
-                PreciseDisconnectCause.SIP_REQUEST_TIMEOUT);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_TEMPRARILY_UNAVAILABLE,
-                PreciseDisconnectCause.SIP_TEMPRARILY_UNAVAILABLE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_BAD_ADDRESS,
-                PreciseDisconnectCause.SIP_BAD_ADDRESS);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_BUSY,
-                PreciseDisconnectCause.SIP_BUSY);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_REQUEST_CANCELLED,
-                PreciseDisconnectCause.SIP_REQUEST_CANCELLED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_NOT_ACCEPTABLE,
-                PreciseDisconnectCause.SIP_NOT_ACCEPTABLE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_NOT_REACHABLE,
-                PreciseDisconnectCause.SIP_NOT_REACHABLE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_CLIENT_ERROR,
-                PreciseDisconnectCause.SIP_CLIENT_ERROR);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_TRANSACTION_DOES_NOT_EXIST,
-                PreciseDisconnectCause.SIP_TRANSACTION_DOES_NOT_EXIST);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_SERVER_INTERNAL_ERROR,
-                PreciseDisconnectCause.SIP_SERVER_INTERNAL_ERROR);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE,
-                PreciseDisconnectCause.SIP_SERVICE_UNAVAILABLE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_SERVER_TIMEOUT,
-                PreciseDisconnectCause.SIP_SERVER_TIMEOUT);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_SERVER_ERROR,
-                PreciseDisconnectCause.SIP_SERVER_ERROR);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_USER_REJECTED,
-                PreciseDisconnectCause.SIP_USER_REJECTED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SIP_GLOBAL_ERROR,
-                PreciseDisconnectCause.SIP_GLOBAL_ERROR);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_EMERGENCY_TEMP_FAILURE,
-                PreciseDisconnectCause.EMERGENCY_TEMP_FAILURE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_EMERGENCY_PERM_FAILURE,
-                PreciseDisconnectCause.EMERGENCY_PERM_FAILURE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_MEDIA_INIT_FAILED,
-                PreciseDisconnectCause.MEDIA_INIT_FAILED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_MEDIA_NO_DATA,
-                PreciseDisconnectCause.MEDIA_NO_DATA);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_MEDIA_NOT_ACCEPTABLE,
-                PreciseDisconnectCause.MEDIA_NOT_ACCEPTABLE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_MEDIA_UNSPECIFIED,
-                PreciseDisconnectCause.MEDIA_UNSPECIFIED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_USER_TERMINATED,
-                PreciseDisconnectCause.USER_TERMINATED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_USER_NOANSWER,
-                PreciseDisconnectCause.USER_NOANSWER);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_USER_IGNORE,
-                PreciseDisconnectCause.USER_IGNORE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_USER_DECLINE,
-                PreciseDisconnectCause.USER_DECLINE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_LOW_BATTERY,
-                PreciseDisconnectCause.LOW_BATTERY);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_BLACKLISTED_CALL_ID,
-                PreciseDisconnectCause.BLACKLISTED_CALL_ID);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE,
-                PreciseDisconnectCause.USER_TERMINATED_BY_REMOTE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_UT_NOT_SUPPORTED,
-                PreciseDisconnectCause.UT_NOT_SUPPORTED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE,
-                PreciseDisconnectCause.UT_SERVICE_UNAVAILABLE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_UT_OPERATION_NOT_ALLOWED,
-                PreciseDisconnectCause.UT_OPERATION_NOT_ALLOWED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_UT_NETWORK_ERROR,
-                PreciseDisconnectCause.UT_NETWORK_ERROR);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_UT_CB_PASSWORD_MISMATCH,
-                PreciseDisconnectCause.UT_CB_PASSWORD_MISMATCH);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_ECBM_NOT_SUPPORTED,
-                PreciseDisconnectCause.ECBM_NOT_SUPPORTED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_MULTIENDPOINT_NOT_SUPPORTED,
-                PreciseDisconnectCause.MULTIENDPOINT_NOT_SUPPORTED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE,
-                PreciseDisconnectCause.CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_ANSWERED_ELSEWHERE,
-                PreciseDisconnectCause.ANSWERED_ELSEWHERE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_CALL_PULL_OUT_OF_SYNC,
-                PreciseDisconnectCause.CALL_PULL_OUT_OF_SYNC);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_CALL_END_CAUSE_CALL_PULL,
-                PreciseDisconnectCause.CALL_PULLED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SUPP_SVC_FAILED,
-                PreciseDisconnectCause.SUPP_SVC_FAILED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SUPP_SVC_CANCELLED,
-                PreciseDisconnectCause.SUPP_SVC_CANCELLED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_SUPP_SVC_REINVITE_COLLISION,
-                PreciseDisconnectCause.SUPP_SVC_REINVITE_COLLISION);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_IWLAN_DPD_FAILURE,
-                PreciseDisconnectCause.IWLAN_DPD_FAILURE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_EPDG_TUNNEL_ESTABLISH_FAILURE,
-                PreciseDisconnectCause.EPDG_TUNNEL_ESTABLISH_FAILURE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_EPDG_TUNNEL_REKEY_FAILURE,
-                PreciseDisconnectCause.EPDG_TUNNEL_REKEY_FAILURE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_EPDG_TUNNEL_LOST_CONNECTION,
-                PreciseDisconnectCause.EPDG_TUNNEL_LOST_CONNECTION);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED,
-                PreciseDisconnectCause.MAXIMUM_NUMBER_OF_CALLS_REACHED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_REMOTE_CALL_DECLINE,
-                PreciseDisconnectCause.REMOTE_CALL_DECLINE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_DATA_LIMIT_REACHED,
-                PreciseDisconnectCause.DATA_LIMIT_REACHED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_DATA_DISABLED,
-                PreciseDisconnectCause.DATA_DISABLED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_WIFI_LOST,
-                PreciseDisconnectCause.WIFI_LOST);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_RADIO_OFF,
-                PreciseDisconnectCause.RADIO_OFF);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_NO_VALID_SIM,
-                PreciseDisconnectCause.NO_VALID_SIM);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_RADIO_INTERNAL_ERROR,
-                PreciseDisconnectCause.RADIO_INTERNAL_ERROR);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_NETWORK_RESP_TIMEOUT,
-                PreciseDisconnectCause.NETWORK_RESP_TIMEOUT);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_NETWORK_REJECT,
-                PreciseDisconnectCause.NETWORK_REJECT);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_RADIO_ACCESS_FAILURE,
-                PreciseDisconnectCause.RADIO_ACCESS_FAILURE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_RADIO_LINK_FAILURE,
-                PreciseDisconnectCause.RADIO_LINK_FAILURE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_RADIO_LINK_LOST,
-                PreciseDisconnectCause.RADIO_LINK_LOST);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_RADIO_UPLINK_FAILURE,
-                PreciseDisconnectCause.RADIO_UPLINK_FAILURE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_RADIO_SETUP_FAILURE,
-                PreciseDisconnectCause.RADIO_SETUP_FAILURE);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_RADIO_RELEASE_NORMAL,
-                PreciseDisconnectCause.RADIO_RELEASE_NORMAL);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_RADIO_RELEASE_ABNORMAL,
-                PreciseDisconnectCause.RADIO_RELEASE_ABNORMAL);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_ACCESS_CLASS_BLOCKED,
-                PreciseDisconnectCause.ACCESS_CLASS_BLOCKED);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_NETWORK_DETACH,
-                PreciseDisconnectCause.NETWORK_DETACH);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_UNOBTAINABLE_NUMBER,
-                PreciseDisconnectCause.UNOBTAINABLE_NUMBER);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_1,
-                PreciseDisconnectCause.OEM_CAUSE_1);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_2,
-                PreciseDisconnectCause.OEM_CAUSE_2);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_3,
-                PreciseDisconnectCause.OEM_CAUSE_3);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_4,
-                PreciseDisconnectCause.OEM_CAUSE_4);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_5,
-                PreciseDisconnectCause.OEM_CAUSE_5);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_6,
-                PreciseDisconnectCause.OEM_CAUSE_6);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_7,
-                PreciseDisconnectCause.OEM_CAUSE_7);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_8,
-                PreciseDisconnectCause.OEM_CAUSE_8);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_9,
-                PreciseDisconnectCause.OEM_CAUSE_9);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_10,
-                PreciseDisconnectCause.OEM_CAUSE_10);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_11,
-                PreciseDisconnectCause.OEM_CAUSE_11);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_12,
-                PreciseDisconnectCause.OEM_CAUSE_12);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_13,
-                PreciseDisconnectCause.OEM_CAUSE_13);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_14,
-                PreciseDisconnectCause.OEM_CAUSE_14);
-        PRECISE_CAUSE_MAP.append(ImsReasonInfo.CODE_OEM_CAUSE_15,
-                PreciseDisconnectCause.OEM_CAUSE_15);
-    }
-
-    /**
      * Carrier configuration option which determines whether the carrier wants to inform the user
      * when a video call is handed over from WIFI to LTE.
      * See {@link CarrierConfigManager#KEY_NOTIFY_HANDOVER_VIDEO_FROM_WIFI_TO_LTE_BOOL} for more
@@ -721,7 +491,7 @@
         mPhone.getContext().registerReceiver(mReceiver, intentfilter);
         cacheCarrierConfiguration(mPhone.getSubId());
 
-        mPhone.getDefaultPhone().registerForDataEnabledChanged(
+        mPhone.getDefaultPhone().getDataEnabledSettings().registerForDataEnabledChanged(
                 this, EVENT_DATA_ENABLED_CHANGED, null);
 
         final TelecomManager telecomManager =
@@ -858,7 +628,7 @@
             mUtInterface.unregisterForSuppServiceIndication(this);
         }
         mPhone.getContext().unregisterReceiver(mReceiver);
-        mPhone.getDefaultPhone().unregisterForDataEnabledChanged(this);
+        mPhone.getDefaultPhone().getDataEnabledSettings().unregisterForDataEnabledChanged(this);
         mImsManagerConnector.disconnect();
     }
 
@@ -1200,8 +970,9 @@
 
         // Always unmute when initiating a new call
         setMute(false);
-        int serviceType = mPhoneNumberUtilsProxy.isEmergencyNumber(conn.getAddress()) ?
-                ImsCallProfile.SERVICE_TYPE_EMERGENCY : ImsCallProfile.SERVICE_TYPE_NORMAL;
+        boolean isEmergencyCall = mPhoneNumberUtilsProxy.isEmergencyNumber(conn.getAddress());
+        int serviceType = isEmergencyCall
+                ? ImsCallProfile.SERVICE_TYPE_EMERGENCY : ImsCallProfile.SERVICE_TYPE_NORMAL;
         int callType = ImsCallProfile.getCallTypeFromVideoState(videoState);
         //TODO(vt): Is this sufficient?  At what point do we know the video state of the call?
         conn.setVideoState(videoState);
@@ -1211,6 +982,28 @@
             ImsCallProfile profile = mImsManager.createCallProfile(serviceType, callType);
             profile.setCallExtraInt(ImsCallProfile.EXTRA_OIR, clirMode);
 
+            if (isEmergencyCall) {
+                // Set emergency service categories in ImsCallProfile
+                int emergencyServiceCategories =
+                        EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
+                TelephonyManager tm = (TelephonyManager) mPhone.getContext().getSystemService(
+                        Context.TELEPHONY_SERVICE);
+                if (tm.getCurrentEmergencyNumberList() != null) {
+                    for (List<EmergencyNumber> emergencyNumberList :
+                            tm.getCurrentEmergencyNumberList().values()) {
+                        if (emergencyNumberList != null) {
+                            for (EmergencyNumber num : emergencyNumberList) {
+                                if (num.getNumber().equals(conn.getAddress())) {
+                                    emergencyServiceCategories =
+                                            num.getEmergencyServiceCategoryBitmask();
+                                }
+                            }
+                        }
+                    }
+                }
+                profile.setEmergencyServiceCategories(emergencyServiceCategories);
+            }
+
             // Translate call subject intent-extra from Telecom-specific extra key to the
             // ImsCallProfile key.
             if (intentExtras != null) {
@@ -2201,11 +1994,6 @@
         return cause;
     }
 
-    private int getPreciseDisconnectCauseFromReasonInfo(ImsReasonInfo reasonInfo) {
-        return PRECISE_CAUSE_MAP.get(maybeRemapReasonCode(reasonInfo),
-                PreciseDisconnectCause.ERROR_UNSPECIFIED);
-    }
-
     /**
      * @return true if the phone is in Emergency Callback mode, otherwise false
      */
@@ -2404,10 +2192,6 @@
             mMetrics.writeOnImsCallTerminated(mPhone.getPhoneId(), imsCall.getCallSession(),
                     reasonInfo);
 
-            if(conn != null) {
-                conn.setPreciseDisconnectCause(getPreciseDisconnectCauseFromReasonInfo(reasonInfo));
-            }
-
             if (reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL
                     && mAutoRetryFailedWifiEmergencyCall) {
                 Pair<ImsCall, ImsReasonInfo> callInfo = new Pair<>(imsCall, reasonInfo);
@@ -2803,11 +2587,8 @@
             // Check with the DCTracker to see if data is enabled; there may be a case when
             // ImsPhoneCallTracker isn't being informed of the right data enabled state via its
             // registration, so we'll refresh now.
-            boolean isDataEnabled = false;
-            if (mPhone.getDefaultPhone().getDcTracker(TransportType.WWAN) != null) {
-                isDataEnabled = mPhone.getDefaultPhone().getDcTracker(TransportType.WWAN)
-                        .isDataEnabled();
-            }
+            boolean isDataEnabled = mPhone.getDefaultPhone().getDataEnabledSettings()
+                    .isDataEnabled();
 
             if (DBG) {
                 log("onCallHandover ::  srcAccessTech=" + srcAccessTech + ", targetAccessTech="
@@ -3152,11 +2933,6 @@
         }
         int cause = getDisconnectCauseFromReasonInfo(reasonInfo, callState);
 
-        if (conn != null) {
-            conn.setPreciseDisconnectCause(
-                    getPreciseDisconnectCauseFromReasonInfo(reasonInfo));
-        }
-
         processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause);
     }
 
@@ -3847,10 +3623,9 @@
     /**
      * Handler of data enabled changed event
      * @param enabled True if data is enabled, otherwise disabled.
-     * @param reason Reason for data enabled/disabled (see {@code REASON_*} in
-     *      {@link DataEnabledSettings}.
+     * @param reason Reason for data enabled/disabled. See {@link DataEnabledChangedReason}.
      */
-    private void onDataEnabledChanged(boolean enabled, int reason) {
+    private void onDataEnabledChanged(boolean enabled, @DataEnabledChangedReason int reason) {
 
         log("onDataEnabledChanged: enabled=" + enabled + ", reason=" + reason);
 
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
index 2d024d1..3f96b59 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
@@ -102,12 +102,13 @@
     }
 
     @Override
-    public void dial(String address, int clirMode, Message result) {
+    public void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+               int clirMode, Message result) {
     }
 
     @Override
-    public void dial(String address, int clirMode, UUSInfo uusInfo,
-            Message result) {
+    public void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+              int clirMode, UUSInfo uusInfo, Message result) {
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
index 47844ca..ac219ea 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
@@ -165,6 +165,11 @@
      */
     private final SparseArray<TelephonySettings> mLastSettings = new SparseArray<>();
 
+    /**
+     * Last carrier id matching.
+     */
+    private final SparseArray<CarrierIdMatching> mLastCarrierId = new SparseArray<>();
+
     /** The start system time of the TelephonyLog in milliseconds*/
     private long mStartSystemTimeMs;
 
@@ -516,6 +521,13 @@
                     .setImsConnectionState(mLastImsConnectionState.get(key)).build();
             addTelephonyEvent(event);
         }
+
+        for (int i = 0; i < mLastCarrierId.size(); i++) {
+            final int key = mLastCarrierId.keyAt(i);
+            TelephonyEvent event = new TelephonyEventBuilder(mStartElapsedTimeMs, key)
+                    .setCarrierIdMatching(mLastCarrierId.get(key)).build();
+            addTelephonyEvent(event);
+        }
     }
 
     /**
@@ -2006,6 +2018,7 @@
 
         TelephonyEvent event = new TelephonyEventBuilder(phoneId).setCarrierIdMatching(
                 carrierIdMatching).build();
+        mLastCarrierId.put(phoneId, carrierIdMatching);
         addTelephonyEvent(event);
     }
 
diff --git a/src/java/com/android/internal/telephony/sip/SipCommandInterface.java b/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
index 83a5ff9..a8d3438 100644
--- a/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
+++ b/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
@@ -101,12 +101,13 @@
     }
 
     @Override
-    public void dial(String address, int clirMode, Message result) {
+    public void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+                     int clirMode, Message result) {
     }
 
     @Override
-    public void dial(String address, int clirMode, UUSInfo uusInfo,
-            Message result) {
+    public void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+                     int clirMode, UUSInfo uusInfo, Message result) {
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/sip/SipPhoneBase.java b/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
index 272187e..ee89638 100755
--- a/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -423,15 +423,6 @@
         return false;
     }
 
-    @Override
-    public boolean isDataEnabled() {
-        return false;
-    }
-
-    @Override
-    public void setUserDataEnabled(boolean enable) {
-    }
-
     public boolean enableDataConnectivity() {
         return false;
     }
diff --git a/src/java/com/android/internal/telephony/test/SimulatedCommands.java b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
index 9a87d01..8e0b730 100644
--- a/src/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -32,6 +32,11 @@
 import android.service.carrier.CarrierIdentifier;
 import android.telephony.CellInfo;
 import android.telephony.CellInfoGsm;
+import android.telephony.CellSignalStrengthCdma;
+import android.telephony.CellSignalStrengthGsm;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthTdscdma;
+import android.telephony.CellSignalStrengthWcdma;
 import android.telephony.IccOpenLogicalChannelResponse;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.NetworkRegistrationState;
@@ -549,8 +554,10 @@
      * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
      */
     @Override
-    public void dial (String address, int clirMode, Message result) {
-        SimulatedCommandsVerifier.getInstance().dial(address, clirMode, result);
+    public void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+                      int clirMode, Message result) {
+        SimulatedCommandsVerifier.getInstance().dial(address, isEmergencyCall,
+                emergencyServiceCategories, clirMode, result);
         simulatedCallState.onDial(address);
 
         resultSuccess(result, null);
@@ -568,8 +575,10 @@
      * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
      */
     @Override
-    public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
-        SimulatedCommandsVerifier.getInstance().dial(address, clirMode, uusInfo, result);
+    public void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+                     int clirMode, UUSInfo uusInfo, Message result) {
+        SimulatedCommandsVerifier.getInstance().dial(address, isEmergencyCall,
+                emergencyServiceCategories, clirMode, uusInfo, result);
         simulatedCallState.onDial(address);
 
         resultSuccess(result, null);
@@ -858,25 +867,14 @@
 
     @Override
     public void getSignalStrength (Message result) {
-
         if (mSignalStrength == null) {
             mSignalStrength = new SignalStrength(
-                20, // gsmSignalStrength
-                0,  // gsmBitErrorRate
-                -1, // cdmaDbm
-                -1, // cdmaEcio
-                -1, // evdoDbm
-                -1, // evdoEcio
-                -1, // evdoSnr
-                99, // lteSignalStrength
-                SignalStrength.INVALID,     // lteRsrp
-                SignalStrength.INVALID,     // lteRsrq
-                SignalStrength.INVALID,     // lteRssnr
-                SignalStrength.INVALID,     // lteCqi
-                SignalStrength.INVALID      // tdScdmaRscp
-            );
+                    new CellSignalStrengthCdma(),
+                    new CellSignalStrengthGsm(20, 0, CellInfo.UNAVAILABLE),
+                    new CellSignalStrengthWcdma(),
+                    new CellSignalStrengthTdscdma(),
+                    new CellSignalStrengthLte());
         }
-
         resultSuccess(result, mSignalStrength);
     }
 
@@ -2151,20 +2149,11 @@
     public void notifySignalStrength() {
         if (mSignalStrength == null) {
             mSignalStrength = new SignalStrength(
-                    20, // gsmSignalStrength
-                    0,  // gsmBitErrorRate
-                    -1, // cdmaDbm
-                    -1, // cdmaEcio
-                    -1, // evdoDbm
-                    -1, // evdoEcio
-                    -1, // evdoSnr
-                    99, // lteSignalStrength
-                    SignalStrength.INVALID,     // lteRsrp
-                    SignalStrength.INVALID,     // lteRsrq
-                    SignalStrength.INVALID,     // lteRssnr
-                    SignalStrength.INVALID,     // lteCqi
-                    SignalStrength.INVALID      // tdScdmaRscp
-            );
+                    new CellSignalStrengthCdma(),
+                    new CellSignalStrengthGsm(20, 0, CellInfo.UNAVAILABLE),
+                    new CellSignalStrengthWcdma(),
+                    new CellSignalStrengthTdscdma(),
+                    new CellSignalStrengthLte());
         }
 
         if (mSignalStrengthRegistrant != null) {
diff --git a/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java b/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java
index 5cb130b..22e670b 100644
--- a/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java
+++ b/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java
@@ -672,13 +672,13 @@
     }
 
     @Override
-    public void dial(String address, int clirMode, Message result) {
-
+    public void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+                     int clirMode, Message result) {
     }
 
     @Override
-    public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
-
+    public void dial(String address, boolean isEmergencyCall, int emergencyServiceCategories,
+                     int clirMode, UUSInfo uusInfo, Message result) {
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCard.java b/src/java/com/android/internal/telephony/uicc/UiccCard.java
index 2cf19f9..97260af 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCard.java
@@ -510,6 +510,8 @@
         pw.println("UiccCard:");
         pw.println(" mCi=" + mCi);
         pw.println(" mCardState=" + mCardState);
+        pw.println(" mCardId=" + mCardId);
+        pw.println(" mPhoneId=" + mPhoneId);
         pw.println();
         if (mUiccProfile != null) {
             mUiccProfile.dump(fd, pw, args);
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 63c9734..b018221 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -30,6 +30,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.Rlog;
 import android.telephony.TelephonyManager;
+import android.telephony.UiccCardInfo;
 import android.text.TextUtils;
 import android.util.LocalLog;
 
@@ -594,6 +595,30 @@
     }
 
     /**
+     * Returns the UiccCardInfo of all currently inserted UICCs and embedded eUICCs.
+     */
+    public ArrayList<UiccCardInfo> getAllUiccCardInfos() {
+        ArrayList<UiccCardInfo> infos = new ArrayList<>();
+        for (int slotIndex = 0; slotIndex < mUiccSlots.length; slotIndex++) {
+            final UiccSlot slot = mUiccSlots[slotIndex];
+            boolean isEuicc = slot.isEuicc();
+            String eid = null;
+            String iccid = slot.getUiccCard().getIccId();
+            int cardId = INVALID_CARD_ID;
+            if (isEuicc) {
+                eid = slot.getUiccCard().getCardId();
+                cardId = convertToPublicCardId(eid);
+            } else {
+                // leave eid null if the UICC is not embedded
+                cardId = convertToPublicCardId(iccid);
+            }
+            UiccCardInfo info = new UiccCardInfo(isEuicc, cardId, eid, iccid, slotIndex);
+            infos.add(info);
+        }
+        return infos;
+    }
+
+    /**
      * Get the card ID of the default eUICC.
      */
     public int getCardIdForDefaultEuicc() {
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index fcc60a1..34c9462 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -393,6 +393,7 @@
         pw.println(" mCi=" + mCi);
         pw.println(" mActive=" + mActive);
         pw.println(" mLastRadioState=" + mLastRadioState);
+        pw.println(" mIccId=" + mIccId);
         pw.println(" mCardState=" + mCardState);
         if (mUiccCard != null) {
             pw.println(" mUiccCard=" + mUiccCard);
diff --git a/tests/telephonytests/Android.bp b/tests/telephonytests/Android.bp
index 3a8a1e6..2fe06d5 100644
--- a/tests/telephonytests/Android.bp
+++ b/tests/telephonytests/Android.bp
@@ -11,7 +11,7 @@
     ],
 
     static_libs: [
-        "android-support-test",
+        "androidx.test.rules",
         "frameworks-base-testutils",
         "guava",
         "mockito-target-minus-junit4",
diff --git a/tests/telephonytests/AndroidManifest.xml b/tests/telephonytests/AndroidManifest.xml
index 35ed2fb..3fbaacc 100644
--- a/tests/telephonytests/AndroidManifest.xml
+++ b/tests/telephonytests/AndroidManifest.xml
@@ -28,7 +28,7 @@
             </intent-filter>
         </activity>
     </application>
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
         android:targetPackage="com.android.frameworks.telephonytests"
         android:label="Frameworks Telephony Tests">
     </instrumentation>
diff --git a/tests/telephonytests/AndroidTest.xml b/tests/telephonytests/AndroidTest.xml
index 74b2799..c3a405b 100644
--- a/tests/telephonytests/AndroidTest.xml
+++ b/tests/telephonytests/AndroidTest.xml
@@ -22,7 +22,7 @@
     <option name="test-tag" value="FrameworksTelephonyTests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.telephonytests" />
-        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsCompatTests.java b/tests/telephonytests/src/android/telephony/ims/ImsCompatTests.java
index caa245f..414cb47 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsCompatTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsCompatTests.java
@@ -21,10 +21,11 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
-import android.support.test.runner.AndroidJUnit4;
 import android.telephony.ims.aidl.IImsCallSessionListener;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.ims.internal.IImsMMTelFeature;
 
 import org.junit.After;
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java b/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
index b7d2998..2695e4c 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
@@ -24,7 +24,6 @@
 
 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;
@@ -32,6 +31,8 @@
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.ims.internal.IImsFeatureStatusCallback;
 
 import org.junit.After;
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
index 3810f76..57f33ce 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
@@ -26,7 +26,6 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.RemoteException;
-import android.support.test.runner.AndroidJUnit4;
 import android.telephony.ServiceState;
 import android.telephony.ims.aidl.IImsRegistration;
 import android.telephony.ims.aidl.IImsRegistrationCallback;
@@ -35,6 +34,8 @@
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java b/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java
index 34febcb..d6841cd 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java
@@ -29,7 +29,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.RemoteException;
-import android.support.test.runner.AndroidJUnit4;
 import android.telephony.ims.aidl.IImsMmTelFeature;
 import android.telephony.ims.aidl.IImsServiceController;
 import android.telephony.ims.feature.ImsFeature;
@@ -38,6 +37,8 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.SparseArray;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.ims.ImsManager;
 import com.android.ims.internal.IImsFeatureStatusCallback;
 
diff --git a/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
index 79b9d60..a1a9baf 100644
--- a/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
@@ -28,7 +28,6 @@
 import android.os.Looper;
 import android.os.Message;
 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;
@@ -36,6 +35,8 @@
 import android.telephony.ims.stub.ImsCallSessionImplBase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.ims.internal.IImsCallSession;
 import com.android.internal.telephony.ims.ImsTestBase;
 
diff --git a/tests/telephonytests/src/android/telephony/mbms/MbmsReceiverTest.java b/tests/telephonytests/src/android/telephony/mbms/MbmsReceiverTest.java
index 46cf4f7..b93d400 100644
--- a/tests/telephonytests/src/android/telephony/mbms/MbmsReceiverTest.java
+++ b/tests/telephonytests/src/android/telephony/mbms/MbmsReceiverTest.java
@@ -18,13 +18,13 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-
 @RunWith(AndroidJUnit4.class)
 public class MbmsReceiverTest {
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityGsmTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityGsmTest.java
index cd4d17d..f50cea1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityGsmTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityGsmTest.java
@@ -18,7 +18,6 @@
 
 import android.os.Parcel;
 import android.telephony.CellIdentityGsm;
-import android.telephony.CellInfo;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -127,24 +126,6 @@
     }
 
     @SmallTest
-    public void testFormerConstructor() {
-        CellIdentityGsm ci =
-                new CellIdentityGsm(MCC, MNC, LAC, CID);
-
-        assertEquals(LAC, ci.getLac());
-        assertEquals(CID, ci.getCid());
-        assertEquals(Integer.MAX_VALUE, ci.getArfcn());
-        assertEquals(Integer.MAX_VALUE, ci.getBsic());
-        assertEquals(MCC, ci.getMcc());
-        assertEquals(MNC, ci.getMnc());
-        assertEquals(MCC_STR, ci.getMccString());
-        assertEquals(MNC_STR, ci.getMncString());
-        assertEquals(MCC_STR + MNC_STR, ci.getMobileNetworkOperator());
-        assertNull(ci.getOperatorAlphaLong());
-        assertNull(ci.getOperatorAlphaShort());
-    }
-
-    @SmallTest
     public void testEquals() {
         CellIdentityGsm ciA = new CellIdentityGsm(
                 LAC, CID, ARFCN, BSIC, MCC_STR, MNC_STR, ALPHA_LONG, ALPHA_SHORT);
@@ -185,15 +166,7 @@
                 new CellIdentityGsm(LAC, CID, ARFCN, BSIC, null, null, ALPHA_LONG, ALPHA_SHORT);
 
         Parcel p = Parcel.obtain();
-        p.writeInt(CellInfo.TYPE_GSM);
-        p.writeString(String.valueOf(Integer.MAX_VALUE));
-        p.writeString(String.valueOf(Integer.MAX_VALUE));
-        p.writeString(ALPHA_LONG);
-        p.writeString(ALPHA_SHORT);
-        p.writeInt(LAC);
-        p.writeInt(CID);
-        p.writeInt(ARFCN);
-        p.writeInt(BSIC);
+        ci.writeToParcel(p, 0);
         p.setDataPosition(0);
 
         CellIdentityGsm newCi = CellIdentityGsm.CREATOR.createFromParcel(p);
@@ -208,15 +181,7 @@
                 new CellIdentityGsm(LAC, CID, ARFCN, BSIC, null, null, ALPHA_LONG, ALPHA_SHORT);
 
         Parcel p = Parcel.obtain();
-        p.writeInt(CellInfo.TYPE_GSM);
-        p.writeString(invalidMcc);
-        p.writeString(invalidMnc);
-        p.writeString(ALPHA_LONG);
-        p.writeString(ALPHA_SHORT);
-        p.writeInt(LAC);
-        p.writeInt(CID);
-        p.writeInt(ARFCN);
-        p.writeInt(BSIC);
+        ci.writeToParcel(p, 0);
         p.setDataPosition(0);
 
         CellIdentityGsm newCi = CellIdentityGsm.CREATOR.createFromParcel(p);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityWcdmaTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityWcdmaTest.java
index 9fc0af4..6a049d6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityWcdmaTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityWcdmaTest.java
@@ -18,7 +18,6 @@
 
 import android.os.Parcel;
 import android.telephony.CellIdentityWcdma;
-import android.telephony.CellInfo;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -127,23 +126,6 @@
     }
 
     @SmallTest
-    public void testFormerConstructor() {
-        CellIdentityWcdma ci =
-                new CellIdentityWcdma(MCC, MNC, LAC, CID, PSC);
-
-        assertEquals(LAC, ci.getLac());
-        assertEquals(CID, ci.getCid());
-        assertEquals(PSC, ci.getPsc());
-        assertEquals(MCC, ci.getMcc());
-        assertEquals(MNC, ci.getMnc());
-        assertEquals(MCC_STR, ci.getMccString());
-        assertEquals(MNC_STR, ci.getMncString());
-        assertEquals(MCC_STR + MNC_STR, ci.getMobileNetworkOperator());
-        assertNull(ci.getOperatorAlphaLong());
-        assertNull(ci.getOperatorAlphaShort());
-    }
-
-    @SmallTest
     public void testEquals() {
         CellIdentityWcdma ciA = new CellIdentityWcdma(
                 LAC, CID, PSC, UARFCN, MCC_STR, MNC_STR, ALPHA_LONG, ALPHA_SHORT);
@@ -183,15 +165,7 @@
                 new CellIdentityWcdma(LAC, CID, PSC, UARFCN, null, null, ALPHA_LONG, ALPHA_SHORT);
 
         Parcel p = Parcel.obtain();
-        p.writeInt(CellInfo.TYPE_WCDMA);
-        p.writeString(String.valueOf(Integer.MAX_VALUE));
-        p.writeString(String.valueOf(Integer.MAX_VALUE));
-        p.writeString(ALPHA_LONG);
-        p.writeString(ALPHA_SHORT);
-        p.writeInt(LAC);
-        p.writeInt(CID);
-        p.writeInt(PSC);
-        p.writeInt(UARFCN);
+        ci.writeToParcel(p, 0);
         p.setDataPosition(0);
 
         CellIdentityWcdma newCi = CellIdentityWcdma.CREATOR.createFromParcel(p);
@@ -206,15 +180,7 @@
                 new CellIdentityWcdma(LAC, CID, PSC, UARFCN, null, null, ALPHA_LONG, ALPHA_SHORT);
 
         Parcel p = Parcel.obtain();
-        p.writeInt(CellInfo.TYPE_WCDMA);
-        p.writeString(invalidMcc);
-        p.writeString(invalidMnc);
-        p.writeString(ALPHA_LONG);
-        p.writeString(ALPHA_SHORT);
-        p.writeInt(LAC);
-        p.writeInt(CID);
-        p.writeInt(PSC);
-        p.writeInt(UARFCN);
+        ci.writeToParcel(p, 0);
         p.setDataPosition(0);
 
         CellIdentityWcdma newCi = CellIdentityWcdma.CREATOR.createFromParcel(p);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthCdmaTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthCdmaTest.java
index 7ad38fc..063fb3c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthCdmaTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthCdmaTest.java
@@ -29,26 +29,26 @@
 
 public class CellSignalStrengthCdmaTest extends AndroidTestCase {
 
-    private static final int CDMA_DBM = 74;
-    private static final int CDMA_ECIO = 124;
-    private static final int EVDO_DBM = 23;
-    private static final int EVDO_ECIO = 108;
+    private static final int CDMA_DBM = -74;
+    private static final int CDMA_ECIO = -124;
+    private static final int EVDO_DBM = -23;
+    private static final int EVDO_ECIO = -108;
     private static final int EVDO_SNR = 7;
 
     @SmallTest
     public void testConstructor() {
         CellSignalStrengthCdma css = new CellSignalStrengthCdma(
                 CDMA_DBM, CDMA_ECIO, EVDO_DBM, EVDO_ECIO, EVDO_SNR);
-        assertEquals(-CDMA_DBM, css.getCdmaDbm());
-        assertEquals(-CDMA_ECIO, css.getCdmaEcio());
-        assertEquals(-EVDO_DBM, css.getEvdoDbm());
-        assertEquals(-EVDO_ECIO, css.getEvdoEcio());
+        assertEquals(CDMA_DBM, css.getCdmaDbm());
+        assertEquals(CDMA_ECIO, css.getCdmaEcio());
+        assertEquals(EVDO_DBM, css.getEvdoDbm());
+        assertEquals(EVDO_ECIO, css.getEvdoEcio());
         assertEquals(EVDO_SNR, css.getEvdoSnr());
     }
 
     @SmallTest
     public void testInvalidConstructor() {
-        CellSignalStrengthCdma css = new CellSignalStrengthCdma(-1, -1, -1, -1, -1);
+        CellSignalStrengthCdma css = new CellSignalStrengthCdma(200, 2000, 20, 400, 200);
         assertEquals(Integer.MAX_VALUE, css.getCdmaDbm());
         assertEquals(Integer.MAX_VALUE, css.getCdmaEcio());
         assertEquals(Integer.MAX_VALUE, css.getEvdoDbm());
@@ -74,7 +74,7 @@
                                 CDMA_DBM, CDMA_ECIO, EVDO_DBM, EVDO_ECIO, EVDO_SNR)));
         assertFalse(new CellSignalStrengthCdma(
                 CDMA_DBM, CDMA_ECIO, EVDO_DBM, EVDO_ECIO, EVDO_SNR).equals(
-                    new CellSignalStrengthCdma(CDMA_DBM, CDMA_ECIO, -1, EVDO_ECIO, EVDO_SNR)));
+                    new CellSignalStrengthCdma(CDMA_DBM, CDMA_ECIO, -24, EVDO_ECIO, EVDO_SNR)));
     }
 
     @SmallTest
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java
index 2fdf0b1..074e9fc 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java
@@ -30,13 +30,13 @@
 
 public class CellSignalStrengthNrTest extends AndroidTestCase {
     private static final int CSIRSRP = -123;
-    private static final int CSIRSRQ = -111;
+    private static final int CSIRSRQ = -11;
     private static final int ANOTHER_CSIRSRP = -111;
-    private static final int ANOTHER_CSIRSRQ = -120;
+    private static final int ANOTHER_CSIRSRQ = -12;
     private static final int INVALID_CSIRSRP = Integer.MAX_VALUE;
-    private static final int CSISINR = 64;
+    private static final int CSISINR = 18;
     private static final int SSRSRP = -112;
-    private static final int SSRSRQ = -94;
+    private static final int SSRSRQ = -13;
     private static final int SSSINR = 32;
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthWcdmaTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthWcdmaTest.java
new file mode 100644
index 0000000..8323ba3
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthWcdmaTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.CellInfo;
+import android.telephony.CellSignalStrengthWcdma;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/** Unit tests for {@link CellSignalStrengthCdma}. */
+
+public class CellSignalStrengthWcdmaTest extends AndroidTestCase {
+
+    private static final int RSSI = -95;
+    private static final int BER = 3;
+    private static final int RSCP = -106;
+    private static final int ECNO = -5;
+
+    @SmallTest
+    public void testConstructor() {
+        CellSignalStrengthWcdma css = new CellSignalStrengthWcdma(RSSI, BER, RSCP, ECNO);
+        assertEquals(RSSI, css.getRssi());
+        assertEquals(BER, css.getBitErrorRate());
+        assertEquals(RSCP, css.getRscp());
+        assertEquals(ECNO, css.getEcNo());
+    }
+
+    @SmallTest
+    public void testInvalidConstructor() {
+        CellSignalStrengthWcdma css = new CellSignalStrengthWcdma(-1, -1, -1, 10);
+        assertEquals(CellInfo.UNAVAILABLE, css.getRssi());
+        assertEquals(CellInfo.UNAVAILABLE, css.getBitErrorRate());
+        assertEquals(CellInfo.UNAVAILABLE, css.getRscp());
+        assertEquals(CellInfo.UNAVAILABLE, css.getEcNo());
+    }
+
+    @SmallTest
+    public void testDefaultConstructor() {
+        CellSignalStrengthWcdma css = new CellSignalStrengthWcdma();
+        assertEquals(CellInfo.UNAVAILABLE, css.getRssi());
+        assertEquals(CellInfo.UNAVAILABLE, css.getBitErrorRate());
+        assertEquals(CellInfo.UNAVAILABLE, css.getRscp());
+        assertEquals(CellInfo.UNAVAILABLE, css.getEcNo());
+    }
+
+    @SmallTest
+    public void testEquals() {
+        assertTrue(new CellSignalStrengthWcdma(RSSI, BER, RSCP, ECNO).equals(
+                        new CellSignalStrengthWcdma(RSSI, BER, RSCP, ECNO)));
+        assertFalse(new CellSignalStrengthWcdma(RSSI, BER, RSCP, ECNO).equals(
+                    new CellSignalStrengthWcdma(RSSI, BER, RSCP + 1, ECNO)));
+    }
+
+    @SmallTest
+    public void testParcel() {
+        CellSignalStrengthWcdma css = new CellSignalStrengthWcdma(-1, -1, -1, 10);
+
+        Parcel p = Parcel.obtain();
+        css.writeToParcel(p, 0);
+        p.setDataPosition(0);
+
+        CellSignalStrengthWcdma newCss = CellSignalStrengthWcdma.CREATOR.createFromParcel(p);
+        assertEquals(css, newCss);
+    }
+
+    @SmallTest
+    public void testLevel() {
+        CellSignalStrengthWcdma css = new CellSignalStrengthWcdma(RSSI, BER, RSCP, ECNO);
+        PersistableBundle b = new PersistableBundle();
+
+        // No keys in the bundle - should use RSSI and default levels.
+        css.updateLevel(b, null); // ServiceState isn't used in WCDMA (yet)
+        assertEquals(2 /* MODERATE */, css.getLevel());
+
+        // Add RSCP levels but set the measurement as an invalid (empty string), should still use
+        // RSSI.
+        b.putIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY,
+                new int[] {
+                        -115, /* SIGNAL_STRENGTH_POOR */
+                        -105, /* SIGNAL_STRENGTH_MODERATE */
+                        -95, /* SIGNAL_STRENGTH_GOOD */
+                        -85 /* SIGNAL_STRENGTH_GREAT */
+                });
+        b.putString(CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, "");
+        css.updateLevel(b, null); // ServiceState isn't used in WCDMA (yet)
+        assertEquals(2 /* MODERATE */, css.getLevel());
+
+        // Update the calculation to use RSCP, and expect the level to be calculated accordingly.
+        b.putString(CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING,
+                "rscp");
+        css.updateLevel(b, null); // ServiceState isn't used in WCDMA (yet)
+        assertEquals(1 /* POOR */, css.getLevel());
+    }
+
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockTrackerTest.java
index 28ac9eb..742e3e1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockTrackerTest.java
@@ -18,7 +18,7 @@
 
 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
 
-import android.support.test.filters.FlakyTest;
+import androidx.test.filters.FlakyTest;
 
 import junit.framework.TestCase;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index 6313633..5637892 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -590,6 +590,8 @@
         //doReturn(mBundle).when(mCarrierConfigManager).getConfig(anyInt());
         doReturn(mBundle).when(mCarrierConfigManager).getConfig();
 
+        doReturn(true).when(mEuiccManager).isEnabled();
+
         mConfiguration.locale = Locale.US;
         doReturn(mConfiguration).when(mResources).getConfiguration();
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
index 1785c8f..2758d7c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
@@ -168,21 +168,15 @@
 
     @Test @SmallTest
     public void testNotifyDataConnectionFailed() throws Exception {
-        mDefaultPhoneNotifierUT.notifyDataConnectionFailed(mPhone, "BUSY", "APN_0");
-        verify(mTelephonyRegisteryMock).notifyDataConnectionFailedForSubscriber(0, "BUSY", "APN_0");
+        mDefaultPhoneNotifierUT.notifyDataConnectionFailed(mPhone, "APN_0");
+        verify(mTelephonyRegisteryMock).notifyDataConnectionFailedForSubscriber(0, "APN_0");
 
-        mDefaultPhoneNotifierUT.notifyDataConnectionFailed(mPhone, "LOCAL", "APN_0");
-        verify(mTelephonyRegisteryMock).notifyDataConnectionFailedForSubscriber(0, "LOCAL",
-                "APN_0");
-
-        mDefaultPhoneNotifierUT.notifyDataConnectionFailed(mPhone, "LOCAL", "APN_1");
-        verify(mTelephonyRegisteryMock).notifyDataConnectionFailedForSubscriber(0, "LOCAL",
-                "APN_1");
+        mDefaultPhoneNotifierUT.notifyDataConnectionFailed(mPhone, "APN_1");
+        verify(mTelephonyRegisteryMock).notifyDataConnectionFailedForSubscriber(0, "APN_1");
 
         doReturn(1).when(mPhone).getSubId();
-        mDefaultPhoneNotifierUT.notifyDataConnectionFailed(mPhone, "LOCAL", "APN_1");
-        verify(mTelephonyRegisteryMock).notifyDataConnectionFailedForSubscriber(1, "LOCAL",
-                "APN_1");
+        mDefaultPhoneNotifierUT.notifyDataConnectionFailed(mPhone, "APN_1");
+        verify(mTelephonyRegisteryMock).notifyDataConnectionFailedForSubscriber(1, "APN_1");
     }
 
     @Test @SmallTest
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java b/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java
index 1f2124b..a5eb233 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java
@@ -26,20 +26,21 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import static java.util.Arrays.asList;
-
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.os.BatteryManager;
 import android.os.HandlerThread;
 import android.os.Message;
-import android.support.test.filters.FlakyTest;
 import android.test.suitebuilder.annotation.MediumTest;
 
+import androidx.test.filters.FlakyTest;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import static java.util.Arrays.asList;
+
 import java.util.ArrayList;
 
 public class DeviceStateMonitorTest extends TelephonyTest {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java b/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java
index f9a883a..7c303bd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java
@@ -25,7 +25,8 @@
 
 import android.os.Handler;
 import android.os.Looper;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.telephony.ims.ImsTestBase;
 
@@ -34,6 +35,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+
 @RunWith(AndroidJUnit4.class)
 public class ExponentialBackoffTest extends ImsTestBase {
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
index d020010..10dd12b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
@@ -25,11 +25,12 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.BaseColumns;
-import android.support.test.InstrumentationRegistry;
 import android.telephony.SubscriptionManager;
 import android.test.mock.MockContentProvider;
 import android.util.Log;
 
+import androidx.test.InstrumentationRegistry;
+
 public class FakeTelephonyProvider extends MockContentProvider {
     static final String TAG = "FakeTelephonyProvider";
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
index d12b6cc..1d68aea 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
@@ -31,13 +32,14 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
-import android.support.test.filters.FlakyTest;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.ServiceState;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.filters.FlakyTest;
+
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -115,9 +117,8 @@
         assertEquals(1, mCTUT.mForegroundCall.getConnections().size());
         /* verify the command is sent out to RIL */
         verify(mSimulatedCommandsVerifier).dial(eq(PhoneNumberUtils.
-                        extractNetworkPortionAlt(mDialString)), anyInt(),
-                eq((UUSInfo) null),
-                isA(Message.class));
+                        extractNetworkPortionAlt(mDialString)), anyBoolean(), anyInt(),
+                anyInt(), eq((UUSInfo) null), isA(Message.class));
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index f5d5a82..d54ae1d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -49,7 +49,6 @@
 import android.os.Process;
 import android.os.WorkSource;
 import android.preference.PreferenceManager;
-import android.support.test.filters.FlakyTest;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellLocation;
 import android.telephony.ServiceState;
@@ -58,6 +57,8 @@
 import android.telephony.gsm.GsmCellLocation;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.internal.telephony.test.SimulatedCommands;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus;
 import com.android.internal.telephony.uicc.IccException;
@@ -728,7 +729,7 @@
         assertEquals(EVENT_EMERGENCY_CALL_TOGGLE, msgList.get(1).what);
 
         // verify setInternalDataEnabled
-        verify(mDcTracker).setInternalDataEnabled(true);
+        verify(mDataEnabledSettings).setInternalDataEnabled(true);
 
         // verify wakeLock released
         assertEquals(false, mPhoneUT.getWakeLock().isHeld());
@@ -816,7 +817,7 @@
         assertEquals(EVENT_EMERGENCY_CALL_TOGGLE, msgList.get(1).what);
 
         // verify setInternalDataEnabled
-        verify(mDcTracker).setInternalDataEnabled(true);
+        verify(mDataEnabledSettings).setInternalDataEnabled(true);
 
         // verify wakeLock released
         assertEquals(false, mPhoneUT.getWakeLock().isHeld());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
index ce2d62f..be18cfb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
@@ -31,6 +31,7 @@
 import android.os.HandlerThread;
 import android.os.Message;
 import android.telephony.CellIdentityGsm;
+import android.telephony.CellInfo;
 import android.telephony.CellInfoGsm;
 import android.telephony.ServiceState;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -83,8 +84,10 @@
         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
 
         mCellInfo = new CellInfoGsm();
-        mCellInfo.setCellIdentity(new CellIdentityGsm(Integer.parseInt(US_MCC),
-                Integer.parseInt(FAKE_MNC), 0, 0));
+        mCellInfo.setCellIdentity(new CellIdentityGsm(
+                    CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                    CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                    US_MCC, FAKE_MNC, null, null));
         doAnswer(invocation -> {
             Message m = invocation.getArgument(1);
             AsyncResult.forMessage(m, Arrays.asList(mCellInfo), null);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java
index eb52e7c..1f553fe 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java
@@ -19,16 +19,16 @@
 import static junit.framework.Assert.assertEquals;
 
 import android.os.Parcel;
-import android.support.test.filters.SmallTest;
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CellIdentityLte;
 import android.telephony.NetworkRegistrationState;
 import android.telephony.TelephonyManager;
 
+import androidx.test.filters.SmallTest;
+
 import org.junit.Test;
 
 /** Unit tests for {@link NetworkRegistrationState}. */
-
 public class NetworkRegistrationStateTest {
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkScanRequestTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkScanRequestTest.java
index ed1a723..4538dea 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkScanRequestTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkScanRequestTest.java
@@ -19,19 +19,19 @@
 import static org.junit.Assert.assertEquals;
 
 import android.os.Parcel;
-import android.support.test.filters.SmallTest;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.AccessNetworkConstants.EutranBand;
 import android.telephony.AccessNetworkConstants.GeranBand;
 import android.telephony.NetworkScanRequest;
 import android.telephony.RadioAccessSpecifier;
 
+import androidx.test.filters.SmallTest;
+
 import org.junit.Test;
 
 import java.util.ArrayList;
 
 /** Unit tests for {@link NetworkScanRequest}. */
-
 public class NetworkScanRequestTest {
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkScanResultTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkScanResultTest.java
index 041c5f5..1b58f36 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkScanResultTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkScanResultTest.java
@@ -19,7 +19,6 @@
 import static org.junit.Assert.assertEquals;
 
 import android.os.Parcel;
-import android.support.test.filters.SmallTest;
 import android.telephony.CellIdentityGsm;
 import android.telephony.CellIdentityLte;
 import android.telephony.CellInfo;
@@ -28,12 +27,13 @@
 import android.telephony.CellSignalStrengthGsm;
 import android.telephony.CellSignalStrengthLte;
 
+import androidx.test.filters.SmallTest;
+
 import org.junit.Test;
 
 import java.util.ArrayList;
 
 /** Unit tests for {@link NetworkScanResult}. */
-
 public class NetworkScanResultTest {
 
     @Test
@@ -41,7 +41,7 @@
     public void testParcel() {
         ArrayList<CellInfo> infos = new ArrayList<CellInfo>();
 
-        CellIdentityGsm cig = new CellIdentityGsm(310, 310, 1, 2, 3, 4);
+        CellIdentityGsm cig = new CellIdentityGsm(1, 2, 40, 5, "001", "01", "test", "tst");
         CellSignalStrengthGsm cssg = new CellSignalStrengthGsm(5, 6, 7);
         CellInfoGsm gsm = new CellInfoGsm();
         gsm.setRegistered(true);
@@ -50,7 +50,8 @@
         gsm.setCellSignalStrength(cssg);
         infos.add(gsm);
 
-        CellIdentityLte cil = new CellIdentityLte(320, 320, 11, 12, 13, 14);
+        CellIdentityLte cil = new CellIdentityLte(
+                10, 5, 200, 2000, 10000, "001", "01", "test", "tst");
         CellSignalStrengthLte cssl = new CellSignalStrengthLte(15, 16, 17, 18, 19, 20);
         CellInfoLte lte = new CellInfoLte();
         lte.setRegistered(false);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index b9c8163..c3adcc6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -22,12 +22,13 @@
 import static junit.framework.Assert.assertTrue;
 
 import android.net.Uri;
-import android.support.test.filters.FlakyTest;
 import android.telephony.PhoneNumberUtils;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.SpannableStringBuilder;
 import android.text.style.TtsSpan;
 
+import androidx.test.filters.FlakyTest;
+
 import org.junit.Ignore;
 import org.junit.Test;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
index 56bf746..e3ffa59 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
@@ -103,14 +103,14 @@
 
         // verify nothing has been done while there are no inputs
         assertFalse("data allowed initially", mDataAllowed[0]);
-        assertFalse("data allowed initially", mDataAllowed[0]);
-        assertFalse("phone active initially", mPhoneSwitcher.shouldApplySpecifiedRequests(0));
+        assertFalse("data allowed initially", mDataAllowed[1]);
 
         NetworkRequest internetNetworkRequest = addInternetNetworkRequest(null, 50);
         waitABit();
 
         assertFalse("data allowed after request", mDataAllowed[0]);
-        assertFalse("phone active after request", mPhoneSwitcher.shouldApplySpecifiedRequests(0));
+        assertFalse("phone active after request", mPhoneSwitcher
+                .shouldApplyNetworkRequest(internetNetworkRequest, 0));
 
         // not registered yet - shouldn't inc
         verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong());
@@ -413,38 +413,34 @@
         setSlotIndexToSubId(1, 2);
         setDefaultDataSubId(1);
         waitABit();
-        // Phone 0 (sub 1) should preferredDataModem it has default data sub.
+        // Phone 0 (sub 1) should be preferred data phone as it has default data sub.
         verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
         verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
-        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(0));
-        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(1));
-        assertTrue(mPhoneSwitcher.shouldApplyUnspecifiedRequests(0));
-        assertFalse(mPhoneSwitcher.shouldApplyUnspecifiedRequests(1));
 
         clearInvocations(mMockRadioConfig);
         clearInvocations(mActivePhoneSwitchHandler);
 
         // Notify phoneSwitcher about default data sub and default network request.
         // It shouldn't change anything.
-        addInternetNetworkRequest(null, 50);
-        addMmsNetworkRequest(2);
+        NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
+        NetworkRequest mmsRequest = addMmsNetworkRequest(2);
         waitABit();
         verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
         verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong());
-        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(0));
-        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(1));
-        assertTrue(mPhoneSwitcher.shouldApplyUnspecifiedRequests(0));
-        assertFalse(mPhoneSwitcher.shouldApplyUnspecifiedRequests(1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));
 
         // Set sub 2 as preferred sub should make phone 1 preferredDataModem
         mPhoneSwitcher.setPreferredData(2);
         waitABit();
         verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
         verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
-        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(0));
-        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(1));
-        assertFalse(mPhoneSwitcher.shouldApplyUnspecifiedRequests(0));
-        assertTrue(mPhoneSwitcher.shouldApplyUnspecifiedRequests(1));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));
 
         clearInvocations(mMockRadioConfig);
         clearInvocations(mActivePhoneSwitchHandler);
@@ -454,10 +450,10 @@
         waitABit();
         verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
         verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
-        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(0));
-        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(1));
-        assertTrue(mPhoneSwitcher.shouldApplyUnspecifiedRequests(0));
-        assertFalse(mPhoneSwitcher.shouldApplyUnspecifiedRequests(1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));
 
         // SetDataAllowed should never be triggered.
         verify(mCommandsInterface0, never()).setDataAllowed(anyBoolean(), any());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
index f528ac4..b87b416 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
@@ -110,7 +110,6 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.WorkSource;
-import android.support.test.filters.FlakyTest;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CellIdentityCdma;
 import android.telephony.CellIdentityGsm;
@@ -133,6 +132,8 @@
 import android.telephony.data.ApnSetting;
 import android.telephony.data.DataProfile;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.internal.telephony.RIL.RilHandler;
 import com.android.internal.telephony.dataconnection.DcTracker;
 
@@ -177,10 +178,10 @@
     private static final int CI = 268435456;
     private static final int CID = 65535;
     private static final int CQI = 2147483647;
-    private static final int DBM = 74;
+    private static final int DBM = -74;
     private static final int EARFCN = 262140;
     private static final int BANDWIDTH = 5000;
-    private static final int ECIO = 124;
+    private static final int ECIO = -124;
     private static final String EMPTY_ALPHA_LONG = "";
     private static final String EMPTY_ALPHA_SHORT = "";
     private static final int LAC = 65535;
@@ -194,13 +195,16 @@
     private static final int PCI = 503;
     private static final int PSC = 500;
     private static final int RIL_TIMESTAMP_TYPE_OEM_RIL = 3;
-    private static final int RSSNR = 2147483647;
-    private static final int RSRP = 96;
-    private static final int RSRQ = 10;
-    private static final int RSCP = 94;
-    private static final int ECNO = 5;
+    private static final int RSSNR = CellInfo.UNAVAILABLE;
+    private static final int RSRP = -96;
+    private static final int RSRQ = -10;
+    private static final int RSCP = -94;
+    private static final int RSCP_ASU = 26;
+    private static final int ECNO = -21;
+    private static final int ECNO_ASU = 6;
     private static final int SIGNAL_NOISE_RATIO = 6;
-    private static final int SIGNAL_STRENGTH = 24;
+    private static final int RSSI = -65;
+    private static final int RSSI_ASU = 24;
     private static final int SYSTEM_ID = 65533;
     private static final int TAC = 65535;
     private static final int TIME_ADVANCE = 4;
@@ -1087,9 +1091,9 @@
         lte.cellIdentityLte.earfcn = EARFCN;
         lte.cellIdentityLte.mcc = MCC_STR;
         lte.cellIdentityLte.mnc = MNC_STR;
-        lte.signalStrengthLte.signalStrength = SIGNAL_STRENGTH;
-        lte.signalStrengthLte.rsrp = RSRP;
-        lte.signalStrengthLte.rsrq = RSRQ;
+        lte.signalStrengthLte.signalStrength = RSSI_ASU;
+        lte.signalStrengthLte.rsrp = -RSRP;
+        lte.signalStrengthLte.rsrq = -RSRQ;
         lte.signalStrengthLte.rssnr = RSSNR;
         lte.signalStrengthLte.cqi = CQI;
         lte.signalStrengthLte.timingAdvance = TIME_ADVANCE;
@@ -1113,7 +1117,7 @@
         CellIdentityLte cil = new CellIdentityLte(CI, PCI, TAC, EARFCN, Integer.MAX_VALUE, MCC_STR,
                 MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
         CellSignalStrengthLte css = new CellSignalStrengthLte(
-                SIGNAL_STRENGTH, -RSRP, -RSRQ, RSSNR, CQI, TIME_ADVANCE);
+                RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
         expected.setCellIdentity(cil);
         expected.setCellSignalStrength(css);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_UNKNOWN);
@@ -1131,7 +1135,7 @@
         cellinfo.cellIdentityGsm.arfcn = ARFCN;
         cellinfo.cellIdentityGsm.mcc = MCC_STR;
         cellinfo.cellIdentityGsm.mnc = MNC_STR;
-        cellinfo.signalStrengthGsm.signalStrength = SIGNAL_STRENGTH;
+        cellinfo.signalStrengthGsm.signalStrength = RSSI_ASU;
         cellinfo.signalStrengthGsm.bitErrorRate = BIT_ERROR_RATE;
         cellinfo.signalStrengthGsm.timingAdvance = TIME_ADVANCE;
         android.hardware.radio.V1_0.CellInfo record = new android.hardware.radio.V1_0.CellInfo();
@@ -1154,7 +1158,7 @@
         CellIdentityGsm ci = new CellIdentityGsm(
                 LAC, CID, ARFCN, BSIC, MCC_STR, MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
         CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
-                SIGNAL_STRENGTH, BIT_ERROR_RATE, TIME_ADVANCE);
+                RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_UNKNOWN);
@@ -1172,7 +1176,7 @@
         cellinfo.cellIdentityWcdma.uarfcn = UARFCN;
         cellinfo.cellIdentityWcdma.mcc = MCC_STR;
         cellinfo.cellIdentityWcdma.mnc = MNC_STR;
-        cellinfo.signalStrengthWcdma.signalStrength = SIGNAL_STRENGTH;
+        cellinfo.signalStrengthWcdma.signalStrength = RSSI_ASU;
         cellinfo.signalStrengthWcdma.bitErrorRate = BIT_ERROR_RATE;
         android.hardware.radio.V1_0.CellInfo record = new android.hardware.radio.V1_0.CellInfo();
         record.cellInfoType = TYPE_WCDMA;
@@ -1194,7 +1198,7 @@
         CellIdentityWcdma ci = new CellIdentityWcdma(
                 LAC, CID, PSC, UARFCN, MCC_STR, MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
         CellSignalStrengthWcdma cs = new CellSignalStrengthWcdma(
-                SIGNAL_STRENGTH, BIT_ERROR_RATE, Integer.MAX_VALUE, Integer.MAX_VALUE);
+                RSSI, BIT_ERROR_RATE, Integer.MAX_VALUE, Integer.MAX_VALUE);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_UNKNOWN);
@@ -1212,9 +1216,9 @@
         cellinfo.cellIdentityTdscdma.uarfcn = UARFCN;
         cellinfo.cellIdentityTdscdma.base.mcc = MCC_STR;
         cellinfo.cellIdentityTdscdma.base.mnc = MNC_STR;
-        cellinfo.signalStrengthTdscdma.signalStrength = SIGNAL_STRENGTH;
+        cellinfo.signalStrengthTdscdma.signalStrength = RSSI_ASU;
         cellinfo.signalStrengthTdscdma.bitErrorRate = BIT_ERROR_RATE;
-        cellinfo.signalStrengthTdscdma.rscp = RSCP;
+        cellinfo.signalStrengthTdscdma.rscp = RSCP_ASU;
         android.hardware.radio.V1_2.CellInfo record = new android.hardware.radio.V1_2.CellInfo();
         record.cellInfoType = TYPE_TD_SCDMA;
         record.registered = false;
@@ -1236,7 +1240,7 @@
         CellIdentityTdscdma ci = new CellIdentityTdscdma(
                 MCC_STR, MNC_STR, LAC, CID, PSC, UARFCN, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
         CellSignalStrengthTdscdma cs = new CellSignalStrengthTdscdma(
-                SIGNAL_STRENGTH, BIT_ERROR_RATE, RSCP);
+                RSSI, BIT_ERROR_RATE, RSCP);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         cellInfoTdscdma.setTimeStamp(TIMESTAMP); // override the timestamp
@@ -1252,10 +1256,10 @@
         cellinfo.cellIdentityCdma.baseStationId = BASESTATION_ID;
         cellinfo.cellIdentityCdma.longitude = LONGITUDE;
         cellinfo.cellIdentityCdma.latitude = LATITUDE;
-        cellinfo.signalStrengthCdma.dbm = DBM;
-        cellinfo.signalStrengthCdma.ecio = ECIO;
-        cellinfo.signalStrengthEvdo.dbm = DBM;
-        cellinfo.signalStrengthEvdo.ecio = ECIO;
+        cellinfo.signalStrengthCdma.dbm = -DBM;
+        cellinfo.signalStrengthCdma.ecio = -ECIO;
+        cellinfo.signalStrengthEvdo.dbm = -DBM;
+        cellinfo.signalStrengthEvdo.ecio = -ECIO;
         cellinfo.signalStrengthEvdo.signalNoiseRatio = SIGNAL_NOISE_RATIO;
         android.hardware.radio.V1_0.CellInfo record = new android.hardware.radio.V1_0.CellInfo();
         record.cellInfoType = TYPE_CDMA;
@@ -1298,7 +1302,7 @@
         CellIdentityLte cil = new CellIdentityLte(
                 CI, PCI, TAC, EARFCN, BANDWIDTH, MCC_STR, MNC_STR, ALPHA_LONG, ALPHA_SHORT);
         CellSignalStrengthLte css = new CellSignalStrengthLte(
-                SIGNAL_STRENGTH, -RSRP, -RSRQ, RSSNR, CQI, TIME_ADVANCE);
+                RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
         expected.setCellIdentity(cil);
         expected.setCellSignalStrength(css);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1319,7 +1323,7 @@
         CellIdentityLte cil = new CellIdentityLte(CI, PCI, TAC, EARFCN, BANDWIDTH, MCC_STR, MNC_STR,
                 EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
         CellSignalStrengthLte css = new CellSignalStrengthLte(
-                SIGNAL_STRENGTH, -RSRP, -RSRQ, RSSNR, CQI, TIME_ADVANCE);
+                RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
         expected.setCellIdentity(cil);
         expected.setCellSignalStrength(css);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1342,7 +1346,7 @@
         CellIdentityLte cil = new CellIdentityLte(
                 CI, PCI, TAC, EARFCN, BANDWIDTH, null, null, ALPHA_LONG, ALPHA_SHORT);
         CellSignalStrengthLte css = new CellSignalStrengthLte(
-                SIGNAL_STRENGTH, -RSRP, -RSRQ, RSSNR, CQI, TIME_ADVANCE);
+                RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
         expected.setCellIdentity(cil);
         expected.setCellSignalStrength(css);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1362,7 +1366,7 @@
         CellIdentityGsm ci = new CellIdentityGsm(
                 LAC, CID, ARFCN, BSIC, MCC_STR, MNC_STR, ALPHA_LONG, ALPHA_SHORT);
         CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
-                SIGNAL_STRENGTH, BIT_ERROR_RATE, TIME_ADVANCE);
+                RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1383,7 +1387,7 @@
         CellIdentityGsm ci = new CellIdentityGsm(
                 LAC, CID, ARFCN, BSIC, MCC_STR, MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
         CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
-                SIGNAL_STRENGTH, BIT_ERROR_RATE, TIME_ADVANCE);
+                RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1406,7 +1410,7 @@
         CellIdentityGsm ci = new CellIdentityGsm(
                 LAC, CID, ARFCN, BSIC, null, null, ALPHA_LONG, ALPHA_SHORT);
         CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
-                SIGNAL_STRENGTH, BIT_ERROR_RATE, TIME_ADVANCE);
+                RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
         expected.setCellIdentity(ci);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
         expected.setCellSignalStrength(cs);
@@ -1427,7 +1431,7 @@
         CellIdentityWcdma ci = new CellIdentityWcdma(
                 LAC, CID, PSC, UARFCN, MCC_STR, MNC_STR, ALPHA_LONG, ALPHA_SHORT);
         CellSignalStrengthWcdma cs =
-                new CellSignalStrengthWcdma(SIGNAL_STRENGTH, BIT_ERROR_RATE, RSCP, ECNO);
+                new CellSignalStrengthWcdma(RSSI, BIT_ERROR_RATE, RSCP, ECNO);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1448,7 +1452,7 @@
         CellIdentityWcdma ci = new CellIdentityWcdma(
                 LAC, CID, PSC, UARFCN, MCC_STR, MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
         CellSignalStrengthWcdma cs = new CellSignalStrengthWcdma(
-                SIGNAL_STRENGTH, BIT_ERROR_RATE, RSCP, ECNO);
+                RSSI, BIT_ERROR_RATE, RSCP, ECNO);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1471,7 +1475,7 @@
         CellIdentityWcdma ci = new CellIdentityWcdma(
                 LAC, CID, PSC, UARFCN, null, null, ALPHA_LONG, ALPHA_SHORT);
         CellSignalStrengthWcdma cs = new CellSignalStrengthWcdma(
-                SIGNAL_STRENGTH, BIT_ERROR_RATE, RSCP, ECNO);
+                RSSI, BIT_ERROR_RATE, RSCP, ECNO);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1557,9 +1561,9 @@
         lte.cellIdentityLte.base.mnc = mnc;
         lte.cellIdentityLte.operatorNames.alphaLong = alphaLong;
         lte.cellIdentityLte.operatorNames.alphaShort = alphaShort;
-        lte.signalStrengthLte.signalStrength = SIGNAL_STRENGTH;
-        lte.signalStrengthLte.rsrp = RSRP;
-        lte.signalStrengthLte.rsrq = RSRQ;
+        lte.signalStrengthLte.signalStrength = RSSI_ASU;
+        lte.signalStrengthLte.rsrp = -RSRP;
+        lte.signalStrengthLte.rsrq = -RSRQ;
         lte.signalStrengthLte.rssnr = RSSNR;
         lte.signalStrengthLte.cqi = CQI;
         lte.signalStrengthLte.timingAdvance = TIME_ADVANCE;
@@ -1588,7 +1592,7 @@
         cellinfo.cellIdentityGsm.base.mnc = mnc;
         cellinfo.cellIdentityGsm.operatorNames.alphaLong = alphaLong;
         cellinfo.cellIdentityGsm.operatorNames.alphaShort = alphaShort;
-        cellinfo.signalStrengthGsm.signalStrength = SIGNAL_STRENGTH;
+        cellinfo.signalStrengthGsm.signalStrength = RSSI_ASU;
         cellinfo.signalStrengthGsm.bitErrorRate = BIT_ERROR_RATE;
         cellinfo.signalStrengthGsm.timingAdvance = TIME_ADVANCE;
         android.hardware.radio.V1_2.CellInfo record = new android.hardware.radio.V1_2.CellInfo();
@@ -1617,10 +1621,10 @@
         cellinfo.cellIdentityWcdma.base.mnc = mnc;
         cellinfo.cellIdentityWcdma.operatorNames.alphaLong = alphaLong;
         cellinfo.cellIdentityWcdma.operatorNames.alphaShort = alphaShort;
-        cellinfo.signalStrengthWcdma.base.signalStrength = SIGNAL_STRENGTH;
+        cellinfo.signalStrengthWcdma.base.signalStrength = RSSI_ASU;
         cellinfo.signalStrengthWcdma.base.bitErrorRate = BIT_ERROR_RATE;
-        cellinfo.signalStrengthWcdma.rscp = RSCP;
-        cellinfo.signalStrengthWcdma.ecno = ECNO;
+        cellinfo.signalStrengthWcdma.rscp = RSCP_ASU;
+        cellinfo.signalStrengthWcdma.ecno = ECNO_ASU;
         android.hardware.radio.V1_2.CellInfo record = new android.hardware.radio.V1_2.CellInfo();
         record.cellInfoType = TYPE_WCDMA;
         record.registered = false;
@@ -1645,10 +1649,10 @@
         cellinfo.cellIdentityCdma.base.latitude = LATITUDE;
         cellinfo.cellIdentityCdma.operatorNames.alphaLong = alphaLong;
         cellinfo.cellIdentityCdma.operatorNames.alphaShort = alphaShort;
-        cellinfo.signalStrengthCdma.dbm = DBM;
-        cellinfo.signalStrengthCdma.ecio = ECIO;
-        cellinfo.signalStrengthEvdo.dbm = DBM;
-        cellinfo.signalStrengthEvdo.ecio = ECIO;
+        cellinfo.signalStrengthCdma.dbm = -DBM;
+        cellinfo.signalStrengthCdma.ecio = -ECIO;
+        cellinfo.signalStrengthEvdo.dbm = -DBM;
+        cellinfo.signalStrengthEvdo.ecio = -ECIO;
         cellinfo.signalStrengthEvdo.signalNoiseRatio = SIGNAL_NOISE_RATIO;
         android.hardware.radio.V1_2.CellInfo record = new android.hardware.radio.V1_2.CellInfo();
         record.cellInfoType = TYPE_CDMA;
@@ -1664,63 +1668,6 @@
         return RIL.convertHalCellInfoList_1_2(records);
     }
 
-    public android.telephony.SignalStrength getTdScdmaSignalStrength_1_0(int tdscdmaNegDbm) {
-        android.hardware.radio.V1_0.SignalStrength halSs =
-                new android.hardware.radio.V1_0.SignalStrength();
-        halSs.lte.signalStrength = SIGNAL_STRENGTH;
-        halSs.lte.rsrp = RSRP;
-        halSs.lte.rsrq = RSRQ;
-        halSs.lte.rssnr = RSSNR;
-        halSs.gw.signalStrength = SIGNAL_STRENGTH;
-        halSs.gw.bitErrorRate = BIT_ERROR_RATE;
-        halSs.cdma.dbm = DBM;
-        halSs.cdma.ecio = ECIO;
-        halSs.evdo.dbm = DBM;
-        halSs.evdo.ecio = ECIO;
-        halSs.evdo.signalNoiseRatio = SIGNAL_NOISE_RATIO;
-        halSs.tdScdma.rscp = tdscdmaNegDbm;
-        android.telephony.SignalStrength ss = RIL.convertHalSignalStrength(halSs);
-        // FIXME: We should not need to call validateInput here b/74115980.
-        ss.validateInput();
-        return ss;
-    }
-
-    public android.telephony.SignalStrength getTdScdmaSignalStrength_1_2(int tdscdmaAsu) {
-        android.hardware.radio.V1_2.SignalStrength halSs =
-                new android.hardware.radio.V1_2.SignalStrength();
-        halSs.lte.signalStrength = SIGNAL_STRENGTH;
-        halSs.lte.rsrp = RSRP;
-        halSs.lte.rsrq = RSRQ;
-        halSs.lte.rssnr = RSSNR;
-        halSs.gsm.signalStrength = SIGNAL_STRENGTH;
-        halSs.gsm.bitErrorRate = BIT_ERROR_RATE;
-        halSs.cdma.dbm = DBM;
-        halSs.cdma.ecio = ECIO;
-        halSs.evdo.dbm = DBM;
-        halSs.evdo.ecio = ECIO;
-        halSs.evdo.signalNoiseRatio = SIGNAL_NOISE_RATIO;
-        halSs.wcdma.base.signalStrength = 99;
-        halSs.wcdma.rscp = 255;
-        halSs.tdScdma.rscp = tdscdmaAsu;
-        android.telephony.SignalStrength ss = RIL.convertHalSignalStrength_1_2(halSs);
-        // FIXME: We should not need to call validateInput here b/74115980
-        // but unless we call it, we have to pass Integer.MAX_VALUE for wcdma RSCP,
-        // which is outside the allowable range for the HAL. This value is being
-        // coerced inside SignalStrength.validateInput().
-        ss.validateInput();
-        return ss;
-    }
-
-    @Test
-    public void testHalSignalStrengthTdScdma() throws Exception {
-        // Check that the minimum value is the same.
-        assertEquals(getTdScdmaSignalStrength_1_0(120), getTdScdmaSignalStrength_1_2(0));
-        // Check that the maximum common value is the same.
-        assertEquals(getTdScdmaSignalStrength_1_0(25), getTdScdmaSignalStrength_1_2(95));
-        // Check that an invalid value is the same.
-        assertEquals(getTdScdmaSignalStrength_1_0(-1), getTdScdmaSignalStrength_1_2(255));
-    }
-
     @Test
     @FlakyTest
     public void testSetupDataCall() throws Exception {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RadioAccessSpecifierTest.java b/tests/telephonytests/src/com/android/internal/telephony/RadioAccessSpecifierTest.java
index 511b5c2..e4cc90e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RadioAccessSpecifierTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RadioAccessSpecifierTest.java
@@ -19,15 +19,15 @@
 import static org.junit.Assert.assertEquals;
 
 import android.os.Parcel;
-import android.support.test.filters.SmallTest;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.AccessNetworkConstants.GeranBand;
 import android.telephony.RadioAccessSpecifier;
 
+import androidx.test.filters.SmallTest;
+
 import org.junit.Test;
 
 /** Unit tests for {@link RadioAccessSpecifier}. */
-
 public class RadioAccessSpecifierTest {
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 2fa4d3f..55ba99f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -52,14 +52,11 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Parcel;
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.support.test.filters.FlakyTest;
-import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellIdentity;
 import android.telephony.CellIdentityCdma;
@@ -67,6 +64,12 @@
 import android.telephony.CellIdentityLte;
 import android.telephony.CellInfo;
 import android.telephony.CellInfoGsm;
+import android.telephony.CellSignalStrength;
+import android.telephony.CellSignalStrengthCdma;
+import android.telephony.CellSignalStrengthGsm;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthTdscdma;
+import android.telephony.CellSignalStrengthWcdma;
 import android.telephony.INetworkService;
 import android.telephony.NetworkRegistrationState;
 import android.telephony.NetworkService;
@@ -82,6 +85,8 @@
 import android.util.Pair;
 import android.util.TimestampedValue;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.internal.R;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.test.SimulatedCommands;
@@ -374,31 +379,10 @@
     }
 
     private CellInfoGsm getCellInfoGsm() {
-        Parcel p = Parcel.obtain();
-        // CellInfo
-        p.writeInt(1);
-        p.writeInt(1);
-        p.writeInt(2);
-        p.writeLong(1453510289108L);
-        p.writeInt(0);
-        // CellIdentity
-        p.writeInt(1);
-        p.writeString("310");
-        p.writeString("260");
-        p.writeString("long");
-        p.writeString("short");
-        // CellIdentityGsm
-        p.writeInt(123);
-        p.writeInt(456);
-        p.writeInt(950);
-        p.writeInt(27);
-        // CellSignalStrength
-        p.writeInt(99);
-        p.writeInt(0);
-        p.writeInt(3);
-        p.setDataPosition(0);
-
-        return CellInfoGsm.CREATOR.createFromParcel(p);
+        CellInfoGsm tmp = new CellInfoGsm();
+        tmp.setCellIdentity(new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst"));
+        tmp.setCellSignalStrength(new CellSignalStrengthGsm(-85, 2, 3));
+        return tmp;
     }
 
     @Test
@@ -520,71 +504,56 @@
         verify(mPhone, times(1)).notifyServiceStateChanged(any(ServiceState.class));
     }
 
-    @Test
-    @MediumTest
-    public void testSignalStrength() {
-        SignalStrength ss = new SignalStrength(
-                30, // gsmSignalStrength
-                0,  // gsmBitErrorRate
-                -1, // cdmaDbm
-                -1, // cdmaEcio
-                -1, // evdoDbm
-                -1, // evdoEcio
-                -1, // evdoSnr
-                99, // lteSignalStrength
-                SignalStrength.INVALID,     // lteRsrp
-                SignalStrength.INVALID,     // lteRsrq
-                SignalStrength.INVALID,     // lteRssnr
-                SignalStrength.INVALID,     // lteCqi
-                SignalStrength.INVALID      // tdScdmaRscp
-        );
-
+    private void sendSignalStrength(SignalStrength ss) {
         mSimulatedCommands.setSignalStrength(ss);
         mSimulatedCommands.notifySignalStrength();
         waitForMs(300);
+    }
+
+    @Test
+    @MediumTest
+    public void testSignalStrength() {
+        // Send in GSM Signal Strength Info and expect isGsm == true
+        SignalStrength ss = new SignalStrength(
+                new CellSignalStrengthCdma(),
+                new CellSignalStrengthGsm(-53, 0, SignalStrength.INVALID),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte());
+
+        sendSignalStrength(ss);
         assertEquals(sst.getSignalStrength(), ss);
         assertEquals(sst.getSignalStrength().isGsm(), true);
 
-        // switch to CDMA
-        doReturn(false).when(mPhone).isPhoneTypeGsm();
-        doReturn(true).when(mPhone).isPhoneTypeCdmaLte();
-        sst.updatePhoneType();
-        sst.mSS.setRilDataRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
+        // Send in CDMA+LTE Signal Strength Info and expect isGsm == true
+        ss = new SignalStrength(
+                new CellSignalStrengthCdma(-90, -12,
+                        SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte(
+                        -110, -114, -5, 0, SignalStrength.INVALID, SignalStrength.INVALID));
 
-        mSimulatedCommands.notifySignalStrength();
-        waitForMs(300);
+        sendSignalStrength(ss);
         assertEquals(sst.getSignalStrength(), ss);
         assertEquals(sst.getSignalStrength().isGsm(), true);
 
-        // notify signal strength again, but this time data RAT is not LTE
-        sst.mSS.setRilVoiceRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT);
-        sst.mSS.setRilDataRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD);
-        mSimulatedCommands.notifySignalStrength();
-        waitForMs(300);
+        // Send in CDMA-only Signal Strength Info and expect isGsm == false
+        ss = new SignalStrength(
+                new CellSignalStrengthCdma(-90, -12,
+                        SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte());
+
+        sendSignalStrength(ss);
         assertEquals(sst.getSignalStrength(), ss);
         assertEquals(sst.getSignalStrength().isGsm(), false);
     }
 
-    @Test
-    public void testSetsNewSignalStrengthReportingCriteria() {
-        int[] wcdmaThresholds = {
-                -110, /* SIGNAL_STRENGTH_POOR */
-                -100, /* SIGNAL_STRENGTH_MODERATE */
-                -90, /* SIGNAL_STRENGTH_GOOD */
-                -80  /* SIGNAL_STRENGTH_GREAT */
-        };
-        mBundle.putIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY,
-                wcdmaThresholds);
-
-        int[] lteThresholds = {
-                -130, /* SIGNAL_STRENGTH_POOR */
-                -120, /* SIGNAL_STRENGTH_MODERATE */
-                -110, /* SIGNAL_STRENGTH_GOOD */
-                -100,  /* SIGNAL_STRENGTH_GREAT */
-        };
-        mBundle.putIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
-                lteThresholds);
-
+    private void sendCarrierConfigUpdate() {
         CarrierConfigManager mockConfigManager = Mockito.mock(CarrierConfigManager.class);
         when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
                 .thenReturn(mockConfigManager);
@@ -593,160 +562,89 @@
         Intent intent = new Intent().setAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         mContext.sendBroadcast(intent);
         waitForMs(300);
-
-        verify(mPhone).setSignalStrengthReportingCriteria(eq(wcdmaThresholds),
-                eq(AccessNetworkType.UTRAN));
-        verify(mPhone).setSignalStrengthReportingCriteria(eq(lteThresholds),
-                eq(AccessNetworkType.EUTRAN));
     }
 
     @Test
-    @MediumTest
-    public void testSignalLevelWithWcdmaRscpThresholds() {
+    public void testLteSignalStrengthReportingCriteria() {
+        SignalStrength ss = new SignalStrength(
+                new CellSignalStrengthCdma(),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte(
+                        -110, /* rssi */
+                        -114, /* rsrp */
+                        -5, /* rsrq */
+                        0, /* rssnr */
+                        SignalStrength.INVALID, /* cqi */
+                        SignalStrength.INVALID /* ta */));
+
+        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL,
+                true);
+
+        sendCarrierConfigUpdate();
+
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForMs(300);
+        // Default thresholds are POOR=-115 MODERATE=-105 GOOD=-95 GREAT=-85
+        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR, sst.getSignalStrength().getLevel());
+
+        int[] lteThresholds = {
+                -130, // SIGNAL_STRENGTH_POOR
+                -120, // SIGNAL_STRENGTH_MODERATE
+                -110, // SIGNAL_STRENGTH_GOOD
+                -100,  // SIGNAL_STRENGTH_GREAT
+        };
+        mBundle.putIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
+                lteThresholds);
+        sendCarrierConfigUpdate();
+
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForMs(300);
+        assertEquals(sst.getSignalStrength().getLevel(),
+                CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
+    }
+
+    @Test
+    public void testWcdmaSignalStrengthReportingCriteria() {
+        SignalStrength ss = new SignalStrength(
+                new CellSignalStrengthCdma(),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(-79, 0, -85, -5),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte());
+
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForMs(300);
+        assertEquals(sst.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+
+        int[] wcdmaThresholds = {
+                -110, // SIGNAL_STRENGTH_POOR
+                -100, // SIGNAL_STRENGTH_MODERATE
+                -90, // SIGNAL_STRENGTH_GOOD
+                -80  // SIGNAL_STRENGTH_GREAT
+        };
         mBundle.putIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY,
-                new int[] {
-                        -110, /* SIGNAL_STRENGTH_POOR */
-                        -100, /* SIGNAL_STRENGTH_MODERATE */
-                        -90, /* SIGNAL_STRENGTH_GOOD */
-                        -80  /* SIGNAL_STRENGTH_GREAT */
-                });
+                wcdmaThresholds);
         mBundle.putString(
                 CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING,
                 "rscp");
-
-        SignalStrength ss = new SignalStrength(
-                30, // gsmSignalStrength
-                0,  // gsmBitErrorRate
-                -1, // cdmaDbm
-                -1, // cdmaEcio
-                -1, // evdoDbm
-                -1, // evdoEcio
-                -1, // evdoSnr
-                99, // lteSignalStrength
-                SignalStrength.INVALID,     // lteRsrp
-                SignalStrength.INVALID,     // lteRsrq
-                SignalStrength.INVALID,     // lteRssnr
-                SignalStrength.INVALID,     // lteCqi
-                SignalStrength.INVALID,     // tdScdmaRscp
-                99,                         // wcdmaSignalStrength
-                45                         // wcdmaRscpAsu
-        );
+        sendCarrierConfigUpdate();
         mSimulatedCommands.setSignalStrength(ss);
         mSimulatedCommands.notifySignalStrength();
         waitForMs(300);
-        assertEquals(sst.getSignalStrength(), ss);
-        assertEquals(sst.getSignalStrength().getWcdmaLevel(), SignalStrength.SIGNAL_STRENGTH_GREAT);
-        assertEquals(sst.getSignalStrength().getWcdmaAsuLevel(), 45);
-        assertEquals(sst.getSignalStrength().getWcdmaDbm(), -75);
-
-        ss = new SignalStrength(
-                30, // gsmSignalStrength
-                0,  // gsmBitErrorRate
-                -1, // cdmaDbm
-                -1, // cdmaEcio
-                -1, // evdoDbm
-                -1, // evdoEcio
-                -1, // evdoSnr
-                99, // lteSignalStrength
-                SignalStrength.INVALID,     // lteRsrp
-                SignalStrength.INVALID,     // lteRsrq
-                SignalStrength.INVALID,     // lteRssnr
-                SignalStrength.INVALID,     // lteCqi
-                SignalStrength.INVALID,     // tdScdmaRscp
-                99,                         // wcdmaSignalStrength
-                35                          // wcdmaRscpAsu
-        );
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        waitForMs(300);
-        assertEquals(sst.getSignalStrength(), ss);
-        assertEquals(sst.getSignalStrength().getWcdmaLevel(), SignalStrength.SIGNAL_STRENGTH_GOOD);
-        assertEquals(sst.getSignalStrength().getWcdmaAsuLevel(), 35);
-        assertEquals(sst.getSignalStrength().getWcdmaDbm(), -85);
-
-        ss = new SignalStrength(
-                30, // gsmSignalStrength
-                0,  // gsmBitErrorRate
-                -1, // cdmaDbm
-                -1, // cdmaEcio
-                -1, // evdoDbm
-                -1, // evdoEcio
-                -1, // evdoSnr
-                99, // lteSignalStrength
-                SignalStrength.INVALID,     // lteRsrp
-                SignalStrength.INVALID,     // lteRsrq
-                SignalStrength.INVALID,     // lteRssnr
-                SignalStrength.INVALID,     // lteCqi
-                SignalStrength.INVALID,     // tdScdmaRscp
-                99,                         // wcdmaSignalStrength
-                25                          // wcdmaRscpAsu
-        );
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        waitForMs(300);
-        assertEquals(sst.getSignalStrength(), ss);
-        assertEquals(sst.getSignalStrength().getWcdmaLevel(),
-                SignalStrength.SIGNAL_STRENGTH_MODERATE);
-        assertEquals(sst.getSignalStrength().getWcdmaAsuLevel(), 25);
-        assertEquals(sst.getSignalStrength().getWcdmaDbm(), -95);
-
-        ss = new SignalStrength(
-                30, // gsmSignalStrength
-                0,  // gsmBitErrorRate
-                -1, // cdmaDbm
-                -1, // cdmaEcio
-                -1, // evdoDbm
-                -1, // evdoEcio
-                -1, // evdoSnr
-                99, // lteSignalStrength
-                SignalStrength.INVALID,     // lteRsrp
-                SignalStrength.INVALID,     // lteRsrq
-                SignalStrength.INVALID,     // lteRssnr
-                SignalStrength.INVALID,     // lteCqi
-                SignalStrength.INVALID,     // tdScdmaRscp
-                99,                         // wcdmaSignalStrength
-                15                          // wcdmaRscpAsu
-        );
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        waitForMs(300);
-        assertEquals(sst.getSignalStrength(), ss);
-        assertEquals(sst.getSignalStrength().getWcdmaLevel(), SignalStrength.SIGNAL_STRENGTH_POOR);
-        assertEquals(sst.getSignalStrength().getWcdmaAsuLevel(), 15);
-        assertEquals(sst.getSignalStrength().getWcdmaDbm(), -105);
-
-        ss = new SignalStrength(
-                30, // gsmSignalStrength
-                0,  // gsmBitErrorRate
-                -1, // cdmaDbm
-                -1, // cdmaEcio
-                -1, // evdoDbm
-                -1, // evdoEcio
-                -1, // evdoSnr
-                99, // lteSignalStrength
-                SignalStrength.INVALID,     // lteRsrp
-                SignalStrength.INVALID,     // lteRsrq
-                SignalStrength.INVALID,     // lteRssnr
-                SignalStrength.INVALID,     // lteCqi
-                SignalStrength.INVALID,     // tdScdmaRscp
-                99,                         // wcdmaSignalStrength
-                5                           // wcdmaRscpAsu
-        );
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        waitForMs(300);
-        assertEquals(sst.getSignalStrength(), ss);
-        assertEquals(sst.getSignalStrength().getWcdmaLevel(),
-                SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
-        assertEquals(sst.getSignalStrength().getWcdmaAsuLevel(), 5);
-        assertEquals(sst.getSignalStrength().getWcdmaDbm(), -115);
+        assertEquals(sst.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
     }
 
     @Test
     @MediumTest
     // TODO(nharold): we probably should remove support for this procedure (GET_LOC)
     public void testGsmCellLocation() {
-        CellIdentityGsm cellIdentityGsm = new CellIdentityGsm(0, 0, 2, 3);
+        CellIdentityGsm cellIdentityGsm = new CellIdentityGsm(
+                2, 3, 900, 5, "001", "01", "test", "tst");
         NetworkRegistrationState result = new NetworkRegistrationState(
                 0, 0, 0, 0, 0, false, null, cellIdentityGsm);
 
@@ -765,7 +663,7 @@
     @MediumTest
     // TODO(nharold): we probably should remove support for this procedure (GET_LOC)
     public void testCdmaCellLocation() {
-        CellIdentityCdma cellIdentityCdma = new CellIdentityCdma(1, 2, 3, 4, 5);
+        CellIdentityCdma cellIdentityCdma = new CellIdentityCdma(1, 2, 3, 4, 5, "test", "tst");
         NetworkRegistrationState result = new NetworkRegistrationState(
                 0, 0, 0, 0, 0, false, null, cellIdentityCdma);
 
@@ -1690,7 +1588,8 @@
     // Expect no rat update when move from E to G.
     @Test
     public void testRatRatchet() throws Exception {
-        CellIdentityGsm cellIdentity = new CellIdentityGsm(-1, -1, -1, -1, -1, -1);
+        CellIdentityGsm cellIdentity =
+                new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst");
         // start on GPRS
         changeRegState(1, cellIdentity, 16, 1);
         assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
@@ -1707,14 +1606,15 @@
     // Bypass rat rachet when cell id changed. Expect rat update from E to G
     @Test
     public void testRatRatchetWithCellChange() throws Exception {
-        CellIdentityGsm cellIdentity = new CellIdentityGsm(-1, -1, -1, -1, -1, -1);
+        CellIdentityGsm cellIdentity =
+                new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst");
         // update data reg state to be in service
         changeRegState(1, cellIdentity, 16, 2);
         assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
         assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GSM, sst.mSS.getRilVoiceRadioTechnology());
         assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilDataRadioTechnology());
-        // RAT: EDGE -> GPRS cell ID: -1 -> 5
-        cellIdentity = new CellIdentityGsm(-1, -1, -1, 5, -1, -1);
+        // RAT: EDGE -> GPRS cell ID: 1 -> 2
+        cellIdentity = new CellIdentityGsm(0, 2, 900, 5, "001", "01", "test", "tst");
         changeRegState(1, cellIdentity, 16, 1);
         assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilDataRadioTechnology());
 
@@ -1728,7 +1628,8 @@
     @Test
     public void testRatRatchetWithCellChangeBeforeRatChange() throws Exception {
         // cell ID update
-        CellIdentityGsm cellIdentity = new CellIdentityGsm(-1, -1, -1, 5, -1, -1);
+        CellIdentityGsm cellIdentity =
+                new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst");
         changeRegState(1, cellIdentity, 16, 2);
         assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
         assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilDataRadioTechnology());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java
index 0b33c80..c090221 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java
@@ -20,9 +20,16 @@
 import static org.junit.Assert.assertTrue;
 
 import android.os.Parcel;
-import android.support.test.filters.SmallTest;
+import android.telephony.CellInfo;
+import android.telephony.CellSignalStrengthCdma;
+import android.telephony.CellSignalStrengthGsm;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthTdscdma;
+import android.telephony.CellSignalStrengthWcdma;
 import android.telephony.SignalStrength;
 
+import androidx.test.filters.SmallTest;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -35,12 +42,15 @@
     @Test
     public void testDefaults() throws Exception {
         SignalStrength s = new SignalStrength();
-        assertEquals(SignalStrength.INVALID, s.getCdmaDbm());
-        assertEquals(-1, s.getCdmaEcio());
-        assertEquals(SignalStrength.INVALID, s.getEvdoDbm());
-        assertEquals(-1, s.getEvdoEcio());
-        assertEquals(-1, s.getEvdoSnr());
-        assertEquals(-1, s.getGsmBitErrorRate());
+        assertEquals(CellInfo.UNAVAILABLE, s.getCdmaDbm());
+        assertEquals(CellInfo.UNAVAILABLE, s.getCdmaEcio());
+        assertEquals(CellInfo.UNAVAILABLE, s.getEvdoDbm());
+        assertEquals(CellInfo.UNAVAILABLE, s.getEvdoEcio());
+        assertEquals(CellInfo.UNAVAILABLE, s.getEvdoSnr());
+        assertEquals(CellInfo.UNAVAILABLE, s.getGsmBitErrorRate());
+        // getGsmSignalStrength is an oddball because internally it actually returns an AsuLevel
+        // rather than a dBm value. For backwards compatibility reasons, this is left as the
+        // RSSI ASU value [0-31], 99.
         assertEquals(99, s.getGsmSignalStrength());
         assertEquals(true, s.isGsm());
     }
@@ -50,25 +60,16 @@
         assertParcelingIsLossless(new SignalStrength());
 
         SignalStrength s = new SignalStrength(
-                20,      // gsmSignalStrength
-                5,       // gsmBitErrorRate
-                -95,     // cdmaDbm
-                10,      // cdmaEcio
-                -98,     // evdoDbm
-                -5,      // evdoEcio
-                -2,      // evdoSnr
-                45,      // lteSignalStrength
-                -105,    // lteRsrp
-                -110,    // lteRsrq
-                -115,    // lteRssnr
-                13,      // lteCqi
-                -90,     // tdscdmaRscp
-                45,      // wcdmaSignalStrength
-                20,      // wcdmaRscpAsu
-                2,       // lteRsrpBoost
-                false,   // gsmFlag
-                true,    // lteLevelBaseOnRsrp
-                "rscp"); // wcdmaDefaultMeasurement
+                // Accepts HAL inputs (neg of actual) directly and -1 as invalid
+                new CellSignalStrengthCdma(40, 5, 45, 3, 5),
+                // Accepts ASU values or UNAVAILABLE
+                new CellSignalStrengthGsm(2, 4, 68),
+                // Accepts ASU or UNAVAILABLE
+                new CellSignalStrengthWcdma(12, 4, 22, 18),
+                // Accepts ASU values or UNAVAILABLE
+                new CellSignalStrengthTdscdma(13, 2, 34),
+                // Accepts actual values (HAL values must be converted, except RSSI) or UNAVAILABLE
+                new CellSignalStrengthLte(-85, -91, -6, -10, 12, 1));
         assertParcelingIsLossless(s);
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/Sms7BitEncodingTranslatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/Sms7BitEncodingTranslatorTest.java
index cf11d1b..0ada744 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/Sms7BitEncodingTranslatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/Sms7BitEncodingTranslatorTest.java
@@ -21,9 +21,10 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 
-import android.support.test.filters.FlakyTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.filters.FlakyTest;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java
index 76fce94..2d7fc4f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java
@@ -25,7 +25,8 @@
 import static org.junit.Assert.assertEquals;
 
 import android.os.Looper;
-import android.support.test.filters.FlakyTest;
+
+import androidx.test.filters.FlakyTest;
 
 import org.junit.Ignore;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index 535628d..a9476d9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doReturn;
@@ -417,14 +418,17 @@
         mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
 
         int[] subIdList = new int[] {1, 2};
-        // It should fail since it has no permission.
-        String groupId = mSubscriptionControllerUT.setSubscriptionGroup(
-                subIdList, mContext.getOpPackageName());
-        assertEquals(null, groupId);
+        try {
+            mSubscriptionControllerUT.setSubscriptionGroup(
+                    subIdList, mContext.getOpPackageName());
+            fail("setSubscriptionGroup should fail with no permission.");
+        } catch (SecurityException e) {
+            // Expected result.
+        }
 
         // With modify permission it should succeed.
         mContextFixture.addCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
-        groupId = mSubscriptionControllerUT.setSubscriptionGroup(
+        String groupId = mSubscriptionControllerUT.setSubscriptionGroup(
                 subIdList, mContext.getOpPackageName());
         assertNotEquals(null, groupId);
 
@@ -433,13 +437,6 @@
                 subIdList, mContext.getOpPackageName());
         assertNotEquals(null, newGroupId);
         assertNotEquals(groupId, newGroupId);
-
-        // SubId 6 doesn't exist. Should fail.
-        subIdList = new int[] {1, 6};
-        mContextFixture.addCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
-        groupId = mSubscriptionControllerUT.setSubscriptionGroup(
-                subIdList, mContext.getOpPackageName());
-        assertEquals(null, groupId);
     }
 
     @Test
@@ -447,7 +444,7 @@
     public void testSetSubscriptionGroupWithCarrierPrivilegePermission() throws Exception {
         testInsertSim();
         // Adding a second profile and mark as embedded.
-        mSubscriptionControllerUT.addSubInfoRecord("test2", 0);
+        mSubscriptionControllerUT.addSubInfoRecord("test2", 1);
         ContentValues values = new ContentValues();
         values.put(SubscriptionManager.IS_EMBEDDED, 1);
         mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
@@ -459,26 +456,38 @@
 
         int[] subIdList = new int[] {1, 2};
         // It should fail since it has no permission.
-        String groupId = mSubscriptionControllerUT.setSubscriptionGroup(
-                subIdList, mContext.getOpPackageName());
-        assertEquals(null, groupId);
+        try {
+            mSubscriptionControllerUT.setSubscriptionGroup(
+                    subIdList, mContext.getOpPackageName());
+            fail("setSubscriptionGroup should fail with no permission.");
+        } catch (SecurityException e) {
+            // Expected result.
+        }
 
-        // With modify permission it should succeed.
         doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
-        groupId = mSubscriptionControllerUT.setSubscriptionGroup(
-                subIdList, mContext.getOpPackageName());
-        assertEquals(null, groupId);
+        try {
+            mSubscriptionControllerUT.setSubscriptionGroup(
+                    subIdList, mContext.getOpPackageName());
+            fail("setSubscriptionGroup should fail with no permission on sub 2.");
+        } catch (SecurityException e) {
+            // Expected result.
+        }
 
         doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(2);
-        groupId = mSubscriptionControllerUT.setSubscriptionGroup(
+        String groupId = mSubscriptionControllerUT.setSubscriptionGroup(
                 subIdList, mContext.getOpPackageName());
         assertNotEquals(null, groupId);
 
         List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT
                 .getActiveSubscriptionInfoList(mContext.getOpPackageName());
 
-        // Revoke carrier privilege of sub 2 but make it manageable by caller.
-        doReturn(false).when(mTelephonyManager).hasCarrierPrivileges(2);
+        // Put sub3 into slot 1 to make sub2 inactive.
+        mContextFixture.addCallingOrSelfPermission(
+                android.Manifest.permission.MODIFY_PHONE_STATE);
+        mSubscriptionControllerUT.addSubInfoRecord("test3", 1);
+        mContextFixture.removeCallingOrSelfPermission(
+                android.Manifest.permission.MODIFY_PHONE_STATE);
+        // As sub2 is inactive, it will checks carrier privilege against access rules in the db.
         doReturn(true).when(mSubscriptionManager).canManageSubscription(
                 eq(subInfoList.get(1)), anyString());
 
@@ -536,6 +545,42 @@
         assertEquals(true, opptSubList.get(0).isGroupDisabled());
     }
 
+    @Test
+    @SmallTest
+    public void testSetSubscriptionGroup() throws Exception {
+        testInsertSim();
+        // Adding a second profile and mark as embedded.
+        mSubscriptionControllerUT.addSubInfoRecord("test2", 0);
+        ContentValues values = new ContentValues();
+        values.put(SubscriptionManager.IS_EMBEDDED, 1);
+        mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
+                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
+        mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
+
+        int[] subIdList = new int[] {1, 2};
+        String groupUuid = mSubscriptionControllerUT.setSubscriptionGroup(
+                subIdList, mContext.getOpPackageName());
+        assertNotEquals(null, groupUuid);
+
+        // Sub 1 and sub 2 should be in same group.
+        List<SubscriptionInfo> infoList = mSubscriptionControllerUT
+                .getSubscriptionsInGroup(1, mContext.getOpPackageName());
+        assertNotEquals(null, infoList);
+        assertEquals(2, infoList.size());
+        assertEquals(1, infoList.get(0).getSubscriptionId());
+        assertEquals(2, infoList.get(1).getSubscriptionId());
+
+        // Remove group of sub 1.
+        subIdList = new int[] {1};
+        boolean result = mSubscriptionControllerUT.removeSubscriptionsFromGroup(
+                subIdList, mContext.getOpPackageName());
+        assertEquals(true, result);
+        infoList = mSubscriptionControllerUT
+                .getSubscriptionsInGroup(2, mContext.getOpPackageName());
+        assertEquals(1, infoList.size());
+        assertEquals(2, infoList.get(0).getSubscriptionId());
+    }
+
     private void registerMockTelephonyRegistry() {
         mServiceManagerMockedServices.put("telephony.registry", mTelephonyRegisteryMock);
         doReturn(mTelephonyRegisteryMock).when(mTelephonyRegisteryMock)
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 2517d22..74f288d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -60,6 +60,7 @@
 import com.android.ims.ImsManager;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.cdma.EriManager;
+import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 import com.android.internal.telephony.dataconnection.DcTracker;
 import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
@@ -209,6 +210,8 @@
     protected LocaleTracker mLocaleTracker;
     @Mock
     protected RestrictedState mRestrictedState;
+    @Mock
+    protected DataEnabledSettings mDataEnabledSettings;
 
     protected ImsCallProfile mImsCallProfile;
     protected TelephonyManager mTelephonyManager;
@@ -384,6 +387,8 @@
         doReturn(mLocaleTracker).when(mTelephonyComponentFactory)
                 .makeLocaleTracker(nullable(Phone.class), nullable(NitzStateMachine.class),
                         nullable(Looper.class));
+        doReturn(mDataEnabledSettings).when(mTelephonyComponentFactory)
+                .makeDataEnabledSettings(nullable(Phone.class));
 
         //mPhone
         doReturn(mContext).when(mPhone).getContext();
@@ -393,7 +398,6 @@
         doReturn(mServiceState).when(mPhone).getServiceState();
         doReturn(mServiceState).when(mImsPhone).getServiceState();
         doReturn(mPhone).when(mImsPhone).getDefaultPhone();
-        doReturn(true).when(mDcTracker).isDataEnabled();
         doReturn(true).when(mPhone).isPhoneTypeGsm();
         doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mPhone).getPhoneType();
         doReturn(mCT).when(mPhone).getCallTracker();
@@ -404,6 +408,7 @@
         doReturn(mAppSmsManager).when(mPhone).getAppSmsManager();
         doReturn(mIccSmsInterfaceManager).when(mPhone).getIccSmsInterfaceManager();
         doReturn(mTransportManager).when(mPhone).getTransportManager();
+        doReturn(mDataEnabledSettings).when(mPhone).getDataEnabledSettings();
         doReturn(mDcTracker).when(mPhone).getDcTracker(anyInt());
         mIccSmsInterfaceManager.mDispatchersController = mSmsDispatchersController;
         mPhone.mEriManager = mEriManager;
@@ -480,6 +485,8 @@
         doReturn(new int[]{TransportType.WWAN, TransportType.WLAN})
                 .when(mTransportManager).getAvailableTransports();
         doReturn(TransportType.WWAN).when(mTransportManager).getCurrentTransport(anyInt());
+        doReturn(true).when(mDataEnabledSettings).isDataEnabled();
+        doReturn(true).when(mDataEnabledSettings).isInternalDataEnabled();
 
         //SIM
         doReturn(1).when(mTelephonyManager).getSimCount();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
index 08e54ac..604772b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
@@ -40,10 +40,11 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Telephony;
-import android.support.test.filters.FlakyTest;
 import android.test.mock.MockContentResolver;
 import android.test.suitebuilder.annotation.MediumTest;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.internal.telephony.FakeSmsContentProvider;
 import com.android.internal.telephony.InboundSmsHandler;
 import com.android.internal.telephony.InboundSmsTracker;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
index 55036ad..cae6566 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
@@ -17,7 +17,6 @@
 package com.android.internal.telephony.cdma;
 
 import android.hardware.radio.V1_0.CdmaSmsMessage;
-import android.support.test.filters.FlakyTest;
 import android.telephony.Rlog;
 import android.telephony.SmsCbCmasInfo;
 import android.telephony.SmsCbMessage;
@@ -25,6 +24,8 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.internal.telephony.GsmAlphabet;
 import com.android.internal.telephony.cdma.sms.BearerData;
 import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
index 32cad59..2d2d7ba 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
@@ -111,7 +111,7 @@
         mApnContext.setDependencyMet(true);
         assertFalse(mApnContext.isConnectable());
 
-        mApnContext.setState(DctConstants.State.SCANNING);
+        mApnContext.setState(DctConstants.State.RETRYING);
         assertTrue(mApnContext.isConnectable());
         assertTrue(mApnContext.isConnectedOrConnecting());
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
index dab06d8..2bd4d2d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
@@ -201,7 +201,6 @@
                 ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
         doReturn(mApn1).when(mApnContext).getApnSetting();
         doReturn(PhoneConstants.APN_TYPE_DEFAULT).when(mApnContext).getApnType();
-        doReturn(true).when(mDcTracker).isDataEnabled();
 
         mDcFailBringUp.saveParameters(0, 0, -2);
         doReturn(mDcFailBringUp).when(mDcTesterFailBringUpAll).getDcFailBringUp();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcFailCauseTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataFailCauseTest.java
similarity index 85%
rename from tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcFailCauseTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataFailCauseTest.java
index e0deb63..e881cc9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcFailCauseTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataFailCauseTest.java
@@ -37,7 +37,7 @@
 import java.util.ArrayList;
 import java.util.Random;
 
-public class DcFailCauseTest extends TelephonyTest {
+public class DataFailCauseTest extends TelephonyTest {
 
     private PersistableBundle mPersistableBundle;
 
@@ -163,10 +163,11 @@
     public void testPermanentFailDefault() throws Exception {
         for (DcFailCauseData data : mFailCauseDataList) {
             assertEquals("cause = " + data.mCause, data.mPermanentFailure,
-                    DataFailCause.fromInt(
-                    data.mCause).isPermanentFailure(mContext, mPhone.getSubId()));
+                    DataFailCause.isPermanentFailure(mContext, DataFailCause.getFailCause(
+                    data.mCause), mPhone.getSubId()));
         }
-        assertFalse(DataFailCause.fromInt(123456).isPermanentFailure(mContext, mPhone.getSubId()));
+        assertFalse(DataFailCause.isPermanentFailure(mContext,
+                DataFailCause.getFailCause(123456), mPhone.getSubId()));
     }
 
     @Test
@@ -182,17 +183,17 @@
         // Run it twice to make sure the cached carrier config is working as expected.
         for (int i = 0; i < 2; i++) {
             for (DcFailCauseData data : mFailCauseDataList) {
-                if (DataFailCause.fromInt(data.mCause).equals(
+                if (DataFailCause.getFailCause(data.mCause) == (
                         DataFailCause.SERVICE_OPTION_NOT_SUBSCRIBED) ||
-                        DataFailCause.fromInt(data.mCause).equals(
+                        DataFailCause.getFailCause(data.mCause) == (
                                 DataFailCause.TETHERED_CALL_ACTIVE)) {
                     assertTrue("cause = " + data.mCause,
-                            DataFailCause.fromInt(data.mCause).
-                            isPermanentFailure(mContext, mPhone.getSubId()));
+                            DataFailCause.isPermanentFailure(mContext,
+                                    DataFailCause.getFailCause(data.mCause), mPhone.getSubId()));
                 } else {
                     assertFalse("cause = " + data.mCause,
-                            DataFailCause.fromInt(data.mCause).
-                            isPermanentFailure(mContext, mPhone.getSubId()));
+                            DataFailCause.isPermanentFailure(mContext,
+                                    DataFailCause.getFailCause(data.mCause), mPhone.getSubId()));
                 }
             }
         }
@@ -203,43 +204,43 @@
     public void testEventLoggable() throws Exception {
         for (DcFailCauseData data : mFailCauseDataList) {
             assertEquals("cause = " + data.mCause, data.mEventLoggable,
-                    DataFailCause.fromInt(data.mCause).isEventLoggable());
+                    DataFailCause.isEventLoggable(DataFailCause.getFailCause(data.mCause)));
         }
-        assertFalse(DataFailCause.fromInt(123456).isEventLoggable());
+        assertFalse(DataFailCause.isEventLoggable(DataFailCause.getFailCause(123456)));
     }
 
     @Test
     @SmallTest
     public void testGetErrorCode() throws Exception {
         for (DcFailCauseData data : mFailCauseDataList) {
-            assertEquals(data.mCause, DataFailCause.fromInt(data.mCause).getErrorCode());
+            assertEquals(data.mCause, DataFailCause.getFailCause(data.mCause));
         }
-        assertEquals(DataFailCause.UNKNOWN.getErrorCode(),
-                DataFailCause.fromInt(123456).getErrorCode());
+        assertEquals(DataFailCause.UNKNOWN,
+                DataFailCause.getFailCause(123456));
     }
 
     @Test
     public void testIsRadioRestartFailureRegularDeactivation() {
-        assertFalse(DataFailCause.fromInt(DataFailCause.REGULAR_DEACTIVATION.getErrorCode())
-                .isRadioRestartFailure(mContext, mPhone.getSubId()));
+        assertFalse(DataFailCause.isRadioRestartFailure(mContext,
+                DataFailCause.getFailCause(DataFailCause.REGULAR_DEACTIVATION), mPhone.getSubId()));
         mPersistableBundle.putBoolean(CarrierConfigManager
                 .KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL, true);
-        assertTrue(DataFailCause.fromInt(DataFailCause.REGULAR_DEACTIVATION.getErrorCode())
-                .isRadioRestartFailure(mContext, mPhone.getSubId()));
+        assertTrue(DataFailCause.isRadioRestartFailure(mContext,
+                DataFailCause.getFailCause(DataFailCause.REGULAR_DEACTIVATION), mPhone.getSubId()));
     }
 
     @Test
     public void testIsRadioRestartFailureNotRegularDeactivation() {
-        DataFailCause randomCause = DataFailCause.fromInt(mFailCauseDataList
+        int randomCause = DataFailCause.getFailCause(mFailCauseDataList
                 .get(new Random().nextInt(mFailCauseDataList.size())).mCause);
         while (randomCause == DataFailCause.REGULAR_DEACTIVATION) {
-            randomCause = DataFailCause.fromInt(mFailCauseDataList
+            randomCause = DataFailCause.getFailCause(mFailCauseDataList
                     .get(new Random().nextInt(mFailCauseDataList.size())).mCause);
         }
-        assertFalse(randomCause.isRadioRestartFailure(mContext, mPhone.getSubId()));
-        int [] matchingErrorCodes = {randomCause.getErrorCode()};
+        assertFalse(DataFailCause.isRadioRestartFailure(mContext, randomCause, mPhone.getSubId()));
+        int [] matchingErrorCodes = {randomCause};
         mPersistableBundle.putIntArray(CarrierConfigManager
                 .KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY, matchingErrorCodes);
-        assertTrue(randomCause.isRadioRestartFailure(mContext, mPhone.getSubId()));
+        assertTrue(DataFailCause.isRadioRestartFailure(mContext, randomCause, mPhone.getSubId()));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
index 12c87e0..3a567e8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -29,10 +29,10 @@
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -59,7 +59,6 @@
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.provider.Telephony;
-import android.support.test.filters.FlakyTest;
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
@@ -77,10 +76,11 @@
 import android.util.LocalLog;
 import android.util.Pair;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.internal.R;
 import com.android.internal.telephony.DctConstants;
 import com.android.internal.telephony.ISub;
-import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.server.pm.PackageManagerService;
@@ -210,7 +210,7 @@
                     || uri.toString().startsWith(Uri.withAppendedPath(
                             Telephony.Carriers.CONTENT_URI, "filtered").toString())
                     || uri.toString().startsWith(Uri.withAppendedPath(
-                            Telephony.Carriers.SIM_APN_LIST, "filtered").toString())) {
+                            Telephony.Carriers.SIM_APN_URI, "filtered").toString())) {
                 if (projection == null) {
 
                     logd("Query '" + FAKE_PLMN + "' APN settings");
@@ -536,7 +536,7 @@
     }
 
     private void verifyDataConnected(final String apnSetting) {
-        verify(mPhone, times(1)).notifyDataConnection(eq(Phone.REASON_CONNECTED),
+        verify(mPhone, atLeastOnce()).notifyDataConnection(
                 eq(PhoneConstants.APN_TYPE_DEFAULT));
 
         verify(mAlarmManager, times(1)).set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
@@ -573,9 +573,6 @@
     @Test
     @MediumTest
     public void testDataSetup() throws Exception {
-
-        mDct.setUserDataEnabled(true);
-
         mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
 
         DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
@@ -586,31 +583,10 @@
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
         waitForMs(200);
 
-        ArgumentCaptor<String> apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
-                eq(Phone.REASON_SIM_LOADED), apnTypeArgumentCaptor.capture(),
-                eq(PhoneConstants.DataState.DISCONNECTED));
-
-        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
-
         logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
         waitForMs(200);
 
-        apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
-                eq(Phone.REASON_DATA_ATTACHED), apnTypeArgumentCaptor.capture(),
-                eq(PhoneConstants.DataState.DISCONNECTED));
-
-        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
-
-        apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
-                eq(Phone.REASON_DATA_ENABLED), apnTypeArgumentCaptor.capture(),
-                eq(PhoneConstants.DataState.DISCONNECTED));
-
-        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
-
         logd("Sending EVENT_ENABLE_NEW_APN");
         // APN id 0 is APN_TYPE_DEFAULT
         mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
@@ -636,16 +612,12 @@
     @Test
     @MediumTest
     public void testDataRetry() throws Exception {
-
-        mDct.setUserDataEnabled(true);
+        AsyncResult ar = new AsyncResult(null,
+                new Pair<>(true, DataEnabledSettings.REASON_USER_DATA_ENABLED), null);
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_CHANGED, ar));
+        waitForMs(200);
 
         // LOST_CONNECTION(0x10004) is a non-permanent failure, so we'll retry data setup later.
-        /*DataCallResponse dcResponse = new DataCallResponse(0x10004, -1, 1, 2, "IP", FAKE_IFNAME,
-                Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)),
-                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
-                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
-                Arrays.asList(FAKE_PCSCF_ADDRESS),
-                1440);*/
         SetupDataCallResult result = createSetupDataCallResult();
         result.status = 0x10004;
 
@@ -660,37 +632,15 @@
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
         waitForMs(200);
 
-        ArgumentCaptor<String> apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
-                eq(Phone.REASON_SIM_LOADED), apnTypeArgumentCaptor.capture(),
-                eq(PhoneConstants.DataState.DISCONNECTED));
-
-        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
-
         logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
         waitForMs(200);
 
-        apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
-                eq(Phone.REASON_DATA_ATTACHED), apnTypeArgumentCaptor.capture(),
-                eq(PhoneConstants.DataState.DISCONNECTED));
-
-        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
-
-        apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
-                eq(Phone.REASON_DATA_ENABLED), apnTypeArgumentCaptor.capture(),
-                eq(PhoneConstants.DataState.DISCONNECTED));
-
-        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
-
         logd("Sending EVENT_ENABLE_NEW_APN");
         // APN id 0 is APN_TYPE_DEFAULT
         mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
         waitForMs(200);
 
-
         dataConnectionReasons = new DataConnectionReasons();
         allowed = isDataAllowed(dataConnectionReasons);
         assertTrue(dataConnectionReasons.toString(), allowed);
@@ -704,10 +654,6 @@
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 5, 1, LTE_BEARER_BITMASK);
 
-        // Make sure we never notify connected because the data call setup is supposed to fail.
-        verify(mPhone, never()).notifyDataConnection(eq(Phone.REASON_CONNECTED),
-                eq(PhoneConstants.APN_TYPE_DEFAULT));
-
         // Verify the retry manger schedule another data call setup.
         verify(mAlarmManager, times(1)).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
                 anyLong(), any(PendingIntent.class));
@@ -744,7 +690,6 @@
     public void testUserDisableData() throws Exception {
         //step 1: setup two DataCalls one for Metered: default, another one for Non-metered: IMS
         //set Default and MMS to be metered in the CarrierConfigManager
-        boolean dataEnabled = mDct.isUserDataEnabled();
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
         mDct.setEnabled(ApnSetting.TYPE_IMS, true);
@@ -758,10 +703,6 @@
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
         waitForMs(200);
 
-        logd("Sending DATA_ENABLED_CMD");
-        mDct.setUserDataEnabled(true);
-
-        waitForMs(200);
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
                 eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
@@ -771,7 +712,10 @@
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 5, 1, LTE_BEARER_BITMASK);
 
         logd("Sending DATA_DISABLED_CMD");
-        mDct.setUserDataEnabled(false);
+        doReturn(false).when(mDataEnabledSettings).isDataEnabled();
+        AsyncResult ar = new AsyncResult(null,
+                new Pair<>(false, DataEnabledSettings.REASON_USER_DATA_ENABLED), null);
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_CHANGED, ar));
         waitForMs(200);
 
         // expected tear down all metered DataConnections
@@ -781,10 +725,6 @@
         assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
         assertEquals(DctConstants.State.IDLE, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT));
         assertEquals(DctConstants.State.CONNECTED, mDct.getState(PhoneConstants.APN_TYPE_IMS));
-
-        // reset the setting at the end of this test
-        mDct.setUserDataEnabled(dataEnabled);
-        waitForMs(200);
     }
 
     @Test
@@ -797,7 +737,6 @@
 
         //set Default and MMS to be metered in the CarrierConfigManager
         boolean roamingEnabled = mDct.getDataRoamingEnabled();
-        boolean dataEnabled = mDct.isUserDataEnabled();
 
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
@@ -813,10 +752,6 @@
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
         waitForMs(200);
 
-        logd("Sending DATA_ENABLED_CMD");
-        mDct.setUserDataEnabled(true);
-
-        waitForMs(300);
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
                 eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
@@ -842,7 +777,6 @@
 
         // reset roaming settings / data enabled settings at end of this test
         mDct.setDataRoamingEnabledByUser(roamingEnabled);
-        mDct.setUserDataEnabled(dataEnabled);
         waitForMs(200);
     }
 
@@ -854,7 +788,6 @@
         //step 3: only non-metered data call is established
 
         boolean roamingEnabled = mDct.getDataRoamingEnabled();
-        boolean dataEnabled = mDct.isUserDataEnabled();
         doReturn(true).when(mServiceState).getDataRoaming();
 
         //set Default and MMS to be metered in the CarrierConfigManager
@@ -863,9 +796,6 @@
         mDct.setEnabled(ApnSetting.TYPE_IMS, true);
         mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
 
-        logd("Sending DATA_ENABLED_CMD");
-        mDct.setUserDataEnabled(true);
-
         logd("Sending DISABLE_ROAMING_CMD");
         mDct.setDataRoamingEnabledByUser(false);
 
@@ -892,7 +822,6 @@
 
         // reset roaming settings / data enabled settings at end of this test
         mDct.setDataRoamingEnabledByUser(roamingEnabled);
-        mDct.setUserDataEnabled(dataEnabled);
         waitForMs(200);
     }
 
@@ -905,13 +834,16 @@
         ContentResolver resolver = mContext.getContentResolver();
         Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONED, 1);
 
-        mDct.setUserDataEnabled(true);
-
         mContextFixture.putBooleanResource(
                 com.android.internal.R.bool.config_auto_attach_data_on_creation, true);
 
         mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
 
+        AsyncResult ar = new AsyncResult(null,
+                new Pair<>(true, DataEnabledSettings.REASON_USER_DATA_ENABLED), null);
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_CHANGED, ar));
+        waitForMs(200);
+
         DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
         boolean allowed = isDataAllowed(dataConnectionReasons);
         assertFalse(dataConnectionReasons.toString(), allowed);
@@ -973,9 +905,6 @@
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
 
-        boolean dataEnabled = mDct.isUserDataEnabled();
-        mDct.setUserDataEnabled(true);
-
         mDct.setEnabled(ApnSetting.TYPE_IMS, true);
         mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
 
@@ -996,11 +925,10 @@
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 5, 1, LTE_BEARER_BITMASK);
         assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
 
-        Message msg = mDct.obtainMessage(DctConstants.EVENT_SET_CARRIER_DATA_ENABLED);
-        AsyncResult.forMessage(msg).result = false;
-        mDct.sendMessage(msg);
-
-        waitForMs(100);
+        AsyncResult ar = new AsyncResult(null,
+                new Pair<>(false, DataEnabledSettings.REASON_DATA_ENABLED_BY_CARRIER), null);
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_CHANGED, ar));
+        waitForMs(200);
 
         // Validate all metered data connections have been torn down
         verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(
@@ -1008,10 +936,6 @@
                 any(Message.class));
         assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
         assertEquals(DctConstants.State.IDLE, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT));
-
-        // Reset settings at the end of test
-        mDct.setUserDataEnabled(dataEnabled);
-        waitForMs(200);
     }
 
     private void initApns(String targetApn, String[] canHandleTypes) {
@@ -1048,8 +972,6 @@
     public void testGetDataConnectionState() throws Exception {
         initApns(PhoneConstants.APN_TYPE_SUPL,
                 new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_DEFAULT});
-        mDct.setUserDataEnabled(false);
-
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
 
@@ -1075,7 +997,8 @@
     @SmallTest
     public void testTrySetupDataUnmeteredDataDisabled() throws Exception {
         initApns(PhoneConstants.APN_TYPE_FOTA, new String[]{PhoneConstants.APN_TYPE_ALL});
-        mDct.setUserDataEnabled(false);
+        //mDct.setUserDataEnabled(false);
+        doReturn(false).when(mDataEnabledSettings).isDataEnabled();
 
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
@@ -1103,7 +1026,8 @@
     @SmallTest
     public void testTrySetupMeteredDataDisabled() throws Exception {
         initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
-        mDct.setUserDataEnabled(false);
+        //mDct.setUserDataEnabled(false);
+        doReturn(false).when(mDataEnabledSettings).isDataEnabled();
 
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
@@ -1131,7 +1055,8 @@
         initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
         doReturn(true).when(mApnContext).hasRestrictedRequests(eq(true));
 
-        mDct.setUserDataEnabled(false);
+        //mDct.setUserDataEnabled(false);
+        doReturn(false).when(mDataEnabledSettings).isDataEnabled();
 
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
@@ -1159,7 +1084,6 @@
         initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
         doReturn(true).when(mApnContext).hasRestrictedRequests(eq(true));
 
-        mDct.setUserDataEnabled(true);
         mDct.setDataRoamingEnabledByUser(false);
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
@@ -1188,7 +1112,6 @@
     public void testTrySetupNotConnectable() throws Exception {
         initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
         doReturn(false).when(mApnContext).isConnectable();
-        mDct.setUserDataEnabled(true);
 
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
@@ -1216,7 +1139,6 @@
         initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
         doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN).when(mServiceState)
                 .getRilDataRadioTechnology();
-        mDct.setUserDataEnabled(true);
 
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
@@ -1243,7 +1165,6 @@
     public void testTrySetupDefaultInECBM() throws Exception {
         initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
         doReturn(true).when(mPhone).isInEcm();
-        mDct.setUserDataEnabled(true);
 
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
@@ -1274,7 +1195,6 @@
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
         mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
-        mDct.setUserDataEnabled(true);
         initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
 
         logd("Sending EVENT_RECORDS_LOADED");
@@ -1395,7 +1315,6 @@
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
         mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
-        mDct.setUserDataEnabled(true);
         initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
 
         logd("Sending EVENT_RECORDS_LOADED");
@@ -1440,7 +1359,7 @@
     }
 
     // Test provisioning
-    @Test
+    /*@Test
     @SmallTest
     public void testDataEnableInProvisioning() throws Exception {
         ContentResolver resolver = mContext.getContentResolver();
@@ -1474,8 +1393,9 @@
         assertTrue(mDct.isDataEnabled());
         assertTrue(mDct.isUserDataEnabled());
         assertEquals(1, Settings.Global.getInt(resolver, Settings.Global.MOBILE_DATA));
-    }
+    }*/
 
+    /*
     @Test
     @SmallTest
     public void testNotifyDataEnabledChanged() throws Exception {
@@ -1511,7 +1431,7 @@
         waitForMs(200);
         verifyDataEnabledChangedMessage(
                 true, DataEnabledSettings.REASON_PROVISIONING_DATA_ENABLED_CHANGED);
-    }
+    }*/
 
     private void verifyDataEnabledChangedMessage(boolean enabled, int reason) {
         verify(mHandler, times(1)).sendMessageDelayed(any(), anyLong());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
index 0a11a5b..8521369 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
@@ -20,6 +20,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.doAnswer;
 
 import android.content.Context;
@@ -30,10 +31,11 @@
 import android.os.Binder;
 import android.os.HandlerThread;
 import android.os.Looper;
-import android.support.test.filters.FlakyTest;
 import android.telephony.Rlog;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.internal.telephony.PhoneSwitcher;
 import com.android.internal.telephony.RadioConfig;
 import com.android.internal.telephony.SubscriptionController;
@@ -74,7 +76,7 @@
         Rlog.d(LOG_TAG + " " + mTestName, str);
     }
 
-    private NetworkRequest makeSubSpecificDefaultRequest(int subId) {
+    private NetworkRequest makeSubSpecificInternetRequest(int subId) {
         NetworkCapabilities netCap = (new NetworkCapabilities()).
                 addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).
                 addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED).
@@ -116,7 +118,7 @@
         doAnswer(invocation -> {
             mNetworkRequestList.remove((NetworkRequest) invocation.getArguments()[0]);
             return null;
-        }).when(mDcTracker).releaseNetwork(any(), any());
+        }).when(mDcTracker).releaseNetwork(any(), any(), anyBoolean());
     }
 
     @After
@@ -181,8 +183,8 @@
         waitForMs(250);
         assertEquals(1, mNetworkRequestList.size());
 
-        log("makeSubSpecificDefaultRequest: subId = " + subId);
-        NetworkRequest subSpecificDefault = makeSubSpecificDefaultRequest(subId);
+        log("makeSubSpecificInternetRequest: subId = " + subId);
+        NetworkRequest subSpecificDefault = makeSubSpecificInternetRequest(subId);
         waitForMs(250);
         assertEquals(2, mNetworkRequestList.size());
 
@@ -191,7 +193,7 @@
         waitForMs(250);
         assertEquals(0, mNetworkRequestList.size());
 
-        log("makeSubSpecificDefaultRequest: subId = " + subId);
+        log("makeSubSpecificInternetRequest: subId = " + subId);
         NetworkRequest subSpecificMms = makeSubSpecificMmsRequest(subId);
         waitForMs(250);
         assertEquals(0, mNetworkRequestList.size());
@@ -274,14 +276,16 @@
         waitForMs(250);
         assertEquals(0, mNetworkRequestList.size());
 
-        makeSubSpecificDefaultRequest(subId);
+        makeSubSpecificInternetRequest(subId);
         waitForMs(250);
         assertEquals(0, mNetworkRequestList.size());
 
         mSubscriptionControllerMock.setSlotSubId(phoneId, subId);
         mSubscriptionMonitorMock.notifySubscriptionChanged(phoneId);
         waitForMs(250);
-        assertEquals(2, mNetworkRequestList.size());
+        // Although specified a subId, Internet request is only handled by
+        // preferred data phone.
+        assertEquals(1, mNetworkRequestList.size());
 
         mSubscriptionControllerMock.setDefaultDataSubId(subId);
         mPhoneSwitcherMock.setPreferredDataPhoneId(phoneId);
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 5e4cc44..2ade4ab 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTest.java
@@ -29,10 +29,12 @@
         EmergencyNumber number = new EmergencyNumber(
                 "911",
                 "us",
+                "30",
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
         assertEquals(number.getNumber(), "911");
         assertEquals(number.getCountryIso(), "us");
+        assertEquals(number.getMnc(), "30");
         assertTrue(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED));
         assertTrue(number.isInEmergencyServiceCategories(
@@ -73,11 +75,13 @@
         EmergencyNumber number = new EmergencyNumber(
                 "911",
                 "us",
+                "30",
                 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");
+        assertEquals(number.getMnc(), "30");
         assertFalse(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED));
         assertFalse(number.isInEmergencyServiceCategories(
@@ -123,6 +127,7 @@
         EmergencyNumber number = new EmergencyNumber(
                 "110",
                 "jp",
+                "30",
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC,
@@ -131,6 +136,7 @@
                         | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT);
         assertEquals(number.getNumber(), "110");
         assertEquals(number.getCountryIso(), "jp");
+        assertEquals(number.getMnc(), "30");
         assertFalse(number.isInEmergencyServiceCategories(
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED));
         assertTrue(number.isInEmergencyServiceCategories(
@@ -186,12 +192,14 @@
         EmergencyNumber numberHighestDisplayPriority = new EmergencyNumber(
                 "911",
                 "us",
+                "30",
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
 
         EmergencyNumber numberHigherDisplayPriority = new EmergencyNumber(
                 "922",
                 "us",
+                "30",
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC,
@@ -200,6 +208,7 @@
         EmergencyNumber numberLowestDisplayPriority = new EmergencyNumber(
                 "110",
                 "us",
+                "30",
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
                         | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java
index 11936f5..00e68de 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java
@@ -73,7 +73,7 @@
     }
 
     private void initializeEmergencyNumberListTestSamples() {
-        EmergencyNumber emergencyNumberForTest = new EmergencyNumber("119", "jp",
+        EmergencyNumber emergencyNumberForTest = new EmergencyNumber("119", "jp", "30",
                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
         mEmergencyNumberListTestSample.add(emergencyNumberForTest);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccCardControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccCardControllerTest.java
index f5a079a..a7ba5be 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccCardControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccCardControllerTest.java
@@ -27,10 +27,11 @@
 import android.content.SharedPreferences;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
-import android.support.test.runner.AndroidJUnit4;
 import android.telephony.TelephonyManager;
 import android.telephony.euicc.EuiccManager;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.telephony.uicc.UiccSlot;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccConnectorTest.java b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccConnectorTest.java
index f757388..761a4f0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccConnectorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccConnectorTest.java
@@ -40,7 +40,8 @@
 import android.service.euicc.EuiccService;
 import android.service.euicc.IEuiccService;
 import android.service.euicc.IGetEidCallback;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.telephony.TelephonyTest;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
index aafe865..a8751f4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
@@ -49,7 +49,6 @@
 import android.service.euicc.EuiccService;
 import android.service.euicc.GetDefaultDownloadableSubscriptionListResult;
 import android.service.euicc.GetDownloadableSubscriptionMetadataResult;
-import android.support.test.runner.AndroidJUnit4;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.UiccAccessRule;
@@ -57,6 +56,8 @@
 import android.telephony.euicc.EuiccInfo;
 import android.telephony.euicc.EuiccManager;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.euicc.EuiccConnector.GetOtaStatusCommandCallback;
 import com.android.internal.telephony.euicc.EuiccConnector.OtaStatusChangedCallback;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmCellBroadcastHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmCellBroadcastHandlerTest.java
index b117eb1..756c585 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmCellBroadcastHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmCellBroadcastHandlerTest.java
@@ -38,7 +38,8 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Telephony;
-import android.support.test.filters.FlakyTest;
+
+import androidx.test.filters.FlakyTest;
 
 import com.android.internal.telephony.SmsStorageMonitor;
 import com.android.internal.telephony.TelephonyTest;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
index 1e29908..e950797 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -46,10 +46,11 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Telephony;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.MediumTest;
 import android.test.mock.MockContentResolver;
 
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.MediumTest;
+
 import com.android.internal.telephony.FakeSmsContentProvider;
 import com.android.internal.telephony.InboundSmsHandler;
 import com.android.internal.telephony.InboundSmsTracker;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
index a24bdfc..28f5297 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
@@ -44,12 +44,13 @@
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.provider.Telephony;
-import android.support.test.filters.FlakyTest;
 import android.telephony.SmsManager;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Singleton;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.internal.telephony.ContextFixture;
 import com.android.internal.telephony.ISub;
 import com.android.internal.telephony.SMSDispatcher;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsCallProfileTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsCallProfileTest.java
index 2ea1f28..751db91 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsCallProfileTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsCallProfileTest.java
@@ -24,11 +24,11 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.support.test.runner.AndroidJUnit4;
 import android.telecom.DisconnectCause;
+import android.telephony.ims.ImsCallProfile;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import android.telephony.ims.ImsCallProfile;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
index 3587b8b..b7c450c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
@@ -44,13 +44,14 @@
 import android.os.Bundle;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
-import android.support.test.runner.AndroidJUnit4;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ims.ImsService;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.stub.ImsFeatureConfiguration;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
index af2f81b..00e27c2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
@@ -36,11 +36,12 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
-import android.support.test.filters.FlakyTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.telephony.ims.ImsService;
 import android.telephony.ims.stub.ImsFeatureConfiguration;
 
+import androidx.test.filters.FlakyTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.ims.internal.IImsServiceFeatureCallback;
 
 import org.junit.After;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsTestBase.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsTestBase.java
index e9fba8e..ad8cd47 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsTestBase.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsTestBase.java
@@ -19,7 +19,8 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.Looper;
-import android.support.test.InstrumentationRegistry;
+
+import androidx.test.InstrumentationRegistry;
 
 import org.mockito.MockitoAnnotations;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsVideoProviderWrapperTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsVideoProviderWrapperTest.java
index 338e8a4..beeeefa 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsVideoProviderWrapperTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsVideoProviderWrapperTest.java
@@ -19,10 +19,11 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.when;
 
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.telecom.VideoProfile;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.ims.internal.ImsVideoCallProviderWrapper;
 import com.android.ims.internal.VideoPauseTracker;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/RcsMessageStoreControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/RcsMessageStoreControllerTest.java
new file mode 100644
index 0000000..38bc061
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/RcsMessageStoreControllerTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 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 com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+
+import android.database.Cursor;
+import android.net.Uri;
+import android.telephony.ims.RcsParticipant;
+import android.telephony.ims.RcsThreadQueryParameters;
+import android.test.mock.MockContentProvider;
+import android.test.mock.MockContentResolver;
+
+import com.android.internal.telephony.TelephonyTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class RcsMessageStoreControllerTest extends TelephonyTest {
+
+    private RcsMessageStoreController mRcsMessageStoreController;
+    private MockContentResolver mContentResolver;
+    private FakeRcsProvider mFakeRcsProvider;
+
+    @Mock
+    RcsParticipant mMockParticipant;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp("RcsMessageStoreControllerTest");
+        MockitoAnnotations.initMocks(this);
+
+        mFakeRcsProvider = new FakeRcsProvider();
+        mContentResolver = (MockContentResolver) mContext.getContentResolver();
+        mContentResolver.addProvider("rcs", mFakeRcsProvider);
+
+        mRcsMessageStoreController = new RcsMessageStoreController(mContentResolver, null);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testGetRcsThreads() {
+        doReturn(123).when(mMockParticipant).getId();
+        RcsThreadQueryParameters queryParameters =
+                RcsThreadQueryParameters.builder().withParticipant(mMockParticipant).isGroupThread(
+                        true).limitResultsTo(30).sort(true).build();
+
+        mFakeRcsProvider.setExpectedQueryParameters(Uri.parse("content://rcs/thread"),
+                new String[]{"_id"}, null, null, "ASCENDING");
+        mRcsMessageStoreController.getRcsThreads(queryParameters);
+    }
+
+    /**
+     * TODO(sahinc): fix the test once there is an implementation in place
+     */
+    @Test
+    public void testGetMessageCount() {
+        assertEquals(1018, mRcsMessageStoreController.getMessageCount(0));
+    }
+
+    /**
+     * Mocking/spying ContentProviders break in different ways. Use a fake instead. The
+     * RcsMessageStoreController doesn't care if RcsProvider works as expected (and doesn't have
+     * visibility into it) - so verifying whether we use the correct parameters should suffice.
+     */
+    class FakeRcsProvider extends MockContentProvider {
+        private Uri mExpectedUri;
+        private String[] mExpectedProjection;
+        private String mExpectedWhereClause;
+        private String[] mExpectedWhereArgs;
+        private String mExpectedSortOrder;
+
+        void setExpectedQueryParameters(Uri uri, String[] projection, String whereClause,
+                String[] whereArgs, String sortOrder) {
+            mExpectedUri = uri;
+            mExpectedProjection = projection;
+            mExpectedWhereClause = whereClause;
+            mExpectedWhereArgs = whereArgs;
+            mExpectedSortOrder = sortOrder;
+        }
+
+        @Override
+        public Cursor query(Uri uri, String[] projection, String whereClause, String[] whereArgs,
+                String sortOrder) {
+            assertThat(uri).isEqualTo(mExpectedUri);
+            assertThat(projection).isEqualTo(mExpectedProjection);
+            assertThat(whereClause).isEqualTo(mExpectedWhereClause);
+            assertThat(whereArgs).isEqualTo(mExpectedWhereArgs);
+            assertThat(sortOrder).isEqualTo(mExpectedSortOrder);
+            return null;
+        }
+
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java
index 80be96c..e44d8b1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java
@@ -21,10 +21,11 @@
 import static org.mockito.Mockito.verify;
 
 import android.net.Uri;
-import android.support.test.filters.FlakyTest;
-
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsExternalCallState;
+
+import androidx.test.filters.FlakyTest;
+
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.Connection;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
index c602108..f0b93a9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
@@ -24,9 +24,10 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.support.test.filters.FlakyTest;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.telephony.ims.ImsStreamMediaProfile;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.FlakyTest;
 
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.TelephonyTest;
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 5728648..e8a002c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -43,7 +43,6 @@
 import android.os.HandlerThread;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.support.test.filters.FlakyTest;
 import android.telecom.VideoProfile;
 import android.telephony.CarrierConfigManager;
 import android.telephony.DisconnectCause;
@@ -60,6 +59,8 @@
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.ims.ImsCall;
 import com.android.ims.ImsConfig;
 import com.android.ims.ImsException;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
index 97e6691..2555488 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -49,13 +49,14 @@
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.SystemProperties;
-import android.support.test.filters.FlakyTest;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsReasonInfo;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.ims.ImsEcbmStateListener;
 import com.android.ims.ImsManager;
 import com.android.ims.ImsUtInterface;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
index 22d9f78..82a3c0c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
@@ -18,9 +18,10 @@
 
 import android.os.HandlerThread;
 import android.os.ParcelFileDescriptor;
-import android.support.test.filters.FlakyTest;
 import android.telecom.Connection;
 
+import androidx.test.filters.FlakyTest;
+
 import com.android.internal.telephony.TelephonyTest;
 
 import org.junit.After;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneMock.java b/tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneMock.java
index d6c86c6..cf9e72a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneMock.java
@@ -1287,14 +1287,6 @@
         throw new RuntimeException("not implemented");
     }
 
-    public boolean isDataEnabled() {
-        throw new RuntimeException("not implemented");
-    }
-
-    public void setUserDataEnabled(boolean enable) {
-        throw new RuntimeException("not implemented");
-    }
-
     public String getDeviceId() {
         throw new RuntimeException("not implemented");
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneSwitcherMock.java b/tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneSwitcherMock.java
index d3ab208..b4293b1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneSwitcherMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneSwitcherMock.java
@@ -27,14 +27,12 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 
 public class PhoneSwitcherMock extends PhoneSwitcher {
-    private final int mNumPhones;
     private final RegistrantList mActivePhoneRegistrants;
     private final AtomicBoolean mIsActive[];
 
     public PhoneSwitcherMock(int numPhones, Looper looper) {
-        super(looper);
+        super(numPhones, looper);
 
-        mNumPhones = numPhones;
         mActivePhoneRegistrants = new RegistrantList();
         mIsActive = new AtomicBoolean[numPhones];
         for(int i = 0; i < numPhones; i++) {
@@ -48,16 +46,11 @@
     }
 
     @Override
-    public boolean shouldApplySpecifiedRequests(int phoneId) {
+    protected boolean isPhoneActive(int phoneId) {
         return mIsActive[phoneId].get();
     }
 
     @Override
-    public boolean shouldApplyUnspecifiedRequests(int phoneId) {
-        return mIsActive[phoneId].get() && phoneId == mPreferredDataPhoneId;
-    }
-
-    @Override
     public void registerForActivePhoneSwitch(Handler h, int what, Object o) {
         Registrant r = new Registrant(h, what, o);
         mActivePhoneRegistrants.add(r);
@@ -69,12 +62,6 @@
         mActivePhoneRegistrants.remove(h);
     }
 
-    private void validatePhoneId(int phoneId) {
-        if (phoneId < 0 || phoneId >= mNumPhones) {
-            throw new IllegalArgumentException("Invalid PhoneId");
-        }
-    }
-
     @VisibleForTesting
     public void setPhoneActive(int phoneId, boolean active) {
         validatePhoneId(phoneId);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java b/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
index 19906bd..1c636d5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
@@ -28,7 +28,6 @@
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionManager;
-import android.telephony.emergency.EmergencyNumber;
 
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
 import com.android.internal.telephony.IPhoneStateListener;
@@ -307,26 +306,26 @@
 
     @Override
     public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
-            String reason, String apn, String apnType, LinkProperties linkProperties,
+            String apn, String apnType, LinkProperties linkProperties,
             NetworkCapabilities networkCapabilities, int networkType, boolean roaming) {
         throw new RuntimeException("Not implemented");
     }
 
     @Override
     public void notifyDataConnectionForSubscriber(int subId, int state,
-            boolean isDataConnectivityPossible, String reason, String apn, String apnType,
+            boolean isDataConnectivityPossible, String apn, String apnType,
             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
             int networkType, boolean roaming) {
         throw new RuntimeException("Not implemented");
     }
 
     @Override
-    public void notifyDataConnectionFailed(String reason, String apnType) {
+    public void notifyDataConnectionFailed(String apnType) {
         throw new RuntimeException("Not implemented");
     }
 
     @Override
-    public void notifyDataConnectionFailedForSubscriber(int subId, String reason, String apnType) {
+    public void notifyDataConnectionFailedForSubscriber(int subId, String apnType) {
         throw new RuntimeException("Not implemented");
     }
 
@@ -362,7 +361,7 @@
     }
 
     @Override
-    public void notifyEmergencyNumberList(List<EmergencyNumber> emergencyNumberList) {
+    public void notifyEmergencyNumberList() {
         throw new RuntimeException("Not implemented");
     }
 
@@ -378,7 +377,7 @@
     }
 
     @Override
-    public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
+    public void notifyPreciseDataConnectionFailed(String apnType, String apn,
             String failCause) {
         throw new RuntimeException("Not implemented");
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/rcs/RcsMessageStoreControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/rcs/RcsMessageStoreControllerTest.java
deleted file mode 100644
index 869ec84..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/rcs/RcsMessageStoreControllerTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 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.rcs;
-
-import static org.junit.Assert.assertEquals;
-
-import com.android.internal.telephony.RcsMessageStoreController;
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class RcsMessageStoreControllerTest extends TelephonyTest {
-
-    private RcsMessageStoreController mRcsMessageStoreController;
-
-    @Before
-    public void setUp() {
-        mRcsMessageStoreController = new RcsMessageStoreController(mContext, null);
-    }
-
-    /**
-     * TODO(sahinc): fix the test once there is an implementation in place
-     */
-    @Test
-    public void testGetMessageCount() {
-        assertEquals(1018, mRcsMessageStoreController.getMessageCount(0));
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/InstallCarrierAppUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/InstallCarrierAppUtilsTest.java
index bc297a3..867d44f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/InstallCarrierAppUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/InstallCarrierAppUtilsTest.java
@@ -19,7 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 
-import android.support.test.filters.SmallTest;
+import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
index 3b8b799..e1a5be0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
@@ -30,9 +30,11 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
 import android.telephony.TelephonyManager;
+import android.telephony.UiccCardInfo;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
 
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.TelephonyTest;
@@ -222,7 +224,7 @@
         doReturn("A1B2C3D4").when(mMockCard).getCardId();
         doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mMockCard).getCardState();
 
-        // simulate card status loaded
+        // simulate card status loaded so that the UiccController sets the card ID
         IccCardStatus ics = new IccCardStatus();
         ics.setCardState(1 /* present */);
         ics.setUniversalPinState(3 /* disabled */);
@@ -246,7 +248,7 @@
         mUiccControllerUT.mUiccSlots[0] = mMockSlot;
         doReturn(true).when(mMockSlot).isEuicc();
 
-        // simulate slot status loaded
+        // simulate slot status loaded so that the UiccController sets the card ID
         IccSlotStatus iss = new IccSlotStatus();
         iss.setSlotState(1 /* active */);
         iss.eid = "ABADACB";
@@ -269,7 +271,7 @@
         mUiccControllerUT.mUiccSlots[0] = mMockSlot;
         doReturn(true).when(mMockSlot).isEuicc();
 
-        // simulate slot status loaded
+        // simulate slot status loaded so that the UiccController sets the card ID
         IccSlotStatus iss = new IccSlotStatus();
         iss.setSlotState(1 /* active */);
         iss.eid = "ABADACB";
@@ -283,4 +285,38 @@
         assertEquals(mUiccControllerUT.convertToPublicCardId(iss.eid),
                 mUiccControllerUT.getCardIdForDefaultEuicc());
     }
+
+    @Test
+    public void testGetAllUiccCardInfos() {
+        // Give UiccController a real context so it can use shared preferences
+        mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
+
+        // Mock out UiccSlots
+        mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+        doReturn(true).when(mMockSlot).isEuicc();
+        doReturn(mMockCard).when(mMockSlot).getUiccCard();
+        doReturn("A1B2C3D4").when(mMockCard).getCardId();
+        doReturn("123451234567890").when(mMockCard).getIccId();
+        doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mMockCard).getCardState();
+
+        // simulate card status loaded so that the UiccController sets the card ID
+        IccCardStatus ics = new IccCardStatus();
+        ics.setCardState(1 /* present */);
+        ics.setUniversalPinState(3 /* disabled */);
+        ics.atr = "abcdef0123456789abcdef";
+        ics.iccid = "123451234567890";
+        ics.eid = "A1B2C3D4";
+        AsyncResult ar = new AsyncResult(null, ics, null);
+        Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
+        mUiccControllerUT.handleMessage(msg);
+
+        // assert that the default cardId is the slot with the lowest slot index, even if inactive
+        UiccCardInfo uiccCardInfo = new UiccCardInfo(
+                true,      // isEuicc
+                0,         // cardId
+                ics.eid,   // eid
+                ics.iccid, // iccid is unknown
+                0);        // slotIndex
+        assertEquals(uiccCardInfo, mUiccControllerUT.getAllUiccCardInfos().get(0));
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
index e99a4e5..1e9b643 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
@@ -35,9 +35,10 @@
 import android.os.HandlerThread;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.support.test.filters.SmallTest;
 import android.telephony.CarrierConfigManager;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.internal.telephony.IccCardConstants.State;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.cat.CatService;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
index 457f021..2c55915 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
@@ -28,7 +28,8 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
-import android.support.test.filters.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyTest;