Merge "Add method to get phoneId from slotId"
diff --git a/Android.bp b/Android.bp
index 4925d51..7530b7a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -57,7 +57,6 @@
     static_libs: [
         "telephony-protos",
         "ecc-protos-lite",
-        "android-support-annotations",
     ],
 
     product_variables: {
diff --git a/proto/src/telephony.proto b/proto/src/telephony.proto
index 14e2e12..30c2771 100644
--- a/proto/src/telephony.proto
+++ b/proto/src/telephony.proto
@@ -50,6 +50,9 @@
 
   // Hardware revision (EVT, DVT, PVT etc.)
   optional string hardware_revision = 9;
+
+  // The last active subscription info for each slot.
+  repeated ActiveSubscriptionInfo last_active_subscription_info = 10;
 }
 
 // The time information
@@ -276,9 +279,6 @@
 
   // Current data radio technology
   optional RadioAccessTechnology data_rat = 6 [default = UNKNOWN];
-
-  // All the active subscription information.
-  repeated ActiveSubscriptionInfo active_subscription_info = 7;
 }
 
 // Radio access families
@@ -620,8 +620,23 @@
   // The network interface name e.g. wlan0, rmnet_data0.
   optional string iframe = 3;
 
-  // All the active subscription information.
-  repeated ActiveSubscriptionInfo active_subscription_info = 4;
+  // State of the Data Call connection
+  optional State state = 4;
+
+  // Bitmask of APN types
+  optional int32 apn_type_bitmask = 5;
+
+  enum State {
+
+    // Unknown event
+    UNKNOWN = 0;
+
+    // Connected event
+    CONNECTED = 1;
+
+    // Disconnected event
+    DISCONNECTED = 2;
+  }
 }
 
 message TelephonyEvent {
@@ -675,73 +690,99 @@
     // Carrier Key Change event.
     CARRIER_KEY_CHANGED = 14;
 
-    // Phone status change event.
-    PHONE_STATUS_CHANGED = 15;
-
     // Data switch event.
-    DATA_SWITCH = 16;
+    DATA_SWITCH = 15;
 
     // Network validate event.
-    NETWORK_VALIDATE = 17;
+    NETWORK_VALIDATE = 16;
 
     // On deman data switch event.
-    ON_DEMAND_DATA_SWITCH = 18;
+    ON_DEMAND_DATA_SWITCH = 17;
+
+    // SIM state change event.
+    SIM_STATE_CHANGED = 18;
+
+    // Active subscription info change event.
+    ACTIVE_SUBSCRIPTION_INFO_CHANGED = 19;
+
+    // Enabled modem change event.
+    ENABLED_MODEM_CHANGED = 20;
   }
 
   enum ApnType {
-      DEFAULT = 0;
-      MMS = 1;
-      SUPL = 2;
-      DUN = 3;
-      HIPRI = 4;
-      FOTA = 5;
-      IMS = 6;
-      CBS = 7;
-      IA = 8;
-      EMERGENCY = 9;
+    APN_TYPE_UNKNOWN = 0;
+
+    APN_TYPE_DEFAULT = 1;
+
+    APN_TYPE_MMS = 2;
+
+    APN_TYPE_SUPL = 3;
+
+    APN_TYPE_DUN = 4;
+
+    APN_TYPE_HIPRI = 5;
+
+    APN_TYPE_FOTA = 6;
+
+    APN_TYPE_IMS = 7;
+
+    APN_TYPE_CBS = 8;
+
+    APN_TYPE_IA = 9;
+
+    APN_TYPE_EMERGENCY = 10;
   }
 
   enum EventState {
-      START = 0;
-      END = 1;
+    EVENT_STATE_UNKNOWN = 0;
+
+    EVENT_STATE_START = 1;
+
+    EVENT_STATE_END = 2;
   }
 
   enum NetworkValidationState {
-      /** The network under validation is initial established. */
-      AVAILABLE = 0;
+    /** The network validation state is unknown. */
+    NETWORK_VALIDATION_STATE_UNKNOWN = 0;
 
-      /** The validation is failed. */
-      FAILED = 1;
+    /** The network under validation is initial established. */
+    NETWORK_VALIDATION_STATE_AVAILABLE = 1;
 
-      /** The validation is passed. */
-      PASSED = 2;
+    /** The validation is failed. */
+    NETWORK_VALIDATION_STATE_FAILED = 2;
+
+    /** The validation is passed. */
+    NETWORK_VALIDATION_STATE_PASSED = 3;
   }
 
   message DataSwitch {
-      enum Reason {
-          /** Data switch caused by user's manual switch. */
-          MANUAL = 0;
+    enum Reason {
+      /** Data switch caused by unknown reason. */
+      DATA_SWITCH_REASON_UNKNOWN = 0;
 
-          /** Data switch caused by incoming/outgoing call. */
-          IN_CALL = 1;
+      /** Data switch caused by user's manual switch. */
+      DATA_SWITCH_REASON_MANUAL = 1;
 
-          /** Data switch caused by CBRS switch. */
-          CBRS = 2;
-      }
+      /** Data switch caused by incoming/outgoing call. */
+      DATA_SWITCH_REASON_IN_CALL = 2;
 
-      /** The reason for data switch. */
-      optional Reason reason = 1;
+      /** Data switch caused by CBRS switch. */
+      DATA_SWITCH_REASON_CBRS = 3;
+    }
 
-      /** Current state of the data switch event. */
-      optional EventState state = 2;
+    /** The reason for data switch. */
+    optional Reason reason = 1;
+
+    /** Current state of the data switch event. */
+    optional EventState state = 2;
   }
 
   message OnDemandDataSwitch {
-      /** The apn associated with this event. */
-      optional ApnType apn = 1;
+    /** The apn associated with this event. */
+    optional ApnType apn = 1;
 
-      /** Current state of the on demand data switch event. */
-      optional EventState state = 2;
+    /** Current state of the on demand data switch event. */
+    optional EventState state = 2;
   }
 
   // Setup a packet data connection
@@ -1536,17 +1577,6 @@
     optional string mccmnc = 3;
   }
 
-  message PhoneStatus {
-      /** The sim state of each active slot. */
-      repeated SimState sim_state = 1;
-
-      /**
-       * The modem state represent by a bitmap, the i-th bit(LSB) indicates the i-th modem
-       * state(0 - disabled, 1 - enabled).
-       */
-      optional int32 enabled_modem_bitmap = 2;
-  }
-
   // Time when event happened on device, in milliseconds since epoch
   optional int64 timestamp_millis = 1;
 
@@ -1598,9 +1628,6 @@
   // Carrier key change
   optional CarrierKeyChange carrier_key_change = 17;
 
-  // Phone status
-  optional PhoneStatus phone_status = 18;
-
   // Data switch event
   optional DataSwitch data_switch = 19;
 
@@ -1609,31 +1636,41 @@
 
   // On demand data switch event
   optional OnDemandDataSwitch on_demand_data_switch = 21;
+
+  // Sim state for each slot.
+  repeated SimState sim_state = 22;
+
+  // The active subscription info for a specific slot.
+  optional ActiveSubscriptionInfo active_subscription_info = 23;
+
+  // The modem state represent by a bitmap, the i-th bit(LSB) indicates the i-th modem
+  // state (0 - disabled, 1 - enabled).
+  optional int32 enabled_modem_bitmap = 24;
 }
 
 message ActiveSubscriptionInfo {
-    /** The slot index which this subscription associated with. */
-    optional int32 slot_index = 1;
+  /** The slot index which this subscription is associated with. */
+  optional int32 slot_index = 1;
 
-    /** The Carrier id of this subscription. */
-    optional int32 carrier_id = 2;
+  /** The Carrier id of this subscription. -1 indicates unknown value. */
+  optional int32 carrier_id = 2;
 
-    /** whether subscription is opportunistic. */
-    optional bool is_opportunistic = 3;
+  /** whether subscription is opportunistic (0 - false, 1 - true, -1 - unknown). */
+  optional int32 is_opportunistic = 3;
 };
 
 enum SimState {
-    /**
-     * SIM card is inserted, but the state is unknown. Typically happened when the SIM is inserted
-     * but not loaded.
-     */
-    SIM_STATE_UNKNOWN = 0;
+  /**
+   * SIM card is inserted, but the state is unknown. Typically happened when the SIM is inserted
+   * but not loaded.
+   */
+  SIM_STATE_UNKNOWN = 0;
 
-    /** No SIM card is inserted in the slot. */
-    SIM_STATE_ABSENT = 1;
+  /** No SIM card is inserted in the slot. */
+  SIM_STATE_ABSENT = 1;
 
-    /** SIM card applications have been loaded. */
-    SIM_STATE_LOADED = 2;
+  /** SIM card applications have been loaded. */
+  SIM_STATE_LOADED = 2;
 };
 
 enum TimeInterval {
@@ -2001,12 +2038,6 @@
 
   // Indicating some call events are dropped
   optional bool events_dropped = 4;
-
-  // SIM state of the active slots
-  repeated SimState sim_states = 5;
-
-  // All the active subscription information.
-  repeated ActiveSubscriptionInfo active_subscription_info = 6;
 }
 
 message SmsSession {
@@ -2221,12 +2252,6 @@
 
   // Indicating some sms session events are dropped
   optional bool events_dropped = 4;
-
-  // SIM state of the active slots.
-  repeated SimState sim_state = 5;
-
-  // All the active subscription information.
-  repeated ActiveSubscriptionInfo active_subscription_info = 6;
 }
 
 // Power stats for modem
diff --git a/src/java/com/android/internal/telephony/BaseCommands.java b/src/java/com/android/internal/telephony/BaseCommands.java
index 2695951..5d8e9cd 100644
--- a/src/java/com/android/internal/telephony/BaseCommands.java
+++ b/src/java/com/android/internal/telephony/BaseCommands.java
@@ -17,6 +17,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -30,8 +31,10 @@
  */
 public abstract class BaseCommands implements CommandsInterface {
     //***** Instance Variables
+    @UnsupportedAppUsage
     protected Context mContext;
     protected int mState = TelephonyManager.RADIO_POWER_UNAVAILABLE;
+    @UnsupportedAppUsage
     protected Object mStateMonitor = new Object();
 
     protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
@@ -39,17 +42,24 @@
     protected RegistrantList mAvailRegistrants = new RegistrantList();
     protected RegistrantList mOffOrNotAvailRegistrants = new RegistrantList();
     protected RegistrantList mNotAvailRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mCallStateRegistrants = new RegistrantList();
     protected RegistrantList mNetworkStateRegistrants = new RegistrantList();
     protected RegistrantList mDataCallListChangedRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mVoiceRadioTechChangedRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mImsNetworkStateChangedRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
     protected RegistrantList mIccSlotStatusChangedRegistrants = new RegistrantList();
     protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
     protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected Registrant mUnsolOemHookRawRegistrant;
+    @UnsupportedAppUsage
     protected RegistrantList mOtaProvisionRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList();
     protected RegistrantList mDisplayInfoRegistrants = new RegistrantList();
     protected RegistrantList mSignalInfoRegistrants = new RegistrantList();
@@ -58,17 +68,28 @@
     protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
     protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
     protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mCdmaSubscriptionChangedRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList();
     protected RegistrantList mRilConnectedRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mIccRefreshRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mRilCellInfoListRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mSubscriptionStatusRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mSrvccStateRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mHardwareConfigChangeRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mPhoneRadioCapabilityChangedRegistrants =
             new RegistrantList();
     protected RegistrantList mPcoDataRegistrants = new RegistrantList();
@@ -80,33 +101,54 @@
     protected RegistrantList mLceInfoRegistrants = new RegistrantList();
     protected RegistrantList mEmergencyNumberListRegistrants = new RegistrantList();
 
+    @UnsupportedAppUsage
     protected Registrant mGsmSmsRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mCdmaSmsRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mNITZTimeRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mSignalStrengthRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mUSSDRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mSmsOnSimRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mSmsStatusRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mSsnRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mCatSessionEndRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mCatProCmdRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mCatEventRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mCatCallSetUpRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mIccSmsFullRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mEmergencyCallbackModeRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mRingRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mRestrictedStateRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mGsmBroadcastSmsRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mCatCcAlphaRegistrant;
+    @UnsupportedAppUsage
     protected Registrant mSsRegistrant;
 
     // Preferred network type received from PhoneFactory.
     // This is used when establishing a connection to the
     // vendor ril so it starts up in the correct mode.
+    @UnsupportedAppUsage
     protected int mPreferredNetworkType;
     // CDMA subscription received from PhoneFactory
     protected int mCdmaSubscription;
     // Type of Phone, GSM or CDMA. Set by GsmCdmaPhone.
+    @UnsupportedAppUsage
     protected int mPhoneType;
     // RIL Version
     protected int mRilVersion = -1;
diff --git a/src/java/com/android/internal/telephony/Call.java b/src/java/com/android/internal/telephony/Call.java
index 1c99fbd..37fefd9 100644
--- a/src/java/com/android/internal/telephony/Call.java
+++ b/src/java/com/android/internal/telephony/Call.java
@@ -21,6 +21,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 /**
@@ -32,12 +33,15 @@
     /* Enums */
 
     public enum State {
+        @UnsupportedAppUsage
         IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING;
 
+        @UnsupportedAppUsage
         public boolean isAlive() {
             return !(this == IDLE || this == DISCONNECTED || this == DISCONNECTING);
         }
 
+        @UnsupportedAppUsage
         public boolean isRinging() {
             return this == INCOMING || this == WAITING;
         }
@@ -47,18 +51,6 @@
         }
     }
 
-    public enum HoldingRequestState {
-        NONE, STARTED, ENDED;
-
-        public boolean isStarted() {
-            return this == STARTED;
-        }
-
-        public boolean isFinished() {
-            return this == ENDED;
-        }
-    }
-
     public static State
     stateFromDCState (DriverCall.State dcState) {
         switch (dcState) {
@@ -78,21 +70,25 @@
 
     /* Instance Variables */
 
+    @UnsupportedAppUsage
     public State mState = State.IDLE;
 
+    @UnsupportedAppUsage
     public ArrayList<Connection> mConnections = new ArrayList<Connection>();
 
-    public HoldingRequestState mHoldingRequestState = HoldingRequestState.NONE;
-
     /* Instance Methods */
 
     /** Do not modify the List result!!! This list is not yours to keep
      *  It will change across event loop iterations            top
      */
 
+    @UnsupportedAppUsage
     public abstract List<Connection> getConnections();
+    @UnsupportedAppUsage
     public abstract Phone getPhone();
+    @UnsupportedAppUsage
     public abstract boolean isMultiparty();
+    @UnsupportedAppUsage
     public abstract void hangup() throws CallStateException;
 
 
@@ -124,6 +120,7 @@
      * getState
      * @return state of class call
      */
+    @UnsupportedAppUsage
     public State getState() {
         return mState;
     }
@@ -142,6 +139,7 @@
      * FIXME rename
      * @return true if the call contains only disconnected connections (if any)
      */
+    @UnsupportedAppUsage
     public boolean isIdle() {
         return !getState().isAlive();
     }
@@ -150,6 +148,7 @@
      * Returns the Connection associated with this Call that was created
      * first, or null if there are no Connections in this Call
      */
+    @UnsupportedAppUsage
     public Connection
     getEarliestConnection() {
         List<Connection> l;
@@ -237,6 +236,7 @@
      * Returns the Connection associated with this Call that was created
      * last, or null if there are no Connections in this Call
      */
+    @UnsupportedAppUsage
     public Connection
     getLatestConnection() {
         List<Connection> l = getConnections();
@@ -291,8 +291,4 @@
     protected void setState(State newState) {
         mState = newState;
     }
-
-    public void updateHoldingRequestState(HoldingRequestState state) {
-        mHoldingRequestState = state;
-    }
 }
diff --git a/src/java/com/android/internal/telephony/CallForwardInfo.java b/src/java/com/android/internal/telephony/CallForwardInfo.java
index e40028f..ea3ba27 100644
--- a/src/java/com/android/internal/telephony/CallForwardInfo.java
+++ b/src/java/com/android/internal/telephony/CallForwardInfo.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telecom.Log;
 
 /**
@@ -26,11 +27,17 @@
 public class CallForwardInfo {
     private static final String TAG = "CallForwardInfo";
 
+    @UnsupportedAppUsage
     public int             status;      /*1 = active, 0 = not active */
+    @UnsupportedAppUsage
     public int             reason;      /* from TS 27.007 7.11 "reason" */
+    @UnsupportedAppUsage
     public int             serviceClass; /* Saum of CommandsInterface.SERVICE_CLASS */
+    @UnsupportedAppUsage
     public int             toa;         /* "type" from TS 27.007 7.11 */
+    @UnsupportedAppUsage
     public String          number;      /* "number" from TS 27.007 7.11 */
+    @UnsupportedAppUsage
     public int             timeSeconds; /* for CF no reply only */
 
     @Override
diff --git a/src/java/com/android/internal/telephony/CallManager.java b/src/java/com/android/internal/telephony/CallManager.java
index 3a49a12..5112376 100644
--- a/src/java/com/android/internal/telephony/CallManager.java
+++ b/src/java/com/android/internal/telephony/CallManager.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -89,18 +90,23 @@
     private static final CallManager INSTANCE = new CallManager();
 
     // list of registered phones, which are Phone objs
+    @UnsupportedAppUsage
     private final ArrayList<Phone> mPhones;
 
     // list of supported ringing calls
+    @UnsupportedAppUsage
     private final ArrayList<Call> mRingingCalls;
 
     // list of supported background calls
+    @UnsupportedAppUsage
     private final ArrayList<Call> mBackgroundCalls;
 
     // list of supported foreground calls
+    @UnsupportedAppUsage
     private final ArrayList<Call> mForegroundCalls;
 
     // empty connection list
+    @UnsupportedAppUsage
     private final ArrayList<Connection> mEmptyConnections = new ArrayList<Connection>();
 
     // mapping of phones to registered handler instances used for callbacks from RIL
@@ -197,6 +203,7 @@
      * get singleton instance of CallManager
      * @return CallManager
      */
+    @UnsupportedAppUsage
     public static CallManager getInstance() {
         return INSTANCE;
     }
@@ -223,6 +230,7 @@
      * then the phone state is RINGING not OFFHOOK
      *
      */
+    @UnsupportedAppUsage
     public PhoneConstants.State getState() {
         PhoneConstants.State s = PhoneConstants.State.IDLE;
 
@@ -242,6 +250,7 @@
      * then the phone state is RINGING not OFFHOOK
      *
      */
+    @UnsupportedAppUsage
     public PhoneConstants.State getState(int subId) {
         PhoneConstants.State s = PhoneConstants.State.IDLE;
 
@@ -325,6 +334,7 @@
     /**
      * @return the phone associated with any call
      */
+    @UnsupportedAppUsage
     public Phone getPhoneInCall() {
         Phone phone = null;
         if (!getFirstActiveRingingCall().isIdle()) {
@@ -343,6 +353,7 @@
      * @param phone to be registered
      * @return true if register successfully
      */
+    @UnsupportedAppUsage
     public boolean registerPhone(Phone phone) {
         if (phone != null && !mPhones.contains(phone)) {
 
@@ -368,6 +379,7 @@
      * unregister phone from CallManager
      * @param phone to be unregistered
      */
+    @UnsupportedAppUsage
     public void unregisterPhone(Phone phone) {
         if (phone != null && mPhones.contains(phone)) {
 
@@ -399,6 +411,7 @@
     /**
      * return the default phone or null if no phone available
      */
+    @UnsupportedAppUsage
     public Phone getDefaultPhone() {
         return mDefaultPhone;
     }
@@ -406,6 +419,7 @@
     /**
      * @return the phone associated with the foreground call
      */
+    @UnsupportedAppUsage
     public Phone getFgPhone() {
         return getActiveFgCall().getPhone();
     }
@@ -414,6 +428,7 @@
      * @return the phone associated with the foreground call
      * of a particular subId
      */
+    @UnsupportedAppUsage
     public Phone getFgPhone(int subId) {
         return getActiveFgCall(subId).getPhone();
     }
@@ -421,6 +436,7 @@
     /**
      * @return the phone associated with the background call
      */
+    @UnsupportedAppUsage
     public Phone getBgPhone() {
         return getFirstActiveBgCall().getPhone();
     }
@@ -428,6 +444,7 @@
     /**
      * @return the phone associated with the ringing call
      */
+    @UnsupportedAppUsage
     public Phone getRingingPhone() {
         return getFirstActiveRingingCall().getPhone();
     }
@@ -515,6 +532,7 @@
     }
     */
 
+    @UnsupportedAppUsage
     private Context getContext() {
         Phone defaultPhone = getDefaultPhone();
         return ((defaultPhone == null) ? null : defaultPhone.getContext());
@@ -686,6 +704,7 @@
      * to the provided subId.
      * @return true if the phone can conference; false otherwise.
      */
+    @UnsupportedAppUsage
     public boolean canConference(Call heldCall, int subId) {
         Phone activePhone = null;
         Phone heldPhone = null;
@@ -710,6 +729,7 @@
      * @exception CallStateException if canConference() would return false.
      * In these cases, this operation may not be performed.
      */
+    @UnsupportedAppUsage
     public void conference(Call heldCall) throws CallStateException {
         int subId  = heldCall.getPhone().getSubId();
 
@@ -858,6 +878,7 @@
      * @param phone
      * @return true if the phone can make a new call
      */
+    @UnsupportedAppUsage
     private boolean canDial(Phone phone) {
         int serviceState = phone.getServiceState().getState();
         int subId = phone.getSubId();
@@ -1148,6 +1169,7 @@
      *  <li>AsyncResult.result = a Connection object that is
      *  no longer connected.</li></ul>
      */
+    @UnsupportedAppUsage
     public void registerForDisconnect(Handler h, int what, Object obj) {
         mDisconnectRegistrants.addUnique(h, what, obj);
     }
@@ -1156,6 +1178,7 @@
      * Unregisters for voice disconnection notification.
      * Extraneous calls are tolerated silently
      */
+    @UnsupportedAppUsage
     public void unregisterForDisconnect(Handler h){
         mDisconnectRegistrants.remove(h);
     }
@@ -1169,6 +1192,7 @@
      * AsyncResult.userData will be set to the obj argument here.
      * The <em>h</em> parameter is held only by a weak reference.
      */
+    @UnsupportedAppUsage
     public void registerForPreciseCallStateChanged(Handler h, int what, Object obj){
         mPreciseCallStateRegistrants.addUnique(h, what, obj);
     }
@@ -1177,6 +1201,7 @@
      * Unregisters for voice call state change notifications.
      * Extraneous calls are tolerated silently.
      */
+    @UnsupportedAppUsage
     public void unregisterForPreciseCallStateChanged(Handler h){
         mPreciseCallStateRegistrants.remove(h);
     }
@@ -1209,6 +1234,7 @@
      *  If Connection.isRinging() is true, then
      *   Connection.getCall() == Phone.getRingingCall()
      */
+    @UnsupportedAppUsage
     public void registerForNewRingingConnection(Handler h, int what, Object obj){
         mNewRingingConnectionRegistrants.addUnique(h, what, obj);
     }
@@ -1218,6 +1244,7 @@
      * Extraneous calls are tolerated silently
      */
 
+    @UnsupportedAppUsage
     public void unregisterForNewRingingConnection(Handler h){
         mNewRingingConnectionRegistrants.remove(h);
     }
@@ -1620,6 +1647,7 @@
     /**
      * @return list of all ringing calls
      */
+    @UnsupportedAppUsage
     public List<Call> getRingingCalls() {
         return Collections.unmodifiableList(mRingingCalls);
     }
@@ -1634,6 +1662,7 @@
     /**
      * @return list of all background calls
      */
+    @UnsupportedAppUsage
     public List<Call> getBackgroundCalls() {
         return Collections.unmodifiableList(mBackgroundCalls);
     }
@@ -1641,6 +1670,7 @@
     /**
      * Return true if there is at least one active foreground call
      */
+    @UnsupportedAppUsage
     public boolean hasActiveFgCall() {
         return (getFirstActiveCall(mForegroundCalls) != null);
     }
@@ -1649,6 +1679,7 @@
      * Return true if there is at least one active foreground call
      * on a particular subId or an active sip call
      */
+    @UnsupportedAppUsage
     public boolean hasActiveFgCall(int subId) {
         return (getFirstActiveCall(mForegroundCalls, subId) != null);
     }
@@ -1656,6 +1687,7 @@
     /**
      * Return true if there is at least one active background call
      */
+    @UnsupportedAppUsage
     public boolean hasActiveBgCall() {
         // TODO since hasActiveBgCall may get called often
         // better to cache it to improve performance
@@ -1666,6 +1698,7 @@
      * Return true if there is at least one active background call
      * on a particular subId or an active sip call
      */
+    @UnsupportedAppUsage
     public boolean hasActiveBgCall(int subId) {
         // TODO since hasActiveBgCall may get called often
         // better to cache it to improve performance
@@ -1683,6 +1716,7 @@
     /**
      * Return true if there is at least one active ringing call
      */
+    @UnsupportedAppUsage
     public boolean hasActiveRingingCall(int subId) {
         return (getFirstActiveCall(mRingingCalls, subId) != null);
     }
@@ -1708,6 +1742,7 @@
         return call;
     }
 
+    @UnsupportedAppUsage
     public Call getActiveFgCall(int subId) {
         Call call = getFirstNonIdleCall(mForegroundCalls, subId);
         if (call == null) {
@@ -1763,6 +1798,7 @@
      *
      * Complete background calls list can be get by getBackgroundCalls()
      */
+    @UnsupportedAppUsage
     public Call getFirstActiveBgCall() {
         Call call = getFirstNonIdleCall(mBackgroundCalls);
         if (call == null) {
@@ -1787,6 +1823,7 @@
      *
      * Complete background calls list can be get by getBackgroundCalls()
      */
+    @UnsupportedAppUsage
     public Call getFirstActiveBgCall(int subId) {
         Phone phone = getPhone(subId);
         if (hasMoreThanOneHoldingCall(subId)) {
@@ -1815,6 +1852,7 @@
      *
      * Complete ringing calls list can be get by getRingingCalls()
      */
+    @UnsupportedAppUsage
     public Call getFirstActiveRingingCall() {
         Call call = getFirstNonIdleCall(mRingingCalls);
         if (call == null) {
@@ -1825,6 +1863,7 @@
         return call;
     }
 
+    @UnsupportedAppUsage
     public Call getFirstActiveRingingCall(int subId) {
         Phone phone = getPhone(subId);
         Call call = getFirstNonIdleCall(mRingingCalls, subId);
@@ -1850,6 +1889,7 @@
         return Call.State.IDLE;
     }
 
+    @UnsupportedAppUsage
     public Call.State getActiveFgCallState(int subId) {
         Call fgCall = getActiveFgCall(subId);
 
@@ -1864,6 +1904,7 @@
      * @return the connections of active foreground call
      * return empty list if there is no active foreground call
      */
+    @UnsupportedAppUsage
     public List<Connection> getFgCallConnections() {
         Call fgCall = getActiveFgCall();
         if ( fgCall != null) {
@@ -1888,6 +1929,7 @@
      * @return the connections of active background call
      * return empty list if there is no active background call
      */
+    @UnsupportedAppUsage
     public List<Connection> getBgCallConnections() {
         Call bgCall = getFirstActiveBgCall();
         if ( bgCall != null) {
@@ -1979,6 +2021,7 @@
         return null;
     }
 
+    @UnsupportedAppUsage
     private boolean hasMoreThanOneRingingCall() {
         int count = 0;
         for (Call call : mRingingCalls) {
@@ -1996,6 +2039,7 @@
      * subId and also active calls on SIP Phone.
      *
      */
+    @UnsupportedAppUsage
     private boolean hasMoreThanOneRingingCall(int subId) {
         int count = 0;
         for (Call call : mRingingCalls) {
diff --git a/src/java/com/android/internal/telephony/CallStateException.java b/src/java/com/android/internal/telephony/CallStateException.java
index a712d95..1356a2b 100644
--- a/src/java/com/android/internal/telephony/CallStateException.java
+++ b/src/java/com/android/internal/telephony/CallStateException.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * {@hide}
  */
@@ -39,6 +41,7 @@
     {
     }
 
+    @UnsupportedAppUsage
     public
     CallStateException(String string)
     {
diff --git a/src/java/com/android/internal/telephony/CallTracker.java b/src/java/com/android/internal/telephony/CallTracker.java
index e48b3e5..c5f7400 100644
--- a/src/java/com/android/internal/telephony/CallTracker.java
+++ b/src/java/com/android/internal/telephony/CallTracker.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -41,13 +42,17 @@
 
     static final int POLL_DELAY_MSEC = 250;
 
+    @UnsupportedAppUsage
     protected int mPendingOperations;
+    @UnsupportedAppUsage
     protected boolean mNeedsPoll;
     protected Message mLastRelevantPoll;
     protected ArrayList<Connection> mHandoverConnections = new ArrayList<Connection>();
 
+    @UnsupportedAppUsage
     public CommandsInterface mCi;
 
+    @UnsupportedAppUsage
     protected boolean mNumberConverted = false;
     private final int VALID_COMPARE_LENGTH   = 3;
 
@@ -291,9 +296,12 @@
     public abstract void handleMessage (Message msg);
     public abstract void registerForVoiceCallStarted(Handler h, int what, Object obj);
     public abstract void unregisterForVoiceCallStarted(Handler h);
+    @UnsupportedAppUsage
     public abstract void registerForVoiceCallEnded(Handler h, int what, Object obj);
     public abstract void unregisterForVoiceCallEnded(Handler h);
+    @UnsupportedAppUsage
     public abstract PhoneConstants.State getState();
+    @UnsupportedAppUsage
     protected abstract void log(String msg);
 
     /**
diff --git a/src/java/com/android/internal/telephony/CarrierResolver.java b/src/java/com/android/internal/telephony/CarrierResolver.java
index 9f96c67..60233f9 100644
--- a/src/java/com/android/internal/telephony/CarrierResolver.java
+++ b/src/java/com/android/internal/telephony/CarrierResolver.java
@@ -45,7 +45,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * CarrierResolver identifies the subscription carrier and returns a canonical carrier Id
@@ -71,15 +70,15 @@
     private List<CarrierMatchingRule> mCarrierMatchingRulesOnMccMnc = new ArrayList<>();
     // cached carrier Id
     private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
-    // cached precise carrier Id
-    private int mPreciseCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+    // cached specific carrier Id
+    private int mSpecificCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
     // cached MNO carrier Id. mno carrier shares the same mccmnc as cid and can be solely
     // identified by mccmnc only. If there is no such mno carrier, mno carrier id equals to
     // the cid.
     private int mMnoCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
     // cached carrier name
     private String mCarrierName;
-    private String mPreciseCarrierName;
+    private String mSpecificCarrierName;
     // cached preferapn name
     private String mPreferApn;
     // cached service provider name. telephonyManager API returns empty string as default value.
@@ -350,7 +349,7 @@
     }
 
     private void updateCarrierIdAndName(int cid, String name,
-                                        int preciseCarrierId, String preciseCarrierName,
+                                        int specificCarrierId, String specificCarrierName,
                                         int mnoCid) {
         boolean update = false;
         if (!equals(name, mCarrierName, true)) {
@@ -391,34 +390,34 @@
         }
 
         update = false;
-        if (preciseCarrierId != mPreciseCarrierId) {
-            logd("[updatePreciseCarrierId] from:" + mPreciseCarrierId + " to:"
-                    + preciseCarrierId);
-            mPreciseCarrierId = preciseCarrierId;
+        if (specificCarrierId != mSpecificCarrierId) {
+            logd("[updateSpecificCarrierId] from:" + mSpecificCarrierId + " to:"
+                    + specificCarrierId);
+            mSpecificCarrierId = specificCarrierId;
             update = true;
         }
-        if (preciseCarrierName != mPreciseCarrierName) {
-            logd("[updatePreciseCarrierName] from:" + mPreciseCarrierName + " to:"
-                    + preciseCarrierName);
-            mPreciseCarrierName = preciseCarrierName;
+        if (specificCarrierName != mSpecificCarrierName) {
+            logd("[updateSpecificCarrierName] from:" + mSpecificCarrierName + " to:"
+                    + specificCarrierName);
+            mSpecificCarrierName = specificCarrierName;
             update = true;
         }
         if (update) {
-            mCarrierIdLocalLog.log("[updatePreciseCarrierIdAndName] cid:" + mPreciseCarrierId
-                    + " name:" + mPreciseCarrierName);
+            mCarrierIdLocalLog.log("[updateSpecificCarrierIdAndName] cid:"
+                    + mSpecificCarrierId + " name:" + mSpecificCarrierName);
             final Intent intent = new Intent(TelephonyManager
-                    .ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED);
-            intent.putExtra(TelephonyManager.EXTRA_PRECISE_CARRIER_ID, mPreciseCarrierId);
-            intent.putExtra(TelephonyManager.EXTRA_PRECISE_CARRIER_NAME, mPreciseCarrierName);
+                    .ACTION_SUBSCRIPTION_SPECIFIC_CARRIER_IDENTITY_CHANGED);
+            intent.putExtra(TelephonyManager.EXTRA_SPECIFIC_CARRIER_ID, mSpecificCarrierId);
+            intent.putExtra(TelephonyManager.EXTRA_SPECIFIC_CARRIER_NAME, mSpecificCarrierName);
             intent.putExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID, mPhone.getSubId());
             mContext.sendBroadcast(intent);
 
-            // notify content observers for precise carrier id change event.
+            // notify content observers for specific carrier id change event.
             ContentValues cv = new ContentValues();
-            cv.put(CarrierId.PRECISE_CARRIER_ID, mPreciseCarrierId);
-            cv.put(CarrierId.PRECISE_CARRIER_ID_NAME, mPreciseCarrierName);
+            cv.put(CarrierId.SPECIFIC_CARRIER_ID, mSpecificCarrierId);
+            cv.put(CarrierId.SPECIFIC_CARRIER_ID_NAME, mSpecificCarrierName);
             mContext.getContentResolver().update(
-                    Telephony.CarrierId.getPreciseCarrierIdUriForSubscriptionId(mPhone.getSubId()),
+                    Telephony.CarrierId.getSpecificCarrierIdUriForSubscriptionId(mPhone.getSubId()),
                     cv, null, null);
         }
     }
@@ -742,8 +741,8 @@
                 maxRuleParent.mCid = maxRuleParent.mParentCid;
                 maxRuleParent.mName = getCarrierNameFromId(maxRuleParent.mCid);
             }
-            logd("[matchSubscriptionCarrier] precise cid: " + maxRule.mCid + " precise name: "
-                    + maxRule.mName +" cid: " + maxRuleParent.mCid
+            logd("[matchSubscriptionCarrier] specific cid: " + maxRule.mCid
+                    + " specific name: " + maxRule.mName +" cid: " + maxRuleParent.mCid
                     + " name: " + maxRuleParent.mName);
             updateCarrierIdAndName(maxRuleParent.mCid, maxRuleParent.mName,
                     maxRule.mCid, maxRule.mName,
@@ -783,25 +782,29 @@
     }
     /**
      * Returns fine-grained carrier id of the current subscription. Carrier ids with a valid parent
-     * id are precise carrier ids.
-     * The precise carrier id can be used to further differentiate a carrier by different
-     * networks, by prepaid v.s.postpaid or even by 4G v.s.3G plan. Each carrier has a unique
-     * carrier id but can have multiple precise carrier id. e.g,
-     * {@link #getCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM, while
-     * {@link #getPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based on the
-     * current underlying network.
+     * id are specific carrier ids.
+     *
+     * A specific carrier ID can represent the fact that a carrier may be in effect an aggregation
+     * of other carriers (ie in an MVNO type scenario) where each of these specific carriers which
+     * are used to make up the actual carrier service may have different carrier configurations.
+     * A specific carrier ID could also be used, for example, in a scenario where a carrier requires
+     * different carrier configuration for different service offering such as a prepaid plan.
+     * e.g, {@link #getCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM, while
+     * {@link #getSpecificCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based on the
+     * IMSI from the current subscription.
+     *
      * For carriers without any fine-grained carrier ids, return {@link #getCarrierId()}
      */
-    public int getPreciseCarrierId() {
-        return mPreciseCarrierId;
+    public int getSpecificCarrierId() {
+        return mSpecificCarrierId;
     }
 
     public String getCarrierName() {
         return mCarrierName;
     }
 
-    public String getPreciseCarrierName() {
-        return mPreciseCarrierName;
+    public String getSpecificCarrierName() {
+        return mSpecificCarrierName;
     }
 
     public int getMnoCarrierId() {
@@ -963,10 +966,10 @@
         ipw.decreaseIndent();
 
         ipw.println("mCarrierId: " + mCarrierId);
-        ipw.println("mPreciseCarrierId: " + mPreciseCarrierId);
+        ipw.println("mSpecificCarrierId: " + mSpecificCarrierId);
         ipw.println("mMnoCarrierId: " + mMnoCarrierId);
         ipw.println("mCarrierName: " + mCarrierName);
-        ipw.println("mPreciseCarrierName: " + mPreciseCarrierName);
+        ipw.println("mSpecificCarrierName: " + mSpecificCarrierName);
         ipw.println("carrier_list_version: " + getCarrierListVersion());
 
         ipw.println("mCarrierMatchingRules on mccmnc: "
diff --git a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
index d2f0a16..7f6887d 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -56,6 +57,7 @@
      */
     private static final int UNBIND_DELAY_MILLIS = 30 * 1000; // 30 seconds
 
+    @UnsupportedAppUsage
     private Context mContext;
     private AppBinding[] mBindings;
     private String[] mLastSimState;
@@ -80,6 +82,7 @@
     private static final int EVENT_REBIND = 0;
     private static final int EVENT_PERFORM_IMMEDIATE_UNBIND = 1;
 
+    @UnsupportedAppUsage
     private Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
diff --git a/src/java/com/android/internal/telephony/CellularNetworkService.java b/src/java/com/android/internal/telephony/CellularNetworkService.java
index ee10023..37f302c 100644
--- a/src/java/com/android/internal/telephony/CellularNetworkService.java
+++ b/src/java/com/android/internal/telephony/CellularNetworkService.java
@@ -23,8 +23,8 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CellIdentity;
 import android.telephony.CellIdentityCdma;
 import android.telephony.CellIdentityGsm;
@@ -71,7 +71,7 @@
         CellularNetworkServiceProvider(int slotId) {
             super(slotId);
 
-            mPhone = PhoneFactory.getPhone(getSlotId());
+            mPhone = PhoneFactory.getPhone(getSlotIndex());
 
             mHandlerThread = new HandlerThread(CellularNetworkService.class.getSimpleName());
             mHandlerThread.start();
@@ -210,7 +210,7 @@
         }
 
         private NetworkRegistrationState createRegistrationStateFromVoiceRegState(Object result) {
-            int transportType = TransportType.WWAN;
+            int transportType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
             int domain = NetworkRegistrationState.DOMAIN_CS;
 
             if (result instanceof android.hardware.radio.V1_0.VoiceRegStateResult) {
@@ -260,7 +260,7 @@
 
         private NetworkRegistrationState createRegistrationStateFromDataRegState(Object result) {
             int domain = NetworkRegistrationState.DOMAIN_PS;
-            int transportType = TransportType.WWAN;
+            int transportType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
 
             if (result instanceof android.hardware.radio.V1_0.DataRegStateResult) {
                 android.hardware.radio.V1_0.DataRegStateResult dataRegState =
@@ -488,13 +488,13 @@
     }
 
     @Override
-    protected NetworkServiceProvider createNetworkServiceProvider(int slotId) {
-        if (DBG) log("Cellular network service created for slot " + slotId);
-        if (!SubscriptionManager.isValidSlotIndex(slotId)) {
-            loge("Tried to Cellular network service with invalid slotId " + slotId);
+    public NetworkServiceProvider onCreateNetworkServiceProvider(int slotIndex) {
+        if (DBG) log("Cellular network service created for slot " + slotIndex);
+        if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
+            loge("Tried to Cellular network service with invalid slotId " + slotIndex);
             return null;
         }
-        return new CellularNetworkServiceProvider(slotId);
+        return new CellularNetworkServiceProvider(slotIndex);
     }
 
     private void log(String s) {
diff --git a/src/java/com/android/internal/telephony/CellularNetworkValidator.java b/src/java/com/android/internal/telephony/CellularNetworkValidator.java
new file mode 100644
index 0000000..e88949b
--- /dev/null
+++ b/src/java/com/android/internal/telephony/CellularNetworkValidator.java
@@ -0,0 +1,250 @@
+/*
+ * 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 android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.os.Handler;
+import android.telephony.SubscriptionManager;
+import android.util.Log;
+
+import com.android.internal.telephony.metrics.TelephonyMetrics;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent;
+
+/**
+ * This class will validate whether cellular network verified by Connectivity's
+ * validation process. It listens request on a specific subId, sends a network request
+ * to Connectivity and listens to its callback or timeout.
+ */
+public class CellularNetworkValidator {
+    private static final String LOG_TAG = "NetworkValidator";
+
+    // States of validator. Only one validation can happen at once.
+    // IDLE: no validation going on.
+    private static final int STATE_IDLE                = 0;
+    // VALIDATING: validation going on.
+    private static final int STATE_VALIDATING          = 1;
+    // VALIDATED: validation is done and successful.
+    // Waiting for stopValidation() to release
+    // validationg NetworkRequest.
+    private static final int STATE_VALIDATED           = 2;
+
+    // Singleton instance.
+    private static CellularNetworkValidator sInstance;
+
+    private int mState = STATE_IDLE;
+    private int mSubId;
+    private int mTimeoutInMs;
+    private boolean mReleaseAfterValidation;
+
+    private NetworkRequest mNetworkRequest;
+    private ValidationCallback mValidationCallback;
+    private Context mContext;
+    private ConnectivityManager mConnectivityManager;
+    private Handler mHandler = new Handler();
+    private ConnectivityNetworkCallback mNetworkCallback;
+
+    /**
+     * Callback to pass in when starting validation.
+     */
+    public interface ValidationCallback {
+        /**
+         * Validation failed, passed or timed out.
+         */
+        void onValidationResult(boolean validated, int subId);
+    }
+
+    /**
+     * Create instance.
+     */
+    public static CellularNetworkValidator make(Context context) {
+        if (sInstance != null) {
+            logd("createCellularNetworkValidator failed. Instance already exists.");
+        } else {
+            sInstance = new CellularNetworkValidator(context);
+        }
+
+        return sInstance;
+    }
+
+    /**
+     * Get instance.
+     */
+    public static CellularNetworkValidator getInstance() {
+        return sInstance;
+    }
+
+    /**
+     * Check whether this feature is supported or not.
+     */
+    public static boolean isValidationFeatureSupported() {
+        return PhoneConfigurationManager.getInstance().getCurrentPhoneCapability()
+                .validationBeforeSwitchSupported;
+    }
+
+    private CellularNetworkValidator(Context context) {
+        mContext = context;
+        mConnectivityManager = (ConnectivityManager)
+                mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    /**
+     * API to start a validation
+     */
+    public synchronized void validate(int subId, int timeoutInMs,
+            boolean releaseAfterValidation, ValidationCallback callback) {
+        // If it's already validating the same subscription, do nothing.
+        if (subId == mSubId) return;
+
+        Phone phone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
+        if (phone == null) {
+            logd("Failed to start validation. Inactive subId " + subId);
+            callback.onValidationResult(false, subId);
+            return;
+        }
+
+        if (isValidating()) {
+            stopValidation();
+        }
+
+        mState = STATE_VALIDATING;
+        mSubId = subId;
+        mTimeoutInMs = timeoutInMs;
+        mValidationCallback = callback;
+        mReleaseAfterValidation = releaseAfterValidation;
+        mNetworkRequest = createNetworkRequest();
+
+        logd("Start validating subId " + mSubId + " mTimeoutInMs " + mTimeoutInMs
+                + " mReleaseAfterValidation " + mReleaseAfterValidation);
+
+        mNetworkCallback = new ConnectivityNetworkCallback(subId);
+
+        mConnectivityManager.requestNetwork(
+                mNetworkRequest, mNetworkCallback, mHandler, mTimeoutInMs);
+    }
+
+    /**
+     * API to stop the current validation.
+     */
+    public synchronized void stopValidation() {
+        if (!isValidating()) {
+            logd("No need to stop validation.");
+        } else {
+            mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+            mState = STATE_IDLE;
+        }
+        mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    }
+
+    /**
+     * Return which subscription is under validating.
+     */
+    public synchronized int getSubIdInValidation() {
+        return mSubId;
+    }
+
+    /**
+     * Return whether there's an ongoing validation.
+     */
+    public synchronized boolean isValidating() {
+        return mState != STATE_IDLE;
+    }
+
+    private NetworkRequest createNetworkRequest() {
+        return new NetworkRequest.Builder()
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+                .setNetworkSpecifier(String.valueOf(mSubId))
+                .build();
+    }
+
+    private synchronized void reportValidationResult(boolean passed, int subId) {
+        // If the validation result is not for current subId, do nothing.
+        if (mSubId != subId) return;
+
+        // Deal with the result only when state is still VALIDATING. This is to avoid
+        // receiving multiple callbacks in queue.
+        if (mState == STATE_VALIDATING) {
+            mValidationCallback.onValidationResult(passed, mSubId);
+            if (!mReleaseAfterValidation && passed) {
+                mState = STATE_VALIDATED;
+            } else {
+                mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+                mState = STATE_IDLE;
+            }
+
+            TelephonyMetrics.getInstance().writeNetworkValidate(passed
+                    ? TelephonyEvent.NetworkValidationState.NETWORK_VALIDATION_STATE_PASSED
+                    : TelephonyEvent.NetworkValidationState.NETWORK_VALIDATION_STATE_FAILED);
+        }
+
+        mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    }
+
+    class ConnectivityNetworkCallback extends ConnectivityManager.NetworkCallback {
+        private final int mSubId;
+
+        ConnectivityNetworkCallback(int subId) {
+            mSubId = subId;
+        }
+        /**
+         * ConnectivityManager.NetworkCallback implementation
+         */
+        @Override
+        public void onAvailable(Network network) {
+            logd("network onAvailable " + network);
+            if (ConnectivityNetworkCallback.this.mSubId == CellularNetworkValidator.this.mSubId) {
+                TelephonyMetrics.getInstance().writeNetworkValidate(
+                        TelephonyEvent.NetworkValidationState.NETWORK_VALIDATION_STATE_AVAILABLE);
+            }
+        }
+
+        @Override
+        public void onLosing(Network network, int maxMsToLive) {
+            logd("network onLosing " + network + " maxMsToLive " + maxMsToLive);
+            reportValidationResult(false, ConnectivityNetworkCallback.this.mSubId);
+        }
+
+        @Override
+        public void onLost(Network network) {
+            logd("network onLost " + network);
+            reportValidationResult(false, ConnectivityNetworkCallback.this.mSubId);
+        }
+
+        @Override
+        public void onUnavailable() {
+            logd("onUnavailable");
+            reportValidationResult(false, ConnectivityNetworkCallback.this.mSubId);
+        }
+
+        @Override
+        public void onCapabilitiesChanged(Network network,
+                NetworkCapabilities networkCapabilities) {
+            if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
+                logd("onValidated");
+                reportValidationResult(true, ConnectivityNetworkCallback.this.mSubId);
+            }
+        }
+    }
+
+    private static void logd(String log) {
+        Log.d(LOG_TAG, log);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/CommandException.java b/src/java/com/android/internal/telephony/CommandException.java
index fe9fa72..4642d90 100644
--- a/src/java/com/android/internal/telephony/CommandException.java
+++ b/src/java/com/android/internal/telephony/CommandException.java
@@ -16,24 +16,32 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 /**
  * {@hide}
  */
 public class CommandException extends RuntimeException {
+    @UnsupportedAppUsage
     private Error mError;
 
     public enum Error {
         INVALID_RESPONSE,
+        @UnsupportedAppUsage
         RADIO_NOT_AVAILABLE,
+        @UnsupportedAppUsage
         GENERIC_FAILURE,
+        @UnsupportedAppUsage
         PASSWORD_INCORRECT,
         SIM_PIN2,
+        @UnsupportedAppUsage
         SIM_PUK2,
+        @UnsupportedAppUsage
         REQUEST_NOT_SUPPORTED,
         OP_NOT_ALLOWED_DURING_VOICE_CALL,
         OP_NOT_ALLOWED_BEFORE_REG_NW,
+        @UnsupportedAppUsage
         SMS_FAIL_RETRY,
         SIM_ABSENT,
         SUBSCRIPTION_NOT_AVAILABLE,
@@ -117,6 +125,7 @@
         OEM_ERROR_25,
     }
 
+    @UnsupportedAppUsage
     public CommandException(Error e) {
         super(e.toString());
         mError = e;
@@ -127,6 +136,7 @@
         mError = e;
     }
 
+    @UnsupportedAppUsage
     public static CommandException
     fromRilErrno(int ril_errno) {
         switch(ril_errno) {
@@ -318,6 +328,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public Error getCommandError() {
         return mError;
     }
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index 73b0e7d..7f3174d 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.net.KeepalivePacketData;
 import android.net.LinkProperties;
 import android.os.Handler;
@@ -30,7 +31,6 @@
 import android.telephony.emergency.EmergencyNumber;
 
 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
-import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
 import com.android.internal.telephony.uicc.IccCardStatus;
 
@@ -137,11 +137,14 @@
      * on previous invocations of this notification. Instead, use the other
      * registration methods
      */
+    @UnsupportedAppUsage
     void registerForRadioStateChanged(Handler h, int what, Object obj);
     void unregisterForRadioStateChanged(Handler h);
 
     void registerForVoiceRadioTechChanged(Handler h, int what, Object obj);
+    @UnsupportedAppUsage
     void unregisterForVoiceRadioTechChanged(Handler h);
+    @UnsupportedAppUsage
     void registerForImsNetworkStateChanged(Handler h, int what, Object obj);
     void unregisterForImsNetworkStateChanged(Handler h);
 
@@ -151,7 +154,9 @@
      * In general, actions should be idempotent. State may change
      * before event is received.
      */
+    @UnsupportedAppUsage
     void registerForOn(Handler h, int what, Object obj);
+    @UnsupportedAppUsage
     void unregisterForOn(Handler h);
 
     /**
@@ -160,7 +165,9 @@
      * In general, actions should be idempotent. State may change
      * before event is received.
      */
+    @UnsupportedAppUsage
     void registerForAvailable(Handler h, int what, Object obj);
+    @UnsupportedAppUsage
     void unregisterForAvailable(Handler h);
 
     /**
@@ -169,6 +176,7 @@
      * In general, actions should be idempotent. State may change
      * before event is received.
      */
+    @UnsupportedAppUsage
     void registerForNotAvailable(Handler h, int what, Object obj);
     void unregisterForNotAvailable(Handler h);
 
@@ -178,7 +186,9 @@
      * In general, actions should be idempotent. State may change
      * before event is received.
      */
+    @UnsupportedAppUsage
     void registerForOffOrNotAvailable(Handler h, int what, Object obj);
+    @UnsupportedAppUsage
     void unregisterForOffOrNotAvailable(Handler h);
 
     /**
@@ -253,6 +263,7 @@
      *
      * AsyncResult.result is a byte array containing the SMS-CB PDU
      */
+    @UnsupportedAppUsage
     void setOnNewGsmBroadcastSms(Handler h, int what, Object obj);
     void unSetOnNewGsmBroadcastSms(Handler h);
 
@@ -261,6 +272,7 @@
      *
      * AsyncResult.result is an int array containing the index of new SMS
      */
+    @UnsupportedAppUsage
     void setOnSmsOnSim(Handler h, int what, Object obj);
     void unSetOnSmsOnSim(Handler h);
 
@@ -269,6 +281,7 @@
      *
      * AsyncResult.result is a String containing the status report PDU
      */
+    @UnsupportedAppUsage
     void setOnSmsStatus(Handler h, int what, Object obj);
     void unSetOnSmsStatus(Handler h);
 
@@ -284,6 +297,7 @@
      * Please note that the delivery of this message may be delayed several
      * seconds on system startup
      */
+    @UnsupportedAppUsage
     void setOnNITZTime(Handler h, int what, Object obj);
     void unSetOnNITZTime(Handler h);
 
@@ -317,6 +331,7 @@
      * as defined in TS 27.007 8.5
      */
 
+    @UnsupportedAppUsage
     void setOnSignalStrengthUpdate(Handler h, int what, Object obj);
     void unSetOnSignalStrengthUpdate(Handler h);
 
@@ -328,6 +343,7 @@
      * @param what User-defined message code.
      * @param obj User object.
      */
+    @UnsupportedAppUsage
     void setOnIccSmsFull(Handler h, int what, Object obj);
     void unSetOnIccSmsFull(Handler h);
 
@@ -338,9 +354,11 @@
      * @param what User-defined message code.
      * @param obj User object.
      */
+    @UnsupportedAppUsage
     void registerForIccRefresh(Handler h, int what, Object obj);
     void unregisterForIccRefresh(Handler h);
 
+    @UnsupportedAppUsage
     void setOnIccRefresh(Handler h, int what, Object obj);
     void unsetOnIccRefresh(Handler h);
 
@@ -352,6 +370,7 @@
      * @param what User-defined message code.
      * @param obj User object.
      */
+    @UnsupportedAppUsage
     void setOnCallRing(Handler h, int what, Object obj);
     void unSetOnCallRing(Handler h);
 
@@ -375,6 +394,7 @@
      * @param what User-defined message code.
      * @param obj User object.
      */
+    @UnsupportedAppUsage
     void setOnSuppServiceNotification(Handler h, int what, Object obj);
     void unSetOnSuppServiceNotification(Handler h);
 
@@ -386,6 +406,7 @@
      * @param what User-defined message code.
      * @param obj User object.
      */
+    @UnsupportedAppUsage
     void setOnCatSessionEnd(Handler h, int what, Object obj);
     void unSetOnCatSessionEnd(Handler h);
 
@@ -397,6 +418,7 @@
      * @param what User-defined message code.
      * @param obj User object.
      */
+    @UnsupportedAppUsage
     void setOnCatProactiveCmd(Handler h, int what, Object obj);
     void unSetOnCatProactiveCmd(Handler h);
 
@@ -408,6 +430,7 @@
      * @param what User-defined message code.
      * @param obj User object.
      */
+    @UnsupportedAppUsage
     void setOnCatEvent(Handler h, int what, Object obj);
     void unSetOnCatEvent(Handler h);
 
@@ -419,6 +442,7 @@
      * @param what User-defined message code.
      * @param obj User object.
      */
+    @UnsupportedAppUsage
     void setOnCatCallSetUp(Handler h, int what, Object obj);
     void unSetOnCatCallSetUp(Handler h);
 
@@ -440,6 +464,7 @@
      * @param what User-defined message code.
      * @param obj User object.
      */
+    @UnsupportedAppUsage
     void setOnCatCcAlphaNotify(Handler h, int what, Object obj);
     void unSetOnCatCcAlphaNotify(Handler h);
 
@@ -546,12 +571,15 @@
     /**
      * Fires on if Modem enters Emergency Callback mode
      */
+    @UnsupportedAppUsage
     void setEmergencyCallbackMode(Handler h, int what, Object obj);
 
      /**
       * Fires on any CDMA OTA provision status change
       */
+     @UnsupportedAppUsage
      void registerForCdmaOtaProvision(Handler h,int what, Object obj);
+     @UnsupportedAppUsage
      void unregisterForCdmaOtaProvision(Handler h);
 
      /**
@@ -621,7 +649,9 @@
       * @param what User-defined message code.
       * @param obj User object.
       */
+     @UnsupportedAppUsage
      void registerForRilConnected(Handler h, int what, Object obj);
+     @UnsupportedAppUsage
      void unregisterForRilConnected(Handler h);
 
     /**
@@ -639,6 +669,7 @@
      * ar.exception and ar.result are null on success
      */
 
+    @UnsupportedAppUsage
     void supplyIccPin(String pin, Message result);
 
     /**
@@ -781,6 +812,7 @@
     void changeIccPin2(String oldPin2, String newPin2, Message result);
     void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result);
 
+    @UnsupportedAppUsage
     void changeBarringPassword(String facility, String oldPwd, String newPwd, Message result);
 
     void supplyNetworkDepersonalization(String netpin, Message result);
@@ -803,6 +835,7 @@
      *  ar.result contains a List of DataCallResponse
      *  @deprecated Do not use.
      */
+    @UnsupportedAppUsage
     @Deprecated
     void getPDPContextList(Message result);
 
@@ -813,6 +846,7 @@
      *  ar.userObject contains the orignal value of result.obj
      *  ar.result contains a List of DataCallResponse
      */
+    @UnsupportedAppUsage
     void getDataCallList(Message result);
 
     /**
@@ -827,7 +861,7 @@
      * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
      */
     void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-              int clirMode, Message result);
+              boolean hasKnownUserIntentEmergency, int clirMode, Message result);
 
     /**
      *  returned message
@@ -841,7 +875,7 @@
      * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
      */
     void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-              int clirMode, UUSInfo uusInfo, Message result);
+              boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo, Message result);
 
     /**
      *  returned message
@@ -850,6 +884,7 @@
      *  ar.userObject contains the orignal value of result.obj
      *  ar.result is String containing IMSI on success
      */
+    @UnsupportedAppUsage
     void getIMSI(Message result);
 
     /**
@@ -877,6 +912,7 @@
      *  ar.userObject contains the orignal value of result.obj
      *  ar.result is String containing IMEISV on success
      */
+    @UnsupportedAppUsage
     void getIMEISV(Message result);
 
     /**
@@ -922,6 +958,7 @@
      *  ar.userObject contains the orignal value of result.obj
      *  ar.result is null on success and failure
      */
+    @UnsupportedAppUsage
     void switchWaitingOrHoldingAndActive (Message result);
 
     /**
@@ -962,6 +999,7 @@
      *  ar.userObject contains the orignal value of result.obj
      *  ar.result is null on success and failure
      */
+    @UnsupportedAppUsage
     void acceptCall (Message result);
 
     /**
@@ -1000,6 +1038,7 @@
      * section 6.1.3.1.3 or close approximation
      * @deprecated Do not use.
      */
+    @UnsupportedAppUsage
     @Deprecated
     void getLastPdpFailCause (Message result);
 
@@ -1007,6 +1046,7 @@
      * The preferred new alternative to getLastPdpFailCause
      * that is also CDMA-compatible.
      */
+    @UnsupportedAppUsage
     void getLastDataCallFailCause (Message result);
 
     void setMute (boolean enableMute, Message response);
@@ -1020,6 +1060,7 @@
      * response.obj.result[1] is  bit error rate (0-7, 99)
      * as defined in TS 27.007 8.5
      */
+    @UnsupportedAppUsage
     void getSignalStrength (Message response);
 
 
@@ -1033,6 +1074,7 @@
      * Please note that registration state 4 ("unknown") is treated
      * as "out of service" above
      */
+    @UnsupportedAppUsage
     void getVoiceRegistrationState (Message response);
 
     /**
@@ -1053,6 +1095,7 @@
      * response.obj.result[1] is short alpha or null if unregistered
      * response.obj.result[2] is numeric or null if unregistered
      */
+    @UnsupportedAppUsage
     void getOperator(Message response);
 
     /**
@@ -1060,6 +1103,7 @@
      *  ar.userObject contains the orignal value of result.obj
      *  ar.result is null on success and failure
      */
+    @UnsupportedAppUsage
     void sendDtmf(char c, Message result);
 
 
@@ -1139,6 +1183,7 @@
      * @param index index of the SMS record to delete
      * @param response sent when operation completes
      */
+    @UnsupportedAppUsage
     void deleteSmsOnSim(int index, Message response);
 
     /**
@@ -1147,6 +1192,7 @@
      * @param index index of the SMS record to delete
      * @param response sent when operation completes
      */
+    @UnsupportedAppUsage
     void deleteSmsOnRuim(int index, Message response);
 
     /**
@@ -1162,14 +1208,19 @@
      *                  response.obj will be an AsyncResult, and will indicate
      *                  any error that may have occurred (eg, out of memory).
      */
+    @UnsupportedAppUsage
     void writeSmsToSim(int status, String smsc, String pdu, Message response);
 
+    @UnsupportedAppUsage
     void writeSmsToRuim(int status, String pdu, Message response);
 
+    @UnsupportedAppUsage
     void setRadioPower(boolean on, Message response);
 
+    @UnsupportedAppUsage
     void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message response);
 
+    @UnsupportedAppUsage
     void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response);
 
     /**
@@ -1188,6 +1239,7 @@
      * response.obj will be an AsyncResult
      * response.obj.result will be an IccIoResult on success
      */
+    @UnsupportedAppUsage
     void iccIO (int command, int fileid, String path, int p1, int p2, int p3,
             String data, String pin2, Message response);
 
@@ -1196,6 +1248,7 @@
      * response.obj will be an AsyncResult
      * response.obj.userObj will be a IccIoResult on success
      */
+    @UnsupportedAppUsage
     void iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3,
             String data, String pin2, String aid, Message response);
 
@@ -1242,6 +1295,7 @@
      * @param response is callback message
      */
 
+    @UnsupportedAppUsage
     void queryCallWaiting(int serviceClass, Message response);
 
     /**
@@ -1250,6 +1304,7 @@
      * @param response is callback message
      */
 
+    @UnsupportedAppUsage
     void setCallWaiting(boolean enable, int serviceClass, Message response);
 
     /**
@@ -1257,6 +1312,7 @@
      * @param cfReason is one of CF_REASON_*
      * @param serviceClass is a sum of SERVICE_CLASSS_*
      */
+    @UnsupportedAppUsage
     void setCallForward(int action, int cfReason, int serviceClass,
                 String number, int timeSeconds, Message response);
 
@@ -1268,11 +1324,14 @@
      *
      * An array of length 0 means "disabled for all codes"
      */
+    @UnsupportedAppUsage
     void queryCallForwardStatus(int cfReason, int serviceClass,
             String number, Message response);
 
+    @UnsupportedAppUsage
     void setNetworkSelectionModeAutomatic(Message response);
 
+    @UnsupportedAppUsage
     void setNetworkSelectionModeManual(String operatorNumeric, Message response);
 
     /**
@@ -1283,6 +1342,7 @@
      * a 0 for automatic selection and a 1 for manual selection
      */
 
+    @UnsupportedAppUsage
     void getNetworkSelectionMode(Message response);
 
     /**
@@ -1310,6 +1370,7 @@
     /**
      * Gets the baseband version
      */
+    @UnsupportedAppUsage
     void getBasebandVersion(Message response);
 
     /**
@@ -1322,6 +1383,7 @@
      * @param response is callback message
      */
 
+    @UnsupportedAppUsage
     void queryFacilityLock (String facility, String password, int serviceClass,
         Message response);
 
@@ -1347,6 +1409,7 @@
      * @param serviceClass is a sum of SERVICE_CLASS_*
      * @param response is callback message
      */
+    @UnsupportedAppUsage
     void setFacilityLock (String facility, boolean lockState, String password,
         int serviceClass, Message response);
 
@@ -1397,6 +1460,7 @@
      * @param networkType one of  NT_*_TYPE
      * @param response is callback message
      */
+    @UnsupportedAppUsage
     void setPreferredNetworkType(int networkType , Message response);
 
      /**
@@ -1404,6 +1468,7 @@
      *
      * @param response is callback message to report one of  NT_*_TYPE
      */
+    @UnsupportedAppUsage
     void getPreferredNetworkType(Message response);
 
     /**
@@ -1420,6 +1485,7 @@
      *
      * @param result Callback message contains the SMSC address.
      */
+    @UnsupportedAppUsage
     void getSmscAddress(Message result);
 
     /**
@@ -1428,6 +1494,7 @@
      * @param address new SMSC address
      * @param result Callback message is empty on completion
      */
+    @UnsupportedAppUsage
     void setSmscAddress(String address, Message result);
 
     /**
@@ -1435,6 +1502,7 @@
      * @param available true if storage is available
      * @param result callback message
      */
+    @UnsupportedAppUsage
     void reportSmsMemoryStatus(boolean available, Message result);
 
     /**
@@ -1443,8 +1511,10 @@
      *
      * @param result callback message
      */
+    @UnsupportedAppUsage
     void reportStkServiceIsRunning(Message result);
 
+    @UnsupportedAppUsage
     void invokeOemRilRequestRaw(byte[] data, Message response);
 
     /**
@@ -1476,6 +1546,7 @@
      *                  TS 102 223 for details.
      * @param response  Callback message
      */
+    @UnsupportedAppUsage
     public void sendTerminalResponse(String contents, Message response);
 
     /**
@@ -1487,6 +1558,7 @@
      *                  details.
      * @param response  Callback message
      */
+    @UnsupportedAppUsage
     public void sendEnvelope(String contents, Message response);
 
     /**
@@ -1511,6 +1583,7 @@
      * @param accept   true if the call is to be accepted, false otherwise.
      * @param response Callback message
      */
+    @UnsupportedAppUsage
     public void handleCallSetupRequestFromSim(boolean accept, Message response);
 
     /**
@@ -1560,6 +1633,7 @@
      *       if CDMA subscription is available
      *   [3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available
      */
+    @UnsupportedAppUsage
     public void getCDMASubscription(Message response);
 
     /**
@@ -1570,6 +1644,7 @@
     public void sendCDMAFeatureCode(String FeatureCode, Message response);
 
     /** Set the Phone type created */
+    @UnsupportedAppUsage
     void setPhoneType(int phoneType);
 
     /**
@@ -1609,6 +1684,7 @@
      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
      * @param response is callback message
      */
+    @UnsupportedAppUsage
     void setTTYMode(int ttyMode, Message response);
 
     /**
@@ -1621,6 +1697,7 @@
      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
      * @param response is callback message
      */
+    @UnsupportedAppUsage
     void queryTTYMode(Message response);
 
     /**
@@ -1667,6 +1744,7 @@
      * @param result
      *            Callback message is empty on completion
      */
+    @UnsupportedAppUsage
     public void setCdmaBroadcastActivation(boolean activate, Message result);
 
     /**
@@ -1683,6 +1761,7 @@
      * @param result
      *            Callback message contains the configuration from the modem on completion
      */
+    @UnsupportedAppUsage
     public void getCdmaBroadcastConfig(Message result);
 
     /**
@@ -1691,6 +1770,7 @@
      *
      * @param response callback message
      */
+    @UnsupportedAppUsage
     public void exitEmergencyCallbackMode(Message response);
 
     /**
@@ -1699,6 +1779,7 @@
      * @param result
      *          Callback message containing {@link IccCardStatus} structure for the card.
      */
+    @UnsupportedAppUsage
     public void getIccCardStatus(Message result);
 
     /**
@@ -1740,6 +1821,7 @@
      *            102.221 8.1 and 101.220 4
      * @param response a callback message with the String response in the obj field
      */
+    @UnsupportedAppUsage
     public void requestIccSimAuthentication(int authContext, String data, String aid, Message response);
 
     /**
@@ -1783,6 +1865,7 @@
     /**
      * Fires when RIL_UNSOL_CELL_INFO_LIST is received from the RIL.
      */
+    @UnsupportedAppUsage
     void registerForCellInfoList(Handler h, int what, Object obj);
     void unregisterForCellInfoList(Handler h);
 
@@ -1956,6 +2039,7 @@
      *          Callback message contains the information of SUCCESS/FAILURE.
      */
     // FIXME Update the doc and consider modifying the request to make more generic.
+    @UnsupportedAppUsage
     public void setUiccSubscription(int slotId, int appIndex, int subId, int subStatus,
             Message result);
 
@@ -1968,6 +2052,7 @@
      *          Callback message contains the information of SUCCESS/FAILURE.
      */
     // FIXME We may need to pass AID and slotid also
+    @UnsupportedAppUsage
     public void setDataAllowed(boolean allowed, Message result);
 
     /**
@@ -1975,6 +2060,7 @@
      *
      * @param result Callback message contains the information of SUCCESS/FAILURE
      */
+    @UnsupportedAppUsage
     public void requestShutdown(Message result);
 
     /**
@@ -2266,11 +2352,14 @@
      */
     default void enableModem(boolean enable, Message result) {};
 
+    /**
+     * Query whether logical modem is enabled or disabled
+     *
+     * @param result a Message to return to the requester
+     */
+    default void getModemStatus(Message result) {};
+
     default List<ClientRequestStats> getClientRequestStats() {
         return null;
     }
-
-    default int getIwlanOperationMode() {
-        return TransportManager.IWLAN_OPERATION_MODE_DEFAULT;
-    }
 }
diff --git a/src/java/com/android/internal/telephony/Connection.java b/src/java/com/android/internal/telephony/Connection.java
index 0594bd9..f5941c7 100755
--- a/src/java/com/android/internal/telephony/Connection.java
+++ b/src/java/com/android/internal/telephony/Connection.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.SystemClock;
@@ -173,11 +174,17 @@
     private String mTelecomCallId;
 
     //Caller Name Display
+    @UnsupportedAppUsage
     protected String mCnapName;
+    @UnsupportedAppUsage
     protected int mCnapNamePresentation  = PhoneConstants.PRESENTATION_ALLOWED;
+    @UnsupportedAppUsage
     protected String mAddress;     // MAY BE NULL!!!
+    @UnsupportedAppUsage
     protected String mDialString;          // outgoing calls only
+    @UnsupportedAppUsage
     protected int mNumberPresentation = PhoneConstants.PRESENTATION_ALLOWED;
+    @UnsupportedAppUsage
     protected boolean mIsIncoming;
     /*
      * These time/timespan values are based on System.currentTimeMillis(),
@@ -191,6 +198,7 @@
      * calculating deltas.
      */
     protected long mConnectTimeReal;
+    @UnsupportedAppUsage
     protected long mDuration;
     protected long mHoldingStartTime;  // The time when the Connection last transitioned
                             // into HOLDING
@@ -207,6 +215,7 @@
     protected int mCause = DisconnectCause.NOT_DISCONNECTED;
     protected PostDialState mPostDialState = PostDialState.NOT_STARTED;
 
+    @UnsupportedAppUsage
     private static String LOG_TAG = "Connection";
 
     Object mUserData;
@@ -238,6 +247,12 @@
     private EmergencyNumber mEmergencyNumberInfo;
 
     /**
+     * Whether the call is from emergency dialer, only valid if {@link #isEmergencyCall} returns
+     * {@code true}.
+     */
+    private boolean mHasKnownUserIntentEmergency;
+
+    /**
      * When {@code true}, the network has indicated that this is an emergency call.
      */
     private boolean mIsNetworkIdentifiedEmergencyCall;
@@ -255,6 +270,7 @@
      */
     private int mPulledDialogId;
 
+    @UnsupportedAppUsage
     protected Connection(int phoneType) {
         mPhoneType = phoneType;
     }
@@ -285,6 +301,7 @@
      * @return address or null if unavailable
      */
 
+    @UnsupportedAppUsage
     public String getAddress() {
         return mAddress;
     }
@@ -317,6 +334,7 @@
     /**
      * @return Call that owns this Connection, or null if none
      */
+    @UnsupportedAppUsage
     public abstract Call getCall();
 
     /**
@@ -325,6 +343,7 @@
      * Effectively, when an incoming call starts ringing or an
      * outgoing call starts dialing
      */
+    @UnsupportedAppUsage
     public long getCreateTime() {
         return mCreateTime;
     }
@@ -335,6 +354,7 @@
      * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition.
      * Returns 0 before then.
      */
+    @UnsupportedAppUsage
     public long getConnectTime() {
         return mConnectTime;
     }
@@ -372,6 +392,7 @@
      * The time when this Connection makes a transition into ENDED or FAIL.
      * Returns 0 before then.
      */
+    @UnsupportedAppUsage
     public abstract long getDisconnectTime();
 
     /**
@@ -380,6 +401,7 @@
      * If the call is still connected, then returns the elapsed
      * time since connect.
      */
+    @UnsupportedAppUsage
     public long getDurationMillis() {
         if (mConnectTimeReal == 0) {
             return 0;
@@ -412,6 +434,7 @@
      * {@link android.telephony.DisconnectCause}. If the call is not yet
      * disconnected, NOT_DISCONNECTED is returned.
      */
+    @UnsupportedAppUsage
     public int getDisconnectCause() {
         return mCause;
     }
@@ -430,6 +453,7 @@
      * ("MT" or mobile terminated; another party called this terminal)
      * or false if this call originated here (MO or mobile originated).
      */
+    @UnsupportedAppUsage
     public boolean isIncoming() {
         return mIsIncoming;
     }
@@ -464,7 +488,21 @@
     }
 
     /**
-     * Set the emergency numbe information if it is an emergency call.
+     * Checks if we have known the user's intent for the call is emergency.
+     *
+     * This is only used to specify when the dialed number is ambiguous, identified as both
+     * emergency number and any other non-emergency number; e.g. in some situation, 611 could
+     * be both an emergency number in a country and a non-emergency number of a carrier's
+     * customer service hotline.
+     *
+     * @return whether the call is from emergency dialer
+     */
+    public boolean hasKnownUserIntentEmergency() {
+        return mHasKnownUserIntentEmergency;
+    }
+
+    /**
+     * Set the emergency number information if it is an emergency call.
      *
      * @hide
      */
@@ -486,12 +524,27 @@
     }
 
     /**
+     * Set if we have known the user's intent for the call is emergency.
+     *
+     * This is only used to specify when the dialed number is ambiguous, identified as both
+     * emergency number and any other non-emergency number; e.g. in some situation, 611 could
+     * be both an emergency number in a country and a non-emergency number of a carrier's
+     * customer service hotline.
+     *
+     * @hide
+     */
+    public void setHasKnownUserIntentEmergency(boolean hasKnownUserIntentEmergency) {
+        mHasKnownUserIntentEmergency = hasKnownUserIntentEmergency;
+    }
+
+    /**
      * If this Connection is connected, then it is associated with
      * a Call.
      *
      * Returns getCall().getState() or Call.State.IDLE if not
      * connected
      */
+    @UnsupportedAppUsage
     public Call.State getState() {
         Call c;
 
@@ -534,6 +587,7 @@
      * @return true if the connection isn't disconnected
      * (could be active, holding, ringing, dialing, etc)
      */
+    @UnsupportedAppUsage
     public boolean
     isAlive() {
         return getState().isAlive();
@@ -551,6 +605,7 @@
      *
      * @return the userdata set in setUserData()
      */
+    @UnsupportedAppUsage
     public Object getUserData() {
         return mUserData;
     }
@@ -571,6 +626,7 @@
     /**
      * Hangup individual Connection
      */
+    @UnsupportedAppUsage
     public abstract void hangup() throws CallStateException;
 
     /**
@@ -581,15 +637,21 @@
     public abstract void separate() throws CallStateException;
 
     public enum PostDialState {
+        @UnsupportedAppUsage
         NOT_STARTED,    /* The post dial string playback hasn't
                            been started, or this call is not yet
                            connected, or this is an incoming call */
+        @UnsupportedAppUsage
         STARTED,        /* The post dial string playback has begun */
+        @UnsupportedAppUsage
         WAIT,           /* The post dial string playback is waiting for a
                            call to proceedAfterWaitChar() */
+        @UnsupportedAppUsage
         WILD,           /* The post dial string playback is waiting for a
                            call to proceedAfterWildChar() */
+        @UnsupportedAppUsage
         COMPLETE,       /* The post dial string playback is complete */
+        @UnsupportedAppUsage
         CANCELLED,       /* The post dial string playback was cancelled
                            with cancelPostDial() */
         PAUSE           /* The post dial string playback is pausing for a
@@ -866,6 +928,7 @@
      *
      * @return The video state.
      */
+    @UnsupportedAppUsage
     public void setVideoState(int videoState) {
         mVideoState = videoState;
         for (Listener l : mListeners) {
diff --git a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index fa26d0a..c5de580 100644
--- a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.net.LinkProperties;
 import android.net.NetworkCapabilities;
 import android.os.Bundle;
@@ -45,6 +46,7 @@
     private static final String LOG_TAG = "DefaultPhoneNotifier";
     private static final boolean DBG = false; // STOPSHIP if true
 
+    @UnsupportedAppUsage
     protected ITelephonyRegistry mRegistry;
 
     public DefaultPhoneNotifier() {
@@ -387,10 +389,12 @@
     }
 
     @Override
-    public void notifyCallQualityChanged(Phone sender, CallQuality callQuality) {
+    public void notifyCallQualityChanged(Phone sender, CallQuality callQuality,
+            int callNetworkType) {
         try {
             if (mRegistry != null) {
-                mRegistry.notifyCallQualityChanged(callQuality, sender.getPhoneId());
+                mRegistry.notifyCallQualityChanged(callQuality, sender.getPhoneId(),
+                        callNetworkType);
             }
         } catch (RemoteException ex) {
             // system process is dead
diff --git a/src/java/com/android/internal/telephony/DriverCall.java b/src/java/com/android/internal/telephony/DriverCall.java
index 96e1556..8c2c3db 100644
--- a/src/java/com/android/internal/telephony/DriverCall.java
+++ b/src/java/com/android/internal/telephony/DriverCall.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 import java.lang.Comparable;
 import android.telephony.PhoneNumberUtils;
@@ -27,11 +28,17 @@
     static final String LOG_TAG = "DriverCall";
 
     public enum State {
+        @UnsupportedAppUsage
         ACTIVE,
+        @UnsupportedAppUsage
         HOLDING,
+        @UnsupportedAppUsage
         DIALING,    // MO call only
+        @UnsupportedAppUsage
         ALERTING,   // MO call only
+        @UnsupportedAppUsage
         INCOMING,   // MT call only
+        @UnsupportedAppUsage
         WAITING;    // MT call only
         // If you add a state, make sure to look for the switch()
         // statements that use this enum
@@ -61,16 +68,23 @@
     /** Enhanced Variable rate codec (Narrowband) */
     public static final int AUDIO_QUALITY_EVRC_NW = 9;
 
+    @UnsupportedAppUsage
     public int index;
+    @UnsupportedAppUsage
     public boolean isMT;
+    @UnsupportedAppUsage
     public State state;     // May be null if unavail
     public boolean isMpty;
+    @UnsupportedAppUsage
     public String number;
     public int TOA;
+    @UnsupportedAppUsage
     public boolean isVoice;
     public boolean isVoicePrivacy;
     public int als;
+    @UnsupportedAppUsage
     public int numberPresentation;
+    @UnsupportedAppUsage
     public String name;
     public int namePresentation;
     public UUSInfo uusInfo;
@@ -122,6 +136,7 @@
         return ret;
     }
 
+    @UnsupportedAppUsage
     public
     DriverCall() {
     }
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCall.java b/src/java/com/android/internal/telephony/GsmCdmaCall.java
index 6c9089d..da2b057 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaCall.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCall.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import java.util.List;
 
 /**
@@ -72,6 +73,7 @@
         mState = stateFromDCState (dc.state);
     }
 
+    @UnsupportedAppUsage
     public void attachFake(Connection conn, State state) {
         mConnections.add(conn);
 
@@ -118,9 +120,6 @@
         newState = stateFromDCState(dc.state);
 
         if (newState != mState) {
-            if (mState == State.HOLDING) {
-                updateHoldingRequestState(HoldingRequestState.ENDED);
-            }
             mState = newState;
             changed = true;
         }
@@ -152,4 +151,4 @@
         }
         mState = State.DISCONNECTING;
     }
-}
+}
\ No newline at end of file
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
index edc5b19..ad0e383 100755
--- a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -28,6 +29,7 @@
 import android.os.Registrant;
 import android.os.RegistrantList;
 import android.os.SystemProperties;
+import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellLocation;
 import android.telephony.DisconnectCause;
@@ -78,18 +80,24 @@
     private ArrayList<GsmCdmaConnection> mDroppedDuringPoll =
             new ArrayList<GsmCdmaConnection>(MAX_CONNECTIONS_GSM);
 
+    @UnsupportedAppUsage
     public GsmCdmaCall mRingingCall = new GsmCdmaCall(this);
     // A call that is ringing or (call) waiting
+    @UnsupportedAppUsage
     public GsmCdmaCall mForegroundCall = new GsmCdmaCall(this);
+    @UnsupportedAppUsage
     public GsmCdmaCall mBackgroundCall = new GsmCdmaCall(this);
 
+    @UnsupportedAppUsage
     private GsmCdmaConnection mPendingMO;
     private boolean mHangupPendingMO;
 
+    @UnsupportedAppUsage
     private GsmCdmaPhone mPhone;
 
     private boolean mDesiredMute = false;    // false = mute off
 
+    @UnsupportedAppUsage
     public PhoneConstants.State mState = PhoneConstants.State.IDLE;
 
     private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
@@ -250,6 +258,7 @@
         mCallWaitingRegistrants.remove(h);
     }
 
+    @UnsupportedAppUsage
     private void fakeHoldForegroundBeforeDial() {
         List<Connection> connCopy;
 
@@ -268,7 +277,7 @@
     /**
      * clirMode is one of the CLIR_ constants
      */
-    public synchronized Connection dial(String dialString, int clirMode, UUSInfo uusInfo,
+    public synchronized Connection dialGsm(String dialString, int clirMode, UUSInfo uusInfo,
                                         Bundle intentExtras)
             throws CallStateException {
         // note that this triggers call state changed notif
@@ -314,6 +323,12 @@
 
         mPendingMO = new GsmCdmaConnection(mPhone, checkForTestEmergencyNumber(dialString),
                 this, mForegroundCall, isEmergencyCall);
+        if (intentExtras != null) {
+            Rlog.d(LOG_TAG, "dialGsm - emergency dialer: " + intentExtras.getBoolean(
+                    TelecomManager.EXTRA_IS_USER_INTENT_EMERGENCY_CALL));
+            mPendingMO.setHasKnownUserIntentEmergency(intentExtras.getBoolean(
+                    TelecomManager.EXTRA_IS_USER_INTENT_EMERGENCY_CALL));
+        }
         mHangupPendingMO = false;
         mMetrics.writeRilDial(mPhone.getPhoneId(), mPendingMO, clirMode, uusInfo);
 
@@ -331,8 +346,8 @@
             setMute(false);
 
             mCi.dial(mPendingMO.getAddress(), mPendingMO.isEmergencyCall(),
-                    mPendingMO.getEmergencyNumberInfo(), clirMode, uusInfo,
-                    obtainCompleteMessage());
+                    mPendingMO.getEmergencyNumberInfo(), mPendingMO.hasKnownUserIntentEmergency(),
+                    clirMode, uusInfo, obtainCompleteMessage());
         }
 
         if (mNumberConverted) {
@@ -350,6 +365,7 @@
     /**
      * Handle Ecm timer to be canceled or re-started
      */
+    @UnsupportedAppUsage
     private void handleEcmTimer(int action) {
         mPhone.handleTimerInEmergencyCallbackMode(action);
         switch(action) {
@@ -364,6 +380,7 @@
     /**
      * Disable data call when emergency call is connected
      */
+    @UnsupportedAppUsage
     private void disableDataCallInEmergencyCall(String dialString) {
         if (PhoneNumberUtils.isLocalEmergencyNumber(mPhone.getContext(), dialString)) {
             if (Phone.DEBUG_PHONE) log("disableDataCallInEmergencyCall");
@@ -383,7 +400,8 @@
     /**
      * clirMode is one of the CLIR_ constants
      */
-    private Connection dial(String dialString, int clirMode) throws CallStateException {
+    private Connection dialCdma(String dialString, int clirMode, Bundle intentExtras)
+            throws CallStateException {
         // note that this triggers call state changed notif
         clearDisconnected();
 
@@ -423,11 +441,17 @@
         // That call must be idle, so place anything that's
         // there on hold
         if (mForegroundCall.getState() == GsmCdmaCall.State.ACTIVE) {
-            return dialThreeWay(dialString);
+            return dialThreeWay(dialString, intentExtras);
         }
 
         mPendingMO = new GsmCdmaConnection(mPhone, checkForTestEmergencyNumber(dialString),
                 this, mForegroundCall, isEmergencyCall);
+        if (intentExtras != null) {
+            Rlog.d(LOG_TAG, "dialGsm - emergency dialer: " + intentExtras.getBoolean(
+                    TelecomManager.EXTRA_IS_USER_INTENT_EMERGENCY_CALL));
+            mPendingMO.setHasKnownUserIntentEmergency(intentExtras.getBoolean(
+                    TelecomManager.EXTRA_IS_USER_INTENT_EMERGENCY_CALL));
+        }
         mHangupPendingMO = false;
 
         if ( mPendingMO.getAddress() == null || mPendingMO.getAddress().length() == 0
@@ -448,8 +472,9 @@
             // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
             if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
                 mCi.dial(mPendingMO.getAddress(), mPendingMO.isEmergencyCall(),
-                        mPendingMO.getEmergencyNumberInfo(), clirMode,
-                        obtainCompleteMessage());
+                        mPendingMO.getEmergencyNumberInfo(),
+                        mPendingMO.hasKnownUserIntentEmergency(),
+                        clirMode, obtainCompleteMessage());
             } else {
                 mPhone.exitEmergencyCallbackMode();
                 mPhone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
@@ -470,7 +495,7 @@
     }
 
     //CDMA
-    private Connection dialThreeWay(String dialString) {
+    private Connection dialThreeWay(String dialString, Bundle intentExtras) {
         if (!mForegroundCall.isIdle()) {
             // Check data call and possibly set mIsInEmergencyCall
             disableDataCallInEmergencyCall(dialString);
@@ -479,6 +504,12 @@
             mPendingMO = new GsmCdmaConnection(mPhone,
                     checkForTestEmergencyNumber(dialString), this, mForegroundCall,
                     mIsInEmergencyCall);
+            if (intentExtras != null) {
+                Rlog.d(LOG_TAG, "dialThreeWay - emergency dialer " + intentExtras.getBoolean(
+                        TelecomManager.EXTRA_IS_USER_INTENT_EMERGENCY_CALL));
+                mPendingMO.setHasKnownUserIntentEmergency(intentExtras.getBoolean(
+                        TelecomManager.EXTRA_IS_USER_INTENT_EMERGENCY_CALL));
+            }
             // Some networks need an empty flash before sending the normal one
             CarrierConfigManager configManager = (CarrierConfigManager)
                     mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -501,24 +532,24 @@
         return null;
     }
 
-    public Connection dial(String dialString) throws CallStateException {
+    public Connection dial(String dialString, Bundle intentExtras) throws CallStateException {
         if (isPhoneTypeGsm()) {
-            return dial(dialString, CommandsInterface.CLIR_DEFAULT, null);
+            return dialGsm(dialString, CommandsInterface.CLIR_DEFAULT, intentExtras);
         } else {
-            return dial(dialString, CommandsInterface.CLIR_DEFAULT);
+            return dialCdma(dialString, CommandsInterface.CLIR_DEFAULT, intentExtras);
         }
     }
 
     //GSM
-    public Connection dial(String dialString, UUSInfo uusInfo, Bundle intentExtras)
+    public Connection dialGsm(String dialString, UUSInfo uusInfo, Bundle intentExtras)
             throws CallStateException {
-        return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo, intentExtras);
+        return dialGsm(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo, intentExtras);
     }
 
     //GSM
-    private Connection dial(String dialString, int clirMode, Bundle intentExtras)
+    private Connection dialGsm(String dialString, int clirMode, Bundle intentExtras)
             throws CallStateException {
-        return dial(dialString, clirMode, null, intentExtras);
+        return dialGsm(dialString, clirMode, null, intentExtras);
     }
 
     public void acceptCall() throws CallStateException {
@@ -568,6 +599,7 @@
         mPhone.notifyPreciseCallStateChanged();
     }
 
+    @UnsupportedAppUsage
     public void switchWaitingOrHoldingAndActive() throws CallStateException {
         // Should we bother with this check?
         if (mRingingCall.getState() == GsmCdmaCall.State.INCOMING) {
@@ -603,6 +635,7 @@
         mCi.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
     }
 
+    @UnsupportedAppUsage
     public void clearDisconnected() {
         internalClearDisconnected();
 
@@ -687,6 +720,7 @@
      * Obtain a message to use for signalling "invoke getCurrentCalls() when
      * this operation and all other pending operations are complete
      */
+    @UnsupportedAppUsage
     private Message obtainCompleteMessage() {
         return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
     }
@@ -695,6 +729,7 @@
      * Obtain a message to use for signalling "invoke getCurrentCalls() when
      * this operation and all other pending operations are complete
      */
+    @UnsupportedAppUsage
     private Message obtainCompleteMessage(int what) {
         mPendingOperations++;
         mLastRelevantPoll = null;
@@ -722,6 +757,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void updatePhoneState() {
         PhoneConstants.State oldState = mState;
         if (mRingingCall.isRinging()) {
@@ -1230,6 +1266,7 @@
 
     //***** Called from GsmCdmaPhone
 
+    @UnsupportedAppUsage
     public void setMute(boolean mute) {
         mDesiredMute = mute;
         mCi.setMute(mDesiredMute, null);
@@ -1262,12 +1299,6 @@
                 // Do not auto-answer ringing on CHUP, instead just end active calls
                 log("hangup all conns in active/background call, without affecting ringing call");
                 hangupAllConnections(call);
-            } else if (call.mHoldingRequestState.isStarted()) {
-                // Even if the progress of holding is not completed, lower layer expects to hang up
-                // as background call because of being going to holding.
-                log("hangup waiting or background call");
-                logHangupEvent(call);
-                hangupWaitingOrBackground();
             } else {
                 logHangupEvent(call);
                 hangupForegroundResumeBackground();
@@ -1543,6 +1574,7 @@
                     if (mPendingCallInEcm) {
                         mCi.dial(mPendingMO.getAddress(), mPendingMO.isEmergencyCall(),
                                 mPendingMO.getEmergencyNumberInfo(),
+                                mPendingMO.hasKnownUserIntentEmergency(),
                                 mPendingCallClirMode, obtainCompleteMessage());
                         mPendingCallInEcm = false;
                     }
@@ -1704,14 +1736,17 @@
                 .count() > 0);
     }
 
+    @UnsupportedAppUsage
     private boolean isPhoneTypeGsm() {
         return mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM;
     }
 
+    @UnsupportedAppUsage
     public GsmCdmaPhone getPhone() {
         return mPhone;
     }
 
+    @UnsupportedAppUsage
     @Override
     protected void log(String msg) {
         Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + msg);
diff --git a/src/java/com/android/internal/telephony/GsmCdmaConnection.java b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
index 4aa98d8..f5f2519 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaConnection.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
@@ -15,6 +15,7 @@
  */
 
 package com.android.internal.telephony;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -49,11 +50,13 @@
 
     //***** Instance Variables
 
+    @UnsupportedAppUsage
     GsmCdmaCallTracker mOwner;
     GsmCdmaCall mParent;
 
     boolean mDisconnected;
 
+    @UnsupportedAppUsage
     int mIndex;          // index in GsmCdmaCallTracker.connections[], -1 if unassigned
                         // The GsmCdma index is 1 + this
 
@@ -264,6 +267,7 @@
      *    If consecutive PAUSE/WAIT sequence in the middle of the string,
      *    and if there is any WAIT in PAUSE/WAIT sequence, treat them like WAIT.
      */
+    @UnsupportedAppUsage
     public static String formatDialString(String phoneNumber) {
         /**
          * TODO(cleanup): This function should move to PhoneNumberUtils, and
@@ -353,6 +357,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public GsmCdmaCall.State getState() {
         if (mDisconnected) {
@@ -446,6 +451,7 @@
      * @param causeCode RIL disconnect code
      * @return the corresponding value from {@link DisconnectCause}
      */
+    @UnsupportedAppUsage
     int disconnectCauseFromCode(int causeCode) {
         /**
          * See 22.001 Annex F.4 for mapping of cause codes
@@ -758,6 +764,7 @@
     /**
      * An incoming or outgoing call has connected
      */
+    @UnsupportedAppUsage
     void
     onConnectedInOrOut() {
         mConnectTime = System.currentTimeMillis();
@@ -860,6 +867,7 @@
     }
 
     //CDMA
+    @UnsupportedAppUsage
     public void updateParent(GsmCdmaCall oldParent, GsmCdmaCall newParent){
         if (newParent != oldParent) {
             if (oldParent != null) {
@@ -1015,11 +1023,13 @@
         notifyPostDialListeners();
     }
 
+    @UnsupportedAppUsage
     private void createWakeLock(Context context) {
         PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
     }
 
+    @UnsupportedAppUsage
     private void acquireWakeLock() {
         if (mPartialWakeLock != null) {
             synchronized (mPartialWakeLock) {
@@ -1050,10 +1060,12 @@
         }
     }
 
+    @UnsupportedAppUsage
     private static boolean isPause(char c) {
         return c == PhoneNumberUtils.PAUSE;
     }
 
+    @UnsupportedAppUsage
     private static boolean isWait(char c) {
         return c == PhoneNumberUtils.WAIT;
     }
@@ -1066,6 +1078,7 @@
     // This function is to find the next PAUSE character index if
     // multiple pauses in a row. Otherwise it finds the next non PAUSE or
     // non WAIT character index.
+    @UnsupportedAppUsage
     private static int findNextPCharOrNonPOrNonWCharIndex(String phoneNumber, int currIndex) {
         boolean wMatched = isWait(phoneNumber.charAt(currIndex));
         int index = currIndex + 1;
@@ -1097,6 +1110,7 @@
     // This function returns either PAUSE or WAIT character to append.
     // It is based on the next non PAUSE/WAIT character in the phoneNumber and the
     // index for the current PAUSE/WAIT character
+    @UnsupportedAppUsage
     private static char findPOrWCharToAppend(String phoneNumber, int currPwIndex,
                                              int nextNonPwCharIndex) {
         char c = phoneNumber.charAt(currPwIndex);
@@ -1117,6 +1131,7 @@
         return ret;
     }
 
+    @UnsupportedAppUsage
     private String maskDialString(String dialString) {
         if (VDBG) {
             return dialString;
@@ -1125,6 +1140,7 @@
         return "<MASKED>";
     }
 
+    @UnsupportedAppUsage
     private void fetchDtmfToneDelay(GsmCdmaPhone phone) {
         CarrierConfigManager configMgr = (CarrierConfigManager)
                 phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -1134,10 +1150,12 @@
         }
     }
 
+    @UnsupportedAppUsage
     private boolean isPhoneTypeGsm() {
         return mOwner.getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_GSM;
     }
 
+    @UnsupportedAppUsage
     private void log(String msg) {
         Rlog.d(LOG_TAG, "[GsmCdmaConn] " + msg);
     }
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 858c624..a6884b6 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -30,6 +30,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentValues;
@@ -54,8 +55,9 @@
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.provider.Telephony;
+import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
-import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellLocation;
 import android.telephony.ImsiEncryptionInfo;
@@ -140,11 +142,13 @@
     public static final int CANCEL_ECM_TIMER = 1; // cancel Ecm timer
     private CdmaSubscriptionSourceManager mCdmaSSM;
     public int mCdmaSubscriptionSource = CdmaSubscriptionSourceManager.SUBSCRIPTION_SOURCE_UNKNOWN;
+    @UnsupportedAppUsage
     public EriManager mEriManager;
     private PowerManager.WakeLock mWakeLock;
     // mEriFileLoadedRegistrants are informed after the ERI text has been loaded
     private final RegistrantList mEriFileLoadedRegistrants = new RegistrantList();
     // mEcmExitRespRegistrant is informed after the phone has been exited
+    @UnsupportedAppUsage
     private Registrant mEcmExitRespRegistrant;
     private String mEsn;
     private String mMeid;
@@ -169,10 +173,14 @@
 
     //Common
     // Instance Variables
+    @UnsupportedAppUsage
     private IsimUiccRecords mIsimUiccRecords;
+    @UnsupportedAppUsage
     public GsmCdmaCallTracker mCT;
+    @UnsupportedAppUsage
     public ServiceStateTracker mSST;
     public EmergencyNumberTracker mEmergencyNumberTracker;
+    @UnsupportedAppUsage
     private ArrayList <MmiCode> mPendingMMIs = new ArrayList<MmiCode>();
     private IccPhoneBookInterfaceManager mIccPhoneBookIntManager;
 
@@ -192,12 +200,14 @@
         final String mSetCfNumber;
         final Message mOnComplete;
 
+        @UnsupportedAppUsage
         Cfu(String cfNumber, Message onComplete) {
             mSetCfNumber = cfNumber;
             mOnComplete = onComplete;
         }
     }
 
+    @UnsupportedAppUsage
     private IccSmsInterfaceManager mIccSmsInterfaceManager;
 
     private boolean mResetModemOnRadioTechnologyChange = false;
@@ -268,6 +278,8 @@
         mSettingsObserver.observe(
                 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
                 EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE);
+
+        loadTtyMode();
         logd("GsmCdmaPhone: constructor: sub = " + mPhoneId);
     }
 
@@ -275,8 +287,17 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             Rlog.d(LOG_TAG, "mBroadcastReceiver: action " + intent.getAction());
-            if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
+            String action = intent.getAction();
+            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) {
                 sendMessage(obtainMessage(EVENT_CARRIER_CONFIG_CHANGED));
+            } else if (TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED.equals(action)) {
+                int ttyMode = intent.getIntExtra(
+                        TelecomManager.EXTRA_CURRENT_TTY_MODE, TelecomManager.TTY_MODE_OFF);
+                updateTtyMode(ttyMode);
+            } else if (TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED.equals(action)) {
+                int newPreferredTtyMode = intent.getIntExtra(
+                        TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
+                updateUiTtyMode(newPreferredTtyMode);
             }
         }
     };
@@ -327,8 +348,12 @@
 
         mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
         mCi.registerForVoiceRadioTechChanged(this, EVENT_VOICE_RADIO_TECH_CHANGED, null);
-        mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(
-                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        IntentFilter filter = new IntentFilter(
+                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
+        filter.addAction(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
+        mContext.registerReceiver(mBroadcastReceiver, filter);
+
         mCDM = new CarrierKeyDownloadManager(this);
         mCIM = new CarrierInfoManager();
     }
@@ -418,6 +443,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public boolean isPhoneTypeGsm() {
         return mPrecisePhoneType == PhoneConstants.PHONE_TYPE_GSM;
     }
@@ -470,6 +496,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public ServiceState getServiceState() {
         if (mSST == null || mSST.mSS.getState() != ServiceState.STATE_IN_SERVICE) {
@@ -492,6 +519,7 @@
         mSST.requestCellLocation(workSource, rspMsg);
     }
 
+    @UnsupportedAppUsage
     @Override
     public PhoneConstants.State getState() {
         if (mImsPhone != null) {
@@ -504,6 +532,7 @@
         return mCT.mState;
     }
 
+    @UnsupportedAppUsage
     @Override
     public int getPhoneType() {
         if (mPrecisePhoneType == PhoneConstants.PHONE_TYPE_GSM) {
@@ -523,6 +552,7 @@
         return mEmergencyNumberTracker;
     }
 
+    @UnsupportedAppUsage
     @Override
     public CallTracker getCallTracker() {
         return mCT;
@@ -610,8 +640,8 @@
         DataActivityState ret = DataActivityState.NONE;
 
         if (mSST.getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE
-                && getDcTracker(TransportType.WWAN) != null) {
-            switch (getDcTracker(TransportType.WWAN).getActivity()) {
+                && getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
+            switch (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).getActivity()) {
                 case DATAIN:
                     ret = DataActivityState.DATAIN;
                 break;
@@ -650,6 +680,7 @@
      * {@link com.android.internal.telephony.Call.State}. Use this when changes
      * in the precise call state are needed, else use notifyPhoneStateChanged.
      */
+    @UnsupportedAppUsage
     public void notifyPreciseCallStateChanged() {
         /* we'd love it if this was package-scoped*/
         super.notifyPreciseCallStateChangedP();
@@ -720,6 +751,7 @@
         mSuppServiceFailedRegistrants.notifyResult(code);
     }
 
+    @UnsupportedAppUsage
     public void notifyServiceStateChanged(ServiceState ss) {
         super.notifyServiceStateChangedP(ss);
     }
@@ -1067,6 +1099,7 @@
         return true;
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean handleInCallMmiCommands(String dialString) throws CallStateException {
         if (!isPhoneTypeGsm()) {
@@ -1116,6 +1149,7 @@
         return result;
     }
 
+    @UnsupportedAppUsage
     public boolean isInCall() {
         GsmCdmaCall.State foregroundCallState = getForegroundCall().getState();
         GsmCdmaCall.State backgroundCallState = getBackgroundCall().getState();
@@ -1296,9 +1330,9 @@
             if (DBG) logd("dialInternal: dialing w/ mmi '" + mmi + "'...");
 
             if (mmi == null) {
-                return mCT.dial(newDialString, dialArgs.uusInfo, dialArgs.intentExtras);
+                return mCT.dialGsm(newDialString, dialArgs.uusInfo, dialArgs.intentExtras);
             } else if (mmi.isTemporaryModeCLIR()) {
-                return mCT.dial(mmi.mDialingNumber, mmi.getCLIRMode(), dialArgs.uusInfo,
+                return mCT.dialGsm(mmi.mDialingNumber, mmi.getCLIRMode(), dialArgs.uusInfo,
                         dialArgs.intentExtras);
             } else {
                 mPendingMMIs.add(mmi);
@@ -1307,7 +1341,7 @@
                 return null;
             }
         } else {
-            return mCT.dial(newDialString);
+            return mCT.dial(newDialString, dialArgs.intentExtras);
         }
     }
 
@@ -1572,6 +1606,7 @@
         return mImei;
     }
 
+    @UnsupportedAppUsage
     @Override
     public String getEsn() {
         if (isPhoneTypeGsm()) {
@@ -1639,13 +1674,13 @@
     }
 
     @Override
-    public int getPreciseCarrierId() {
-        return mCarrierResolver.getPreciseCarrierId();
+    public int getSpecificCarrierId() {
+        return mCarrierResolver.getSpecificCarrierId();
     }
 
     @Override
-    public String getPreciseCarrierName() {
-        return mCarrierResolver.getPreciseCarrierName();
+    public String getSpecificCarrierName() {
+        return mCarrierResolver.getSpecificCarrierName();
     }
 
     @Override
@@ -1705,6 +1740,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public String getLine1Number() {
         if (isPhoneTypeGsm()) {
@@ -1800,6 +1836,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) {
         switch (commandInterfaceCFReason) {
             case CF_REASON_UNCONDITIONAL:
@@ -1814,6 +1851,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public String getSystemProperty(String property, String defValue) {
         if (getUnitTestMode()) {
@@ -1822,6 +1860,7 @@
         return TelephonyManager.getTelephonyProperty(mPhoneId, property, defValue);
     }
 
+    @UnsupportedAppUsage
     private boolean isValidCommandInterfaceCFAction (int commandInterfaceCFAction) {
         switch (commandInterfaceCFAction) {
             case CF_ACTION_DISABLE:
@@ -1834,6 +1873,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private boolean isCfEnable(int action) {
         return (action == CF_ACTION_ENABLE) || (action == CF_ACTION_REGISTRATION);
     }
@@ -2091,16 +2131,17 @@
 
     @Override
     public boolean getDataRoamingEnabled() {
-        if (getDcTracker(TransportType.WWAN) != null) {
-            return getDcTracker(TransportType.WWAN).getDataRoamingEnabled();
+        if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
+            return getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).getDataRoamingEnabled();
         }
         return false;
     }
 
     @Override
     public void setDataRoamingEnabled(boolean enable) {
-        if (getDcTracker(TransportType.WWAN) != null) {
-            getDcTracker(TransportType.WWAN).setDataRoamingEnabledByUser(enable);
+        if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
+            getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                    .setDataRoamingEnabledByUser(enable);
         }
     }
 
@@ -2124,6 +2165,7 @@
         mSST.unregisterForSubscriptionInfoReady(h);
     }
 
+    @UnsupportedAppUsage
     @Override
     public void setOnEcbModeExitResponse(Handler h, int what, Object obj) {
         mEcmExitRespRegistrant = new Registrant(h, what, obj);
@@ -2266,6 +2308,7 @@
     /**
      * Make sure the network knows our preferred setting.
      */
+    @UnsupportedAppUsage
     private void syncClirSetting() {
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
         int clirSetting = sp.getInt(CLIR_KEY + getPhoneId(), -1);
@@ -2919,6 +2962,7 @@
     }
 
     //CDMA
+    @UnsupportedAppUsage
     public boolean isEriFileLoaded() {
         return mEriManager.isEriFileLoaded();
     }
@@ -3017,6 +3061,7 @@
         return false;
     }
 
+    @UnsupportedAppUsage
     private boolean isManualSelProhibitedInGlobalMode() {
         boolean isProhibited = false;
         final String configString = getContext().getResources().getString(com.android.internal.
@@ -3066,6 +3111,7 @@
         r.unregisterForRecordsLoaded(this);
     }
 
+    @UnsupportedAppUsage
     @Override
     public void exitEmergencyCallbackMode() {
         if (DBG) {
@@ -3390,6 +3436,7 @@
     /**
      * Returns the CDMA ERI text,
      */
+    @UnsupportedAppUsage
     @Override
     public String getCdmaEriText() {
         if (isPhoneTypeGsm()) {
@@ -3816,6 +3863,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void logd(String s) {
         Rlog.d(LOG_TAG, "[" + mPhoneId + "] " + s);
     }
@@ -3824,6 +3872,7 @@
         Rlog.i(LOG_TAG, "[" + mPhoneId + "] " + s);
     }
 
+    @UnsupportedAppUsage
     private void loge(String s) {
         Rlog.e(LOG_TAG, "[" + mPhoneId + "] " + s);
     }
@@ -3868,4 +3917,47 @@
         }
         return currentConfig;
     }
+
+    private void updateTtyMode(int ttyMode) {
+        logi(String.format("updateTtyMode ttyMode=%d", ttyMode));
+        setTTYMode(telecomModeToPhoneMode(ttyMode), null);
+    }
+    private void updateUiTtyMode(int ttyMode) {
+        logi(String.format("updateUiTtyMode ttyMode=%d", ttyMode));
+        setUiTTYMode(telecomModeToPhoneMode(ttyMode), null);
+    }
+
+    /**
+     * Given a telecom TTY mode, convert to a Telephony mode equivalent.
+     * @param telecomMode Telecom TTY mode.
+     * @return Telephony phone TTY mode.
+     */
+    private static int telecomModeToPhoneMode(int telecomMode) {
+        switch (telecomMode) {
+            // AT command only has 0 and 1, so mapping VCO
+            // and HCO to FULL
+            case TelecomManager.TTY_MODE_FULL:
+            case TelecomManager.TTY_MODE_VCO:
+            case TelecomManager.TTY_MODE_HCO:
+                return Phone.TTY_MODE_FULL;
+            default:
+                return Phone.TTY_MODE_OFF;
+        }
+    }
+
+    /**
+     * Load the current TTY mode in GsmCdmaPhone based on Telecom and UI settings.
+     */
+    private void loadTtyMode() {
+        int ttyMode = TelecomManager.TTY_MODE_OFF;
+        TelecomManager telecomManager = TelecomManager.from(mContext);
+        if (telecomManager != null) {
+            ttyMode = telecomManager.getCurrentTtyMode();
+        }
+        updateTtyMode(ttyMode);
+        //Get preferred TTY mode from settings as UI Tty mode is always user preferred Tty mode.
+        ttyMode = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.PREFERRED_TTY_MODE, TelecomManager.TTY_MODE_OFF);
+        updateUiTtyMode(ttyMode);
+    }
 }
diff --git a/src/java/com/android/internal/telephony/HalVersion.java b/src/java/com/android/internal/telephony/HalVersion.java
index c05179b..f83d790 100644
--- a/src/java/com/android/internal/telephony/HalVersion.java
+++ b/src/java/com/android/internal/telephony/HalVersion.java
@@ -24,6 +24,10 @@
  * HIDL versioning</a>.
  */
 public class HalVersion implements Comparable<HalVersion> {
+
+    /** The HAL Version indicating that the version is unknown or invalid */
+    public static final HalVersion UNKNOWN = new HalVersion(-1, -1);
+
     public final int major;
 
     public final int minor;
diff --git a/src/java/com/android/internal/telephony/IccCard.java b/src/java/com/android/internal/telephony/IccCard.java
index 75f3377..d15c44c 100644
--- a/src/java/com/android/internal/telephony/IccCard.java
+++ b/src/java/com/android/internal/telephony/IccCard.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
@@ -56,6 +57,7 @@
     /**
      * @return combined Card and current App state
      */
+    @UnsupportedAppUsage
     public State getState() {
         return mIccCardState;
     }
@@ -71,6 +73,7 @@
     /**
      * Notifies handler of any transition into IccCardConstants.State.NETWORK_LOCKED
      */
+    @UnsupportedAppUsage
     public void registerForNetworkLocked(Handler h, int what, Object obj) {
         return;
     }
@@ -99,6 +102,7 @@
      * && ((CommandException)(((AsyncResult)onComplete.obj).exception))
      *          .getCommandError() == CommandException.Error.PASSWORD_INCORRECT
      */
+    @UnsupportedAppUsage
     public void supplyPin(String pin, Message onComplete) {
         sendMessageWithCardAbsentException(onComplete);
     }
@@ -106,6 +110,7 @@
     /**
      * Supply the ICC PUK to the ICC
      */
+    @UnsupportedAppUsage
     public void supplyPuk(String puk, String newPin, Message onComplete) {
         sendMessageWithCardAbsentException(onComplete);
     }
@@ -127,6 +132,7 @@
     /**
      * Supply Network depersonalization code to the RIL
      */
+    @UnsupportedAppUsage
     public void supplyNetworkDepersonalization(String pin, Message onComplete) {
         sendMessageWithCardAbsentException(onComplete);
     }
diff --git a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 42a156a..e619e61 100644
--- a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.pm.PackageManager;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -29,7 +30,6 @@
 import com.android.internal.telephony.uicc.IccConstants;
 import com.android.internal.telephony.uicc.IccFileHandler;
 import com.android.internal.telephony.uicc.IccRecords;
-import com.android.internal.telephony.uicc.UiccCardApplication;
 
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -40,79 +40,74 @@
  */
 public class IccPhoneBookInterfaceManager {
     static final String LOG_TAG = "IccPhoneBookIM";
+    @UnsupportedAppUsage
     protected static final boolean DBG = true;
 
+    @UnsupportedAppUsage
     protected Phone mPhone;
-    private   UiccCardApplication mCurrentApp = null;
+    @UnsupportedAppUsage
     protected AdnRecordCache mAdnCache;
-    protected final Object mLock = new Object();
-    protected int mRecordSize[];
-    protected boolean mSuccess;
-    private   boolean mIs3gCard = false;  // flag to determine if card is 3G or 2G
-    protected List<AdnRecord> mRecords;
-
-
-    protected static final boolean ALLOW_SIM_OP_IN_UI_THREAD = false;
 
     protected static final int EVENT_GET_SIZE_DONE = 1;
     protected static final int EVENT_LOAD_DONE = 2;
     protected static final int EVENT_UPDATE_DONE = 3;
 
+    private static final class Request {
+        AtomicBoolean mStatus = new AtomicBoolean(false);
+        Object mResult = null;
+    }
+
+    @UnsupportedAppUsage
     protected Handler mBaseHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
-            AsyncResult ar;
+            AsyncResult ar = (AsyncResult) msg.obj;
+            Request request = (Request) ar.userObj;
 
             switch (msg.what) {
                 case EVENT_GET_SIZE_DONE:
-                    ar = (AsyncResult) msg.obj;
-                    synchronized (mLock) {
-                        if (ar.exception == null) {
-                            mRecordSize = (int[])ar.result;
-                            // recordSize[0]  is the record length
-                            // recordSize[1]  is the total length of the EF file
-                            // recordSize[2]  is the number of records in the EF file
-                            logd("GET_RECORD_SIZE Size " + mRecordSize[0] +
-                                    " total " + mRecordSize[1] +
-                                    " #record " + mRecordSize[2]);
-                        } else {
-                            loge("EVENT_GET_SIZE_DONE: failed; ex=" + ar.exception);
-                        }
-                        notifyPending(ar);
+                    int[] recordSize = null;
+                    if (ar.exception == null) {
+                        recordSize = (int[]) ar.result;
+                        // recordSize[0]  is the record length
+                        // recordSize[1]  is the total length of the EF file
+                        // recordSize[2]  is the number of records in the EF file
+                        logd("GET_RECORD_SIZE Size " + recordSize[0]
+                                + " total " + recordSize[1]
+                                + " #record " + recordSize[2]);
+                    } else {
+                        loge("EVENT_GET_SIZE_DONE: failed; ex=" + ar.exception);
                     }
+                    notifyPending(request, recordSize);
                     break;
                 case EVENT_UPDATE_DONE:
-                    ar = (AsyncResult) msg.obj;
-                    synchronized (mLock) {
-                        mSuccess = (ar.exception == null);
-                        if (!mSuccess) {
-                            loge("EVENT_UPDATE_DONE - failed; ex=" + ar.exception);
-                        }
-                        notifyPending(ar);
+                    boolean success = (ar.exception == null);
+                    if (!success) {
+                        loge("EVENT_UPDATE_DONE - failed; ex=" + ar.exception);
                     }
+                    notifyPending(request, success);
                     break;
                 case EVENT_LOAD_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    synchronized (mLock) {
-                        if (ar.exception == null) {
-                            mRecords = (List<AdnRecord>) ar.result;
-                        } else {
-                            loge("EVENT_LOAD_DONE: Cannot load ADN records; ex="
-                                    + ar.exception);
-                            mRecords = null;
-                        }
-                        notifyPending(ar);
+                    List<AdnRecord> records = null;
+                    if (ar.exception == null) {
+                        records = (List<AdnRecord>) ar.result;
+                    } else {
+                        loge("EVENT_LOAD_DONE: Cannot load ADN records; ex="
+                                + ar.exception);
                     }
+                    notifyPending(request, records);
                     break;
             }
         }
 
-        private void notifyPending(AsyncResult ar) {
-            if (ar.userObj != null) {
-                AtomicBoolean status = (AtomicBoolean) ar.userObj;
-                status.set(true);
+        private void notifyPending(Request request, Object result) {
+            if (request != null) {
+                synchronized (request) {
+                    request.mResult = result;
+                    request.mStatus.set(true);
+                    request.notifyAll();
+                }
             }
-            mLock.notifyAll();
         }
     };
 
@@ -135,10 +130,12 @@
         }
     }
 
+    @UnsupportedAppUsage
     protected void logd(String msg) {
         Rlog.d(LOG_TAG, "[IccPbInterfaceManager] " + msg);
     }
 
+    @UnsupportedAppUsage
     protected void loge(String msg) {
         Rlog.e(LOG_TAG, "[IccPbInterfaceManager] " + msg);
     }
@@ -184,21 +181,20 @@
 
         efid = updateEfForIccType(efid);
 
-        synchronized(mLock) {
-            checkThread();
-            mSuccess = false;
-            AtomicBoolean status = new AtomicBoolean(false);
-            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
+        checkThread();
+        Request updateRequest = new Request();
+        synchronized (updateRequest) {
+            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, updateRequest);
             AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
             AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
             if (mAdnCache != null) {
                 mAdnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
-                waitForResult(status);
+                waitForResult(updateRequest);
             } else {
                 loge("Failure while trying to update by search due to uninitialised adncache");
             }
         }
-        return mSuccess;
+        return (boolean) updateRequest.mResult;
     }
 
     /**
@@ -233,20 +229,21 @@
                 Integer.toHexString(efid).toUpperCase() + " Index=" + index + " ==> " + "(" +
                 Rlog.pii(LOG_TAG, newTag) + "," + Rlog.pii(LOG_TAG, newPhoneNumber) + ")" +
                 " pin2=" + Rlog.pii(LOG_TAG, pin2));
-        synchronized(mLock) {
-            checkThread();
-            mSuccess = false;
-            AtomicBoolean status = new AtomicBoolean(false);
-            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
+
+
+        checkThread();
+        Request updateRequest = new Request();
+        synchronized (updateRequest) {
+            Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, updateRequest);
             AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
             if (mAdnCache != null) {
                 mAdnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
-                waitForResult(status);
+                waitForResult(updateRequest);
             } else {
                 loge("Failure while trying to update by index due to uninitialised adncache");
             }
         }
-        return mSuccess;
+        return (boolean) updateRequest.mResult;
     }
 
     /**
@@ -260,22 +257,19 @@
      */
     public int[] getAdnRecordsSize(int efid) {
         if (DBG) logd("getAdnRecordsSize: efid=" + efid);
-        synchronized(mLock) {
-            checkThread();
-            mRecordSize = new int[3];
-
+        checkThread();
+        Request getSizeRequest = new Request();
+        synchronized (getSizeRequest) {
             //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
-            AtomicBoolean status = new AtomicBoolean(false);
-            Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
-
+            Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, getSizeRequest);
             IccFileHandler fh = mPhone.getIccFileHandler();
             if (fh != null) {
                 fh.getEFLinearRecordSize(efid, response);
-                waitForResult(status);
+                waitForResult(getSizeRequest);
             }
         }
 
-        return mRecordSize;
+        return getSizeRequest.mResult == null ? new int[3] : (int[]) getSizeRequest.mResult;
     }
 
 
@@ -300,41 +294,43 @@
         efid = updateEfForIccType(efid);
         if (DBG) logd("getAdnRecordsInEF: efid=0x" + Integer.toHexString(efid).toUpperCase());
 
-        synchronized(mLock) {
-            checkThread();
-            AtomicBoolean status = new AtomicBoolean(false);
-            Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, status);
+        checkThread();
+        Request loadRequest = new Request();
+        synchronized (loadRequest) {
+            Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, loadRequest);
             if (mAdnCache != null) {
                 mAdnCache.requestLoadAllAdnLike(efid, mAdnCache.extensionEfForEf(efid), response);
-                waitForResult(status);
+                waitForResult(loadRequest);
             } else {
                 loge("Failure while trying to load from SIM due to uninitialised adncache");
             }
         }
-        return mRecords;
+        return (List<AdnRecord>) loadRequest.mResult;
     }
 
+    @UnsupportedAppUsage
     protected void checkThread() {
-        if (!ALLOW_SIM_OP_IN_UI_THREAD) {
-            // Make sure this isn't the UI thread, since it will block
-            if (mBaseHandler.getLooper().equals(Looper.myLooper())) {
-                loge("query() called on the main UI thread!");
-                throw new IllegalStateException(
-                        "You cannot call query on this provder from the main UI thread.");
+        // Make sure this isn't the UI thread, since it will block
+        if (mBaseHandler.getLooper().equals(Looper.myLooper())) {
+            loge("query() called on the main UI thread!");
+            throw new IllegalStateException(
+                    "You cannot call query on this provder from the main UI thread.");
+        }
+    }
+
+    protected void waitForResult(Request request) {
+        synchronized (request) {
+            while (!request.mStatus.get()) {
+                try {
+                    request.wait();
+                } catch (InterruptedException e) {
+                    logd("interrupted while trying to update by search");
+                }
             }
         }
     }
 
-    protected void waitForResult(AtomicBoolean status) {
-        while (!status.get()) {
-            try {
-                mLock.wait();
-            } catch (InterruptedException e) {
-                logd("interrupted while trying to update by search");
-            }
-        }
-    }
-
+    @UnsupportedAppUsage
     private int updateEfForIccType(int efid) {
         // Check if we are trying to read ADN records
         if (efid == IccConstants.EF_ADN) {
diff --git a/src/java/com/android/internal/telephony/IccProvider.java b/src/java/com/android/internal/telephony/IccProvider.java
index 76af170..3ac4027 100644
--- a/src/java/com/android/internal/telephony/IccProvider.java
+++ b/src/java/com/android/internal/telephony/IccProvider.java
@@ -16,34 +16,37 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.ContentProvider;
-import android.content.UriMatcher;
 import android.content.ContentValues;
+import android.content.UriMatcher;
 import android.database.Cursor;
-import android.database.MergeCursor;
 import android.database.MatrixCursor;
+import android.database.MergeCursor;
 import android.net.Uri;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.telephony.Rlog;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
-import android.telephony.Rlog;
-
-import java.util.List;
 
 import com.android.internal.telephony.uicc.AdnRecord;
 import com.android.internal.telephony.uicc.IccConstants;
 
+import java.util.List;
+
 
 /**
  * {@hide}
  */
 public class IccProvider extends ContentProvider {
     private static final String TAG = "IccProvider";
+    @UnsupportedAppUsage
     private static final boolean DBG = true;
 
 
+    @UnsupportedAppUsage
     private static final String[] ADDRESS_BOOK_COLUMN_NAMES = new String[] {
         "name",
         "number",
@@ -121,7 +124,8 @@
 
     private Cursor loadAllSimContacts(int efType) {
         Cursor [] result;
-        List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
+        List<SubscriptionInfo> subInfoList = mSubscriptionManager
+                .getActiveSubscriptionInfoList(false);
 
         if ((subInfoList == null) || (subInfoList.size() == 0)) {
             result = new Cursor[0];
@@ -511,6 +515,7 @@
      * @param record the ADN record to load from
      * @param cursor the cursor to receive the results
      */
+    @UnsupportedAppUsage
     private void loadRecord(AdnRecord record, MatrixCursor cursor, int id) {
         if (!record.isEmpty()) {
             Object[] contact = new Object[4];
@@ -536,6 +541,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void log(String msg) {
         Rlog.d(TAG, "[IccProvider] " + msg);
     }
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index c17244a..0b69eec 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -21,6 +21,7 @@
 import static android.telephony.SmsManager.STATUS_ON_ICC_UNREAD;
 
 import android.Manifest;
+import android.annotation.UnsupportedAppUsage;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
 import android.content.ContentResolver;
@@ -65,10 +66,14 @@
     static final String LOG_TAG = "IccSmsInterfaceManager";
     static final boolean DBG = true;
 
+    @UnsupportedAppUsage
     protected final Object mLock = new Object();
+    @UnsupportedAppUsage
     protected boolean mSuccess;
+    @UnsupportedAppUsage
     private List<SmsRawData> mSms;
 
+    @UnsupportedAppUsage
     private CellBroadcastRangeManager mCellBroadcastRangeManager =
             new CellBroadcastRangeManager();
     private CdmaBroadcastRangeManager mCdmaBroadcastRangeManager =
@@ -83,14 +88,18 @@
     public static final int SMS_MESSAGE_PRIORITY_NOT_SPECIFIED = -1;
     public static final int SMS_MESSAGE_PERIOD_NOT_SPECIFIED = -1;
 
+    @UnsupportedAppUsage
     protected Phone mPhone;
+    @UnsupportedAppUsage
     final protected Context mContext;
+    @UnsupportedAppUsage
     final protected AppOpsManager mAppOps;
     @VisibleForTesting
     public SmsDispatchersController mDispatchersController;
 
     private final LocalLog mCellBroadcastLocalLog = new LocalLog(100);
 
+    @UnsupportedAppUsage
     protected Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
@@ -183,6 +192,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     protected void enforceReceiveAndSend(String message) {
         mContext.enforceCallingOrSelfPermission(
                 Manifest.permission.RECEIVE_SMS, message);
@@ -202,6 +212,7 @@
      *
      */
 
+    @UnsupportedAppUsage
     public boolean
     updateMessageOnIccEf(String callingPackage, int index, int status, byte[] pdu) {
         if (DBG) log("updateMessageOnIccEf: index=" + index +
@@ -256,6 +267,7 @@
      * @return success or not
      *
      */
+    @UnsupportedAppUsage
     public boolean copyMessageToIccEf(String callingPackage, int status, byte[] pdu, byte[] smsc) {
         //NOTE smsc not used in RUIM
         if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
@@ -294,6 +306,7 @@
      * @return list of SmsRawData of all sms on Icc
      */
 
+    @UnsupportedAppUsage
     public List<SmsRawData> getAllMessagesFromIccEf(String callingPackage) {
         if (DBG) log("getAllMessagesFromEF");
 
@@ -335,25 +348,29 @@
             returnUnspecifiedFailure(sentIntent);
             return;
         }
-        sendDataInternal(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
+        sendDataInternal(callingPackage, destAddr, scAddr, destPort, data, sentIntent,
+                deliveryIntent);
     }
 
     /**
      * A permissions check before passing to {@link IccSmsInterfaceManager#sendDataInternal}.
      * This method checks only if the calling package has the permission to send the data sms.
      */
+    @UnsupportedAppUsage
     public void sendData(String callingPackage, String destAddr, String scAddr, int destPort,
             byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
         if (!checkCallingSendSmsPermission(callingPackage, "Sending SMS message")) {
             returnUnspecifiedFailure(sentIntent);
             return;
         }
-        sendDataInternal(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
+        sendDataInternal(callingPackage, destAddr, scAddr, destPort, data, sentIntent,
+                deliveryIntent);
     }
 
     /**
      * Send a data based SMS to a specific application port.
      *
+     * @param callingPackage the package name of the calling app
      * @param destAddr the address to send the message to
      * @param scAddr is the service center address or null to use
      *  the current default SMSC
@@ -377,7 +394,7 @@
      *  raw pdu of the status report is in the extended data ("pdu").
      */
 
-    private void sendDataInternal(String destAddr, String scAddr,
+    private void sendDataInternal(String callingPackage, String destAddr, String scAddr,
             int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
         if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
             log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" +
@@ -385,8 +402,8 @@
                 sentIntent + " deliveryIntent=" + deliveryIntent);
         }
         destAddr = filterDestAddress(destAddr);
-        mDispatchersController.sendData(destAddr, scAddr, destPort, data, sentIntent,
-                deliveryIntent);
+        mDispatchersController.sendData(callingPackage, destAddr, scAddr, destPort, data,
+                sentIntent, deliveryIntent);
     }
 
     /**
@@ -553,6 +570,7 @@
      *  android application framework. This intent is broadcasted at
      *  the same time an SMS received from radio is acknowledged back.
      */
+    @UnsupportedAppUsage
     public void injectSmsPdu(byte[] pdu, String format, PendingIntent receivedIntent) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -722,11 +740,13 @@
         }
     }
 
+    @UnsupportedAppUsage
     public int getPremiumSmsPermission(String packageName) {
         return mDispatchersController.getPremiumSmsPermission(packageName);
     }
 
 
+    @UnsupportedAppUsage
     public void setPremiumSmsPermission(String packageName, int permission) {
         mDispatchersController.setPremiumSmsPermission(packageName, permission);
     }
@@ -812,6 +832,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     synchronized public boolean enableGsmBroadcastRange(int startMessageId, int endMessageId) {
 
         mContext.enforceCallingPermission(
@@ -842,6 +863,7 @@
         return true;
     }
 
+    @UnsupportedAppUsage
     synchronized public boolean disableGsmBroadcastRange(int startMessageId, int endMessageId) {
 
         mContext.enforceCallingPermission(
@@ -872,6 +894,7 @@
         return true;
     }
 
+    @UnsupportedAppUsage
     synchronized public boolean enableCdmaBroadcastRange(int startMessageId, int endMessageId) {
 
         mContext.enforceCallingPermission(
@@ -901,6 +924,7 @@
         return true;
     }
 
+    @UnsupportedAppUsage
     synchronized public boolean disableCdmaBroadcastRange(int startMessageId, int endMessageId) {
 
         mContext.enforceCallingPermission(
@@ -1010,6 +1034,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) {
         if (DBG)
             log("Calling setGsmBroadcastConfig with " + configs.length + " configurations");
@@ -1050,6 +1075,7 @@
         return mSuccess;
     }
 
+    @UnsupportedAppUsage
     private boolean setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs) {
         if (DBG)
             log("Calling setCdmaBroadcastConfig with " + configs.length + " configurations");
@@ -1090,18 +1116,22 @@
         return mSuccess;
     }
 
+    @UnsupportedAppUsage
     protected void log(String msg) {
         Log.d(LOG_TAG, "[IccSmsInterfaceManager] " + msg);
     }
 
+    @UnsupportedAppUsage
     public boolean isImsSmsSupported() {
         return mDispatchersController.isIms();
     }
 
+    @UnsupportedAppUsage
     public String getImsSmsFormat() {
         return mDispatchersController.getImsSmsFormat();
     }
 
+    @UnsupportedAppUsage
     public void sendStoredText(String callingPkg, Uri messageUri, String scAddress,
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
         if (!checkCallingSendSmsPermission(callingPkg, "Sending SMS message")) {
@@ -1131,6 +1161,7 @@
                 false /* expectMore */, SMS_MESSAGE_PERIOD_NOT_SPECIFIED);
     }
 
+    @UnsupportedAppUsage
     public void sendStoredMultipartText(String callingPkg, Uri messageUri, String scAddress,
             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
         if (!checkCallingSendSmsPermission(callingPkg, "Sending SMS message")) {
@@ -1368,6 +1399,7 @@
         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mPhone.getSubId(), message);
     }
 
+    @UnsupportedAppUsage
     private String filterDestAddress(String destAddr) {
         String result  = null;
         result = SmsNumberUtils.filterDestAddr(mPhone, destAddr);
diff --git a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
index c558721..66e4e4f 100644
--- a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
+++ b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
@@ -90,7 +90,7 @@
                 }
 
                 @Override
-                public void onDeregistered(ImsReasonInfo info) {
+                public void onUnregistered(ImsReasonInfo info) {
                     Rlog.d(TAG, "onImsDisconnected imsReasonInfo=" + info);
                     synchronized (mLock) {
                         mIsRegistered = false;
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index e6c3e9d..aa34559 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -19,6 +19,7 @@
 import static android.service.carrier.CarrierMessagingService.RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE;
 import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
@@ -186,13 +187,17 @@
     protected static final Uri sRawUriPermanentDelete =
             Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
 
+    @UnsupportedAppUsage
     protected final Context mContext;
+    @UnsupportedAppUsage
     private final ContentResolver mResolver;
 
     /** Special handler for WAP push messages. */
+    @UnsupportedAppUsage
     private final WapPushOverSms mWapPush;
 
     /** Wake lock to ensure device stays awake while dispatching the SMS intents. */
+    @UnsupportedAppUsage
     private final PowerManager.WakeLock mWakeLock;
 
     /** DefaultState throws an exception or logs an error for unhandled message types. */
@@ -202,12 +207,15 @@
     private final StartupState mStartupState = new StartupState();
 
     /** Idle state. Waiting for messages to process. */
+    @UnsupportedAppUsage
     private final IdleState mIdleState = new IdleState();
 
     /** Delivering state. Saves the PDU in the raw table and acknowledges to SMSC. */
+    @UnsupportedAppUsage
     private final DeliveringState mDeliveringState = new DeliveringState();
 
     /** Broadcasting state. Waits for current broadcast to complete before delivering next. */
+    @UnsupportedAppUsage
     private final WaitingState mWaitingState = new WaitingState();
 
     /** Helper class to check whether storage is available for incoming messages. */
@@ -215,16 +223,20 @@
 
     private final boolean mSmsReceiveDisabled;
 
+    @UnsupportedAppUsage
     protected Phone mPhone;
 
+    @UnsupportedAppUsage
     protected CellBroadcastHandler mCellBroadcastHandler;
 
+    @UnsupportedAppUsage
     private UserManager mUserManager;
 
     protected TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
 
     private LocalLog mLocalLog = new LocalLog(64);
 
+    @UnsupportedAppUsage
     IDeviceIdleController mDeviceIdleController;
 
     // Delete permanently from raw table
@@ -301,6 +313,7 @@
     }
 
     // CAF_MSIM Is this used anywhere ? if not remove it
+    @UnsupportedAppUsage
     public Phone getPhone() {
         return mPhone;
     }
@@ -575,6 +588,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void handleNewSms(AsyncResult ar) {
         if (ar.exception != null) {
             loge("Exception processing incoming SMS: " + ar.exception);
@@ -603,6 +617,7 @@
      * This method is called when a new SMS PDU is injected into application framework.
      * @param ar is the AsyncResult that has the SMS PDU to be injected.
      */
+    @UnsupportedAppUsage
     private void handleInjectSms(AsyncResult ar) {
         int result;
         SmsDispatchersController.SmsInjectionCallback callback = null;
@@ -687,6 +702,7 @@
      * @param result result code indicating any error
      * @param response callback message sent when operation completes.
      */
+    @UnsupportedAppUsage
     protected abstract void acknowledgeLastIncomingSms(boolean success,
             int result, Message response);
 
@@ -726,6 +742,7 @@
      * @param sms the message to dispatch
      * @return {@link Intents#RESULT_SMS_HANDLED} if the message was accepted, or an error status
      */
+    @UnsupportedAppUsage
     protected int dispatchNormalMessage(SmsMessageBase sms) {
         SmsHeader smsHeader = sms.getUserDataHeader();
         InboundSmsTracker tracker;
@@ -794,6 +811,7 @@
      * @param tracker the tracker containing the message segment to process
      * @return true if an ordered broadcast was sent; false if waiting for more message segments
      */
+    @UnsupportedAppUsage
     private boolean processMessagePart(InboundSmsTracker tracker) {
         int messageCount = tracker.getMessageCount();
         byte[][] pdus;
@@ -1010,6 +1028,7 @@
         return false;
     }
 
+    @UnsupportedAppUsage
     private void showNewMessageNotification() {
         // Do not show the notification on non-FBE devices.
         if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
@@ -1092,6 +1111,7 @@
      * @param appOp app op that is being performed when dispatching to a receiver
      * @param user user to deliver the intent to
      */
+    @UnsupportedAppUsage
     public void dispatchIntent(Intent intent, String permission, int appOp,
             Bundle opts, BroadcastReceiver resultReceiver, UserHandle user) {
         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
@@ -1148,6 +1168,7 @@
     /**
      * Helper for {@link SmsBroadcastUndelivered} to delete an old message in the raw table.
      */
+    @UnsupportedAppUsage
     private void deleteFromRawTable(String deleteWhere, String[] deleteWhereArgs,
                                     int deleteType) {
         Uri uri = deleteType == DELETE_PERMANENTLY ? sRawUriPermanentDelete : sRawUri;
@@ -1159,6 +1180,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private Bundle handleSmsWhitelisting(ComponentName target) {
         String pkgName;
         String reason;
@@ -1398,7 +1420,9 @@
      * logs the broadcast duration (as an error if the other receivers were especially slow).
      */
     private final class SmsBroadcastReceiver extends BroadcastReceiver {
+        @UnsupportedAppUsage
         private final String mDeleteWhere;
+        @UnsupportedAppUsage
         private final String[] mDeleteWhereArgs;
         private long mBroadcastTimeNano;
 
@@ -1536,6 +1560,7 @@
     /** Checks whether the flag to skip new message notification is set in the bitmask returned
      *  from the carrier app.
      */
+    @UnsupportedAppUsage
     private boolean isSkipNotifyFlagSet(int callbackResult) {
         return (callbackResult
             & RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE) > 0;
@@ -1545,6 +1570,7 @@
      * Log with debug level.
      * @param s the string to log
      */
+    @UnsupportedAppUsage
     @Override
     protected void log(String s) {
         Rlog.d(getName(), s);
@@ -1554,6 +1580,7 @@
      * Log with error level.
      * @param s the string to log
      */
+    @UnsupportedAppUsage
     @Override
     protected void loge(String s) {
         Rlog.e(getName(), s);
@@ -1575,6 +1602,7 @@
      * @param intent The intent containing the received SMS
      * @return The URI of written message
      */
+    @UnsupportedAppUsage
     private Uri writeInboxMessage(Intent intent) {
         final SmsMessage[] messages = Telephony.Sms.Intents.getMessagesFromIntent(intent);
         if (messages == null || messages.length < 1) {
diff --git a/src/java/com/android/internal/telephony/InboundSmsTracker.java b/src/java/com/android/internal/telephony/InboundSmsTracker.java
index 50c84c8..2c98239 100644
--- a/src/java/com/android/internal/telephony/InboundSmsTracker.java
+++ b/src/java/com/android/internal/telephony/InboundSmsTracker.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.ContentValues;
 import android.database.Cursor;
 import android.util.Pair;
@@ -306,6 +307,7 @@
         return mIs3gpp2;
     }
 
+    @UnsupportedAppUsage
     public String getFormat() {
         return mIs3gpp2 ? SmsConstants.FORMAT_3GPP2 : SmsConstants.FORMAT_3GPP;
     }
@@ -377,6 +379,7 @@
      * messages, which use a 0-based index.
      * @return the offset to use to convert between mIndex and the sequence number
      */
+    @UnsupportedAppUsage
     public int getIndexOffset() {
         return (mIs3gpp2 && mIs3gpp2WapPdu) ? 0 : 1;
     }
diff --git a/src/java/com/android/internal/telephony/IntRangeManager.java b/src/java/com/android/internal/telephony/IntRangeManager.java
index 3da2cc5..b82a20e 100644
--- a/src/java/com/android/internal/telephony/IntRangeManager.java
+++ b/src/java/com/android/internal/telephony/IntRangeManager.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import java.util.ArrayList;
 import java.util.Iterator;
 
@@ -176,6 +177,7 @@
     /**
      * List of integer ranges, one per client, sorted by start id.
      */
+    @UnsupportedAppUsage
     private ArrayList<IntRange> mRanges = new ArrayList<IntRange>();
 
     protected IntRangeManager() {}
diff --git a/src/java/com/android/internal/telephony/LocaleTracker.java b/src/java/com/android/internal/telephony/LocaleTracker.java
index f952ae4..9e98c64 100755
--- a/src/java/com/android/internal/telephony/LocaleTracker.java
+++ b/src/java/com/android/internal/telephony/LocaleTracker.java
@@ -272,7 +272,7 @@
     public void updateOperatorNumeric(String operatorNumeric) {
         // Check if the operator numeric changes.
         if (!Objects.equals(mOperatorNumeric, operatorNumeric)) {
-            String msg = "Operator numeric changes to " + operatorNumeric;
+            String msg = "Operator numeric changes to \"" + operatorNumeric + "\"";
             if (DBG) log(msg);
             mLocalLog.log(msg);
             mOperatorNumeric = operatorNumeric;
@@ -286,23 +286,8 @@
             return;
         }
         List<CellInfo> cellInfoList = (List<CellInfo>) ar.result;
-        String msg = "getCellInfo: cell info=" + cellInfoList;
+        String msg = "processCellInfo: cell info=" + cellInfoList;
         if (DBG) log(msg);
-        if (cellInfoList != null) {
-            // We only log when cell identity changes, otherwise the local log is flooded with cell
-            // info.
-            if (mCellInfoList == null || cellInfoList.size() != mCellInfoList.size()) {
-                mLocalLog.log(msg);
-            } else {
-                for (int i = 0; i < cellInfoList.size(); i++) {
-                    if (!Objects.equals(mCellInfoList.get(i).getCellIdentity(),
-                            cellInfoList.get(i).getCellIdentity())) {
-                        mLocalLog.log(msg);
-                        break;
-                    }
-                }
-            }
-        }
         mCellInfoList = cellInfoList;
         updateLocale();
     }
@@ -412,7 +397,7 @@
         boolean countryChanged = false;
         if (!Objects.equals(countryIso, mCurrentCountryIso)) {
             String msg = "updateLocale: Change the current country to \"" + countryIso
-                    + "\", mcc = " + mcc;
+                    + "\", mcc = " + mcc + ", mCellInfoList = " + mCellInfoList;
             log(msg);
             mLocalLog.log(msg);
             mCurrentCountryIso = countryIso;
diff --git a/src/java/com/android/internal/telephony/MccTable.java b/src/java/com/android/internal/telephony/MccTable.java
index b1cfb7b..76338c3 100644
--- a/src/java/com/android/internal/telephony/MccTable.java
+++ b/src/java/com/android/internal/telephony/MccTable.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -51,6 +52,7 @@
 
     static class MccEntry implements Comparable<MccEntry> {
         final int mMcc;
+        @UnsupportedAppUsage
         final String mIso;
         final int mSmallestDigitsMnc;
 
@@ -69,6 +71,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private static MccEntry entryForMcc(int mcc) {
         MccEntry m = new MccEntry(mcc, "", 0);
 
@@ -86,6 +89,7 @@
      * @param mcc Mobile Country Code
      * @return default TimeZone ID, or null if not specified
      */
+    @UnsupportedAppUsage
     public static String defaultTimeZoneForMcc(int mcc) {
         MccEntry entry = entryForMcc(mcc);
         if (entry == null) {
@@ -100,6 +104,7 @@
      * an ISO two-character country code if available.
      * Returns "" if unavailable.
      */
+    @UnsupportedAppUsage
     public static String countryCodeForMcc(int mcc) {
         MccEntry entry = entryForMcc(mcc);
 
@@ -128,6 +133,7 @@
      * an ISO 2-3 character language code if available.
      * Returns null if unavailable.
      */
+    @UnsupportedAppUsage
     public static String defaultLanguageForMcc(int mcc) {
         MccEntry entry = entryForMcc(mcc);
         if (entry == null) {
@@ -155,6 +161,7 @@
      * the smallest number of digits that M if available.
      * Returns 2 if unavailable.
      */
+    @UnsupportedAppUsage
     public static int smallestDigitsMccForMnc(int mcc) {
         MccEntry entry = entryForMcc(mcc);
 
@@ -261,6 +268,7 @@
      *
      * @return Locale or null if no appropriate value
      */
+    @UnsupportedAppUsage
     private static Locale getLocaleForLanguageCountry(Context context, String language,
             String country) {
         if (language == null) {
diff --git a/src/java/com/android/internal/telephony/MmiCode.java b/src/java/com/android/internal/telephony/MmiCode.java
index da5321a..eb09621 100644
--- a/src/java/com/android/internal/telephony/MmiCode.java
+++ b/src/java/com/android/internal/telephony/MmiCode.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.ResultReceiver;
 
 import java.util.regex.Pattern;
@@ -29,9 +30,13 @@
      * {@hide}
      */
     public enum State {
+        @UnsupportedAppUsage
         PENDING,
+        @UnsupportedAppUsage
         CANCELLED,
+        @UnsupportedAppUsage
         COMPLETE,
+        @UnsupportedAppUsage
         FAILED
     }
 
@@ -50,6 +55,7 @@
     /**
      * @return Phone associated with the MMI/USSD message
      */
+    @UnsupportedAppUsage
     public Phone getPhone();
 
     /**
diff --git a/src/java/com/android/internal/telephony/NetworkRegistrationManager.java b/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
index 54fbcd6..0d8fc79 100644
--- a/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
+++ b/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
@@ -16,18 +16,21 @@
 
 package com.android.internal.telephony;
 
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.os.Registrant;
 import android.os.RegistrantList;
 import android.os.RemoteException;
+import android.os.UserHandle;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.INetworkService;
@@ -35,6 +38,7 @@
 import android.telephony.NetworkRegistrationState;
 import android.telephony.NetworkService;
 import android.telephony.Rlog;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
 import java.util.Hashtable;
@@ -44,8 +48,10 @@
  * Class that serves as the layer between NetworkService and ServiceStateTracker. It helps binding,
  * sending request and registering for state change to NetworkService.
  */
-public class NetworkRegistrationManager {
-    private static final String TAG = NetworkRegistrationManager.class.getSimpleName();
+public class NetworkRegistrationManager extends Handler {
+    private final String mTag;
+
+    private static final int EVENT_BIND_NETWORK_SERVICE = 1;
 
     private final int mTransportType;
 
@@ -60,13 +66,61 @@
 
     private RegManagerDeathRecipient mDeathRecipient;
 
-    public NetworkRegistrationManager(int transportType, Phone phone) {
+    private String mTargetBindingPackageName;
+
+    private NetworkServiceConnection mServiceConnection;
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)
+                    && mPhone.getPhoneId() == intent.getIntExtra(
+                    CarrierConfigManager.EXTRA_SLOT_INDEX, 0)) {
+                // We should wait for carrier config changed event because the target binding
+                // package name can come from the carrier config. Note that we still get this event
+                // even when SIM is absent.
+                logd("Carrier config changed. Try to bind network service.");
+                sendEmptyMessage(EVENT_BIND_NETWORK_SERVICE);
+            }
+        }
+    };
+
+    public NetworkRegistrationManager(@TransportType int transportType, Phone phone) {
         mTransportType = transportType;
         mPhone = phone;
+
+        String tagSuffix = "-" + ((transportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                ? "C" : "I");
+        if (TelephonyManager.getDefault().getPhoneCount() > 1) {
+            tagSuffix += "-" + mPhone.getPhoneId();
+        }
+        mTag = "NRM" + tagSuffix;
+
         mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService(
                 Context.CARRIER_CONFIG_SERVICE);
 
-        bindService();
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        phone.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+                intentFilter, null, null);
+        sendEmptyMessage(EVENT_BIND_NETWORK_SERVICE);
+    }
+
+    /**
+     * Handle message events
+     *
+     * @param msg The message to handle
+     */
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case EVENT_BIND_NETWORK_SERVICE:
+                bindService();
+                break;
+            default:
+                loge("Unhandled event " + msg.what);
+        }
     }
 
     public boolean isServiceConnected() {
@@ -79,7 +133,6 @@
 
     public void registerForNetworkRegistrationStateChanged(Handler h, int what, Object obj) {
         logd("registerForNetworkRegistrationStateChanged");
-        Registrant r = new Registrant(h, what, obj);
         mRegStateChangeRegistrants.addUnique(h, what, obj);
     }
 
@@ -103,7 +156,7 @@
             mCallbackTable.put(callback, onCompleteMessage);
             mINetworkService.getNetworkRegistrationState(mPhone.getPhoneId(), domain, callback);
         } catch (RemoteException e) {
-            Rlog.e(TAG, "getNetworkRegistrationState RemoteException " + e);
+            loge("getNetworkRegistrationState RemoteException " + e);
             mCallbackTable.remove(callback);
             onCompleteMessage.obj = new AsyncResult(onCompleteMessage.obj, null, e);
             onCompleteMessage.sendToTarget();
@@ -130,7 +183,8 @@
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             logd("service " + name + " for transport "
-                    + TransportType.toString(mTransportType) + " is now connected.");
+                    + AccessNetworkConstants.transportTypeToString(mTransportType)
+                    + " is now connected.");
             mINetworkService = INetworkService.Stub.asInterface(service);
             mDeathRecipient = new RegManagerDeathRecipient(name);
             try {
@@ -148,7 +202,9 @@
         @Override
         public void onServiceDisconnected(ComponentName name) {
             logd("service " + name + " for transport "
-                    + TransportType.toString(mTransportType) + " is now disconnected.");
+                    + AccessNetworkConstants.transportTypeToString(mTransportType)
+                    + " is now disconnected.");
+            mTargetBindingPackageName = null;
             if (mINetworkService != null) {
                 mINetworkService.asBinder().unlinkToDeath(mDeathRecipient, 0);
             }
@@ -178,19 +234,46 @@
         }
     }
 
-    private boolean bindService() {
+    private void bindService() {
+        String packageName = getPackageName();
+        if (TextUtils.isEmpty(packageName)) {
+            loge("Can't find the binding package");
+            return;
+        }
+
+        if (TextUtils.equals(packageName, mTargetBindingPackageName)) {
+            logd("Service " + packageName + " already bound or being bound.");
+            return;
+        }
+
+        if (mINetworkService != null && mINetworkService.asBinder().isBinderAlive()) {
+            // Remove the network availability updater and then unbind the service.
+            try {
+                mINetworkService.removeNetworkServiceProvider(mPhone.getPhoneId());
+            } catch (RemoteException e) {
+                loge("Cannot remove data service provider. " + e);
+            }
+
+            mPhone.getContext().unbindService(mServiceConnection);
+        }
+
         Intent intent = new Intent(NetworkService.NETWORK_SERVICE_INTERFACE);
         intent.setPackage(getPackageName());
+
         try {
             // We bind this as a foreground service because it is operating directly on the SIM,
             // and we do not want it subjected to power-savings restrictions while doing so.
             logd("Trying to bind " + getPackageName() + " for transport "
-                    + TransportType.toString(mTransportType));
-            return mPhone.getContext().bindService(intent, new NetworkServiceConnection(),
-                    Context.BIND_AUTO_CREATE);
+                    + AccessNetworkConstants.transportTypeToString(mTransportType));
+            mServiceConnection = new NetworkServiceConnection();
+            if (!mPhone.getContext().bindService(intent, mServiceConnection,
+                    Context.BIND_AUTO_CREATE)) {
+                loge("Cannot bind to the data service.");
+                return;
+            }
+            mTargetBindingPackageName = packageName;
         } catch (SecurityException e) {
             loge("bindService failed " + e);
-            return false;
         }
     }
 
@@ -200,12 +283,12 @@
         String carrierConfig;
 
         switch (mTransportType) {
-            case TransportType.WWAN:
+            case AccessNetworkConstants.TRANSPORT_TYPE_WWAN:
                 resourceId = com.android.internal.R.string.config_wwan_network_service_package;
                 carrierConfig = CarrierConfigManager
                         .KEY_CARRIER_NETWORK_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING;
                 break;
-            case TransportType.WLAN:
+            case AccessNetworkConstants.TRANSPORT_TYPE_WLAN:
                 resourceId = com.android.internal.R.string.config_wlan_network_service_package;
                 carrierConfig = CarrierConfigManager
                         .KEY_CARRIER_NETWORK_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING;
@@ -228,11 +311,11 @@
         return packageName;
     }
 
-    private static int logd(String msg) {
-        return Rlog.d(TAG, msg);
+    private void logd(String msg) {
+        Rlog.d(mTag, msg);
     }
 
-    private static int loge(String msg) {
-        return Rlog.e(TAG, msg);
+    private void loge(String msg) {
+        Rlog.e(mTag, msg);
     }
 }
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 195d442..806bfdb 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -40,7 +41,7 @@
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.telecom.VideoProfile;
-import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CarrierRestrictionRules;
 import android.telephony.CellInfo;
@@ -262,6 +263,7 @@
     }
 
     /* Instance Variables */
+    @UnsupportedAppUsage
     public CommandsInterface mCi;
     protected int mVmCount = 0;
     private boolean mDnsCheckDisabled;
@@ -287,10 +289,14 @@
     // Variable to cache the video capability. When RAT changes, we lose this info and are unable
     // to recover from the state. We cache it and notify listeners when they register.
     protected boolean mIsVideoCapable = false;
+    @UnsupportedAppUsage
     protected UiccController mUiccController = null;
+    @UnsupportedAppUsage
     protected final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
+    @UnsupportedAppUsage
     public SmsStorageMonitor mSmsStorageMonitor;
     public SmsUsageMonitor mSmsUsageMonitor;
+    @UnsupportedAppUsage
     protected AtomicReference<UiccCardApplication> mUiccApplication =
             new AtomicReference<UiccCardApplication>();
     TelephonyTester mTelephonyTester;
@@ -303,9 +309,11 @@
     // Used for identify the carrier of current subscription
     protected CarrierResolver mCarrierResolver;
 
+    @UnsupportedAppUsage
     protected int mPhoneId;
 
     private boolean mImsServiceReady = false;
+    @UnsupportedAppUsage
     protected Phone mImsPhone = null;
 
     private final AtomicReference<RadioCapability> mRadioCapability =
@@ -342,6 +350,7 @@
 
     protected final RegistrantList mMmiCompleteRegistrants = new RegistrantList();
 
+    @UnsupportedAppUsage
     protected final RegistrantList mMmiRegistrants = new RegistrantList();
 
     protected final RegistrantList mUnknownConnectionRegistrants = new RegistrantList();
@@ -364,6 +373,7 @@
 
     private Looper mLooper; /* to insure registrants are in correct thread*/
 
+    @UnsupportedAppUsage
     protected final Context mContext;
 
     /**
@@ -371,6 +381,7 @@
      * state change notification. DefaultPhoneNotifier is
      * used here unless running we're inside a unit test.
      */
+    @UnsupportedAppUsage
     protected PhoneNotifier mNotifier;
 
     protected SimulatedRadioControl mSimulatedRadioControl;
@@ -386,6 +397,7 @@
      *  outside the phone app process.
      *  @return The string name.
      */
+    @UnsupportedAppUsage
     public String getPhoneName() {
         return mName;
     }
@@ -397,6 +409,7 @@
     /**
      * Retrieves Nai for phones. Returns null if Nai is not set.
      */
+    @UnsupportedAppUsage
     public String getNai(){
          return null;
     }
@@ -448,6 +461,7 @@
      * Set a system property, unless we're in unit test mode
      */
     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
+    @UnsupportedAppUsage
     public String getSystemProperty(String property, String defValue) {
         if(getUnitTestMode()) {
             return null;
@@ -589,8 +603,8 @@
             if (imsManager != null && !imsManager.isDynamicBinding()) {
                 filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
                 filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
+                mContext.registerReceiver(mImsIntentReceiver, filter);
             }
-            mContext.registerReceiver(mImsIntentReceiver, filter);
 
             // Monitor IMS service - but first poll to see if already up (could miss
             // intent). Also, when using new ImsResolver APIs, the service will be available soon,
@@ -796,6 +810,7 @@
     /**
      * Gets the context for the phone, as set at initialization time.
      */
+    @UnsupportedAppUsage
     public Context getContext() {
         return mContext;
     }
@@ -832,6 +847,7 @@
      * AsyncResult.userData will be set to the obj argument here.
      * The <em>h</em> parameter is held only by a weak reference.
      */
+    @UnsupportedAppUsage
     public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
         checkCorrectThread(h);
 
@@ -842,6 +858,7 @@
      * Unregisters for voice call state change notifications.
      * Extraneous calls are tolerated silently.
      */
+    @UnsupportedAppUsage
     public void unregisterForPreciseCallStateChanged(Handler h) {
         mPreciseCallStateRegistrants.remove(h);
     }
@@ -927,6 +944,7 @@
      * Notifies when a previously untracked non-ringing/waiting connection has appeared.
      * This is likely due to some other entity (eg, SIM card application) initiating a call.
      */
+    @UnsupportedAppUsage
     public void registerForUnknownConnection(Handler h, int what, Object obj) {
         checkCorrectThread(h);
 
@@ -936,6 +954,7 @@
     /**
      * Unregisters for unknown connection notifications.
      */
+    @UnsupportedAppUsage
     public void unregisterForUnknownConnection(Handler h) {
         mUnknownConnectionRegistrants.remove(h);
     }
@@ -952,6 +971,7 @@
      *  If Connection.isRinging() is true, then
      *   Connection.getCall() == Phone.getRingingCall()
      */
+    @UnsupportedAppUsage
     public void registerForNewRingingConnection(
             Handler h, int what, Object obj) {
         checkCorrectThread(h);
@@ -963,6 +983,7 @@
      * Unregisters for new ringing connection notification.
      * Extraneous calls are tolerated silently
      */
+    @UnsupportedAppUsage
     public void unregisterForNewRingingConnection(Handler h) {
         mNewRingingConnectionRegistrants.remove(h);
     }
@@ -1041,6 +1062,7 @@
      *  AsyncResult.userObj = obj
      *  AsyncResult.result = a Connection. <p>
      */
+    @UnsupportedAppUsage
     public void registerForIncomingRing(
             Handler h, int what, Object obj) {
         checkCorrectThread(h);
@@ -1052,6 +1074,7 @@
      * Unregisters for ring notification.
      * Extraneous calls are tolerated silently
      */
+    @UnsupportedAppUsage
     public void unregisterForIncomingRing(Handler h) {
         mIncomingRingRegistrants.remove(h);
     }
@@ -1066,6 +1089,7 @@
      *  <li>AsyncResult.result = a Connection object that is
      *  no longer connected.</li></ul>
      */
+    @UnsupportedAppUsage
     public void registerForDisconnect(Handler h, int what, Object obj) {
         checkCorrectThread(h);
 
@@ -1076,6 +1100,7 @@
      * Unregisters for voice disconnection notification.
      * Extraneous calls are tolerated silently
      */
+    @UnsupportedAppUsage
     public void unregisterForDisconnect(Handler h) {
         mDisconnectRegistrants.remove(h);
     }
@@ -1115,6 +1140,7 @@
      *
      * <code>obj.result</code> will be an "MmiCode" object.
      */
+    @UnsupportedAppUsage
     public void registerForMmiInitiate(Handler h, int what, Object obj) {
         checkCorrectThread(h);
 
@@ -1125,6 +1151,7 @@
      * Unregisters for new MMI initiate notification.
      * Extraneous calls are tolerated silently
      */
+    @UnsupportedAppUsage
     public void unregisterForMmiInitiate(Handler h) {
         mMmiRegistrants.remove(h);
     }
@@ -1137,6 +1164,7 @@
      * <code>Message.obj</code> will contain an AsyncResult.
      * <code>obj.result</code> will be an "MmiCode" object
      */
+    @UnsupportedAppUsage
     public void registerForMmiComplete(Handler h, int what, Object obj) {
         checkCorrectThread(h);
 
@@ -1147,6 +1175,7 @@
      * Unregisters for MMI complete notification.
      * Extraneous calls are tolerated silently
      */
+    @UnsupportedAppUsage
     public void unregisterForMmiComplete(Handler h) {
         checkCorrectThread(h);
 
@@ -1159,6 +1188,7 @@
      * @param what what code of message when delivered
      * @param obj placed in Message.obj
      */
+    @UnsupportedAppUsage
     public void registerForSimRecordsLoaded(Handler h, int what, Object obj) {
     }
 
@@ -1166,6 +1196,7 @@
      * Unregister for notifications for Sim records loaded
      * @param h Handler to be removed from the registrant list.
      */
+    @UnsupportedAppUsage
     public void unregisterForSimRecordsLoaded(Handler h) {
     }
 
@@ -1199,6 +1230,7 @@
      *
      * @see #selectNetworkManually(OperatorInfo, boolean, android.os.Message)
      */
+    @UnsupportedAppUsage
     public void setNetworkSelectionModeAutomatic(Message response) {
         Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic, querying current mode");
         // we don't want to do this unecesarily - it acutally causes
@@ -1274,6 +1306,7 @@
      *
      * @see #setNetworkSelectionModeAutomatic(Message)
      */
+    @UnsupportedAppUsage
     public void selectNetworkManually(OperatorInfo network, boolean persistSelection,
             Message response) {
         // wrap the response message in our own message along with
@@ -1442,6 +1475,7 @@
      * Message.obj will contain an AsyncResult.
      * AsyncResult.result will be a ServiceState instance
      */
+    @UnsupportedAppUsage
     public void registerForServiceStateChanged(
             Handler h, int what, Object obj) {
         mServiceStateRegistrants.add(h, what, obj);
@@ -1451,6 +1485,7 @@
      * Unregisters for ServiceStateChange notification.
      * Extraneous calls are tolerated silently
      */
+    @UnsupportedAppUsage
     public void unregisterForServiceStateChanged(Handler h) {
         mServiceStateRegistrants.remove(h);
     }
@@ -1464,6 +1499,7 @@
      *  AsyncResult.result = boolean, true to start play ringback tone
      *                       and false to stop. <p>
      */
+    @UnsupportedAppUsage
     public void registerForRingbackTone(Handler h, int what, Object obj) {
         mCi.registerForRingbackTone(h, what, obj);
     }
@@ -1471,6 +1507,7 @@
     /**
      * Unregisters for ringback tone notification.
      */
+    @UnsupportedAppUsage
     public void unregisterForRingbackTone(Handler h) {
         mCi.unregisterForRingbackTone(h);
     }
@@ -1601,11 +1638,13 @@
      * This registration point provides notification of finer-grained
      * changes.<p>
      */
+    @UnsupportedAppUsage
     public abstract PhoneConstants.State getState();
 
     /**
      * Retrieves the IccFileHandler of the Phone instance
      */
+    @UnsupportedAppUsage
     public IccFileHandler getIccFileHandler(){
         UiccCardApplication uiccApplication = mUiccApplication.get();
         IccFileHandler fh;
@@ -1639,6 +1678,7 @@
     /**
     * Retrieves the ServiceStateTracker of the phone instance.
     */
+    @UnsupportedAppUsage
     public ServiceStateTracker getServiceStateTracker() {
         return null;
     }
@@ -1653,6 +1693,7 @@
     /**
     * Get call tracker
     */
+    @UnsupportedAppUsage
     public CallTracker getCallTracker() {
         return null;
     }
@@ -1709,6 +1750,7 @@
      * Returns the ICC card interface for this phone, or null
      * if not applicable to underlying technology.
      */
+    @UnsupportedAppUsage
     public IccCard getIccCard() {
         return null;
         //throw new Exception("getIccCard Shouldn't be called from Phone");
@@ -1718,6 +1760,7 @@
      * Retrieves the serial number of the ICC, if applicable. Returns only the decimal digits before
      * the first hex digit in the ICC ID.
      */
+    @UnsupportedAppUsage
     public String getIccSerialNumber() {
         IccRecords r = mIccRecords.get();
         return (r != null) ? r.getIccId() : null;
@@ -1767,6 +1810,7 @@
     /**
      * @return the current cell location if known
      */
+    @UnsupportedAppUsage
     public CellLocation getCellLocation() {
         return getServiceStateTracker().getCellLocation();
     }
@@ -1964,6 +2008,7 @@
      * @param networkType one of  NT_*_TYPE
      * @param response is callback message
      */
+    @UnsupportedAppUsage
     public void setPreferredNetworkType(int networkType, Message response) {
         // Only set preferred network types to that which the modem supports
         int modemRaf = getRadioAccessFamily();
@@ -2008,6 +2053,7 @@
      *
      * @param result Callback message contains the SMSC address.
      */
+    @UnsupportedAppUsage
     public void getSmscAddress(Message result) {
         mCi.getSmscAddress(result);
     }
@@ -2018,6 +2064,7 @@
      * @param address new SMSC address
      * @param result Callback message is empty on completion
      */
+    @UnsupportedAppUsage
     public void setSmscAddress(String address, Message result) {
         mCi.setSmscAddress(address, result);
     }
@@ -2114,6 +2161,7 @@
      * @see #invokeOemRilRequestRaw(byte[], android.os.Message)
      * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
      */
+    @UnsupportedAppUsage
     @Deprecated
     public void invokeOemRilRequestRaw(byte[] data, Message response) {
         mCi.invokeOemRilRequestRaw(data, response);
@@ -2134,6 +2182,7 @@
      * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message)
      * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
      */
+    @UnsupportedAppUsage
     @Deprecated
     public void invokeOemRilRequestStrings(String[] strings, Message response) {
         mCi.invokeOemRilRequestStrings(strings, response);
@@ -2210,10 +2259,6 @@
         mNotifier.notifyMessageWaitingChanged(this);
     }
 
-    public void notifyDataConnection(String apnType, PhoneConstants.DataState state) {
-        mNotifier.notifyDataConnection(this, apnType, state);
-    }
-
     public void notifyDataConnection(String apnType) {
         mNotifier.notifyDataConnection(this, apnType, getDataConnectionState(apnType));
     }
@@ -2228,6 +2273,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public void notifyOtaspChanged(int otaspMode) {
         mNotifier.notifyOtaspChanged(this, otaspMode);
     }
@@ -2248,6 +2294,10 @@
         mNotifier.notifySignalStrength(this);
     }
 
+    public PhoneConstants.DataState getDataConnectionState(String apnType) {
+        return PhoneConstants.DataState.DISCONNECTED;
+    }
+
     public void notifyCellInfo(List<CellInfo> cellInfo) {
         AsyncResult ar = new AsyncResult(null, cellInfo, null);
         mCellInfoRegistrants.notifyRegistrants(ar);
@@ -2299,6 +2349,7 @@
         mIsPhoneInEcmState = isInEcm;
     }
 
+    @UnsupportedAppUsage
     private static int getVideoState(Call call) {
         int videoState = VideoProfile.STATE_AUDIO_ONLY;
         Connection conn = call.getEarliestConnection();
@@ -2348,6 +2399,7 @@
      * Return a numerical identifier for the phone radio interface.
      * @return PHONE_TYPE_XXX as defined above.
      */
+    @UnsupportedAppUsage
     public abstract int getPhoneType();
 
     /**
@@ -2550,6 +2602,7 @@
      * Only one post dial character handler may be set. <p>
      * Calling this method with "h" equal to null unsets this handler.<p>
      */
+    @UnsupportedAppUsage
     public void setOnPostDialCharacter(Handler h, int what, Object obj) {
         mPostDialHandler = new Registrant(h, what, obj);
     }
@@ -2563,6 +2616,7 @@
      * the caller should use setOnECMModeExitResponse
      * to receive the emergency callback mode exit response
      */
+    @UnsupportedAppUsage
     public void exitEmergencyCallbackMode() {
     }
 
@@ -2602,6 +2656,7 @@
     /**
      * Returns true if OTA Service Provisioning needs to be performed.
      */
+    @UnsupportedAppUsage
     public boolean needsOtaServiceProvisioning() {
         return false;
     }
@@ -2638,6 +2693,7 @@
      * @param what user-defined message code
      * @param obj placed in Message.obj
      */
+    @UnsupportedAppUsage
     public void registerForEcmTimerReset(Handler h, int what, Object obj) {
     }
 
@@ -2645,6 +2701,7 @@
      * Unregister for notification for Ecm timer reset
      * @param h Handler to be removed from the registrant list.
      */
+    @UnsupportedAppUsage
     public void unregisterForEcmTimerReset(Handler h) {
     }
 
@@ -2825,6 +2882,7 @@
      * @param what User-defined message code.
      * @param obj User object.
      */
+    @UnsupportedAppUsage
     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
     }
 
@@ -2833,6 +2891,7 @@
      *
      * @param h Handler to be removed from the registrant list.
      */
+    @UnsupportedAppUsage
     public void unsetOnEcbModeExitResponse(Handler h){
     }
 
@@ -2862,6 +2921,7 @@
      *
      * @return The string array of APN types. Return null if no active APN types.
      */
+    @UnsupportedAppUsage
     @Nullable
     public String[] getActiveApnTypes() {
         if (mTransportManager != null) {
@@ -2884,8 +2944,9 @@
      * @return true if there is a matching DUN APN.
      */
     public boolean hasMatchedTetherApnSetting() {
-        if (getDcTracker(TransportType.WWAN) != null) {
-            return getDcTracker(TransportType.WWAN).hasMatchedTetherApnSetting();
+        if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
+            return getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                    .hasMatchedTetherApnSetting();
         }
         return false;
     }
@@ -3053,6 +3114,7 @@
      * @return true if this bit is set or EF_CSP data is unavailable,
      * false otherwise
      */
+    @UnsupportedAppUsage
     public boolean isCspPlmnEnabled() {
         return false;
     }
@@ -3061,6 +3123,7 @@
      * Return an interface to retrieve the ISIM records for IMS, if available.
      * @return the interface to retrieve the ISIM records, or null if not supported
      */
+    @UnsupportedAppUsage
     public IsimRecords getIsimRecords() {
         Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
         return null;
@@ -3071,6 +3134,7 @@
      * {@link #getLine1Number()}. For CDMA phones, {@link #getLine1Number()} returns
      * the MDN, so this method is provided to return the MSISDN on CDMA/LTE phones.
      */
+    @UnsupportedAppUsage
     public String getMsisdn() {
         return null;
     }
@@ -3087,6 +3151,7 @@
      * exists at this interface -- use
      * {@link android.telephony.PhoneStateListener} instead.
      */
+    @UnsupportedAppUsage
     public PhoneConstants.DataState getDataConnectionState() {
         return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);
     }
@@ -3140,6 +3205,7 @@
      * Gets the Uicc card corresponding to this phone.
      * @return the UiccCard object corresponding to the phone ID.
      */
+    @UnsupportedAppUsage
     public UiccCard getUiccCard() {
         return mUiccController.getUiccCard(mPhoneId);
     }
@@ -3169,6 +3235,7 @@
     /**
      * Return an instance of a IMS phone
      */
+    @UnsupportedAppUsage
     public Phone getImsPhone() {
         return mImsPhone;
     }
@@ -3207,11 +3274,11 @@
         return TelephonyManager.UNKNOWN_CARRIER_ID;
     }
 
-    public int getPreciseCarrierId() {
+    public int getSpecificCarrierId() {
         return TelephonyManager.UNKNOWN_CARRIER_ID;
     }
 
-    public String getPreciseCarrierName() {
+    public String getSpecificCarrierName() {
         return null;
     }
 
@@ -3234,6 +3301,7 @@
     /**
      * Return if UT capability of ImsPhone is enabled or not
      */
+    @UnsupportedAppUsage
     public boolean isUtEnabled() {
         if (mImsPhone != null) {
             return mImsPhone.isUtEnabled();
@@ -3241,6 +3309,7 @@
         return false;
     }
 
+    @UnsupportedAppUsage
     public void dispose() {
     }
 
@@ -3283,6 +3352,7 @@
     /*
      * Returns the subscription id.
      */
+    @UnsupportedAppUsage
     public int getSubId() {
         if (SubscriptionController.getInstance() == null) {
             // TODO b/78359408 getInstance sometimes returns null in Treehugger tests, which causes
@@ -3297,6 +3367,7 @@
     /**
      * Returns the phone id.
      */
+    @UnsupportedAppUsage
     public int getPhoneId() {
         return mPhoneId;
     }
@@ -3397,6 +3468,7 @@
     /**
      * Get Wifi Calling Feature Availability
      */
+    @UnsupportedAppUsage
     public boolean isWifiCallingEnabled() {
         Phone imsPhone = mImsPhone;
         boolean isWifiCallingEnabled = false;
@@ -3424,6 +3496,7 @@
     /**
      * Get Volte Feature Availability
      */
+    @UnsupportedAppUsage
     public boolean isVolteEnabled() {
         Phone imsPhone = mImsPhone;
         boolean isVolteEnabled = false;
@@ -3626,6 +3699,7 @@
      *
      * @return {@code true} if video calling is enabled, {@code false} otherwise.
      */
+    @UnsupportedAppUsage
     public boolean isVideoEnabled() {
         Phone imsPhone = mImsPhone;
         if (imsPhone != null) {
@@ -3743,6 +3817,7 @@
         return mDataEnabledSettings;
     }
 
+    @UnsupportedAppUsage
     public IccSmsInterfaceManager getIccSmsInterfaceManager(){
         return null;
     }
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
index 2a7728b..a191c47 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
@@ -22,11 +22,15 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.SystemProperties;
+import android.os.storage.StorageManager;
 import android.telephony.PhoneCapability;
 import android.telephony.Rlog;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * This class manages phone's configuration which defines the potential capability (static) of the
  * phone and its current activated capability (current).
@@ -40,13 +44,17 @@
     public static final String SSSS = "";
     private static final String LOG_TAG = "PhoneCfgMgr";
     private static final int EVENT_SWITCH_DSDS_CONFIG_DONE = 100;
+    private static final int EVENT_GET_MODEM_STATUS = 101;
+    private static final int EVENT_GET_MODEM_STATUS_DONE = 102;
+    private static final int EVENT_GET_PHONE_CAPABILITY_DONE = 103;
 
     private static PhoneConfigurationManager sInstance = null;
     private final Context mContext;
     private PhoneCapability mStaticCapability;
-    private PhoneCapability mCurrentCapability;
     private final RadioConfig mRadioConfig;
     private final MainThreadHandler mHandler;
+    private final Phone[] mPhones;
+    private final Map<Integer, Boolean> mPhoneStatusMap;
 
     /**
      * Init method to instantiate the object
@@ -71,12 +79,32 @@
         mContext = context;
         // TODO: send commands to modem once interface is ready.
         TelephonyManager telephonyManager = new TelephonyManager(context);
-        mStaticCapability = PhoneConfigurationModels.DSDS_CAPABILITY;
-        mCurrentCapability = mStaticCapability;
+        //initialize with default, it'll get updated when RADIO is ON/AVAILABLE
+        mStaticCapability = getDefaultCapability();
         mRadioConfig = RadioConfig.getInstance(mContext);
         mHandler = new MainThreadHandler();
+        mPhoneStatusMap = new HashMap<>();
 
         notifyCapabilityChanged();
+
+        mPhones = PhoneFactory.getPhones();
+        if (!StorageManager.inCryptKeeperBounce()) {
+            for (Phone phone : mPhones) {
+                phone.mCi.registerForAvailable(mHandler, Phone.EVENT_RADIO_AVAILABLE, phone);
+            }
+        } else {
+            for (Phone phone : mPhones) {
+                phone.mCi.registerForOn(mHandler, Phone.EVENT_RADIO_ON, phone);
+            }
+        }
+    }
+
+    private PhoneCapability getDefaultCapability() {
+        if (getPhoneCount() > 1) {
+            return PhoneConfigurationModels.DSDS_CAPABILITY;
+        } else {
+            return PhoneConfigurationModels.SSSS_CAPABILITY;
+        }
     }
 
     /**
@@ -96,9 +124,25 @@
     private final class MainThreadHandler extends Handler {
         @Override
         public void handleMessage(Message msg) {
+            AsyncResult ar;
+            Phone phone = null;
             switch (msg.what) {
+                case Phone.EVENT_RADIO_AVAILABLE:
+                case Phone.EVENT_RADIO_ON:
+                    log("Received EVENT_RADIO_AVAILABLE/EVENT_RADIO_ON");
+                    if (msg.obj instanceof Phone) {
+                        phone = (Phone) msg.obj;
+                    }
+                    if (phone == null) {
+                        log("Unable to add phoneStatus to cache. "
+                                + "No phone object provided for event " + msg.what);
+                    } else {
+                        updatePhoneStatus(phone);
+                    }
+                    getStaticPhoneCapability();
+                    break;
                 case EVENT_SWITCH_DSDS_CONFIG_DONE:
-                    AsyncResult ar = (AsyncResult) msg.obj;
+                    ar = (AsyncResult) msg.obj;
                     if (ar != null && ar.exception == null) {
                         int numOfLiveModems = msg.arg1;
                         setMultiSimProperties(numOfLiveModems);
@@ -106,6 +150,25 @@
                         log(msg.what + " failure. Not switching multi-sim config." + ar.exception);
                     }
                     break;
+                case EVENT_GET_MODEM_STATUS_DONE:
+                    ar = (AsyncResult) msg.obj;
+                    if (ar != null && ar.exception == null) {
+                        int phoneId = msg.arg1;
+                        boolean enabled = (boolean) ar.result;
+                        //update the cache each time getModemStatus is requested
+                        mPhoneStatusMap.put(phoneId, enabled);
+                    } else {
+                        log(msg.what + " failure. Not updating modem status." + ar.exception);
+                    }
+                    break;
+                case EVENT_GET_PHONE_CAPABILITY_DONE:
+                    ar = (AsyncResult) msg.obj;
+                    if (ar != null && ar.exception == null) {
+                        mStaticCapability = (PhoneCapability) ar.result;
+                        notifyCapabilityChanged();
+                    } else {
+                        log(msg.what + " failure. Not getting phone capability." + ar.exception);
+                    }
             }
         }
     }
@@ -123,6 +186,48 @@
             return;
         }
         phone.mCi.enableModem(enable, result);
+        updatePhoneStatus(phone);
+    }
+
+    /**
+     * Get phone status (enabled/disabled)
+     *
+     * @param phone which phone to operate on
+     */
+    public boolean getPhoneStatus(Phone phone) {
+        if (phone == null) {
+            log("getPhonetatus failed phone is null");
+            return false;
+        }
+
+        int phoneId = phone.getPhoneId();
+
+        //use cache if the status has already been updated/queried
+        if (mPhoneStatusMap.containsKey(phoneId)) {
+            return mPhoneStatusMap.get(phoneId);
+        } else {
+            //return false if modem status is not in cache
+            updatePhoneStatus(phone);
+            return false;
+        }
+    }
+
+    /**
+     * method to call RIL getModemStatus
+     */
+    private void updatePhoneStatus(Phone phone) {
+        Message callback = Message.obtain(
+                mHandler, EVENT_GET_MODEM_STATUS_DONE, phone.getPhoneId(), 0 /**dummy arg*/);
+        phone.mCi.getModemStatus(callback);
+    }
+
+    /**
+     * Add status of the phone to the status HashMap
+     * @param phoneId
+     * @param status
+     */
+    public void addToPhoneStatusCache(int phoneId, boolean status) {
+        mPhoneStatusMap.put(phoneId, status);
     }
 
     /**
@@ -136,7 +241,13 @@
     /**
      * get static overall phone capabilities for all phones.
      */
-    public PhoneCapability getStaticPhoneCapability() {
+    public synchronized PhoneCapability getStaticPhoneCapability() {
+        if (getDefaultCapability().equals(mStaticCapability)) {
+            log("getStaticPhoneCapability: sending the request for getting PhoneCapability");
+            Message callback = Message.obtain(
+                    mHandler, EVENT_GET_PHONE_CAPABILITY_DONE);
+            mRadioConfig.getPhoneCapability(callback);
+        }
         return mStaticCapability;
     }
 
@@ -144,17 +255,17 @@
      * get configuration related status of each phone.
      */
     public PhoneCapability getCurrentPhoneCapability() {
-        return mCurrentCapability;
+        return getStaticPhoneCapability();
     }
 
     public int getNumberOfModemsWithSimultaneousDataConnections() {
-        return mCurrentCapability.maxActiveData;
+        return mStaticCapability.maxActiveData;
     }
 
     private void notifyCapabilityChanged() {
         PhoneNotifier notifier = new DefaultPhoneNotifier();
 
-        notifier.notifyPhoneCapabilityChanged(mCurrentCapability);
+        notifier.notifyPhoneCapabilityChanged(mStaticCapability);
     }
 
     /**
@@ -180,28 +291,6 @@
     }
 
     /**
-     * Get how many sims have been activated on the phone
-     * NOTE: In order to support more than 3 sims, we need to change this method.
-     */
-    public int getNumOfActiveSims() {
-        String mSimConfig =
-                SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG);
-        int numOfSims;
-        switch (mSimConfig) {
-            case TSTS:
-                numOfSims = 3;
-                break;
-            case DSDA:
-            case DSDS:
-                numOfSims = 2;
-                break;
-            default:
-                numOfSims = 1;
-        }
-        return numOfSims;
-    }
-
-    /**
      * Get whether reboot is required or not after making changes to modem configurations.
      * Return value defaults to true
      */
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationModels.java b/src/java/com/android/internal/telephony/PhoneConfigurationModels.java
index fb8cc5e..aca4955 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationModels.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationModels.java
@@ -40,7 +40,7 @@
         List<ModemInfo> logicalModemList = new ArrayList<>();
         logicalModemList.add(modemInfo1);
         logicalModemList.add(modemInfo2);
-        DSDS_CAPABILITY = new PhoneCapability(1, 2, 0, logicalModemList, false);
+        DSDS_CAPABILITY = new PhoneCapability(1, 2, 0, logicalModemList, true);
 
         logicalModemList = new ArrayList<>();
         logicalModemList.add(modemInfo1);
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index 2720e27..cee22fa 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.SharedPreferences;
@@ -27,7 +28,7 @@
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
-import android.telephony.DebugEventReporter;
+import android.telephony.AnomalyReporter;
 import android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -76,11 +77,15 @@
     private static @Nullable EuiccController sEuiccController;
     private static @Nullable EuiccCardController sEuiccCardController;
 
+    @UnsupportedAppUsage
     static private CommandsInterface sCommandsInterface = null;
     static private SubscriptionInfoUpdater sSubInfoRecordUpdater = null;
 
+    @UnsupportedAppUsage
     static private boolean sMadeDefaults = false;
+    @UnsupportedAppUsage
     static private PhoneNotifier sPhoneNotifier;
+    @UnsupportedAppUsage
     static private Context sContext;
     static private PhoneConfigurationManager sPhoneConfigurationManager;
     static private PhoneSwitcher sPhoneSwitcher;
@@ -88,6 +93,7 @@
     static private TelephonyNetworkFactory[] sTelephonyNetworkFactories;
     static private ImsResolver sImsResolver;
     static private NotificationChannelController sNotificationChannelController;
+    static private CellularNetworkValidator sCellularNetworkValidator;
 
     static private final HashMap<String, LocalLog>sLocalLogs = new HashMap<String, LocalLog>();
 
@@ -101,6 +107,7 @@
      * FIXME replace this with some other way of making these
      * instances
      */
+    @UnsupportedAppUsage
     public static void makeDefaultPhone(Context context) {
         synchronized (sLockProxyPhones) {
             if (!sMadeDefaults) {
@@ -142,18 +149,6 @@
                    where as in single SIM mode only instance. isMultiSimEnabled() function checks
                    whether it is single SIM or multi SIM mode */
                 int numPhones = TelephonyManager.getDefault().getPhoneCount();
-                // Return whether or not the device should use dynamic binding or the static
-                // implementation (deprecated)
-                boolean isDynamicBinding = sContext.getResources().getBoolean(
-                        com.android.internal.R.bool.config_dynamic_bind_ims);
-                // Get the package name of the default IMS implementation.
-                String defaultImsPackage = sContext.getResources().getString(
-                        com.android.internal.R.string.config_ims_package);
-                // Start ImsResolver and bind to ImsServices.
-                Rlog.i(LOG_TAG, "ImsResolver: defaultImsPackage: " + defaultImsPackage);
-                sImsResolver = new ImsResolver(sContext, defaultImsPackage, numPhones,
-                        isDynamicBinding);
-                sImsResolver.initPopulateCacheAndStartBind();
 
                 int[] networkModes = new int[numPhones];
                 sPhones = new Phone[numPhones];
@@ -227,12 +222,31 @@
                         BackgroundThread.get().getLooper(), context, sPhones, sCommandsInterfaces);
                 SubscriptionController.getInstance().updatePhonesAvailability(sPhones);
 
-                // Start monitoring after defaults have been made.
-                // Default phone must be ready before ImsPhone is created because ImsService might
-                // need it when it is being opened. This should initialize multiple ImsPhones for
-                // ImsResolver implementations of ImsService.
-                for (int i = 0; i < numPhones; i++) {
-                    sPhones[i].startMonitoringImsService();
+
+                // Only bring up IMS if the device supports having an IMS stack.
+                if (context.getPackageManager().hasSystemFeature(
+                        PackageManager.FEATURE_TELEPHONY_IMS)) {
+                    // Return whether or not the device should use dynamic binding or the static
+                    // implementation (deprecated)
+                    boolean isDynamicBinding = sContext.getResources().getBoolean(
+                            com.android.internal.R.bool.config_dynamic_bind_ims);
+                    // Get the package name of the default IMS implementation.
+                    String defaultImsPackage = sContext.getResources().getString(
+                            com.android.internal.R.string.config_ims_package);
+                    // Start ImsResolver and bind to ImsServices.
+                    Rlog.i(LOG_TAG, "ImsResolver: defaultImsPackage: " + defaultImsPackage);
+                    sImsResolver = new ImsResolver(sContext, defaultImsPackage, numPhones,
+                            isDynamicBinding);
+                    sImsResolver.initPopulateCacheAndStartBind();
+                    // Start monitoring after defaults have been made.
+                    // Default phone must be ready before ImsPhone is created because ImsService
+                    // might need it when it is being opened. This should initialize multiple
+                    // ImsPhones for ImsResolver implementations of ImsService.
+                    for (int i = 0; i < numPhones; i++) {
+                        sPhones[i].startMonitoringImsService();
+                    }
+                } else {
+                    Rlog.i(LOG_TAG, "IMS is not supported on this device, skipping ImsResolver.");
                 }
 
                 ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(
@@ -241,7 +255,10 @@
 
                 sSubscriptionMonitor = new SubscriptionMonitor(tr, sContext, sc, numPhones);
 
-                sPhoneConfigurationManager = PhoneConfigurationManager.init(sContext);
+                sPhoneConfigurationManager = PhoneConfigurationManager.init(
+                        sContext);
+
+                sCellularNetworkValidator = CellularNetworkValidator.make(sContext);
 
                 int maxActivePhones = sPhoneConfigurationManager
                         .getNumberOfModemsWithSimultaneousDataConnections();
@@ -266,6 +283,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public static Phone getDefaultPhone() {
         synchronized (sLockProxyPhones) {
             if (!sMadeDefaults) {
@@ -275,6 +293,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public static Phone getPhone(int phoneId) {
         Phone phone;
         String dbgInfo = "";
@@ -300,6 +319,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public static Phone[] getPhones() {
         synchronized (sLockProxyPhones) {
             if (!sMadeDefaults) {
@@ -313,7 +333,11 @@
         return sSubInfoRecordUpdater;
     }
 
-    public static ImsResolver getImsResolver() {
+    /**
+     * @return The ImsResolver instance or null if IMS is not supported
+     * (FEATURE_TELEPHONY_IMS is not defined).
+     */
+    public static @Nullable ImsResolver getImsResolver() {
         return sImsResolver;
     }
 
@@ -333,6 +357,7 @@
      * @return the preferred network mode that should be set.
      */
     // TODO: Fix when we "properly" have TelephonyDevController/SubscriptionController ..
+    @UnsupportedAppUsage
     public static int calculatePreferredNetworkType(Context context, int phoneSubId) {
         int networkType = android.provider.Settings.Global.getInt(context.getContentResolver(),
                 android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
@@ -356,6 +381,7 @@
     }
 
     /* Gets the default subscription */
+    @UnsupportedAppUsage
     public static int getDefaultSubscription() {
         return SubscriptionController.getInstance().getDefaultSubId();
     }
@@ -552,7 +578,7 @@
         pw.println("DebugEvents:");
         pw.increaseIndent();
         try {
-            DebugEventReporter.dump(fd, pw, args);
+            AnomalyReporter.dump(fd, pw, args);
         } catch (Exception e) {
             e.printStackTrace();
         }
diff --git a/src/java/com/android/internal/telephony/PhoneInternalInterface.java b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
index 41d7ae4..cc55d81 100644
--- a/src/java/com/android/internal/telephony/PhoneInternalInterface.java
+++ b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -55,6 +56,7 @@
                                      but physical link is down</li>
          * </ul>
          */
+        @UnsupportedAppUsage
         NONE, DATAIN, DATAOUT, DATAINANDOUT, DORMANT;
     }
 
@@ -176,6 +178,7 @@
     static final int BM_US_2500M    = RILConstants.BAND_MODE_USA_2500M;
     static final int BM_NUM_BAND_MODES = 19; //Total number of band modes
 
+    @UnsupportedAppUsage
     int PREFERRED_NT_MODE                = RILConstants.PREFERRED_NETWORK_MODE;
 
     // Used for CDMA roaming mode
diff --git a/src/java/com/android/internal/telephony/PhoneNotifier.java b/src/java/com/android/internal/telephony/PhoneNotifier.java
index 9b8cef5..f81c458 100644
--- a/src/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/PhoneNotifier.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.CallQuality;
 import android.telephony.CellInfo;
 import android.telephony.CellLocation;
@@ -39,8 +40,10 @@
     /** Notify registrants of the current CellLocation */
     void notifyCellLocation(Phone sender, CellLocation cl);
 
+    @UnsupportedAppUsage
     void notifySignalStrength(Phone sender);
 
+    @UnsupportedAppUsage
     void notifyMessageWaitingChanged(Phone sender);
 
     void notifyCallForwardingChanged(Phone sender);
@@ -86,5 +89,5 @@
     void notifyEmergencyNumberList();
 
     /** Notify of a change to the call quality of an active foreground call. */
-    void notifyCallQualityChanged(Phone sender, CallQuality callQuality);
+    void notifyCallQualityChanged(Phone sender, CallQuality callQuality, int callNetworkType);
 }
diff --git a/src/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/src/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
index 9dad3cc..1d9f4f0 100644
--- a/src/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
+++ b/src/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -46,11 +47,13 @@
 
     PhoneConstants.State mPhoneState = PhoneConstants.State.IDLE;
     ServiceState mServiceState = new ServiceState();
+    @UnsupportedAppUsage
     SignalStrength mSignalStrength = new SignalStrength();
 
     private Context mContext;
     private Handler mTarget;
     private IntentFilter mFilter;
+    @UnsupportedAppUsage
     private int mWants;
     private int mPhoneStateEventWhat;
     private int mServiceStateEventWhat;
@@ -61,6 +64,7 @@
         mFilter = new IntentFilter();
     }
 
+    @UnsupportedAppUsage
     public PhoneStateIntentReceiver(Context context, Handler target) {
         this();
         setContext(context);
@@ -112,6 +116,7 @@
      * @return signal strength in dBm, -1 if not yet updated
      * Throws RuntimeException if client has not called notifySignalStrength()
      */
+    @UnsupportedAppUsage
     public int getSignalStrengthDbm() {
         if ((mWants & NOTIF_SIGNAL) == 0) {
             throw new RuntimeException
@@ -130,6 +135,7 @@
         return ((mWants & NOTIF_PHONE) != 0);
     }
 
+    @UnsupportedAppUsage
     public void notifyServiceState(int eventWhat) {
         mWants |= NOTIF_SERVICE;
         mServiceStateEventWhat = eventWhat;
@@ -140,6 +146,7 @@
         return ((mWants & NOTIF_SERVICE) != 0);
     }
 
+    @UnsupportedAppUsage
     public void notifySignalStrength (int eventWhat) {
         mWants |= NOTIF_SIGNAL;
         mAsuEventWhat = eventWhat;
@@ -150,10 +157,12 @@
         return ((mWants & NOTIF_SIGNAL) != 0);
     }
 
+    @UnsupportedAppUsage
     public void registerIntent() {
         mContext.registerReceiver(this, mFilter);
     }
 
+    @UnsupportedAppUsage
     public void unregisterIntent() {
         mContext.unregisterReceiver(this);
     }
diff --git a/src/java/com/android/internal/telephony/PhoneSubInfoController.java b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
index 297dc84..42dec21 100644
--- a/src/java/com/android/internal/telephony/PhoneSubInfoController.java
+++ b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
@@ -22,6 +22,7 @@
 import static android.Manifest.permission.MODIFY_PHONE_STATE;
 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -42,7 +43,9 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false; // STOPSHIP if true
 
+    @UnsupportedAppUsage
     private final Phone[] mPhone;
+    @UnsupportedAppUsage
     private final Context mContext;
     private final AppOpsManager mAppOps;
 
@@ -211,6 +214,7 @@
     /**
      * get Phone object based on subId.
      **/
+    @UnsupportedAppUsage
     private Phone getPhone(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
@@ -245,6 +249,7 @@
                 "Requires MODIFY_PHONE_STATE");
     }
 
+    @UnsupportedAppUsage
     private int getDefaultSubscription() {
         return  PhoneFactory.getDefaultSubscription();
     }
@@ -465,6 +470,7 @@
         Rlog.d(TAG, s);
     }
 
+    @UnsupportedAppUsage
     private void loge(String s) {
         Rlog.e(TAG, s);
     }
diff --git a/src/java/com/android/internal/telephony/PhoneSwitcher.java b/src/java/com/android/internal/telephony/PhoneSwitcher.java
index dc448af..3eaa14c 100644
--- a/src/java/com/android/internal/telephony/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/PhoneSwitcher.java
@@ -16,17 +16,25 @@
 
 package com.android.internal.telephony;
 
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.telephony.PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE;
 import static android.telephony.PhoneStateListener.LISTEN_PRECISE_CALL_STATE;
 import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
 import static android.telephony.SubscriptionManager.INVALID_PHONE_INDEX;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_INVALID_PARAMETER;
+import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_SUCCESS;
+import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
 import android.net.MatchAllNetworkSpecifier;
+import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkFactory;
 import android.net.NetworkRequest;
@@ -38,6 +46,7 @@
 import android.os.Registrant;
 import android.os.RegistrantList;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.telephony.PhoneCapability;
 import android.telephony.PhoneStateListener;
 import android.telephony.PreciseCallState;
@@ -48,6 +57,10 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.dataconnection.DcRequest;
+import com.android.internal.telephony.metrics.TelephonyMetrics;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.DataSwitch;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
 import com.android.internal.util.IndentingPrintWriter;
 
 import java.io.FileDescriptor;
@@ -65,8 +78,10 @@
  * the active phones.  Note we don't wait for data attach (which may not happen anyway).
  */
 public class PhoneSwitcher extends Handler {
-    private final static String LOG_TAG = "PhoneSwitcher";
-    private final static boolean VDBG = false;
+    private static final String LOG_TAG = "PhoneSwitcher";
+    private static final boolean VDBG = false;
+
+    private static final int DEFAULT_NETWORK_CHANGE_TIMEOUT_MS = 5000;
 
     private final List<DcRequest> mPrioritizedDcRequests = new ArrayList<DcRequest>();
     private final RegistrantList mActivePhoneRegistrants;
@@ -75,12 +90,18 @@
     private final CommandsInterface[] mCommandsInterfaces;
     private final Context mContext;
     private final PhoneState[] mPhoneStates;
+    @UnsupportedAppUsage
     private final int mNumPhones;
+    @UnsupportedAppUsage
     private final Phone[] mPhones;
     private final LocalLog mLocalLog;
     @VisibleForTesting
     public final PhoneStateListener mPhoneStateListener;
-
+    private final CellularNetworkValidator mValidator;
+    private final CellularNetworkValidator.ValidationCallback mValidationCallback =
+            (validated, subId) -> Message.obtain(PhoneSwitcher.this,
+                    EVENT_NETWORK_VALIDATION_DONE, subId, validated ? 1 : 0).sendToTarget();
+    @UnsupportedAppUsage
     private int mMaxActivePhones;
     private static PhoneSwitcher sPhoneSwitcher = null;
 
@@ -95,20 +116,24 @@
     private int mPreferredDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
 
     @VisibleForTesting
-    // Corresponding phoneId after considerting mPreferredDataSubId and mDefaultDataSubId above.
+    // Corresponding phoneId after considering mPreferredDataSubId and mDefaultDataSubId above.
     protected int mPreferredDataPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
 
     private int mPhoneIdInCall = SubscriptionManager.INVALID_PHONE_INDEX;
 
+    private ISetOpportunisticDataCallback mSetOpptSubCallback;
+
     private static final int EVENT_DEFAULT_SUBSCRIPTION_CHANGED   = 101;
     private static final int EVENT_SUBSCRIPTION_CHANGED           = 102;
     private static final int EVENT_REQUEST_NETWORK                = 103;
     private static final int EVENT_RELEASE_NETWORK                = 104;
     private static final int EVENT_EMERGENCY_TOGGLE               = 105;
     private static final int EVENT_RADIO_CAPABILITY_CHANGED       = 106;
-    private static final int EVENT_PREFERRED_SUBSCRIPTION_CHANGED = 107;
+    private static final int EVENT_CHANGE_PREFERRED_SUBSCRIPTION  = 107;
     private static final int EVENT_RADIO_AVAILABLE                = 108;
     private static final int EVENT_PHONE_IN_CALL_CHANGED          = 109;
+    private static final int EVENT_NETWORK_VALIDATION_DONE        = 110;
+    private static final int EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK = 111;
 
     // Depending on version of IRadioConfig, we need to send either RIL_REQUEST_ALLOW_DATA if it's
     // 1.0, or RIL_REQUEST_SET_PREFERRED_DATA if it's 1.1 or later. So internally mHalCommandToUse
@@ -122,6 +147,27 @@
 
     private final static int MAX_LOCAL_LOG_LINES = 30;
 
+    // Default timeout value of network validation in millisecond.
+    private final static int DEFAULT_VALIDATION_EXPIRATION_TIME = 2000;
+
+    private Boolean mHasRegisteredDefaultNetworkChangeCallback = false;
+
+    private ConnectivityManager mConnectivityManager;
+
+    private final ConnectivityManager.NetworkCallback mDefaultNetworkCallback =
+            new NetworkCallback() {
+                @Override
+                public void onAvailable(Network network) {
+                    if (mConnectivityManager.getNetworkCapabilities(network)
+                            .hasTransport(TRANSPORT_CELLULAR)) {
+                        logDataSwitchEvent(
+                                TelephonyEvent.EventState.EVENT_STATE_END,
+                                TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN);
+                    }
+                    removeDefaultNetworkChangeCallback();
+                }
+            };
+
     /**
      * Method to get singleton instance.
      */
@@ -143,6 +189,7 @@
         return sPhoneSwitcher;
     }
 
+    /** This constructor is only used for testing purpose. */
     @VisibleForTesting
     public PhoneSwitcher(int numPhones, Looper looper) {
         super(looper);
@@ -162,6 +209,7 @@
                 onPhoneCapabilityChangedInternal(capability);
             }
         };
+        mValidator = CellularNetworkValidator.getInstance();
     }
 
     @VisibleForTesting
@@ -208,6 +256,8 @@
             }
         };
 
+        mValidator = CellularNetworkValidator.getInstance();
+
         TelephonyManager telephonyManager =
                 (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
         telephonyManager.listen(mPhoneStateListener, LISTEN_PHONE_CAPABILITY_CHANGE
@@ -231,11 +281,14 @@
         } catch (RemoteException e) {
         }
 
+        mConnectivityManager =
+            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
         mContext.registerReceiver(mDefaultDataChangedReceiver,
                 new IntentFilter(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));
 
         NetworkCapabilities netCap = new NetworkCapabilities();
-        netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        netCap.addTransportType(TRANSPORT_CELLULAR);
         netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
         netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
         netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
@@ -248,6 +301,7 @@
         netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
         netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
         netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_MCX);
         netCap.setNetworkSpecifier(new MatchAllNetworkSpecifier());
 
         NetworkFactory networkFactory = new PhoneSwitcherNetworkRequestListener(looper, context,
@@ -284,7 +338,10 @@
                 break;
             }
             case EVENT_DEFAULT_SUBSCRIPTION_CHANGED: {
+                logDataSwitchEvent(TelephonyEvent.EventState.EVENT_STATE_START,
+                        DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL);
                 onEvaluate(REQUESTS_UNCHANGED, "defaultChanged");
+                registerDefaultNetworkChangeCallback();
                 break;
             }
             case EVENT_REQUEST_NETWORK: {
@@ -303,8 +360,16 @@
                 resendRilCommands(msg);
                 break;
             }
-            case EVENT_PREFERRED_SUBSCRIPTION_CHANGED: {
-                onEvaluate(REQUESTS_UNCHANGED, "preferredDataSubscriptionIdChanged");
+            case EVENT_CHANGE_PREFERRED_SUBSCRIPTION: {
+                int subId = msg.arg1;
+                boolean needValidation = (msg.arg2 == 1);
+                ISetOpportunisticDataCallback callback =
+                        (ISetOpportunisticDataCallback) msg.obj;
+                if (SubscriptionManager.isUsableSubscriptionId(subId)) {
+                    setOpportunisticDataSubscription(subId, needValidation, callback);
+                } else {
+                    unsetOpportunisticDataSubscription(callback);
+                }
                 break;
             }
             case EVENT_RADIO_AVAILABLE: {
@@ -313,7 +378,20 @@
                 break;
             }
             case EVENT_PHONE_IN_CALL_CHANGED: {
+                logDataSwitchEvent(TelephonyEvent.EventState.EVENT_STATE_START,
+                        DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
                 onEvaluate(REQUESTS_UNCHANGED, "EVENT_PHONE_IN_CALL_CHANGED");
+                registerDefaultNetworkChangeCallback();
+                break;
+            }
+            case EVENT_NETWORK_VALIDATION_DONE: {
+                int subId = msg.arg1;
+                boolean passed = (msg.arg2 == 1);
+                onValidationDone(subId, passed);
+                break;
+            }
+            case EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK: {
+                removeDefaultNetworkChangeCallback();
                 break;
             }
         }
@@ -354,7 +432,8 @@
 
     private void onRequestNetwork(NetworkRequest networkRequest) {
         final DcRequest dcRequest = new DcRequest(networkRequest, mContext);
-        if (mPrioritizedDcRequests.contains(dcRequest) == false) {
+        if (!mPrioritizedDcRequests.contains(dcRequest)) {
+            collectRequestNetworkMetrics(networkRequest);
             mPrioritizedDcRequests.add(dcRequest);
             Collections.sort(mPrioritizedDcRequests);
             onEvaluate(REQUESTS_CHANGED, "netRequest");
@@ -366,6 +445,53 @@
 
         if (mPrioritizedDcRequests.remove(dcRequest)) {
             onEvaluate(REQUESTS_CHANGED, "netReleased");
+            collectReleaseNetworkMetrics(networkRequest);
+        }
+    }
+
+    private void removeDefaultNetworkChangeCallback() {
+        synchronized (mHasRegisteredDefaultNetworkChangeCallback) {
+            if (mHasRegisteredDefaultNetworkChangeCallback) {
+                mHasRegisteredDefaultNetworkChangeCallback = false;
+                removeMessages(EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK);
+                mConnectivityManager.unregisterNetworkCallback(mDefaultNetworkCallback);
+            }
+        }
+    }
+
+    private void registerDefaultNetworkChangeCallback() {
+        removeDefaultNetworkChangeCallback();
+
+        synchronized (mHasRegisteredDefaultNetworkChangeCallback) {
+            mHasRegisteredDefaultNetworkChangeCallback = true;
+            mConnectivityManager.registerDefaultNetworkCallback(mDefaultNetworkCallback);
+            sendMessageDelayed(
+                    obtainMessage(EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK),
+                    DEFAULT_NETWORK_CHANGE_TIMEOUT_MS);
+        }
+    }
+
+    private void collectRequestNetworkMetrics(NetworkRequest networkRequest) {
+        // Request network for MMS will temporary disable the network on default data subscription,
+        // this only happen on multi-sim device.
+        if (mNumPhones > 1 && networkRequest.networkCapabilities.hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_MMS)) {
+            OnDemandDataSwitch onDemandDataSwitch = new OnDemandDataSwitch();
+            onDemandDataSwitch.apn = TelephonyEvent.ApnType.APN_TYPE_MMS;
+            onDemandDataSwitch.state = TelephonyEvent.EventState.EVENT_STATE_START;
+            TelephonyMetrics.getInstance().writeOnDemandDataSwitch(onDemandDataSwitch);
+        }
+    }
+
+    private void collectReleaseNetworkMetrics(NetworkRequest networkRequest) {
+        // Release network for MMS will recover the network on default data subscription, this only
+        // happen on multi-sim device.
+        if (mNumPhones > 1 && networkRequest.networkCapabilities.hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_MMS)) {
+            OnDemandDataSwitch onDemandDataSwitch = new OnDemandDataSwitch();
+            onDemandDataSwitch.apn = TelephonyEvent.ApnType.APN_TYPE_MMS;
+            onDemandDataSwitch.state = TelephonyEvent.EventState.EVENT_STATE_END;
+            TelephonyMetrics.getInstance().writeOnDemandDataSwitch(onDemandDataSwitch);
         }
     }
 
@@ -477,6 +603,10 @@
                     activate(phoneId);
                 }
             }
+
+            notifyActiveDataSubIdChanged(mSubscriptionController.getSubIdUsingPhoneId(
+                    mPreferredDataPhoneId));
+
             // Notify all registrants.
             mActivePhoneRegistrants.notifyRegistrants();
         }
@@ -487,10 +617,12 @@
         public long lastRequested = 0;
     }
 
+    @UnsupportedAppUsage
     private void activate(int phoneId) {
         switchPhone(phoneId, true);
     }
 
+    @UnsupportedAppUsage
     private void deactivate(int phoneId) {
         switchPhone(phoneId, false);
     }
@@ -555,7 +687,8 @@
         // 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) {
+                NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                && subId != preferredDataSubId && subId != mValidator.getSubIdInValidation()) {
             // Returning INVALID_PHONE_INDEX will result in netRequest not being handled.
             return INVALID_PHONE_INDEX;
         }
@@ -667,16 +800,97 @@
     }
 
     /**
-     * Set a subscription as preferred data subscription.
-     * See {@link SubscriptionManager#setPreferredDataSubscriptionId(int)} for more details.
+     * Set opportunistic data subscription. It's an indication to switch Internet data to this
+     * subscription. It has to be an active subscription, and PhoneSwitcher will try to validate
+     * it first if needed.
      */
-    public void setPreferredDataSubscriptionId(int subId) {
-        if (mPreferredDataSubId != subId) {
-            log("setPreferredDataSubscriptionId subId changed to " + subId);
-            mPreferredDataSubId = subId;
-            Message msg = PhoneSwitcher.this.obtainMessage(EVENT_PREFERRED_SUBSCRIPTION_CHANGED);
-            msg.sendToTarget();
+    private void setOpportunisticDataSubscription(int subId, boolean needValidation,
+            ISetOpportunisticDataCallback callback) {
+        if (!mSubscriptionController.isActiveSubId(subId)) {
+            log("Can't switch data to inactive subId " + subId);
+            sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_INVALID_PARAMETER);
+            return;
         }
+
+        if (mValidator.isValidating()
+                && (!needValidation || subId != mValidator.getSubIdInValidation())) {
+            mValidator.stopValidation();
+        }
+
+        if (subId == mPreferredDataSubId) {
+            sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
+            return;
+        }
+
+        // If validation feature is not supported, set it directly. Otherwise,
+        // start validation on the subscription first.
+        if (CellularNetworkValidator.isValidationFeatureSupported() && needValidation) {
+            logDataSwitchEvent(TelephonyEvent.EventState.EVENT_STATE_START,
+                    DataSwitch.Reason.DATA_SWITCH_REASON_CBRS);
+            mSetOpptSubCallback = callback;
+            mValidator.validate(subId, DEFAULT_VALIDATION_EXPIRATION_TIME,
+                    false, mValidationCallback);
+        } else {
+            setPreferredSubscription(subId);
+            sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
+        }
+    }
+
+    /**
+     * Unset opportunistic data subscription. It's an indication to switch Internet data back
+     * from opportunistic subscription to primary subscription.
+     */
+    private void unsetOpportunisticDataSubscription(ISetOpportunisticDataCallback callback) {
+        if (mValidator.isValidating()) {
+            mValidator.stopValidation();
+        }
+
+        // Set mPreferredDataSubId back to DEFAULT_SUBSCRIPTION_ID. This will trigger
+        // data switch to mDefaultDataSubId.
+        setPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+        sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
+    }
+
+    private void sendSetOpptCallbackHelper(ISetOpportunisticDataCallback callback, int result) {
+        if (callback == null) return;
+        try {
+            callback.onComplete(result);
+        } catch (RemoteException exception) {
+            log("RemoteException " + exception);
+        }
+    }
+
+    /**
+     * Set opportunistic data subscription.
+     */
+    private void setPreferredSubscription(int subId) {
+        if (mPreferredDataSubId != subId) {
+            mPreferredDataSubId = subId;
+            logDataSwitchEvent(TelephonyEvent.EventState.EVENT_STATE_START,
+                    DataSwitch.Reason.DATA_SWITCH_REASON_CBRS);
+            onEvaluate(REQUESTS_UNCHANGED, "preferredDataSubscriptionIdChanged");
+            registerDefaultNetworkChangeCallback();
+        }
+    }
+
+    private void onValidationDone(int subId, boolean passed) {
+        log("Network validation " + (passed ? "passed" : "failed")
+                + " on subId " + subId);
+        if (passed) setPreferredSubscription(subId);
+
+        // Trigger callback if needed
+        sendSetOpptCallbackHelper(mSetOpptSubCallback, passed ? SET_OPPORTUNISTIC_SUB_SUCCESS
+                : SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED);
+        mSetOpptSubCallback = null;
+    }
+
+    // TODO b/123598154: rename preferredDataSub to opportunisticSubId.
+    public void trySetPreferredSubscription(int subId, boolean needValidation,
+            ISetOpportunisticDataCallback callback) {
+        log("Try set preferred subscription to subId " + subId
+                + (needValidation ? " with " : " without ") + "validation");
+        PhoneSwitcher.this.obtainMessage(EVENT_CHANGE_PREFERRED_SUBSCRIPTION,
+                subId, needValidation ? 1 : 0, callback).sendToTarget();
     }
 
     private boolean isCallActive(Phone phone) {
@@ -685,8 +899,7 @@
         }
 
         return (phone.getForegroundCall().getState() == Call.State.ACTIVE
-                || phone.getBackgroundCall().getState() == Call.State.ACTIVE
-                || phone.getRingingCall().getState() == Call.State.ACTIVE);
+                || phone.getForegroundCall().getState() == Call.State.ALERTING);
     }
 
     private void updateHalCommandToUse() {
@@ -694,11 +907,39 @@
                 ? HAL_COMMAND_PREFERRED_DATA : HAL_COMMAND_ALLOW_DATA;
     }
 
+    public int getPreferredDataSubscriptionId() {
+        return mPreferredDataSubId;
+    }
+
+    public int getPreferredDataPhoneId() {
+        return mPreferredDataPhoneId;
+    }
+
+    @UnsupportedAppUsage
     private void log(String l) {
         Rlog.d(LOG_TAG, l);
         mLocalLog.log(l);
     }
 
+    private void logDataSwitchEvent(int state, int reason) {
+        DataSwitch dataSwitch = new DataSwitch();
+        dataSwitch.state = state;
+        dataSwitch.reason = reason;
+        TelephonyMetrics.getInstance().writeDataSwitch(dataSwitch);
+
+    }
+
+    private void notifyActiveDataSubIdChanged(int activeDataSubId) {
+        ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
+                "telephony.registry"));
+        try {
+            log("notifyActiveDataSubIdChanged to " + activeDataSubId);
+            tr.notifyActiveDataSubIdChanged(activeDataSubId);
+        } catch (RemoteException ex) {
+            // Should never happen because its always available.
+        }
+    }
+
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
         pw.println("PhoneSwitcher:");
diff --git a/src/java/com/android/internal/telephony/ProxyController.java b/src/java/com/android/internal/telephony/ProxyController.java
index aaa753b..7709218 100644
--- a/src/java/com/android/internal/telephony/ProxyController.java
+++ b/src/java/com/android/internal/telephony/ProxyController.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncResult;
@@ -58,6 +59,7 @@
     private static final int SET_RC_TIMEOUT_WAITING_MSEC    = (45 * 1000);
 
     //***** Class Variables
+    @UnsupportedAppUsage
     private static ProxyController sProxyController;
 
     private Phone[] mPhones;
@@ -82,6 +84,7 @@
     WakeLock mWakeLock;
 
     // record each phone's set radio capability status
+    @UnsupportedAppUsage
     private int[] mSetRadioAccessFamilyStatus;
     private int mRadioAccessFamilyStatusCounter;
     private boolean mTransactionFailed = false;
@@ -90,15 +93,18 @@
     private String[] mNewLogicalModemIds;
 
     // Allows the generation of unique Id's for radio capability request session  id
+    @UnsupportedAppUsage
     private AtomicInteger mUniqueIdGenerator = new AtomicInteger(new Random().nextInt());
 
     // on-going radio capability request session id
+    @UnsupportedAppUsage
     private int mRadioCapabilitySessionId;
 
     // Record new and old Radio Access Family (raf) configuration.
     // The old raf configuration is used to restore each logical modem raf when FINISH is
     // issued if any requests fail.
     private int[] mNewRadioAccessFamily;
+    @UnsupportedAppUsage
     private int[] mOldRadioAccessFamily;
 
 
@@ -111,6 +117,7 @@
         return sProxyController;
     }
 
+    @UnsupportedAppUsage
     public static ProxyController getInstance() {
         return sProxyController;
     }
@@ -529,6 +536,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void completeRadioCapabilityTransaction() {
         // Create the intent to broadcast
         Intent intent;
@@ -588,6 +596,7 @@
         mRadioAccessFamilyStatusCounter = mPhones.length;
     }
 
+    @UnsupportedAppUsage
     private void sendRadioCapabilityRequest(int phoneId, int sessionId, int rcPhase,
             int radioFamily, String logicalModemId, int status, int eventId) {
         RadioCapability requestRC = new RadioCapability(
@@ -645,6 +654,7 @@
         return modemUuid;
     }
 
+    @UnsupportedAppUsage
     private void logd(String string) {
         Rlog.d(LOG_TAG, string);
     }
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 5657c9d..73d767e 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -19,6 +19,7 @@
 import static com.android.internal.telephony.RILConstants.*;
 import static com.android.internal.util.Preconditions.checkNotNull;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.hardware.radio.V1_0.Carrier;
 import android.hardware.radio.V1_0.CarrierRestrictions;
@@ -84,6 +85,7 @@
 import android.telephony.SmsManager;
 import android.telephony.TelephonyHistogram;
 import android.telephony.TelephonyManager;
+import android.telephony.TelephonyManager.PrefNetworkMode;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.DataCallResponse;
 import android.telephony.data.DataProfile;
@@ -98,8 +100,6 @@
 import com.android.internal.telephony.cat.ComprehensionTlvTag;
 import com.android.internal.telephony.cdma.CdmaInformationRecords;
 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
-import com.android.internal.telephony.dataconnection.TransportManager;
-import com.android.internal.telephony.dataconnection.TransportManager.IwlanOperationMode;
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.nano.TelephonyProto.SmsSession;
@@ -133,7 +133,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 = true; // STOPSHIP if true
+    static final boolean RILJ_LOGV = false; // STOPSHIP if true
     static final int RIL_HISTOGRAM_BUCKET_COUNT = 5;
 
     /**
@@ -154,7 +154,7 @@
     private final ClientWakelockTracker mClientWakelockTracker = new ClientWakelockTracker();
 
     /** @hide */
-    public static final HalVersion RADIO_HAL_VERSION_UNKNOWN = new HalVersion(-1, -1);
+    public static final HalVersion RADIO_HAL_VERSION_UNKNOWN = HalVersion.UNKNOWN;
 
     /** @hide */
     public static final HalVersion RADIO_HAL_VERSION_1_0 = new HalVersion(1, 0);
@@ -176,6 +176,7 @@
 
     //***** Instance Variables
 
+    @UnsupportedAppUsage
     final WakeLock mWakeLock;           // Wake lock associated with request/response
     final WakeLock mAckWakeLock;        // Wake lock associated with ack sent
     final int mWakeLockTimeout;         // Timeout associated with request/response
@@ -188,6 +189,7 @@
     volatile int mWlSequenceNum = 0;
     volatile int mAckWlSequenceNum = 0;
 
+    @UnsupportedAppUsage
     SparseArray<RILRequest> mRequestList = new SparseArray<RILRequest>();
     static SparseArray<TelephonyHistogram> mRilTimeHistograms = new
             SparseArray<TelephonyHistogram>();
@@ -195,6 +197,7 @@
     Object[] mLastNITZTimeInfo;
 
     // When we are testing emergency calls
+    @UnsupportedAppUsage
     AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false);
 
     final Integer mPhoneId;
@@ -345,6 +348,7 @@
      * @return A default object, such as the one generated by a normal response
      * that is returned to the higher layers.
      **/
+    @UnsupportedAppUsage
     private static Object getResponseForTimedOutRILRequest(RILRequest rr) {
         if (rr == null ) return null;
 
@@ -531,10 +535,12 @@
 
     //***** Constructors
 
+    @UnsupportedAppUsage
     public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
         this(context, preferredNetworkType, cdmaSubscription, null);
     }
 
+    @UnsupportedAppUsage
     public RIL(Context context, int preferredNetworkType,
             int cdmaSubscription, Integer instanceId) {
         super(context);
@@ -865,8 +871,9 @@
 
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-                     int clirMode, Message result) {
-        dial(address, isEmergencyCall, emergencyNumberInfo, clirMode, null, result);
+                     boolean hasKnownUserIntentEmergency, int clirMode, Message result) {
+        dial(address, isEmergencyCall, emergencyNumberInfo, hasKnownUserIntentEmergency,
+                clirMode, null, result);
     }
 
     @Override
@@ -902,11 +909,44 @@
     }
 
     @Override
+    public void getModemStatus(Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
+            if (RILJ_LOGV) riljLog("getModemStatus: not supported.");
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+            return;
+        }
+
+        android.hardware.radio.V1_3.IRadio radioProxy13 =
+                (android.hardware.radio.V1_3.IRadio) radioProxy;
+        if (radioProxy13 != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_MODEM_STATUS, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+            }
+
+            try {
+                radioProxy13.getModemStackStatus(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "getModemStatus", e);
+            }
+        }
+    }
+
+    @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-                     int clirMode, UUSInfo uusInfo, Message result) {
+                     boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
+                     Message result) {
         if (isEmergencyCall && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)
                 && emergencyNumberInfo != null) {
-            emergencyDial(address, emergencyNumberInfo, clirMode, uusInfo, result);
+            emergencyDial(address, emergencyNumberInfo, hasKnownUserIntentEmergency, clirMode,
+                    uusInfo, result);
             return;
         }
 
@@ -940,7 +980,8 @@
     }
 
     private void emergencyDial(String address, EmergencyNumber emergencyNumberInfo,
-                               int clirMode, UUSInfo uusInfo, Message result) {
+                               boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
+                               Message result) {
         IRadio radioProxy = getRadioProxy(result);
         // IRadio V1.4
         android.hardware.radio.V1_4.IRadio radioProxy14 =
@@ -965,12 +1006,11 @@
             }
 
             try {
-                // TODO: populate fromEmergencyDialer correctly
                 radioProxy14.emergencyDial(rr.mSerial, dialInfo,
                         emergencyNumberInfo.getEmergencyServiceCategoryBitmaskInternalDial(),
                         (ArrayList) emergencyNumberInfo.getEmergencyUrns(),
                         emergencyNumberInfo.getEmergencyCallRouting(),
-                        false,
+                        hasKnownUserIntentEmergency,
                         emergencyNumberInfo.getEmergencyNumberSourceBitmask()
                                 == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST);
             } catch (RemoteException | RuntimeException e) {
@@ -1023,6 +1063,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public void hangupWaitingOrBackground(Message result) {
         IRadio radioProxy = getRadioProxy(result);
@@ -1040,6 +1081,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public void hangupForegroundResumeBackground(Message result) {
         IRadio radioProxy = getRadioProxy(result);
@@ -1203,6 +1245,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public void setRadioPower(boolean on, Message result) {
         IRadio radioProxy = getRadioProxy(result);
@@ -1435,7 +1478,8 @@
 
                     if (RILJ_LOGD) {
                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                                + ",accessNetworkType=" + accessNetworkType + ",isRoaming="
+                                + ",accessNetworkType="
+                                + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
                                 + isRoaming + ",allowRoaming=" + allowRoaming + "," + dataProfile
                                 + ",addresses=" + addresses + ",dnses=" + dnses);
                     }
@@ -1453,7 +1497,8 @@
 
                     if (RILJ_LOGD) {
                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                                + ",accessNetworkType=" + accessNetworkType + ",isRoaming="
+                                + ",accessNetworkType="
+                                + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
                                 + isRoaming + ",allowRoaming=" + allowRoaming + ","
                                 + dataProfile + ",addresses=" + addresses + ",dnses=" + dnses);
                     }
@@ -2252,6 +2297,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public void invokeOemRilRequestRaw(byte[] data, Message response) {
         IOemHook oemHookProxy = getOemHookProxy(response);
@@ -2515,7 +2561,7 @@
     }
 
     @Override
-    public void setPreferredNetworkType(int networkType , Message result) {
+    public void setPreferredNetworkType(@PrefNetworkMode int networkType , Message result) {
         IRadio radioProxy = getRadioProxy(result);
         if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, result,
@@ -2539,7 +2585,8 @@
                         (android.hardware.radio.V1_4.IRadio) radioProxy;
                 try {
                     radioProxy14.setPreferredNetworkTypeBitmap(
-                            rr.mSerial, RadioAccessFamily.getRafFromNetworkType(networkType));
+                            rr.mSerial, convertToHalRadioAccessFamily(
+                                    RadioAccessFamily.getRafFromNetworkType(networkType)));
                 } catch (RemoteException | RuntimeException e) {
                     handleRadioProxyExceptionForRR(rr, "setPreferredNetworkTypeBitmap", e);
                 }
@@ -2547,6 +2594,147 @@
         }
     }
 
+    /**
+     * convert RAF from {@link android.hardware.radio.V1_0.RadioAccessFamily} to
+     * {@link TelephonyManager.NetworkTypeBitMask}, the bitmask represented by
+     * {@link TelephonyManager.NetworkType}.
+     *
+     * @param raf {@link android.hardware.radio.V1_0.RadioAccessFamily}
+     * @return {@link TelephonyManager.NetworkTypeBitMask}
+     */
+    @TelephonyManager.NetworkTypeBitMask
+    public static int convertToNetworkTypeBitMask(int raf) {
+        int networkTypeRaf = 0;
+
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GSM) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GSM;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GPRS) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GPRS;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EDGE) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EDGE;
+        }
+        // convert both IS95A/IS95B to CDMA as network mode doesn't support CDMA
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95A) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95B) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EHRPD) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSUPA) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSDPA) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPA) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPAP) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.UMTS) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_UMTS;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
+        }
+        if ((raf & android.hardware.radio.V1_4.RadioAccessFamily.NR) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_NR;
+        }
+        // TODO: need hal definition
+        if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN;
+        }
+        return (networkTypeRaf == 0) ? TelephonyManager.NETWORK_TYPE_UNKNOWN : networkTypeRaf;
+    }
+
+    // convert to android.hardware.radio.V1_0.RadioAccessFamily
+    private static int convertToHalRadioAccessFamily(
+            @TelephonyManager.NetworkTypeBitMask int networkTypeBitmask) {
+        int raf = 0;
+
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_GSM) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.GSM;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_GPRS) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.GPRS;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EDGE) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EDGE;
+        }
+        // convert CDMA to IS95A, consistent with ServiceState.networkTypeToRilRadioTechnology
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_CDMA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.IS95A;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EHRPD;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSUPA;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSDPA;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSPA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSPA;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSPAP;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_UMTS) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.UMTS;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.LTE;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_NR) != 0) {
+            raf |= android.hardware.radio.V1_4.RadioAccessFamily.NR;
+        }
+        // TODO: need hal definition for IWLAN
+        return (raf == 0) ? android.hardware.radio.V1_4.RadioAccessFamily.UNKNOWN : raf;
+    }
+
     @Override
     public void getPreferredNetworkType(Message result) {
         IRadio radioProxy = getRadioProxy(result);
@@ -4657,6 +4845,7 @@
      * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
      * happen often.
      */
+    @UnsupportedAppUsage
     private void acquireWakeLock(RILRequest rr, int wakeLockType) {
         synchronized (rr) {
             if (rr.mWakeLockType != INVALID_WAKELOCK) {
@@ -4721,6 +4910,7 @@
         return mRequestList;
     }
 
+    @UnsupportedAppUsage
     private void decrementWakeLock(RILRequest rr) {
         synchronized (rr) {
             switch(rr.mWakeLockType) {
@@ -4755,6 +4945,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private boolean clearWakeLock(int wakeLockType) {
         if (wakeLockType == FOR_WAKELOCK) {
             synchronized (mWakeLock) {
@@ -4781,6 +4972,7 @@
      * @param error is the RIL_Errno sent back
      * @param loggable true means to print all requests in mRequestList
      */
+    @UnsupportedAppUsage
     private void clearRequestList(int error, boolean loggable) {
         RILRequest rr;
         synchronized (mRequestList) {
@@ -4804,6 +4996,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private RILRequest findAndRemoveRequestFromList(int serial) {
         RILRequest rr = null;
         synchronized (mRequestList) {
@@ -4832,6 +5025,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     RadioCapability makeStaticRadioCapability() {
         // default to UNKNOWN so we fail fast.
         int raf = RadioAccessFamily.RAF_UNKNOWN;
@@ -4847,6 +5041,7 @@
         return rc;
     }
 
+    @UnsupportedAppUsage
     static String retToString(int req, Object ret) {
         if (ret == null) return "";
         switch (req) {
@@ -4947,6 +5142,7 @@
      *
      * @param rilVer is the version of the ril or -1 if disconnected.
      */
+    @UnsupportedAppUsage
     void notifyRegistrantsRilConnectionChanged(int rilVer) {
         mRilVersion = rilVer;
         if (mRilConnectedRegistrants != null) {
@@ -4955,6 +5151,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     void
     notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
         int response = RIL_UNSOL_CDMA_INFO_REC;
@@ -5005,6 +5202,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     static String requestToString(int request) {
         switch(request) {
             case RIL_REQUEST_GET_SIM_STATUS:
@@ -5304,10 +5502,13 @@
                 return "RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA";
             case RIL_REQUEST_ENABLE_MODEM:
                 return "RIL_REQUEST_ENABLE_MODEM";
+            case RIL_REQUEST_GET_MODEM_STATUS:
+                return "RIL_REQUEST_GET_MODEM_STATUS";
             default: return "<unknown request>";
         }
     }
 
+    @UnsupportedAppUsage
     static String responseToString(int request) {
         switch(request) {
             case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
@@ -5419,6 +5620,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     void riljLog(String msg) {
         Rlog.d(RILJ_LOG_TAG, msg + (" [SUB" + mPhoneId + "]"));
     }
@@ -5435,18 +5637,22 @@
         Rlog.v(RILJ_LOG_TAG, msg + (" [SUB" + mPhoneId + "]"));
     }
 
+    @UnsupportedAppUsage
     void unsljLog(int response) {
         riljLog("[UNSL]< " + responseToString(response));
     }
 
+    @UnsupportedAppUsage
     void unsljLogMore(int response, String more) {
         riljLog("[UNSL]< " + responseToString(response) + " " + more);
     }
 
+    @UnsupportedAppUsage
     void unsljLogRet(int response, Object ret) {
         riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
     }
 
+    @UnsupportedAppUsage
     void unsljLogvRet(int response, Object ret) {
         riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
     }
@@ -5568,7 +5774,7 @@
         int session = rcRil.session;
         int phase = rcRil.phase;
         // convert to public bitmask {@link TelephonyManager.NetworkTypeBitMask}
-        int rat = RadioAccessFamily.convertToNetworkTypeBitMask(rcRil.raf);
+        int rat = convertToNetworkTypeBitMask(rcRil.raf);
         String logicModemUuid = rcRil.logicalModemUuid;
         int status = rcRil.status;
 
@@ -5612,7 +5818,9 @@
             ArrayList<android.hardware.radio.V1_0.CellInfo> records) {
         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
 
+        final long nanotime = SystemClock.elapsedRealtimeNanos();
         for (android.hardware.radio.V1_0.CellInfo record : records) {
+            record.timeStamp = nanotime;
             response.add(CellInfo.create(record));
         }
 
@@ -5629,7 +5837,9 @@
             ArrayList<android.hardware.radio.V1_2.CellInfo> records) {
         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
 
+        final long nanotime = SystemClock.elapsedRealtimeNanos();
         for (android.hardware.radio.V1_2.CellInfo record : records) {
+            record.timeStamp = nanotime;
             response.add(CellInfo.create(record));
         }
         return response;
@@ -5645,8 +5855,9 @@
             ArrayList<android.hardware.radio.V1_4.CellInfo> records) {
         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
 
+        final long nanotime = SystemClock.elapsedRealtimeNanos();
         for (android.hardware.radio.V1_4.CellInfo record : records) {
-            response.add(CellInfo.create(record));
+            response.add(CellInfo.create(record, nanotime));
         }
         return response;
     }
@@ -5783,29 +5994,6 @@
     }
 
     /**
-     * @return The {@link IwlanOperationMode IWLAN operation mode}
-     */
-    public @IwlanOperationMode int getIwlanOperationMode() {
-        // Get IWLAN operation mode from the system property. If the system property is missing,
-        // use the default mode.
-        int mode = SystemProperties.getInt(TransportManager.SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE,
-                TransportManager.IWLAN_OPERATION_MODE_DEFAULT);
-
-        // If the operation mode is default, then we use the HAL version to determine it.
-        // On 1.4 or later version of IRadio, it is expected the device to support
-        // IWLAN AP-assisted mode.
-        if (mode == TransportManager.IWLAN_OPERATION_MODE_DEFAULT) {
-            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
-                return TransportManager.IWLAN_OPERATION_MODE_AP_ASSISTED;
-            } else {
-                return TransportManager.IWLAN_OPERATION_MODE_LEGACY;
-            }
-        }
-
-        return mode;
-    }
-
-    /**
      * Get the HAL version.
      *
      * @return the current HalVersion
diff --git a/src/java/com/android/internal/telephony/RILRequest.java b/src/java/com/android/internal/telephony/RILRequest.java
index 174570c..2d8f952 100644
--- a/src/java/com/android/internal/telephony/RILRequest.java
+++ b/src/java/com/android/internal/telephony/RILRequest.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Message;
 import android.os.SystemClock;
@@ -43,8 +44,11 @@
     private static final int MAX_POOL_SIZE = 4;
 
     //***** Instance Variables
+    @UnsupportedAppUsage
     int mSerial;
+    @UnsupportedAppUsage
     int mRequest;
+    @UnsupportedAppUsage
     Message mResult;
     RILRequest mNext;
     int mWakeLockType;
@@ -72,6 +76,7 @@
      * @param result sent when operation completes
      * @return a RILRequest instance from the pool.
      */
+    @UnsupportedAppUsage
     private static RILRequest obtain(int request, Message result) {
         RILRequest rr = null;
 
@@ -154,6 +159,7 @@
      *
      * Note: This should only be called once per use.
      */
+    @UnsupportedAppUsage
     void release() {
         synchronized (sPoolSync) {
             if (sPoolSize < MAX_POOL_SIZE) {
@@ -181,6 +187,7 @@
         sNextSerial.set(sRandom.nextInt(Integer.MAX_VALUE));
     }
 
+    @UnsupportedAppUsage
     String serialString() {
         //Cheesy way to do %04d
         StringBuilder sb = new StringBuilder(8);
@@ -201,6 +208,7 @@
         return sb.toString();
     }
 
+    @UnsupportedAppUsage
     void onError(int error, Object ret) {
         CommandException ex;
 
diff --git a/src/java/com/android/internal/telephony/RadioCapability.java b/src/java/com/android/internal/telephony/RadioCapability.java
index d405c92..2b2615b 100644
--- a/src/java/com/android/internal/telephony/RadioCapability.java
+++ b/src/java/com/android/internal/telephony/RadioCapability.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.TelephonyManager;
 
 /**
@@ -180,6 +181,7 @@
      *
      * @return radio access family
      */
+    @UnsupportedAppUsage
     public int getRadioAccessFamily() {
         return mRadioAccessFamily;
     }
diff --git a/src/java/com/android/internal/telephony/RadioConfig.java b/src/java/com/android/internal/telephony/RadioConfig.java
index ab9afec..a2d4e5b 100644
--- a/src/java/com/android/internal/telephony/RadioConfig.java
+++ b/src/java/com/android/internal/telephony/RadioConfig.java
@@ -324,7 +324,7 @@
      * Wrapper function for IRadioConfig.getPhoneCapability().
      */
     public void getPhoneCapability(Message result) {
-        IRadioConfig radioConfigProxy = getRadioConfigProxy(result);
+        IRadioConfig radioConfigProxy = getRadioConfigProxy(null);
         if (radioConfigProxy == null || mRadioConfigVersion.less(RADIO_CONFIG_HAL_VERSION_1_1)) {
             if (result != null) {
                 AsyncResult.forMessage(result, null,
@@ -393,14 +393,18 @@
 
     static String requestToString(int request) {
         switch (request) {
+            case RIL_REQUEST_GET_PHONE_CAPABILITY:
+                return "GET_PHONE_CAPABILITY";
             case RIL_REQUEST_GET_SLOT_STATUS:
                 return "GET_SLOT_STATUS";
             case RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING:
                 return "SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING";
+            case RIL_REQUEST_SET_PREFERRED_DATA_MODEM:
+                return "SET_PREFERRED_DATA_MODEM";
             case RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG:
-                return "RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG";
+                return "SWITCH_DUAL_SIM_CONFIG";
             default:
-                return "<unknown request>";
+                return "<unknown request " + request + ">";
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/RadioResponse.java b/src/java/com/android/internal/telephony/RadioResponse.java
index 64eb063..a36b7a6 100644
--- a/src/java/com/android/internal/telephony/RadioResponse.java
+++ b/src/java/com/android/internal/telephony/RadioResponse.java
@@ -809,12 +809,14 @@
     /**
      * Callback of the getPreferredNetworkTypeBitmap defined in the IRadio.hal.
      * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param networkTypeBitmap a 32-bit bitmap of
-     * {@link android.telephony.TelephonyManager.NetworkTypeBitMask}.
+     * @param halRadioAccessFamilyBitmap a 32-bit bitmap of
+     * {@link android.hardware.radio.V1_0.RadioAccessFamily}.
      */
     public void getPreferredNetworkTypeBitmapResponse(
-            RadioResponseInfo responseInfo, int networkTypeBitmap) {
-        int networkType = RadioAccessFamily.getNetworkTypeFromRaf(networkTypeBitmap);
+            RadioResponseInfo responseInfo, int halRadioAccessFamilyBitmap) {
+
+        int networkType = RadioAccessFamily.getNetworkTypeFromRaf(
+                RIL.convertToNetworkTypeBitMask(halRadioAccessFamilyBitmap));
         mRil.mPreferredNetworkType = networkType;
         responseInts(responseInfo, networkType);
     }
diff --git a/src/java/com/android/internal/telephony/RetryManager.java b/src/java/com/android/internal/telephony/RetryManager.java
index 0b4bc3c..87d6cf5 100644
--- a/src/java/com/android/internal/telephony/RetryManager.java
+++ b/src/java/com/android/internal/telephony/RetryManager.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Build;
 import android.os.PersistableBundle;
@@ -134,12 +135,14 @@
     /**
      * The delay (in milliseconds) between APN trying within the same round
      */
+    @UnsupportedAppUsage
     private long mInterApnDelay;
 
     /**
      * The delay (in milliseconds) between APN trying within the same round when we are in
      * fail fast mode
      */
+    @UnsupportedAppUsage
     private long mFailFastInterApnDelay;
 
     /**
@@ -176,6 +179,7 @@
      */
     private ArrayList<RetryRec> mRetryArray = new ArrayList<RetryRec>();
 
+    @UnsupportedAppUsage
     private Phone mPhone;
 
     /**
@@ -218,6 +222,7 @@
     /**
      * Apn context type. Could be "default, "mms", "supl", etc...
      */
+    @UnsupportedAppUsage
     private String mApnType;
 
     /**
@@ -237,6 +242,7 @@
      *
      * @return true if successful
      */
+    @UnsupportedAppUsage
     private boolean configure(String configStr) {
         // Strip quotes if present.
         if ((configStr.startsWith("\"") && configStr.endsWith("\""))) {
@@ -404,6 +410,7 @@
     /**
      * Return the timer that should be used to trigger the data reconnection
      */
+    @UnsupportedAppUsage
     private int getRetryTimer() {
         int index;
         if (mRetryCount < mRetryArray.size()) {
@@ -677,6 +684,7 @@
                 + " mConfig={" + mConfig + "}";
     }
 
+    @UnsupportedAppUsage
     private void log(String s) {
         Rlog.d(LOG_TAG, "[" + mApnType + "] " + s);
     }
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index a015bbe..a6bb27d 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -30,6 +30,7 @@
 import static com.android.internal.telephony.IccSmsInterfaceManager.SMS_MESSAGE_PRIORITY_NOT_SPECIFIED;
 
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -61,8 +62,8 @@
 import android.service.carrier.CarrierMessagingService;
 import android.service.carrier.ICarrierMessagingCallback;
 import android.service.carrier.ICarrierMessagingService;
-import android.telephony.CarrierMessagingServiceManager;
 import android.telephony.CarrierConfigManager;
+import android.telephony.CarrierMessagingServiceManager;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
@@ -143,10 +144,15 @@
     protected static final int EVENT_GET_IMS_SERVICE = 16;
 
 
+    @UnsupportedAppUsage
     protected Phone mPhone;
+    @UnsupportedAppUsage
     protected final Context mContext;
+    @UnsupportedAppUsage
     protected final ContentResolver mResolver;
+    @UnsupportedAppUsage
     protected final CommandsInterface mCi;
+    @UnsupportedAppUsage
     protected final TelephonyManager mTelephonyManager;
 
     /** Maximum number of times to retry sending a failed SMS. */
@@ -175,6 +181,7 @@
     protected boolean mSmsCapable = true;
     protected boolean mSmsSendDisabled;
 
+    @UnsupportedAppUsage
     protected static int getNextConcatenatedRef() {
         sConcatenatedRef += 1;
         return sConcatenatedRef;
@@ -224,6 +231,7 @@
     }
 
     /** Unregister for incoming SMS events. */
+    @UnsupportedAppUsage
     public void dispose() {
         mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
     }
@@ -259,6 +267,7 @@
      *       will be dropped.
      */
     /** Sent messages awaiting a delivery status report. */
+    @UnsupportedAppUsage
     protected final ArrayList<SmsTracker> deliveryPendingList = new ArrayList<SmsTracker>();
 
     /**
@@ -488,6 +497,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void processSendSmsResponse(SmsTracker tracker, int result, int messageRef) {
         if (tracker == null) {
             Rlog.e(TAG, "processSendSmsResponse: null tracker");
@@ -535,6 +545,7 @@
             mTrackers = trackers;
         }
 
+        @UnsupportedAppUsage
         void sendSmsByCarrierApp(String carrierPackageName,
                                  MultipartSmsSenderCallback senderCallback) {
             mSenderCallback = senderCallback;
@@ -625,6 +636,7 @@
     /**
      * Send an SMS PDU. Usually just calls {@link sendRawPdu}.
      */
+    @UnsupportedAppUsage
     private void sendSubmitPdu(SmsTracker tracker) {
         if (shouldBlockSmsForEcbm()) {
             Rlog.d(TAG, "Block SMS in Emergency Callback mode");
@@ -754,6 +766,7 @@
     /**
      * Send a data based SMS to a specific application port.
      *
+     * @param callingPackage the package name of the calling app
      * @param destAddr the address to send the message to
      * @param scAddr is the service center address or null to use
      *  the current default SMSC
@@ -777,14 +790,14 @@
      *  broadcast when the message is delivered to the recipient.  The
      *  raw pdu of the status report is in the extended data ("pdu").
      */
-    protected void sendData(String destAddr, String scAddr, int destPort,
+    protected void sendData(String callingPackage, String destAddr, String scAddr, int destPort,
             byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
         SmsMessageBase.SubmitPduBase pdu = getSubmitPdu(
                 scAddr, destAddr, destPort, data, (deliveryIntent != null));
         if (pdu != null) {
             HashMap map = getSmsTrackerMap(destAddr, scAddr, destPort, data, pdu);
-            SmsTracker tracker = getSmsTracker(map, sentIntent, deliveryIntent, getFormat(),
-                    null /*messageUri*/, false /*expectMore*/,
+            SmsTracker tracker = getSmsTracker(callingPackage, map, sentIntent, deliveryIntent,
+                    getFormat(), null /*messageUri*/, false /*expectMore*/,
                     null /*fullMessageText*/, false /*isText*/,
                     true /*persistMessage*/);
 
@@ -851,8 +864,8 @@
                 scAddr, destAddr, text, (deliveryIntent != null), null, priority, validityPeriod);
         if (pdu != null) {
             HashMap map = getSmsTrackerMap(destAddr, scAddr, text, pdu);
-            SmsTracker tracker = getSmsTracker(map, sentIntent, deliveryIntent, getFormat(),
-                    messageUri, expectMore, text, true /*isText*/,
+            SmsTracker tracker = getSmsTracker(callingPkg, map, sentIntent, deliveryIntent,
+                    getFormat(), messageUri, expectMore, text, true /*isText*/,
                     persistMessage, priority, validityPeriod);
 
             if (!sendSmsByCarrierApp(false /* isDataSms */, tracker)) {
@@ -916,6 +929,7 @@
      * @param use7bitOnly ignore (but still count) illegal characters if true
      * @return TextEncodingDetails
      */
+    @UnsupportedAppUsage
     protected abstract TextEncodingDetails calculateLength(CharSequence messageBody,
             boolean use7bitOnly);
 
@@ -1027,8 +1041,8 @@
             }
 
             trackers[i] =
-                getNewSubmitPduTracker(destAddr, scAddr, parts.get(i), smsHeader, encoding,
-                        sentIntent, deliveryIntent, (i == (msgCount - 1)),
+                getNewSubmitPduTracker(callingPkg, destAddr, scAddr, parts.get(i), smsHeader,
+                        encoding, sentIntent, deliveryIntent, (i == (msgCount - 1)),
                         unsentPartCount, anyPartFailed, messageUri,
                         fullMessageText, priority, expectMore, validityPeriod);
             if (trackers[i] == null) {
@@ -1055,8 +1069,8 @@
     /**
      * Create a new SubmitPdu and return the SMS tracker.
      */
-    private SmsTracker getNewSubmitPduTracker(String destinationAddress, String scAddress,
-            String message, SmsHeader smsHeader, int encoding,
+    private SmsTracker getNewSubmitPduTracker(String callingPackage, String destinationAddress,
+            String scAddress, String message, SmsHeader smsHeader, int encoding,
             PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart,
             AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
             String fullMessageText, int priority, boolean expectMore, int validityPeriod) {
@@ -1085,7 +1099,7 @@
             if (submitPdu != null) {
                 HashMap map = getSmsTrackerMap(destinationAddress, scAddress,
                         message, submitPdu);
-                return getSmsTracker(map, sentIntent, deliveryIntent,
+                return getSmsTracker(callingPackage, map, sentIntent, deliveryIntent,
                         getFormat(), unsentPartCount, anyPartFailed, messageUri, smsHeader,
                         (!lastPart || expectMore), fullMessageText, true /*isText*/,
                         true /*persistMessage*/, priority, validityPeriod);
@@ -1103,7 +1117,7 @@
             if (pdu != null) {
                 HashMap map =  getSmsTrackerMap(destinationAddress, scAddress,
                         message, pdu);
-                return getSmsTracker(map, sentIntent,
+                return getSmsTracker(callingPackage, map, sentIntent,
                         deliveryIntent, getFormat(), unsentPartCount, anyPartFailed, messageUri,
                         smsHeader, (!lastPart || expectMore), fullMessageText, true /*isText*/,
                         false /*persistMessage*/, priority, validityPeriod);
@@ -1154,23 +1168,14 @@
             return;
         }
 
-        // Get calling app package name via UID from Binder call
+        String packageName = tracker.getAppPackageName();
         PackageManager pm = mContext.getPackageManager();
-        String[] packageNames = pm.getPackagesForUid(Binder.getCallingUid());
-
-        if (packageNames == null || packageNames.length == 0) {
-            // Refuse to send SMS if we can't get the calling package name.
-            Rlog.e(TAG, "Can't get calling app package name: refusing to send SMS");
-            tracker.onFailed(mContext, RESULT_ERROR_GENERIC_FAILURE, 0/*errorCode*/);
-            return;
-        }
 
         // Get package info via packagemanager
         PackageInfo appInfo;
         try {
-            // XXX this is lossy- apps can share a UID
             appInfo = pm.getPackageInfoAsUser(
-                    packageNames[0], PackageManager.GET_SIGNATURES, tracker.mUserId);
+                    packageName, PackageManager.GET_SIGNATURES, tracker.mUserId);
         } catch (PackageManager.NameNotFoundException e) {
             Rlog.e(TAG, "Can't get calling app package info: refusing to send SMS");
             tracker.onFailed(mContext, RESULT_ERROR_GENERIC_FAILURE, 0/*errorCode*/);
@@ -1352,6 +1357,7 @@
      * @param isPremium true if the destination is known to be a premium short code
      * @param tracker the SmsTracker for the current message.
      */
+    @UnsupportedAppUsage
     protected void handleConfirmShortCode(boolean isPremium, SmsTracker tracker) {
         if (denyIfQueueLimitReached(tracker)) {
             return;     // queue limit reached; error was returned to caller
@@ -1411,6 +1417,7 @@
      *
      * @param tracker holds the SMS message to send
      */
+    @UnsupportedAppUsage
     protected abstract void sendSms(SmsTracker tracker);
 
     /**
@@ -1432,6 +1439,7 @@
      *
      * @param tracker holds the multipart Sms tracker ready to be sent
      */
+    @UnsupportedAppUsage
     private void sendMultipartSms(SmsTracker tracker) {
         ArrayList<String> parts;
         ArrayList<PendingIntent> sentIntents;
@@ -1471,6 +1479,7 @@
      */
     public static class SmsTracker {
         // fields need to be public for derived SmsDispatchers
+        @UnsupportedAppUsage
         private final HashMap<String, Object> mData;
         public int mRetryCount;
         // IMS retry counter. Nonzero indicates initial message was sent over IMS channel in RIL and
@@ -1480,21 +1489,28 @@
         // Tag indicating that this SMS is being handled by the ImsSmsDispatcher. This tracker
         // should not try to use SMS over IMS over the RIL interface in this case when falling back.
         public boolean mUsesImsServiceForIms;
+        @UnsupportedAppUsage
         public int mMessageRef;
         public boolean mExpectMore;
         public int mValidityPeriod;
         public int mPriority;
         String mFormat;
 
+        @UnsupportedAppUsage
         public final PendingIntent mSentIntent;
+        @UnsupportedAppUsage
         public final PendingIntent mDeliveryIntent;
 
+        @UnsupportedAppUsage
         public final PackageInfo mAppInfo;
+        @UnsupportedAppUsage
         public final String mDestAddress;
 
         public final SmsHeader mSmsHeader;
 
+        @UnsupportedAppUsage
         private long mTimestamp = System.currentTimeMillis();
+        @UnsupportedAppUsage
         public Uri mMessageUri; // Uri of persisted message if we wrote one
 
         // Reference to states of a multipart message that this part belongs to
@@ -1509,6 +1525,7 @@
         // If this is a text message (instead of data message)
         private boolean mIsText;
 
+        @UnsupportedAppUsage
         private boolean mPersistMessage;
 
         // User who sends the SMS.
@@ -1548,6 +1565,7 @@
          * Returns whether this tracker holds a multi-part SMS.
          * @return true if the tracker holds a multi-part SMS; false otherwise
          */
+        @UnsupportedAppUsage
         boolean isMultipart() {
             return mData.containsKey("parts");
         }
@@ -1567,6 +1585,7 @@
         /**
          * Update the status of this message if we persisted it
          */
+        @UnsupportedAppUsage
         public void updateSentMessageStatus(Context context, int status) {
             if (mMessageUri != null) {
                 // If we wrote this message in writeSentMessage, update it now
@@ -1682,6 +1701,7 @@
          * @param error The error to send back with
          * @param errorCode
          */
+        @UnsupportedAppUsage
         public void onFailed(Context context, int error, int errorCode) {
             if (mAnyPartFailed != null) {
                 mAnyPartFailed.set(true);
@@ -1721,6 +1741,7 @@
          *
          * @param context The Context
          */
+        @UnsupportedAppUsage
         public void onSent(Context context) {
             // is single part or last part of multipart message
             boolean isSinglePartOrLastPart = true;
@@ -1754,26 +1775,22 @@
         }
     }
 
-    protected SmsTracker getSmsTracker(HashMap<String, Object> data, PendingIntent sentIntent,
-            PendingIntent deliveryIntent, String format, AtomicInteger unsentPartCount,
-            AtomicBoolean anyPartFailed, Uri messageUri, SmsHeader smsHeader,
-            boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage,
-            int priority, int validityPeriod) {
+    protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, String format,
+            AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
+            SmsHeader smsHeader, boolean expectMore, String fullMessageText, boolean isText,
+            boolean persistMessage, int priority, int validityPeriod) {
         // Get calling app package name via UID from Binder call
         PackageManager pm = mContext.getPackageManager();
-        String[] packageNames = pm.getPackagesForUid(Binder.getCallingUid());
 
         // Get package info via packagemanager
         final int userId = UserHandle.getCallingUserId();
         PackageInfo appInfo = null;
-        if (packageNames != null && packageNames.length > 0) {
-            try {
-                // XXX this is lossy- apps can share a UID
-                appInfo = pm.getPackageInfoAsUser(
-                        packageNames[0], PackageManager.GET_SIGNATURES, userId);
-            } catch (PackageManager.NameNotFoundException e) {
-                // error will be logged in sendRawPdu
-            }
+        try {
+            appInfo = pm.getPackageInfoAsUser(
+                    callingPackage, PackageManager.GET_SIGNATURES, userId);
+        } catch (PackageManager.NameNotFoundException e) {
+            // error will be logged in sendRawPdu
         }
         // Strip non-digits from destination phone number before checking for short codes
         // and before displaying the number to the user if confirmation is required.
@@ -1784,22 +1801,22 @@
                 validityPeriod);
     }
 
-    protected SmsTracker getSmsTracker(HashMap<String, Object> data, PendingIntent sentIntent,
-            PendingIntent deliveryIntent, String format, Uri messageUri, boolean expectMore,
-            String fullMessageText, boolean isText, boolean persistMessage) {
-        return getSmsTracker(data, sentIntent, deliveryIntent, format, null/*unsentPartCount*/,
-                null/*anyPartFailed*/, messageUri, null/*smsHeader*/, expectMore,
-                fullMessageText, isText, persistMessage, SMS_MESSAGE_PRIORITY_NOT_SPECIFIED,
-                SMS_MESSAGE_PERIOD_NOT_SPECIFIED);
+    protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri,
+            boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage) {
+        return getSmsTracker(callingPackage, data, sentIntent, deliveryIntent, format,
+                null/*unsentPartCount*/, null/*anyPartFailed*/, messageUri, null/*smsHeader*/,
+                expectMore, fullMessageText, isText, persistMessage,
+                SMS_MESSAGE_PRIORITY_NOT_SPECIFIED, SMS_MESSAGE_PERIOD_NOT_SPECIFIED);
     }
 
-    protected SmsTracker getSmsTracker(HashMap<String, Object> data, PendingIntent sentIntent,
-            PendingIntent deliveryIntent, String format, Uri messageUri, boolean expectMore,
-            String fullMessageText, boolean isText, boolean persistMessage, int priority,
-            int validityPeriod) {
-        return getSmsTracker(data, sentIntent, deliveryIntent, format, null/*unsentPartCount*/,
-                null/*anyPartFailed*/, messageUri, null/*smsHeader*/, expectMore, fullMessageText,
-                isText, persistMessage, priority, validityPeriod);
+    protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri,
+            boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage,
+            int priority, int validityPeriod) {
+        return getSmsTracker(callingPackage, data, sentIntent, deliveryIntent, format,
+                null/*unsentPartCount*/, null/*anyPartFailed*/, messageUri, null/*smsHeader*/,
+                expectMore, fullMessageText, isText, persistMessage, priority, validityPeriod);
     }
 
     protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr,
@@ -1833,9 +1850,12 @@
             CompoundButton.OnCheckedChangeListener {
 
         private final SmsTracker mTracker;
+        @UnsupportedAppUsage
         private Button mPositiveButton;
+        @UnsupportedAppUsage
         private Button mNegativeButton;
         private boolean mRememberChoice;    // default is unchecked
+        @UnsupportedAppUsage
         private final TextView mRememberUndoInstruction;
         private int mConfirmationType;  // 0 - Short Code Msg Sending; 1 - Rate Limit Exceeded
         private static final int SHORT_CODE_MSG = 0; // Short Code Msg
@@ -1930,6 +1950,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private String getMultipartMessageText(ArrayList<String> parts) {
         final StringBuilder sb = new StringBuilder();
         for (String part : parts) {
@@ -1940,6 +1961,7 @@
         return sb.toString();
     }
 
+    @UnsupportedAppUsage
     protected String getCarrierAppPackageName() {
         UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
         if (card == null) {
@@ -1957,10 +1979,12 @@
                 new Intent(CarrierMessagingService.SERVICE_INTERFACE));
     }
 
+    @UnsupportedAppUsage
     protected int getSubId() {
         return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhone.getPhoneId());
     }
 
+    @UnsupportedAppUsage
     private void checkCallerIsPhoneOrCarrierApp() {
         int uid = Binder.getCallingUid();
         int appId = UserHandle.getAppId(uid);
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
old mode 100644
new mode 100755
index baed262..7a19788
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -22,6 +22,7 @@
 import static com.android.internal.telephony.CarrierActionAgent.CARRIER_ACTION_SET_RADIO_ENABLED;
 
 import android.Manifest.permission;
+import android.annotation.UnsupportedAppUsage;
 import android.app.AlarmManager;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -49,6 +50,7 @@
 import android.os.WorkSource;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CarrierConfigManager;
@@ -77,6 +79,7 @@
 import android.util.LocalLog;
 import android.util.Pair;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 import android.util.StatsLog;
 import android.util.TimestampedValue;
 
@@ -120,14 +123,20 @@
 
     private static final String PROP_FORCE_ROAMING = "telephony.test.forceRoaming";
 
+    @UnsupportedAppUsage
     private CommandsInterface mCi;
+    @UnsupportedAppUsage
     private UiccController mUiccController = null;
+    @UnsupportedAppUsage
     private UiccCardApplication mUiccApplcation = null;
+    @UnsupportedAppUsage
     private IccRecords mIccRecords = null;
 
     private boolean mVoiceCapable;
 
+    @UnsupportedAppUsage
     public ServiceState mSS;
+    @UnsupportedAppUsage
     private ServiceState mNewSS;
 
     // This is the minimum interval at which CellInfo requests will be serviced by the modem.
@@ -149,6 +158,7 @@
     private List<CellInfo> mLastCellInfoList = null;
     private List<PhysicalChannelConfig> mLastPhysicalChannelConfigList = null;
 
+    @UnsupportedAppUsage
     private SignalStrength mSignalStrength;
 
     // TODO - this should not be public, right now used externally GsmConnetion.
@@ -161,6 +171,7 @@
      */
     @VisibleForTesting
     public int[] mPollingContext;
+    @UnsupportedAppUsage
     private boolean mDesiredPowerState;
 
     /**
@@ -170,14 +181,19 @@
      */
     private boolean mDontPollSignalStrength = false;
 
+    @UnsupportedAppUsage
     private RegistrantList mVoiceRoamingOnRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     private RegistrantList mVoiceRoamingOffRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     private RegistrantList mDataRoamingOnRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     private RegistrantList mDataRoamingOffRegistrants = new RegistrantList();
-    protected RegistrantList mAttachedRegistrants = new RegistrantList();
-    protected RegistrantList mDetachedRegistrants = new RegistrantList();
+    protected SparseArray<RegistrantList> mAttachedRegistrants = new SparseArray<>();
+    protected SparseArray<RegistrantList> mDetachedRegistrants = new SparseArray();
     private RegistrantList mVoiceRegStateOrRatChangedRegistrants = new RegistrantList();
-    private RegistrantList mDataRegStateOrRatChangedRegistrants = new RegistrantList();
+    private SparseArray<RegistrantList> mDataRegStateOrRatChangedRegistrants = new SparseArray<>();
+    @UnsupportedAppUsage
     private RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
     private RegistrantList mNetworkDetachedRegistrants = new RegistrantList();
     private RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
@@ -189,8 +205,8 @@
     private int mPendingRadioPowerOffAfterDataOffTag = 0;
 
     // This is a flag for debug purposes only. It it set once the RUIM_RECORDS_LOADED event is
-    // received while the phone type is CDMA-LTE, and is never reset after that.
-    private boolean mRuimRecordsLoaded = false;
+    // received and RUIM is provisioned while the phone type is CDMA-LTE.
+    private boolean mRuimProvisionedRecordsLoaded = false;
 
     /** Signal strength poll rate. */
     private static final int POLL_PERIOD_MILLIS = 20 * 1000;
@@ -262,22 +278,33 @@
     private PendingIntent mRadioOffIntent = null;
     private static final String ACTION_RADIO_OFF = "android.intent.action.ACTION_RADIO_OFF";
     private boolean mPowerOffDelayNeed = true;
+    @UnsupportedAppUsage
     private boolean mDeviceShuttingDown = false;
     /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
+    @UnsupportedAppUsage
     private boolean mSpnUpdatePending = false;
+    @UnsupportedAppUsage
     private String mCurSpn = null;
+    @UnsupportedAppUsage
     private String mCurDataSpn = null;
+    @UnsupportedAppUsage
     private String mCurPlmn = null;
+    @UnsupportedAppUsage
     private boolean mCurShowPlmn = false;
+    @UnsupportedAppUsage
     private boolean mCurShowSpn = false;
+    @UnsupportedAppUsage
     @VisibleForTesting
     public int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     private int mPrevSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
     private boolean mImsRegistered = false;
 
+    @UnsupportedAppUsage
     private SubscriptionManager mSubscriptionManager;
+    @UnsupportedAppUsage
     private SubscriptionController mSubscriptionController;
+    @UnsupportedAppUsage
     private final SstSubscriptionsChangedListener mOnSubscriptionsChangedListener =
         new SstSubscriptionsChangedListener();
 
@@ -367,19 +394,26 @@
     };
 
     //Common
+    @UnsupportedAppUsage
     private final GsmCdmaPhone mPhone;
 
     private CellIdentity mCellIdentity;
     private CellIdentity mNewCellIdentity;
     private static final int MS_PER_HOUR = 60 * 60 * 1000;
     private final NitzStateMachine mNitzState;
+    @UnsupportedAppUsage
     private final ContentResolver mCr;
 
     //GSM
+    @UnsupportedAppUsage
     private int mPreferredNetworkType;
+    @UnsupportedAppUsage
     private int mMaxDataCalls = 1;
+    @UnsupportedAppUsage
     private int mNewMaxDataCalls = 1;
+    @UnsupportedAppUsage
     private int mReasonDataDenied = -1;
+    @UnsupportedAppUsage
     private int mNewReasonDataDenied = -1;
 
     /**
@@ -402,10 +436,13 @@
     /**
      * Mark when service state is in emergency call only mode
      */
+    @UnsupportedAppUsage
     private boolean mEmergencyOnly = false;
     /** Started the recheck process after finding gprs should registered but not. */
+    @UnsupportedAppUsage
     private boolean mStartedGprsRegCheck;
     /** Already sent the event-log for no gprs register. */
+    @UnsupportedAppUsage
     private boolean mReportedGprsNoReg;
 
     private CarrierServiceStateTracker mCSST;
@@ -421,6 +458,7 @@
     public static final int CS_NORMAL_ENABLED = 1005;     // Access Control blocks normal voice/sms service
     public static final int CS_EMERGENCY_ENABLED = 1006;  // Access Control blocks emergency call service
     public static final int CS_REJECT_CAUSE_ENABLED = 2001;     // Notify MM rejection cause
+    public static final int CS_REJECT_CAUSE_DISABLED = 2002;    // Cancel MM rejection cause
     /** Notification id. */
     public static final int PS_NOTIFICATION = 888;  // Id to update and cancel PS restricted
     public static final int CS_NOTIFICATION = 999;  // Id to update and cancel CS restricted
@@ -430,6 +468,7 @@
     /** To identify whether EVENT_SIM_READY is received or not */
     private boolean mIsSimReady = false;
 
+    @UnsupportedAppUsage
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -460,8 +499,10 @@
     public static final String UNACTIVATED_MIN_VALUE = "1111110111";
     // Current Otasp value
     private int mCurrentOtaspMode = TelephonyManager.OTASP_UNINITIALIZED;
+    @UnsupportedAppUsage
     private int mRoamingIndicator;
     private boolean mIsInPrl;
+    @UnsupportedAppUsage
     private int mDefaultRoamingIndicator;
     /**
      * Initially assume no data connection.
@@ -475,6 +516,7 @@
     private String mPrlVersion;
     private boolean mIsMinInfoReady = false;
     private boolean mIsEriTextLoaded = false;
+    @UnsupportedAppUsage
     private boolean mIsSubscriptionFromRuim = false;
     private CdmaSubscriptionSourceManager mCdmaSSM;
     public static final String INVALID_MCC = "000";
@@ -573,9 +615,9 @@
                 CarrierServiceStateTracker.CARRIER_EVENT_VOICE_REGISTRATION, null);
         registerForNetworkDetached(mCSST,
                 CarrierServiceStateTracker.CARRIER_EVENT_VOICE_DEREGISTRATION, null);
-        registerForDataConnectionAttached(mCSST,
+        registerForDataConnectionAttached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mCSST,
                 CarrierServiceStateTracker.CARRIER_EVENT_DATA_REGISTRATION, null);
-        registerForDataConnectionDetached(mCSST,
+        registerForDataConnectionDetached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mCSST,
                 CarrierServiceStateTracker.CARRIER_EVENT_DATA_DEREGISTRATION, null);
         registerForImsCapabilityChanged(mCSST,
                 CarrierServiceStateTracker.CARRIER_EVENT_IMS_CAPABILITIES_CHANGED, null);
@@ -602,8 +644,15 @@
         }
 
         // If we are previously in service, we need to notify that we are out of service now.
-        if (mSS != null && mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE) {
-            mDetachedRegistrants.notifyRegistrants();
+        for (int transport : mTransportManager.getAvailableTransports()) {
+            if (mSS != null) {
+                NetworkRegistrationState nrs = mSS.getNetworkRegistrationState(
+                        NetworkRegistrationState.DOMAIN_PS, transport);
+                if (nrs != null && nrs.isInService()
+                        && mDetachedRegistrants.get(transport) != null) {
+                    mDetachedRegistrants.get(transport).notifyRegistrants();
+                }
+            }
         }
 
         mSS = new ServiceState();
@@ -623,7 +672,7 @@
         mNitzState.handleNetworkCountryCodeUnavailable();
         mCellIdentity = null;
         mNewCellIdentity = null;
-        mRuimRecordsLoaded = false;
+        mRuimProvisionedRecordsLoaded = false;
 
         //cancel any pending pollstate request on voice tech switching
         cancelPollState();
@@ -672,7 +721,9 @@
 
         // Tell everybody that the registration state and RAT have changed.
         notifyVoiceRegStateRilRadioTechnologyChanged();
-        notifyDataRegStateRilRadioTechnologyChanged();
+        for (int transport : mTransportManager.getAvailableTransports()) {
+            notifyDataRegStateRilRadioTechnologyChanged(transport);
+        }
     }
 
     @VisibleForTesting
@@ -699,12 +750,14 @@
         }
     }
 
+    @UnsupportedAppUsage
     public boolean getDesiredPowerState() {
         return mDesiredPowerState;
     }
     public boolean getPowerStateFromCarrier() { return !mRadioDisabledByCarrier; }
 
     private SignalStrength mLastSignalStrength = null;
+    @UnsupportedAppUsage
     protected boolean notifySignalStrength() {
         boolean notified = false;
         if (!mSignalStrength.equals(mLastSignalStrength)) {
@@ -738,20 +791,31 @@
      * AsyncResult in msg.obj where AsyncResult#result contains the
      * new RAT as an Integer Object.
      */
-    protected void notifyDataRegStateRilRadioTechnologyChanged() {
-        int rat = mSS.getRilDataRadioTechnology();
-        int drs = mSS.getDataRegState();
-        if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
+    protected void notifyDataRegStateRilRadioTechnologyChanged(int transport) {
+        NetworkRegistrationState nrs = mSS.getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_PS, transport);
+        if (nrs != null) {
+            int rat = ServiceState.networkTypeToRilRadioTechnology(
+                    nrs.getAccessNetworkTechnology());
+            int drs = regCodeToServiceState(nrs.getRegState());
+            if (DBG) {
+                log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
+            }
 
+            RegistrantList registrantList = mDataRegStateOrRatChangedRegistrants.get(transport);
+            if (registrantList != null) {
+                registrantList.notifyResult(new Pair<>(drs, rat));
+            }
+        }
         mPhone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
-                ServiceState.rilRadioTechnologyToString(rat));
-        mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat));
+                ServiceState.rilRadioTechnologyToString(mSS.getRilDataRadioTechnology()));
     }
 
     /**
      * Some operators have been known to report registration failure
      * data only devices, to fix that use DataRegState.
      */
+    @UnsupportedAppUsage
     protected void useDataRegStateForDataOnlyDevices() {
         if (mVoiceCapable == false) {
             if (DBG) {
@@ -763,6 +827,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     protected void updatePhoneObject() {
         if (mPhone.getContext().getResources().
                 getBoolean(com.android.internal.R.bool.config_switch_phone_on_voice_reg_state_change)) {
@@ -871,6 +936,7 @@
      * an AsyncResult, and onComplete.obj.exception will be non-null
      * on failure.
      */
+    @UnsupportedAppUsage
     public void reRegisterNetwork(Message onComplete) {
         mCi.getPreferredNetworkType(
                 obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
@@ -979,6 +1045,7 @@
                     cancelAllNotifications();
                     // clear cached values on SIM removal
                     mMdn = null;
+                    mRuimProvisionedRecordsLoaded = false;
                     logMdnChange("EVENT_ICC_CHANGED: setting mMdn to null");
                     mMin = null;
                     mIsMinInfoReady = false;
@@ -1190,7 +1257,7 @@
                 ar = (AsyncResult) msg.obj;
 
                 if (ar.exception == null) {
-                    mRegStateManagers.get(TransportType.WWAN)
+                    mRegStateManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                             .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
                             obtainMessage(EVENT_GET_LOC_DONE, null));
                 }
@@ -1372,9 +1439,9 @@
                         updateSpnDisplay();
                     } else {
                         RuimRecords ruim = (RuimRecords) mIccRecords;
-                        mRuimRecordsLoaded = true;
                         if (ruim != null) {
                             if (ruim.isProvisioned()) {
+                                mRuimProvisionedRecordsLoaded = true;
                                 mMdn = ruim.getMdn();
                                 logMdnChange("EVENT_RUIM_RECORDS_LOADED: setting mMdn to " + mMdn);
                                 mMin = ruim.getMin();
@@ -1530,16 +1597,17 @@
     }
 
     public String getMdnNumber() {
-        // if for CDMA-LTE phone MDN is null, and it has already been updated from RUIM, in some
-        // unknown error scenario mMdn may still have been updated to null. Detect and fix that case
-        if (mMdn == null && mRuimRecordsLoaded && mPhone.isPhoneTypeCdmaLte()) {
-            // query RuimRecords to see if it's not null and the value from there can be used. This
-            // should never be the case except in certain error scenarios/race conditions.
+        String mdn = mMdn;
+        // if for CDMA-LTE phone MDN is null, return the value from RuimRecords
+        if (mMdn == null && mPhone.isPhoneTypeCdmaLte()) {
             RuimRecords ruim = (RuimRecords) mIccRecords;
-            if (ruim != null) {
-                if (ruim.isProvisioned() && ruim.getMdn() != null) {
-                    logeMdnChange("getMdnNumber: mMdn is null when RuimRecords.getMdn() is not");
+            if (ruim != null && ruim.getMdn() != null) {
+                logeMdnChange("getMdnNumber: mMdn is null when RuimRecords.getMdn() is not");
+                mdn = ruim.getMdn();
 
+                // if mRuimProvisionedRecordsLoaded is true, then mMdn should not have been null and
+                // we should not have reached here. Update mMdn and catch the error scenario.
+                if (mRuimProvisionedRecordsLoaded) {
                     // broadcast intent to indicate an error related to Line1Number has been
                     // detected
                     Intent intent = new Intent(TelephonyIntents.ACTION_LINE1_NUMBER_ERROR_DETECTED);
@@ -1547,12 +1615,11 @@
                     mPhone.getContext().sendBroadcast(intent,
                             permission.READ_PRIVILEGED_PHONE_STATE);
 
-                    // update mdn
-                    mMdn = ruim.getMdn();
+                    mMdn = mdn;
                 }
             }
         }
-        return mMdn;
+        return mdn;
     }
 
     public String getCdmaMin() {
@@ -1652,6 +1719,7 @@
         if (DBG) log("CDMA_SUBSCRIPTION: NID=" + nidStr);
     }
 
+    @UnsupportedAppUsage
     protected void updateOtaspState() {
         int otaspMode = getOtasp();
         int oldOtaspMode = mCurrentOtaspMode;
@@ -1747,8 +1815,7 @@
                          * Roaming Indicator shall be sent if device is registered
                          * on a CDMA or EVDO system.
                          */
-                        boolean isRoamIndForHomeSystem = isRoamIndForHomeSystem(
-                                Integer.toString(mRoamingIndicator));
+                        boolean isRoamIndForHomeSystem = isRoamIndForHomeSystem(mRoamingIndicator);
                         if (mNewSS.getDataRoaming() == isRoamIndForHomeSystem) {
                             log("isRoamIndForHomeSystem=" + isRoamIndForHomeSystem
                                     + ", override data roaming to " + !isRoamIndForHomeSystem);
@@ -1842,7 +1909,7 @@
         int newFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
 
         if (physicalChannelConfigs != null) {
-            DcTracker dcTracker = mPhone.getDcTracker(TransportType.WWAN);
+            DcTracker dcTracker = mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
             for (PhysicalChannelConfig config : physicalChannelConfigs) {
                 if (isNrPhysicalChannelConfig(config)) {
                     // Update the frequency range of the NR parameters if there is an internet data
@@ -1911,9 +1978,9 @@
      */
     private void combinePsRegistrationStates(ServiceState serviceState) {
         NetworkRegistrationState wlanPsRegState = serviceState.getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, TransportType.WLAN);
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
         NetworkRegistrationState wwanPsRegState = serviceState.getNetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, TransportType.WWAN);
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         if (wlanPsRegState != null
                 && wlanPsRegState.getAccessNetworkTechnology()
                 == TelephonyManager.NETWORK_TYPE_IWLAN
@@ -1978,8 +2045,7 @@
                     // list of ERIs for home system, mCdmaRoaming is true.
                     boolean cdmaRoaming =
                             regCodeIsRoaming(registrationState)
-                                    && !isRoamIndForHomeSystem(
-                                            Integer.toString(roamingIndicator));
+                                    && !isRoamIndForHomeSystem(roamingIndicator);
                     mNewSS.setVoiceRoaming(cdmaRoaming);
                     mRoamingIndicator = roamingIndicator;
                     mIsInPrl = (systemIsInPrl == 0) ? false : true;
@@ -2259,20 +2325,22 @@
      * Determine whether a roaming indicator is in the carrier-specified list of ERIs for
      * home system
      *
-     * @param roamInd roaming indicator in String
+     * @param roamInd roaming indicator
      * @return true if the roamInd is in the carrier-specified list of ERIs for home network
      */
-    private boolean isRoamIndForHomeSystem(String roamInd) {
+    private boolean isRoamIndForHomeSystem(int roamInd) {
         // retrieve the carrier-specified list of ERIs for home system
-        String[] homeRoamIndicators = Resources.getSystem()
-                .getStringArray(com.android.internal.R.array.config_cdma_home_system);
+        final PersistableBundle config = getCarrierConfig();
+        int[] homeRoamIndicators = config.getIntArray(CarrierConfigManager
+                    .KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY);
+
         log("isRoamIndForHomeSystem: homeRoamIndicators=" + Arrays.toString(homeRoamIndicators));
 
         if (homeRoamIndicators != null) {
             // searches through the comma-separated list for a match,
             // return true if one is found.
-            for (String homeRoamInd : homeRoamIndicators) {
-                if (homeRoamInd.equals(roamInd)) {
+            for (int homeRoamInd : homeRoamIndicators) {
+                if (homeRoamInd == roamInd) {
                     return true;
                 }
             }
@@ -2290,6 +2358,7 @@
      * Query the carrier configuration to determine if there any network overrides
      * for roaming or not roaming for the current service state.
      */
+    @UnsupportedAppUsage
     protected void updateRoamingState() {
         if (mPhone.isPhoneTypeGsm()) {
             /**
@@ -2414,6 +2483,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     protected void updateSpnDisplay() {
         updateOperatorNameFromEri();
         // carrier config gets a priority over ERI
@@ -2785,10 +2855,12 @@
         loge(msg);
     }
 
+    @UnsupportedAppUsage
     protected final void log(String s) {
         Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + s);
     }
 
+    @UnsupportedAppUsage
     protected final void loge(String s) {
         Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + s);
     }
@@ -2797,6 +2869,7 @@
      * @return The current GPRS state. IN_SERVICE is the same as "attached"
      * and OUT_OF_SERVICE is the same as detached.
      */
+    @UnsupportedAppUsage
     public int getCurrentDataConnectionState() {
         return mSS.getDataRegState();
     }
@@ -2805,6 +2878,7 @@
      * @return true if phone is camping on a technology (eg UMTS)
      * that could support voice and data simultaneously.
      */
+    @UnsupportedAppUsage
     public boolean isConcurrentVoiceAndDataAllowed() {
         if (mSS.getCssIndicator() == 1) {
             // Checking the Concurrent Service Supported flag first for all phone types.
@@ -2856,6 +2930,7 @@
      * and start over again if the radio notifies us that some
      * event has changed
      */
+    @UnsupportedAppUsage
     public void pollState() {
         pollState(false);
     }
@@ -2904,20 +2979,22 @@
                 mCi.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR, mPollingContext));
 
                 mPollingContext[0]++;
-                mRegStateManagers.get(TransportType.WWAN).getNetworkRegistrationState(
-                        NetworkRegistrationState.DOMAIN_PS,
-                        obtainMessage(EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION, mPollingContext));
+                mRegStateManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                        .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
+                                obtainMessage(EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
+                                        mPollingContext));
 
                 mPollingContext[0]++;
-                mRegStateManagers.get(TransportType.WWAN)
+                mRegStateManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                         .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
                         obtainMessage(EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION, mPollingContext));
 
-                if (mRegStateManagers.get(TransportType.WLAN) != null) {
+                if (mRegStateManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN) != null) {
                     mPollingContext[0]++;
-                    mRegStateManagers.get(TransportType.WLAN).getNetworkRegistrationState(
-                            NetworkRegistrationState.DOMAIN_PS,
-                            obtainMessage(EVENT_POLL_STATE_PS_IWLAN_REGISTRATION, mPollingContext));
+                    mRegStateManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
+                            .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
+                                    obtainMessage(EVENT_POLL_STATE_PS_IWLAN_REGISTRATION,
+                                            mPollingContext));
                 }
 
                 if (mPhone.isPhoneTypeGsm()) {
@@ -2962,16 +3039,48 @@
                 mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
                         && mNewSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE;
 
-        boolean hasDataAttached =
-                mSS.getDataRegState() != ServiceState.STATE_IN_SERVICE
-                        && mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE;
+        SparseBooleanArray hasDataAttached = new SparseBooleanArray(
+                mTransportManager.getAvailableTransports().length);
+        SparseBooleanArray hasDataDetached = new SparseBooleanArray(
+                mTransportManager.getAvailableTransports().length);
+        SparseBooleanArray hasRilDataRadioTechnologyChanged = new SparseBooleanArray(
+                mTransportManager.getAvailableTransports().length);
+        SparseBooleanArray hasDataRegStateChanged = new SparseBooleanArray(
+                mTransportManager.getAvailableTransports().length);
+        boolean anyDataRegChanged = false;
+        boolean anyDataRatChanged = false;
+        for (int transport : mTransportManager.getAvailableTransports()) {
+            NetworkRegistrationState oldNrs = mSS.getNetworkRegistrationState(
+                    NetworkRegistrationState.DOMAIN_PS, transport);
+            NetworkRegistrationState newNrs = mNewSS.getNetworkRegistrationState(
+                    NetworkRegistrationState.DOMAIN_PS, transport);
 
-        boolean hasDataDetached =
-                mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE
-                        && mNewSS.getDataRegState() != ServiceState.STATE_IN_SERVICE;
+            boolean changed = (oldNrs == null || !oldNrs.isInService())
+                    && (newNrs != null && newNrs.isInService());
+            hasDataAttached.put(transport, changed);
 
-        boolean hasDataRegStateChanged =
-                mSS.getDataRegState() != mNewSS.getDataRegState();
+            changed = (oldNrs != null && oldNrs.isInService())
+                    && (newNrs == null || !newNrs.isInService());
+            hasDataDetached.put(transport, changed);
+
+            int oldRAT = oldNrs != null ? oldNrs.getAccessNetworkTechnology()
+                    : TelephonyManager.NETWORK_TYPE_UNKNOWN;
+            int newRAT = newNrs != null ? newNrs.getAccessNetworkTechnology()
+                    : TelephonyManager.NETWORK_TYPE_UNKNOWN;
+            hasRilDataRadioTechnologyChanged.put(transport, oldRAT != newRAT);
+            if (oldRAT != newRAT) {
+                anyDataRatChanged = true;
+            }
+
+            int oldRegState = oldNrs != null ? oldNrs.getRegState()
+                    : NetworkRegistrationState.REG_STATE_UNKNOWN;
+            int newRegState = newNrs != null ? newNrs.getRegState()
+                    : NetworkRegistrationState.REG_STATE_UNKNOWN;
+            hasDataRegStateChanged.put(transport, oldRegState != newRegState);
+            if (oldRegState != newRegState) {
+                anyDataRegChanged = true;
+            }
+        }
 
         boolean hasVoiceRegStateChanged =
                 mSS.getVoiceRegState() != mNewSS.getVoiceRegState();
@@ -3001,9 +3110,6 @@
         boolean hasRilVoiceRadioTechnologyChanged =
                 mSS.getRilVoiceRadioTechnology() != mNewSS.getRilVoiceRadioTechnology();
 
-        boolean hasRilDataRadioTechnologyChanged =
-                mSS.getRilDataRadioTechnology() != mNewSS.getRilDataRadioTechnology();
-
         boolean hasChanged = !mNewSS.equals(mSS);
 
         boolean hasVoiceRoamingOn = !mSS.getVoiceRoaming() && mNewSS.getVoiceRoaming();
@@ -3070,7 +3176,7 @@
         }
 
         // Add an event log when connection state changes
-        if (hasVoiceRegStateChanged || hasDataRegStateChanged) {
+        if (hasVoiceRegStateChanged || anyDataRegChanged) {
             EventLog.writeEvent(mPhone.isPhoneTypeGsm() ? EventLogTags.GSM_SERVICE_STATE_CHANGE :
                             EventLogTags.CDMA_SERVICE_STATE_CHANGE,
                     mSS.getVoiceRegState(), mSS.getDataRegState(),
@@ -3127,19 +3233,13 @@
             updatePhoneObject();
         }
 
-        TelephonyManager tm =
-                (TelephonyManager) mPhone.getContext().getSystemService(Context.TELEPHONY_SERVICE);
-
-        if (hasRilDataRadioTechnologyChanged) {
+        TelephonyManager tm = (TelephonyManager) mPhone.getContext().getSystemService(
+                Context.TELEPHONY_SERVICE);
+        if (anyDataRatChanged) {
             tm.setDataNetworkTypeForPhone(mPhone.getPhoneId(), mSS.getRilDataRadioTechnology());
             StatsLog.write(StatsLog.MOBILE_RADIO_TECHNOLOGY_CHANGED,
-                    ServiceState.rilRadioTechnologyToNetworkType(mSS.getRilDataRadioTechnology()),
-                    mPhone.getPhoneId());
-
-            if (ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
-                    == mSS.getRilDataRadioTechnology()) {
-                log("pollStateDone: IWLAN enabled");
-            }
+                    ServiceState.rilRadioTechnologyToNetworkType(
+                            mSS.getRilDataRadioTechnology()), mPhone.getPhoneId());
         }
 
         if (hasRegistered) {
@@ -3159,9 +3259,6 @@
             updateSpnDisplay();
 
             tm.setNetworkOperatorNameForPhone(mPhone.getPhoneId(), mSS.getOperatorAlpha());
-
-            String prevOperatorNumeric = tm.getNetworkOperatorForPhone(mPhone.getPhoneId());
-            String prevCountryIsoCode = tm.getNetworkCountryIso(mPhone.getPhoneId());
             String operatorNumeric = mSS.getOperatorNumeric();
 
             if (!mPhone.isPhoneTypeGsm()) {
@@ -3213,34 +3310,57 @@
             TelephonyMetrics.getInstance().writeServiceStateChanged(mPhone.getPhoneId(), mSS);
         }
 
-        if (hasDataAttached || has4gHandoff || hasDataDetached || hasRegistered
-                || hasDeregistered) {
+        boolean shouldLogAttachedChange = false;
+        boolean shouldLogRatChange = false;
+
+        if (hasRegistered || hasDeregistered) {
+            shouldLogAttachedChange = true;
+        }
+
+        if (has4gHandoff) {
+            mAttachedRegistrants.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                    .notifyRegistrants();
+            shouldLogAttachedChange = true;
+        }
+
+        if (hasRilVoiceRadioTechnologyChanged) {
+            shouldLogRatChange = true;
+            notifySignalStrength();
+        }
+
+        for (int transport : mTransportManager.getAvailableTransports()) {
+            if (hasRilDataRadioTechnologyChanged.get(transport)) {
+                shouldLogRatChange = true;
+                notifySignalStrength();
+            }
+
+            if (hasDataRegStateChanged.get(transport)
+                    || hasRilDataRadioTechnologyChanged.get(transport)) {
+                notifyDataRegStateRilRadioTechnologyChanged(transport);
+                mPhone.notifyDataConnection();
+            }
+
+            if (hasDataAttached.get(transport)) {
+                shouldLogAttachedChange = true;
+                mAttachedRegistrants.get(transport).notifyRegistrants();
+            }
+            if (hasDataDetached.get(transport)) {
+                shouldLogAttachedChange = true;
+                mDetachedRegistrants.get(transport).notifyRegistrants();
+            }
+        }
+
+        if (shouldLogAttachedChange) {
             logAttachChange();
         }
-
-        if (hasDataAttached || has4gHandoff) {
-            mAttachedRegistrants.notifyRegistrants();
-        }
-
-        if (hasDataDetached) {
-            mDetachedRegistrants.notifyRegistrants();
-        }
-
-        if (hasRilDataRadioTechnologyChanged || hasRilVoiceRadioTechnologyChanged) {
+        if (shouldLogRatChange) {
             logRatChange();
-
-            notifySignalStrength();
         }
 
         if (hasVoiceRegStateChanged || hasRilVoiceRadioTechnologyChanged) {
             notifyVoiceRegStateRilRadioTechnologyChanged();
         }
 
-        if (hasDataRegStateChanged || hasRilDataRadioTechnologyChanged) {
-            notifyDataRegStateRilRadioTechnologyChanged();
-            mPhone.notifyDataConnection();
-        }
-
         if (hasVoiceRoamingOn || hasVoiceRoamingOff || hasDataRoamingOn || hasDataRoamingOff) {
             logRoamingChange();
         }
@@ -3353,6 +3473,7 @@
      *
      * @return true if provided sid/nid pair belongs to operator's home network.
      */
+    @UnsupportedAppUsage
     private boolean isInHomeSidNid(int sid, int nid) {
         // if SID/NID is not available, assume this is home network.
         if (isSidsAllZeros()) return true;
@@ -3375,6 +3496,7 @@
         return false;
     }
 
+    @UnsupportedAppUsage
     protected void setOperatorIdd(String operatorNumeric) {
         // Retrieve the current country information
         // with the MCC got from opeatorNumeric.
@@ -3389,11 +3511,13 @@
         }
     }
 
+    @UnsupportedAppUsage
     private boolean isInvalidOperatorNumeric(String operatorNumeric) {
         return operatorNumeric == null || operatorNumeric.length() < 5 ||
                 operatorNumeric.startsWith(INVALID_MCC);
     }
 
+    @UnsupportedAppUsage
     private String fixUnknownMcc(String operatorNumeric, int sid) {
         if (sid <= 0) {
             // no cdma information is available, do nothing
@@ -3444,6 +3568,7 @@
      * @param voiceRegState i.e. CREG in GSM
      * @return false if device only register to voice but not gprs
      */
+    @UnsupportedAppUsage
     private boolean isGprsConsistent(int dataRegState, int voiceRegState) {
         return !((voiceRegState == ServiceState.STATE_IN_SERVICE) &&
                 (dataRegState != ServiceState.STATE_IN_SERVICE));
@@ -3811,6 +3936,8 @@
 
         Context context = mPhone.getContext();
 
+        boolean autoCancelCsRejectNotification = false;
+
         CarrierConfigManager configManager = (CarrierConfigManager)
                 context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         if (configManager != null) {
@@ -3824,6 +3951,8 @@
                     if (DBG) log("Voice/emergency call barred notification disabled");
                     return;
                 }
+                autoCancelCsRejectNotification = bundle.getBoolean(
+                        CarrierConfigManager.KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false);
             }
         }
 
@@ -3884,8 +4013,12 @@
                 notificationId = CS_REJECT_CAUSE_NOTIFICATION;
                 int resId = selectResourceForRejectCode(mRejectCode, multipleSubscriptions);
                 if (0 == resId) {
-                    loge("setNotification: mRejectCode=" + mRejectCode + " is not handled.");
-                    return;
+                    if (autoCancelCsRejectNotification) {
+                        notifyType = CS_REJECT_CAUSE_DISABLED;
+                    } else {
+                        loge("setNotification: mRejectCode=" + mRejectCode + " is not handled.");
+                        return;
+                    }
                 } else {
                     icon = com.android.internal.R.drawable.stat_notify_mmcc_indication_icn;
                     // if using the single SIM resource, simNumber will be ignored
@@ -3916,7 +4049,8 @@
         NotificationManager notificationManager = (NotificationManager)
                 context.getSystemService(Context.NOTIFICATION_SERVICE);
 
-        if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
+        if (notifyType == PS_DISABLED || notifyType == CS_DISABLED
+                || notifyType == CS_REJECT_CAUSE_DISABLED) {
             // cancel previous post notification
             notificationManager.cancel(Integer.toString(mSubId), notificationId);
         } else {
@@ -4020,38 +4154,74 @@
 
     /**
      * Registration point for transition into DataConnection attached.
+     * @param transport Transport type
      * @param h handler to notify
      * @param what what code of message when delivered
      * @param obj placed in Message.obj
      */
-    public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
+    public void registerForDataConnectionAttached(@TransportType int transport, Handler h, int what,
+                                                  Object obj) {
         Registrant r = new Registrant(h, what, obj);
-        mAttachedRegistrants.add(r);
+        if (mAttachedRegistrants.get(transport) == null) {
+            mAttachedRegistrants.put(transport, new RegistrantList());
+        }
+        mAttachedRegistrants.get(transport).add(r);
 
-        if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
-            r.notifyRegistrant();
+        if (mSS != null) {
+            NetworkRegistrationState netRegState = mSS.getNetworkRegistrationState(
+                    NetworkRegistrationState.DOMAIN_PS, transport);
+            if (netRegState == null || netRegState.isInService()) {
+                r.notifyRegistrant();
+            }
         }
     }
-    public void unregisterForDataConnectionAttached(Handler h) {
-        mAttachedRegistrants.remove(h);
+
+    /**
+     * Unregister for data attached event
+     *
+     * @param transport Transport type
+     * @param h Handler to notify
+     */
+    public void unregisterForDataConnectionAttached(@TransportType int transport, Handler h) {
+        if (mAttachedRegistrants.get(transport) != null) {
+            mAttachedRegistrants.get(transport).remove(h);
+        }
     }
 
     /**
      * Registration point for transition into DataConnection detached.
+     * @param transport Transport type
      * @param h handler to notify
      * @param what what code of message when delivered
      * @param obj placed in Message.obj
      */
-    public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
+    public void registerForDataConnectionDetached(@TransportType int transport, Handler h, int what,
+                                                  Object obj) {
         Registrant r = new Registrant(h, what, obj);
-        mDetachedRegistrants.add(r);
+        if (mDetachedRegistrants.get(transport) == null) {
+            mDetachedRegistrants.put(transport, new RegistrantList());
+        }
+        mDetachedRegistrants.get(transport).add(r);
 
-        if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
-            r.notifyRegistrant();
+        if (mSS != null) {
+            NetworkRegistrationState netRegState = mSS.getNetworkRegistrationState(
+                    NetworkRegistrationState.DOMAIN_PS, transport);
+            if (netRegState != null && !netRegState.isInService()) {
+                r.notifyRegistrant();
+            }
         }
     }
-    public void unregisterForDataConnectionDetached(Handler h) {
-        mDetachedRegistrants.remove(h);
+
+    /**
+     * Unregister for data detatched event
+     *
+     * @param transport Transport type
+     * @param h Handler to notify
+     */
+    public void unregisterForDataConnectionDetached(@TransportType int transport, Handler h) {
+        if (mDetachedRegistrants.get(transport) != null) {
+            mDetachedRegistrants.get(transport).remove(h);
+        }
     }
 
     /**
@@ -4078,17 +4248,31 @@
      * new radio technology will be returned AsyncResult#result as an Integer Object.
      * The AsyncResult will be in the notification Message#obj.
      *
+     * @param transport Transport
      * @param h handler to notify
      * @param what what code of message when delivered
      * @param obj placed in Message.obj
      */
-    public void registerForDataRegStateOrRatChanged(Handler h, int what, Object obj) {
+    public void registerForDataRegStateOrRatChanged(@TransportType int transport, Handler h,
+                                                    int what, Object obj) {
         Registrant r = new Registrant(h, what, obj);
-        mDataRegStateOrRatChangedRegistrants.add(r);
-        notifyDataRegStateRilRadioTechnologyChanged();
+        if (mDataRegStateOrRatChangedRegistrants.get(transport) == null) {
+            mDataRegStateOrRatChangedRegistrants.put(transport, new RegistrantList());
+        }
+        mDataRegStateOrRatChangedRegistrants.get(transport).add(r);
+        notifyDataRegStateRilRadioTechnologyChanged(transport);
     }
-    public void unregisterForDataRegStateOrRatChanged(Handler h) {
-        mDataRegStateOrRatChangedRegistrants.remove(h);
+
+    /**
+     * Unregister for data registration state changed or RAT changed event
+     *
+     * @param transport Transport
+     * @param h The handler
+     */
+    public void unregisterForDataRegStateOrRatChanged(@TransportType int transport, Handler h) {
+        if (mDataRegStateOrRatChangedRegistrants.get(transport) != null) {
+            mDataRegStateOrRatChangedRegistrants.get(transport).remove(h);
+        }
     }
 
     /**
@@ -4456,6 +4640,7 @@
         return iccCardExist;
     }
 
+    @UnsupportedAppUsage
     public String getSystemProperty(String property, String defValue) {
         return TelephonyManager.getTelephonyProperty(mPhone.getPhoneId(), property, defValue);
     }
@@ -4716,6 +4901,7 @@
         mNitzState.dumpLogs(fd, ipw, args);
     }
 
+    @UnsupportedAppUsage
     public boolean isImsRegistered() {
         return mImsRegistered;
     }
@@ -4779,6 +4965,7 @@
      * Set both voice and data roaming type,
      * judging from the ISO country of SIM VS network.
      */
+    @UnsupportedAppUsage
     protected void setRoamingType(ServiceState currentServiceState) {
         final boolean isVoiceInService =
                 (currentServiceState.getVoiceRegState() == ServiceState.STATE_IN_SERVICE);
@@ -4869,6 +5056,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void setSignalStrengthDefaultValues() {
         mSignalStrength = new SignalStrength();
     }
@@ -4883,6 +5071,7 @@
         return numeric;
     }
 
+    @UnsupportedAppUsage
     protected int getPhoneId() {
         return mPhone.getPhoneId();
     }
@@ -4890,6 +5079,7 @@
     /* Reset Service state when IWLAN is enabled as polling in airplane mode
      * causes state to go to OUT_OF_SERVICE state instead of STATE_OFF
      */
+    @UnsupportedAppUsage
     protected void resetServiceStateInIwlanMode() {
         if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) {
             boolean resetIwlanRatVal = false;
diff --git a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
index 01c162b..459d97a 100644
--- a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
+++ b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -124,6 +125,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private SmsBroadcastUndelivered(Context context, GsmInboundSmsHandler gsmInboundSmsHandler,
             CdmaInboundSmsHandler cdmaInboundSmsHandler) {
         mResolver = context.getContentResolver();
diff --git a/src/java/com/android/internal/telephony/SmsDispatchersController.java b/src/java/com/android/internal/telephony/SmsDispatchersController.java
index d858cbe..1d71beb 100644
--- a/src/java/com/android/internal/telephony/SmsDispatchersController.java
+++ b/src/java/com/android/internal/telephony/SmsDispatchersController.java
@@ -544,6 +544,7 @@
     /**
      * Send a data based SMS to a specific application port.
      *
+     * @param callingPackage the package name of the calling app
      * @param destAddr the address to send the message to
      * @param scAddr is the service center address or null to use
      *  the current default SMSC
@@ -567,15 +568,17 @@
      *  broadcast when the message is delivered to the recipient.  The
      *  raw pdu of the status report is in the extended data ("pdu").
      */
-    protected void sendData(String destAddr, String scAddr, int destPort,
+    protected void sendData(String callingPackage, String destAddr, String scAddr, int destPort,
                             byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
         if (mImsSmsDispatcher.isAvailable()) {
-            mImsSmsDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent,
+            mImsSmsDispatcher.sendData(callingPackage, destAddr, scAddr, destPort, data, sentIntent,
                     deliveryIntent);
         } else if (isCdmaMo()) {
-            mCdmaDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
+            mCdmaDispatcher.sendData(callingPackage, destAddr, scAddr, destPort, data, sentIntent,
+                    deliveryIntent);
         } else {
-            mGsmDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
+            mGsmDispatcher.sendData(callingPackage, destAddr, scAddr, destPort, data, sentIntent,
+                    deliveryIntent);
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/SmsResponse.java b/src/java/com/android/internal/telephony/SmsResponse.java
index 1aac242..0c9d7ac 100644
--- a/src/java/com/android/internal/telephony/SmsResponse.java
+++ b/src/java/com/android/internal/telephony/SmsResponse.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * Object returned by the RIL upon successful completion of sendSMS.
  * Contains message reference and ackPdu.
@@ -23,15 +25,19 @@
  */
 public class SmsResponse {
     /** Message reference of the just-sent SMS. */
+    @UnsupportedAppUsage
     int mMessageRef;
     /** ackPdu for the just-sent SMS. */
+    @UnsupportedAppUsage
     String mAckPdu;
     /**
      * errorCode: See 3GPP 27.005, 3.2.5 for GSM/UMTS,
      * 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
      */
+    @UnsupportedAppUsage
     public int mErrorCode;
 
+    @UnsupportedAppUsage
     public SmsResponse(int messageRef, String ackPdu, int errorCode) {
         mMessageRef = messageRef;
         mAckPdu = ackPdu;
diff --git a/src/java/com/android/internal/telephony/SmsStorageMonitor.java b/src/java/com/android/internal/telephony/SmsStorageMonitor.java
index 77ac097..1dcbdd6 100755
--- a/src/java/com/android/internal/telephony/SmsStorageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsStorageMonitor.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -58,6 +59,7 @@
     /** it is use to put in to extra value for SIM_FULL_ACTION and SMS_REJECTED_ACTION */
     Phone mPhone;
 
+    @UnsupportedAppUsage
     final CommandsInterface mCi;                            // accessed from inner class
     boolean mStorageAvailable = true;                       // accessed from inner class
 
diff --git a/src/java/com/android/internal/telephony/SmsUsageMonitor.java b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
index 402a5ef..f5e3c10 100644
--- a/src/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.AppGlobals;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -254,6 +255,7 @@
      * Create SMS usage monitor.
      * @param context the context to use to load resources and get TelephonyManager service
      */
+    @UnsupportedAppUsage
     public SmsUsageMonitor(Context context) {
         mContext = context;
         ContentResolver resolver = context.getContentResolver();
@@ -361,6 +363,7 @@
      * @return true if application is allowed to send the requested number
      *  of new sms messages
      */
+    @UnsupportedAppUsage
     public boolean check(String appName, int smsWaiting) {
         synchronized (mSmsStamp) {
             removeExpiredTimestamps();
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index b912119..83519aa 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -20,6 +20,7 @@
 
 import android.Manifest;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
 import android.content.ContentResolver;
@@ -92,7 +93,7 @@
 public class SubscriptionController extends ISub.Stub {
     static final String LOG_TAG = "SubscriptionController";
     static final boolean DBG = true;
-    static final boolean VDBG = false;
+    static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE);
     static final boolean DBG_CACHE = false;
     static final int MAX_LOCAL_LOG_LINES = 500; // TODO: Reduce to 100 when 17678050 is fixed
     private static final int DEPRECATED_SETTING = -1;
@@ -156,11 +157,13 @@
                 return flag;
             };
 
+    @UnsupportedAppUsage
     protected final Object mLock = new Object();
 
     /** The singleton instance. */
     private static SubscriptionController sInstance = null;
     protected static Phone[] sPhones;
+    @UnsupportedAppUsage
     protected Context mContext;
     protected TelephonyManager mTelephonyManager;
 
@@ -169,8 +172,10 @@
     // Each slot can have multiple subs.
     private static Map<Integer, ArrayList<Integer>> sSlotIndexToSubIds = new ConcurrentHashMap<>();
     private static int mDefaultFallbackSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    @UnsupportedAppUsage
     private static int mDefaultPhoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
 
+    @UnsupportedAppUsage
     private int[] colorArr;
     private long mLastISubServiceRegTime;
     private int mPreferredDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
@@ -197,6 +202,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public static SubscriptionController getInstance() {
         if (sInstance == null)
         {
@@ -225,6 +231,7 @@
         if (DBG) logdl("[SubscriptionController] init by Context");
     }
 
+    @UnsupportedAppUsage
     private boolean isSubInfoReady() {
         if (VDBG) {
             // make sure sSlotIndexToSubIds is consistent with cached subinfo list
@@ -260,6 +267,7 @@
         if (DBG) logdl("[SubscriptionController] init by Phone");
     }
 
+    @UnsupportedAppUsage
     private void enforceModifyPhoneState(String message) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.MODIFY_PHONE_STATE, message);
@@ -284,6 +292,7 @@
     /**
      * Notify the changed of subscription info.
      */
+    @UnsupportedAppUsage
     public void notifySubscriptionInfoChanged() {
         ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
                 "telephony.registry"));
@@ -306,6 +315,7 @@
      * @param cursor
      * @return the query result of desired SubInfoRecord
      */
+    @UnsupportedAppUsage
     private SubscriptionInfo getSubInfoRecord(Cursor cursor) {
         int id = cursor.getInt(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID));
@@ -393,6 +403,7 @@
      * @param queryKey query key content
      * @return Array list of queried result from database
      */
+     @UnsupportedAppUsage
      private List<SubscriptionInfo> getSubInfo(String selection, Object queryKey) {
         if (VDBG) logd("selection:" + selection + ", querykey: " + queryKey);
         String[] selectionArgs = null;
@@ -460,6 +471,7 @@
      * @param callingPackage The package making the IPC.
      * @return SubscriptionInfo, maybe null if its not active
      */
+    @UnsupportedAppUsage
     @Override
     public SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
@@ -611,7 +623,7 @@
      */
     @Override
     public List<SubscriptionInfo> getAllSubInfoList(String callingPackage) {
-        if (DBG) logd("[getAllSubInfoList]+");
+        if (VDBG) logd("[getAllSubInfoList]+");
 
         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
         // about carrier-privileged callers not having access.
@@ -627,9 +639,9 @@
             List<SubscriptionInfo> subList = null;
             subList = getSubInfo(null, null);
             if (subList != null) {
-                if (DBG) logd("[getAllSubInfoList]- " + subList.size() + " infos return");
+                if (VDBG) logd("[getAllSubInfoList]- " + subList.size() + " infos return");
             } else {
-                if (DBG) logd("[getAllSubInfoList]- no info return");
+                if (VDBG) logd("[getAllSubInfoList]- no info return");
             }
             return subList;
         } finally {
@@ -643,6 +655,7 @@
      * @param callingPackage The package making the IPC.
      * @return Array list of currently inserted SubInfoRecord(s)
      */
+    @UnsupportedAppUsage
     @Override
     public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage) {
         return getSubscriptionInfoListFromCacheHelper(callingPackage, mCacheActiveSubInfoList);
@@ -702,6 +715,7 @@
      * @param callingPackage The package making the IPC.
      * @return active SIM count
      */
+    @UnsupportedAppUsage
     @Override
     public int getActiveSubInfoCount(String callingPackage) {
         // Let getActiveSubscriptionInfoList perform permission checks / filtering.
@@ -1325,9 +1339,6 @@
         refreshCachedActiveSubscriptionInfoList();
 
         sSlotIndexToSubIds.remove(slotIndex);
-
-        // update default subId
-        clearDefaultsForInactiveSubIds();
     }
 
     /**
@@ -1384,6 +1395,7 @@
      * @param spn spn to be included in carrier text
      * @return true if carrier text is set, false otherwise
      */
+    @UnsupportedAppUsage
     public boolean setPlmnSpn(int slotIndex, boolean showPlmn, String plmn, boolean showSpn,
                               String spn) {
         synchronized (mLock) {
@@ -1757,6 +1769,7 @@
      * Return the subId for specified slot Id.
      * @deprecated
      */
+    @UnsupportedAppUsage
     @Override
     @Deprecated
     public int[] getSubId(int slotIndex) {
@@ -1805,6 +1818,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public int getPhoneId(int subId) {
         if (VDBG) printStackTrace("[getPhoneId] subId=" + subId);
@@ -1883,6 +1897,7 @@
         Rlog.v(LOG_TAG, msg);
     }
 
+    @UnsupportedAppUsage
     private void logdl(String msg) {
         logd(msg);
         mLocalLog.log(msg);
@@ -1892,6 +1907,7 @@
         Rlog.d(LOG_TAG, msg);
     }
 
+    @UnsupportedAppUsage
     private void logd(String msg) {
         Rlog.d(LOG_TAG, msg);
     }
@@ -1901,10 +1917,12 @@
         mLocalLog.log(msg);
     }
 
+    @UnsupportedAppUsage
     private void loge(String msg) {
         Rlog.e(LOG_TAG, msg);
     }
 
+    @UnsupportedAppUsage
     @Override
     public int getDefaultSubId() {
         int subId;
@@ -1925,6 +1943,7 @@
         return subId;
     }
 
+    @UnsupportedAppUsage
     @Override
     public void setDefaultSmsSubId(int subId) {
         enforceModifyPhoneState("setDefaultSmsSubId");
@@ -1949,6 +1968,7 @@
         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
 
+    @UnsupportedAppUsage
     @Override
     public int getDefaultSmsSubId() {
         int subId = Settings.Global.getInt(mContext.getContentResolver(),
@@ -1958,6 +1978,7 @@
         return subId;
     }
 
+    @UnsupportedAppUsage
     @Override
     public void setDefaultVoiceSubId(int subId) {
         enforceModifyPhoneState("setDefaultVoiceSubId");
@@ -1987,6 +2008,7 @@
         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
 
+    @UnsupportedAppUsage
     @Override
     public int getDefaultVoiceSubId() {
         int subId = Settings.Global.getInt(mContext.getContentResolver(),
@@ -1996,6 +2018,7 @@
         return subId;
     }
 
+    @UnsupportedAppUsage
     @Override
     public int getDefaultDataSubId() {
         int subId = Settings.Global.getInt(mContext.getContentResolver(),
@@ -2005,6 +2028,7 @@
         return subId;
     }
 
+    @UnsupportedAppUsage
     @Override
     public void setDefaultDataSubId(int subId) {
         enforceModifyPhoneState("setDefaultDataSubId");
@@ -2048,9 +2072,11 @@
 
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION, subId);
+        updateDataEnabledSettings();
         broadcastDefaultDataSubIdChanged(subId);
     }
 
+    @UnsupportedAppUsage
     private void updateAllDataConnectionTrackers() {
         // Tell Phone Proxies to update data connection tracker
         int len = sPhones.length;
@@ -2061,6 +2087,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void broadcastDefaultDataSubIdChanged(int subId) {
         // Broadcast an Intent for default data sub change
         if (DBG) logdl("[broadcastDefaultDataSubIdChanged] subId=" + subId);
@@ -2076,6 +2103,7 @@
      * sub is set as default subId. If two or more  sub's are active
      * the first sub is set as default subscription
      */
+    @UnsupportedAppUsage
     private void setDefaultFallbackSubId(int subId, int subscriptionType) {
         if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
             throw new RuntimeException("setDefaultSubId called with DEFAULT_SUB_ID");
@@ -2170,8 +2198,26 @@
         return true;
     }
 
+    /**
+     * Make sure in multi SIM scenarios, user data is enabled or disabled correctly.
+     */
+    public void updateDataEnabledSettings() {
+        Phone[] phones = PhoneFactory.getPhones();
+        if (phones == null || phones.length < 2) return;
+
+        for (Phone phone : phones) {
+            if (isActiveSubId(phone.getSubId())) {
+                // Only enable it if it was enabled and it's the default data subscription.
+                // Otherwise it should be disabled.
+                phone.getDataEnabledSettings().setUserDataEnabled(
+                        phone.isUserDataEnabled() && phone.getSubId() == getDefaultDataSubId());
+            }
+        }
+    }
+
     // FIXME: We need we should not be assuming phoneId == slotIndex as it will not be true
     // when there are multiple subscriptions per sim and probably for other reasons.
+    @UnsupportedAppUsage
     public int getSubIdUsingPhoneId(int phoneId) {
         int[] subIds = getSubId(phoneId);
         if (subIds == null || subIds.length == 0) {
@@ -2224,6 +2270,7 @@
         return subList;
     }
 
+    @UnsupportedAppUsage
     private void validateSubId(int subId) {
         if (DBG) logd("validateSubId subId: " + subId);
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -2253,12 +2300,30 @@
         return allSubs;
     }
 
+    private boolean isInvisibleSubscription(int subId) {
+        for (SubscriptionInfo info : mCacheOpportunisticSubInfoList) {
+            if (info.getSubscriptionId() == subId) {
+                return SubscriptionManager.isInvisibleSubscription(info);
+            }
+        }
+
+        return false;
+    }
+
+
     /**
      * @return the list of subId's that are active, is never null but the length maybe 0.
      */
     @Override
-    public int[] getActiveSubIdList() {
-        ArrayList<Integer> allSubs = getActiveSubIdArrayList();
+    public int[] getActiveSubIdList(boolean visibleOnly) {
+        List<Integer> allSubs = getActiveSubIdArrayList();
+
+        if (visibleOnly) {
+            // Grouped opportunistic subscriptions should be hidden.
+            allSubs = allSubs.stream().filter(subId -> isInvisibleSubscription(subId))
+                    .collect(Collectors.toList());
+        }
+
         int[] subIdArr = new int[allSubs.size()];
         int i = 0;
         for (int sub : allSubs) {
@@ -2287,6 +2352,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Deprecated // This should be moved into isActiveSubId(int, String)
     public boolean isActiveSubId(int subId) {
         boolean retVal = SubscriptionManager.isValidSubscriptionId(subId)
@@ -2675,18 +2741,14 @@
     }
 
     @Override
-    public int setPreferredDataSubscriptionId(int subId) {
+    public void setPreferredDataSubscriptionId(int subId, boolean needValidation,
+            ISetOpportunisticDataCallback callback) {
         enforceModifyPhoneState("setPreferredDataSubscriptionId");
         final long token = Binder.clearCallingIdentity();
 
         try {
-            if (mPreferredDataSubId != subId) {
-                mPreferredDataSubId = subId;
-                PhoneSwitcher.getInstance().setPreferredDataSubscriptionId(subId);
-                notifyPreferredDataSubIdChanged();
-            }
-
-            return 0;
+            PhoneSwitcher.getInstance().trySetPreferredSubscription(
+                    subId, needValidation, callback);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -2695,17 +2757,12 @@
     @Override
     public int getPreferredDataSubscriptionId() {
         enforceReadPrivilegedPhoneState("getPreferredDataSubscriptionId");
-        return mPreferredDataSubId;
-    }
+        final long token = Binder.clearCallingIdentity();
 
-    private void notifyPreferredDataSubIdChanged() {
-        ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
-                "telephony.registry"));
         try {
-            if (DBG) logd("notifyPreferredDataSubIdChanged:");
-            tr.notifyPreferredDataSubIdChanged(mPreferredDataSubId);
-        } catch (RemoteException ex) {
-            // Should never happen because its always available.
+            return PhoneSwitcher.getInstance().getPreferredDataSubscriptionId();
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
@@ -2765,6 +2822,8 @@
 
             refreshCachedActiveSubscriptionInfoList();
 
+            notifySubscriptionInfoChanged();
+
             return groupUUID;
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -2812,6 +2871,8 @@
 
             refreshCachedActiveSubscriptionInfoList();
 
+            notifySubscriptionInfoChanged();
+
             return result != 0;
         } finally {
             Binder.restoreCallingIdentity(identity);
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index 4a3a010..3119948 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -18,6 +18,7 @@
 
 import android.Manifest;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.app.UserSwitchObserver;
 import android.content.ContentResolver;
@@ -54,6 +55,7 @@
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.uicc.IccRecords;
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.telephony.uicc.UiccSlot;
 
@@ -68,6 +70,7 @@
  */
 public class SubscriptionInfoUpdater extends Handler {
     private static final String LOG_TAG = "SubscriptionInfoUpdater";
+    @UnsupportedAppUsage
     private static final int PROJECT_SIM_NUM = TelephonyManager.getDefault().getPhoneCount();
 
     private static final boolean DBG = true;
@@ -90,16 +93,21 @@
     // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED.
     public static final String CURR_SUBID = "curr_subid";
 
+    @UnsupportedAppUsage
     private static Phone[] mPhone;
+    @UnsupportedAppUsage
     private static Context mContext = null;
+    @UnsupportedAppUsage
     private static String mIccId[] = new String[PROJECT_SIM_NUM];
     private static int[] sSimCardState = new int[PROJECT_SIM_NUM];
     private static int[] sSimApplicationState = new int[PROJECT_SIM_NUM];
     private SubscriptionManager mSubscriptionManager = null;
     private EuiccManager mEuiccManager;
+    @UnsupportedAppUsage
     private IPackageManager mPackageManager;
 
     // The current foreground user ID.
+    @UnsupportedAppUsage
     private int mCurrentlyActiveUserId;
     private CarrierServiceBindHelper mCarrierServiceBindHelper;
 
@@ -184,6 +192,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private boolean isAllIccIdQueryDone() {
         for (int i = 0; i < PROJECT_SIM_NUM; i++) {
             if (mIccId[i] == null) {
@@ -260,7 +269,13 @@
 
             case EVENT_SIM_NOT_READY:
                 handleSimNotReady(msg.arg1);
-                // intentional fall through
+                int cardId = getCardIdFromPhoneId(msg.arg1);
+                // an eUICC with no active subscriptions never becomes ready, so we need to trigger
+                // the embedded subscriptions update here
+                if (updateEmbeddedSubscriptions(cardId)) {
+                    SubscriptionController.getInstance().notifySubscriptionInfoChanged();
+                }
+                break;
 
             case EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS:
                 if (updateEmbeddedSubscriptions(msg.arg1)) {
@@ -276,6 +291,15 @@
         }
     }
 
+    private int getCardIdFromPhoneId(int phoneId) {
+        UiccController uiccController = UiccController.getInstance();
+        UiccCard card = uiccController.getUiccCardForPhone(phoneId);
+        if (card != null) {
+            return uiccController.convertToPublicCardId(card.getCardId());
+        }
+        return TelephonyManager.UNINITIALIZED_CARD_ID;
+    }
+
     void requestEmbeddedSubscriptionInfoListRefresh(int cardId, @Nullable Runnable callback) {
         sendMessage(obtainMessage(
                 EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS, cardId, 0 /* arg2 */, callback));
@@ -580,11 +604,14 @@
             UiccSlot[] uiccSlots = uiccController.getUiccSlots();
             if (uiccSlots != null) {
                 Arrays.stream(uiccSlots)
-                        .filter(uiccSlot -> uiccSlot.isEuicc() && uiccSlot.getUiccCard() != null)
+                        .filter(uiccSlot -> uiccSlot.getUiccCard() != null)
                         .map(uiccSlot -> uiccController.convertToPublicCardId(
                                 uiccSlot.getUiccCard().getCardId()))
                         .forEach(cardId -> updateEmbeddedSubscriptions(cardId));
             }
+            // update default subId
+            SubscriptionController.getInstance().clearDefaultsForInactiveSubIds();
+            SubscriptionController.getInstance().updateDataEnabledSettings();
         }
 
         SubscriptionController.getInstance().notifySubscriptionInfoChanged();
@@ -751,6 +778,7 @@
         return newSim;
     }
 
+    @UnsupportedAppUsage
     private void broadcastSimStateChanged(int slotId, String state, String reason) {
         Intent i = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
         // TODO - we'd like this intent to have a single snapshot of all sim state,
@@ -834,6 +862,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void logd(String message) {
         Rlog.d(LOG_TAG, message);
     }
diff --git a/src/java/com/android/internal/telephony/TelephonyCapabilities.java b/src/java/com/android/internal/telephony/TelephonyCapabilities.java
index b7c68a3..70f15dc 100644
--- a/src/java/com/android/internal/telephony/TelephonyCapabilities.java
+++ b/src/java/com/android/internal/telephony/TelephonyCapabilities.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 import com.android.internal.telephony.Phone;
@@ -178,6 +179,7 @@
      * of public API, with which the argument should be replaced with
      * something more appropriate.
      */
+    @UnsupportedAppUsage
     public static boolean supportsAdn(int phoneType) {
         return phoneType == PhoneConstants.PHONE_TYPE_GSM;
     }
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index 35b8344..c61b0a6 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -24,7 +24,13 @@
 import android.os.IDeviceIdleController;
 import android.os.Looper;
 import android.os.ServiceManager;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStatVfs;
+import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.Rlog;
+import android.text.TextUtils;
 
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.cdma.EriManager;
@@ -49,6 +55,8 @@
 import java.util.Set;
 import java.util.function.Consumer;
 
+
+
 /**
  * This class has one-line methods to instantiate objects only. The purpose is to make code
  * unit-test friendly and use this class as a way to do dependency injection. Instantiating objects
@@ -68,23 +76,37 @@
         private static final String TAG_INJECTION = "injection";
         private static final String TAG_COMPONENTS = "components";
         private static final String TAG_COMPONENT = "component";
+        private static final String SYSTEM = "/system/";
 
         private final Set<String> mComponentNames = new HashSet<>();
         private TelephonyComponentFactory mInjectedInstance;
         private String mPackageName;
         private String mJarPath;
 
-        private boolean isInjected() {
-            return mPackageName != null && mJarPath != null;
+        /**
+         * @return if jar path is correctly configured to inject.
+         * 1) PackageName and JarPath mustn't be empty.
+         * 2) JarPath is restricted under /system only
+         */
+        private boolean isConfigValid() {
+            return !TextUtils.isEmpty(mPackageName) && !TextUtils.isEmpty(mJarPath)
+                    && mJarPath.startsWith(SYSTEM);
         }
 
         private void makeInjectedInstance() {
-            if (isInjected()) {
-                PathClassLoader classLoader = new PathClassLoader(mJarPath,
-                        ClassLoader.getSystemClassLoader());
+            if (isConfigValid()) {
                 try {
-                    Class<?> cls = classLoader.loadClass(mPackageName);
-                    mInjectedInstance = (TelephonyComponentFactory) cls.newInstance();
+                    StructStatVfs vfs = Os.statvfs(mJarPath);
+                    if ((vfs.f_flag & OsConstants.ST_RDONLY) != 0) {
+                        PathClassLoader classLoader = new PathClassLoader(mJarPath,
+                                ClassLoader.getSystemClassLoader());
+                        Class<?> cls = classLoader.loadClass(mPackageName);
+                        mInjectedInstance = (TelephonyComponentFactory) cls.newInstance();
+                    } else {
+                        Rlog.w(TAG, "Injection jar is not protected");
+                    }
+                } catch (ErrnoException e) {
+                    Rlog.e(TAG, "failed file mount, " + e.getMessage());
                 } catch (ClassNotFoundException e) {
                     Rlog.e(TAG, "failed: " + e.getMessage());
                 } catch (IllegalAccessException | InstantiationException e) {
@@ -203,7 +225,7 @@
      */
     public void injectTheComponentFactory(XmlResourceParser parser) {
         if (mInjectedComponents != null) {
-            Rlog.i(TAG, "Already injected.");
+            Rlog.d(TAG, "Already injected.");
             return;
         }
 
@@ -211,8 +233,8 @@
             mInjectedComponents = new InjectedComponents();
             mInjectedComponents.parseXml(parser);
             mInjectedComponents.makeInjectedInstance();
-            Rlog.i(TAG, "Total components injected: "
-                    + mInjectedComponents.mComponentNames.size());
+            Rlog.d(TAG, "Total components injected: " + (mInjectedComponents.isConfigValid()
+                    ? mInjectedComponents.mComponentNames.size() : 0));
         }
     }
 
@@ -271,7 +293,7 @@
         return new SimActivationTracker(phone);
     }
 
-    public DcTracker makeDcTracker(Phone phone, int transportType) {
+    public DcTracker makeDcTracker(Phone phone, @TransportType int transportType) {
         return new DcTracker(phone, transportType);
     }
 
diff --git a/src/java/com/android/internal/telephony/TelephonyTester.java b/src/java/com/android/internal/telephony/TelephonyTester.java
index 0ab6ec8..fac8bb8 100644
--- a/src/java/com/android/internal/telephony/TelephonyTester.java
+++ b/src/java/com/android/internal/telephony/TelephonyTester.java
@@ -24,6 +24,7 @@
 import android.os.BadParcelableException;
 import android.os.Build;
 import android.os.Bundle;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.ims.ImsCallProfile;
@@ -148,10 +149,12 @@
                 if (DBG) log("sIntentReceiver.onReceive: action=" + action);
                 if (action.equals(mPhone.getActionDetached())) {
                     log("simulate detaching");
-                    mPhone.getServiceStateTracker().mDetachedRegistrants.notifyRegistrants();
+                    mPhone.getServiceStateTracker().mDetachedRegistrants.get(
+                            AccessNetworkConstants.TRANSPORT_TYPE_WWAN).notifyRegistrants();
                 } else if (action.equals(mPhone.getActionAttached())) {
                     log("simulate attaching");
-                    mPhone.getServiceStateTracker().mAttachedRegistrants.notifyRegistrants();
+                    mPhone.getServiceStateTracker().mAttachedRegistrants.get(
+                            AccessNetworkConstants.TRANSPORT_TYPE_WWAN).notifyRegistrants();
                 } else if (action.equals(ACTION_TEST_CONFERENCE_EVENT_PACKAGE)) {
                     log("inject simulated conference event package");
                     handleTestConferenceEventPackage(context,
diff --git a/src/java/com/android/internal/telephony/UUSInfo.java b/src/java/com/android/internal/telephony/UUSInfo.java
index 300887c..9ef1893 100644
--- a/src/java/com/android/internal/telephony/UUSInfo.java
+++ b/src/java/com/android/internal/telephony/UUSInfo.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
+
 public class UUSInfo {
 
     /*
@@ -74,6 +76,7 @@
         mUusData = uusData;
     }
 
+    @UnsupportedAppUsage
     public int getDcs() {
         return mUusDcs;
     }
@@ -82,6 +85,7 @@
         mUusDcs = uusDcs;
     }
 
+    @UnsupportedAppUsage
     public int getType() {
         return mUusType;
     }
@@ -90,6 +94,7 @@
         mUusType = uusType;
     }
 
+    @UnsupportedAppUsage
     public byte[] getUserData() {
         return mUusData;
     }
diff --git a/src/java/com/android/internal/telephony/UiccPhoneBookController.java b/src/java/com/android/internal/telephony/UiccPhoneBookController.java
index f3019f0..5a4d480 100644
--- a/src/java/com/android/internal/telephony/UiccPhoneBookController.java
+++ b/src/java/com/android/internal/telephony/UiccPhoneBookController.java
@@ -18,6 +18,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.ServiceManager;
 import android.telephony.Rlog;
 
@@ -30,9 +31,11 @@
 
 public class UiccPhoneBookController extends IIccPhoneBook.Stub {
     private static final String TAG = "UiccPhoneBookController";
+    @UnsupportedAppUsage
     private Phone[] mPhone;
 
     /* only one UiccPhoneBookController exists */
+    @UnsupportedAppUsage
     public UiccPhoneBookController(Phone[] phone) {
         if (ServiceManager.getService("simphonebook") == null) {
                ServiceManager.addService("simphonebook", this);
@@ -130,6 +133,7 @@
     /**
      * get phone book interface manager object based on subscription.
      **/
+    @UnsupportedAppUsage
     private IccPhoneBookInterfaceManager
             getIccPhoneBookInterfaceManager(int subId) {
 
@@ -147,6 +151,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private int getDefaultSubscription() {
         return PhoneFactory.getDefaultSubscription();
     }
diff --git a/src/java/com/android/internal/telephony/UiccSmsController.java b/src/java/com/android/internal/telephony/UiccSmsController.java
index 48df5c4..de1bdcf 100644
--- a/src/java/com/android/internal/telephony/UiccSmsController.java
+++ b/src/java/com/android/internal/telephony/UiccSmsController.java
@@ -21,6 +21,7 @@
 import static com.android.internal.util.DumpUtils.checkDumpPermission;
 
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityThread;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -63,6 +64,7 @@
         return phone;
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean updateMessageOnIccEfForSubscriber(int subId, String callingPackage, int index,
             int status, byte[] pdu) {
@@ -76,6 +78,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean copyMessageToIccEfForSubscriber(int subId, String callingPackage, int status,
             byte[] pdu, byte[] smsc) {
@@ -89,6 +92,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public List<SmsRawData> getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage) {
         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
@@ -101,6 +105,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public void sendDataForSubscriber(int subId, String callingPackage, String destAddr,
             String scAddr, int destPort, byte[] data, PendingIntent sentIntent,
@@ -210,12 +215,14 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType) {
         return enableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier,
                 ranType);
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
             int endMessageId, int ranType) {
@@ -229,6 +236,7 @@
         return false;
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean disableCellBroadcastForSubscriber(int subId,
             int messageIdentifier, int ranType) {
@@ -236,6 +244,7 @@
                 ranType);
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
             int endMessageId, int ranType) {
@@ -281,6 +290,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean isImsSmsSupportedForSubscriber(int subId) {
         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
@@ -325,6 +335,7 @@
         return false;
     }
 
+    @UnsupportedAppUsage
     @Override
     public String getImsSmsFormatForSubscriber(int subId) {
         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
@@ -353,6 +364,7 @@
      * Get User preferred SMS subscription
      * @return User preferred SMS subscription
      */
+    @UnsupportedAppUsage
     @Override
     public int getPreferredSmsSubscription() {
         return SubscriptionController.getInstance().getDefaultSmsSubId();
@@ -434,6 +446,7 @@
                 true /* persistMessageForNonDefaultSmsApp */);
     }
 
+    @UnsupportedAppUsage
     private void sendErrorInPendingIntent(@Nullable PendingIntent intent, int errorCode) {
         if (intent != null) {
             try {
@@ -443,6 +456,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void sendErrorInPendingIntents(List<PendingIntent> intents, int errorCode) {
         if (intents == null) {
             return;
@@ -457,6 +471,7 @@
      * Get sms interface manager object based on subscription.
      * @return ICC SMS manager
      */
+    @UnsupportedAppUsage
     private @Nullable IccSmsInterfaceManager getIccSmsInterfaceManager(int subId) {
         return getPhone(subId).getIccSmsInterfaceManager();
     }
diff --git a/src/java/com/android/internal/telephony/WakeLockStateMachine.java b/src/java/com/android/internal/telephony/WakeLockStateMachine.java
index aca016f..cd6749c 100644
--- a/src/java/com/android/internal/telephony/WakeLockStateMachine.java
+++ b/src/java/com/android/internal/telephony/WakeLockStateMachine.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -48,14 +49,17 @@
     /** Release wakelock after a short timeout when returning to idle state. */
     static final int EVENT_RELEASE_WAKE_LOCK = 3;
 
+    @UnsupportedAppUsage
     protected Phone mPhone;
 
+    @UnsupportedAppUsage
     protected Context mContext;
 
     /** Wakelock release delay when returning to idle state. */
     private static final int WAKE_LOCK_TIMEOUT = 3000;
 
     private final DefaultState mDefaultState = new DefaultState();
+    @UnsupportedAppUsage
     private final IdleState mIdleState = new IdleState();
     private final WaitingState mWaitingState = new WaitingState();
 
@@ -217,6 +221,7 @@
      * Log with debug level.
      * @param s the string to log
      */
+    @UnsupportedAppUsage
     @Override
     protected void log(String s) {
         Rlog.d(getName(), s);
diff --git a/src/java/com/android/internal/telephony/WapPushOverSms.java b/src/java/com/android/internal/telephony/WapPushOverSms.java
index 2e66a6d..58ce62b 100755
--- a/src/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/src/java/com/android/internal/telephony/WapPushOverSms.java
@@ -20,6 +20,7 @@
 import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND;
 import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_READ_ORIG_IND;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.AppOpsManager;
 import android.app.BroadcastOptions;
@@ -71,12 +72,15 @@
     private static final String TAG = "WAP PUSH";
     private static final boolean DBG = false;
 
+    @UnsupportedAppUsage
     private final Context mContext;
+    @UnsupportedAppUsage
     private IDeviceIdleController mDeviceIdleController;
 
     private String mWapPushManagerPackage;
 
     /** Assigned from ServiceConnection callback on main threaad. */
+    @UnsupportedAppUsage
     private volatile IWapPushManager mWapPushManager;
 
     /** Broadcast receiver that binds to WapPushManager when the user unlocks the phone for the
@@ -326,6 +330,7 @@
      *         {@link Activity#RESULT_OK} if the message has been broadcast
      *         to applications
      */
+    @UnsupportedAppUsage
     public int dispatchWapPdu(byte[] pdu, BroadcastReceiver receiver, InboundSmsHandler handler) {
         return dispatchWapPdu(pdu, receiver, handler, null);
     }
@@ -443,6 +448,7 @@
     /**
      * Check whether the pdu is a MMS WAP push pdu that should be dispatched to the SMS app.
      */
+    @UnsupportedAppUsage
     public boolean isWapPushForMms(byte[] pdu, InboundSmsHandler handler) {
         DecodedResult result = decodeWapPdu(pdu, handler);
         return result.statusCode == Activity.RESULT_OK
@@ -546,6 +552,7 @@
     private static final String THREAD_ID_SELECTION =
             Telephony.Mms.MESSAGE_ID + "=? AND " + Telephony.Mms.MESSAGE_TYPE + "=?";
 
+    @UnsupportedAppUsage
     private static long getDeliveryOrReadReportThreadId(Context context, GenericPdu pdu) {
         String messageId;
         if (pdu instanceof DeliveryInd) {
@@ -586,6 +593,7 @@
     private static final String LOCATION_SELECTION =
             Telephony.Mms.MESSAGE_TYPE + "=? AND " + Telephony.Mms.CONTENT_LOCATION + " =?";
 
+    @UnsupportedAppUsage
     private static boolean isDuplicateNotification(Context context, NotificationInd nInd) {
         final byte[] rawLocation = nInd.getContentLocation();
         if (rawLocation != null) {
diff --git a/src/java/com/android/internal/telephony/WspTypeDecoder.java b/src/java/com/android/internal/telephony/WspTypeDecoder.java
index 281488a..041db61 100755
--- a/src/java/com/android/internal/telephony/WspTypeDecoder.java
+++ b/src/java/com/android/internal/telephony/WspTypeDecoder.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.UnsupportedAppUsage;
 import java.util.HashMap;
 
 /**
@@ -196,6 +197,7 @@
     public static final String CONTENT_TYPE_B_MMS = "application/vnd.wap.mms-message";
     public static final String CONTENT_TYPE_B_PUSH_SYNCML_NOTI = "application/vnd.syncml.notification";
 
+    @UnsupportedAppUsage
     byte[] mWspData;
     int    mDataLength;
     long   mUnsigned32bit;
@@ -203,6 +205,7 @@
 
     HashMap<String, String> mContentParameters;
 
+    @UnsupportedAppUsage
     public WspTypeDecoder(byte[] pdu) {
         mWspData = pdu;
     }
@@ -216,6 +219,7 @@
      *         return value can be retrieved by getValueString() method length of data in pdu can be
      *         retrieved by getDecodedDataLength() method
      */
+    @UnsupportedAppUsage
     public boolean decodeTextString(int startIndex) {
         int index = startIndex;
         while (mWspData[index] != 0) {
@@ -259,6 +263,7 @@
      *         return value can be retrieved by getValue32() method
      *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
+    @UnsupportedAppUsage
     public boolean decodeShortInteger(int startIndex) {
         if ((mWspData[startIndex] & 0x80) == 0) {
             return false;
@@ -300,6 +305,7 @@
      *         return value can be retrieved by getValue32() method
      *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
+    @UnsupportedAppUsage
     public boolean decodeIntegerValue(int startIndex) {
         if (decodeShortInteger(startIndex) == true) {
             return true;
@@ -316,6 +322,7 @@
      *         return value can be retrieved by getValue32() method
      *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
+    @UnsupportedAppUsage
     public boolean decodeUintvarInteger(int startIndex) {
         int index = startIndex;
 
@@ -341,6 +348,7 @@
      *         return value can be retrieved by getValue32() method
      *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
+    @UnsupportedAppUsage
     public boolean decodeValueLength(int startIndex) {
         if ((mWspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) {
             return false;
@@ -412,6 +420,7 @@
      *         length of data in pdu can be retrieved by getDecodedDataLength() method
      *         Any content type parameters will be accessible via getContentParameters()
      */
+    @UnsupportedAppUsage
     public boolean decodeContentType(int startIndex) {
         int mediaPrefixLength;
         mContentParameters = new HashMap<String, String>();
@@ -592,6 +601,7 @@
      *         method
      *         length of data in pdu can be retrieved by getDecodedDataLength() method
      */
+    @UnsupportedAppUsage
     public boolean decodeXWapApplicationId(int startIndex) {
         if (decodeIntegerValue(startIndex) == true) {
             mStringValue = null;
@@ -609,6 +619,7 @@
      * @return false when error(not a X-Wap-Application-Id) occur
      *         return value can be retrieved by getValue32()
      */
+    @UnsupportedAppUsage
     public boolean seekXWapApplicationId(int startIndex, int endIndex) {
         int index = startIndex;
 
@@ -693,6 +704,7 @@
     /**
      * The data length of latest operation.
      */
+    @UnsupportedAppUsage
     public int getDecodedDataLength() {
         return mDataLength;
     }
@@ -700,6 +712,7 @@
     /**
      * The 32-bits result of latest operation.
      */
+    @UnsupportedAppUsage
     public long getValue32() {
         return mUnsigned32bit;
     }
@@ -707,6 +720,7 @@
     /**
      * The String result of latest operation.
      */
+    @UnsupportedAppUsage
     public String getValueString() {
         return mStringValue;
     }
@@ -721,6 +735,7 @@
      *         unassigned parameter.  If a parameter has No-Value the value will be null.
      *
      */
+    @UnsupportedAppUsage
     public HashMap<String, String> getContentParameters() {
         return mContentParameters;
     }
diff --git a/src/java/com/android/internal/telephony/cat/AppInterface.java b/src/java/com/android/internal/telephony/cat/AppInterface.java
index 9410b98..ed7c822 100755
--- a/src/java/com/android/internal/telephony/cat/AppInterface.java
+++ b/src/java/com/android/internal/telephony/cat/AppInterface.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 
 /**
@@ -68,28 +69,50 @@
      * Refer to ETSI TS 102.223 section 9.4
      */
     public static enum CommandType {
+        @UnsupportedAppUsage
         DISPLAY_TEXT(0x21),
+        @UnsupportedAppUsage
         GET_INKEY(0x22),
+        @UnsupportedAppUsage
         GET_INPUT(0x23),
+        @UnsupportedAppUsage
         LAUNCH_BROWSER(0x15),
+        @UnsupportedAppUsage
         PLAY_TONE(0x20),
+        @UnsupportedAppUsage
         REFRESH(0x01),
+        @UnsupportedAppUsage
         SELECT_ITEM(0x24),
+        @UnsupportedAppUsage
         SEND_SS(0x11),
+        @UnsupportedAppUsage
         SEND_USSD(0x12),
+        @UnsupportedAppUsage
         SEND_SMS(0x13),
         RUN_AT(0x34),
+        @UnsupportedAppUsage
         SEND_DTMF(0x14),
+        @UnsupportedAppUsage
         SET_UP_EVENT_LIST(0x05),
+        @UnsupportedAppUsage
         SET_UP_IDLE_MODE_TEXT(0x28),
+        @UnsupportedAppUsage
         SET_UP_MENU(0x25),
+        @UnsupportedAppUsage
         SET_UP_CALL(0x10),
+        @UnsupportedAppUsage
         PROVIDE_LOCAL_INFORMATION(0x26),
+        @UnsupportedAppUsage
         LANGUAGE_NOTIFICATION(0x35),
+        @UnsupportedAppUsage
         OPEN_CHANNEL(0x40),
+        @UnsupportedAppUsage
         CLOSE_CHANNEL(0x41),
+        @UnsupportedAppUsage
         RECEIVE_DATA(0x42),
+        @UnsupportedAppUsage
         SEND_DATA(0x43),
+        @UnsupportedAppUsage
         GET_CHANNEL_STATUS(0x44);
 
         private int mValue;
@@ -110,6 +133,7 @@
          *         value}. If no CommandType object has that value, null is
          *         returned.
          */
+        @UnsupportedAppUsage
         public static CommandType fromInt(int value) {
             for (CommandType e : CommandType.values()) {
                 if (e.mValue == value) {
diff --git a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
index cbad866..313e56f 100644
--- a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
+++ b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -26,12 +27,17 @@
  */
 public class CatCmdMessage implements Parcelable {
     // members
+    @UnsupportedAppUsage
     CommandDetails mCmdDet;
+    @UnsupportedAppUsage
     private TextMessage mTextMsg;
+    @UnsupportedAppUsage
     private Menu mMenu;
+    @UnsupportedAppUsage
     private Input mInput;
     private BrowserSettings mBrowserSettings = null;
     private ToneSettings mToneSettings = null;
+    @UnsupportedAppUsage
     private CallSettings mCallSettings = null;
     private SetupEventListSettings mSetupEventListSettings = null;
     private boolean mLoadIconFailed = false;
@@ -48,11 +54,14 @@
      * Container for Call Setup command settings.
      */
     public class CallSettings {
+        @UnsupportedAppUsage
         public TextMessage confirmMsg;
+        @UnsupportedAppUsage
         public TextMessage callMsg;
     }
 
     public class SetupEventListSettings {
+        @UnsupportedAppUsage
         public int[] eventList;
     }
 
@@ -206,6 +215,7 @@
     }
 
     /* external API to be used by application */
+    @UnsupportedAppUsage
     public AppInterface.CommandType getCmdType() {
         return AppInterface.CommandType.fromInt(mCmdDet.typeOfCommand);
     }
@@ -218,6 +228,7 @@
         return mInput;
     }
 
+    @UnsupportedAppUsage
     public TextMessage geTextMessage() {
         return mTextMsg;
     }
@@ -230,10 +241,12 @@
         return mToneSettings;
     }
 
+    @UnsupportedAppUsage
     public CallSettings getCallSettings() {
         return mCallSettings;
     }
 
+    @UnsupportedAppUsage
     public SetupEventListSettings getSetEventList() {
         return mSetupEventListSettings;
     }
@@ -242,6 +255,7 @@
      * API to be used by application to check if loading optional icon
      * has failed
      */
+    @UnsupportedAppUsage
     public boolean hasIconLoadFailed() {
         return mLoadIconFailed;
     }
diff --git a/src/java/com/android/internal/telephony/cat/CatLog.java b/src/java/com/android/internal/telephony/cat/CatLog.java
index 9a50fdb..128d7ed 100644
--- a/src/java/com/android/internal/telephony/cat/CatLog.java
+++ b/src/java/com/android/internal/telephony/cat/CatLog.java
@@ -16,11 +16,13 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 public abstract class CatLog {
     static final boolean DEBUG = true;
 
+    @UnsupportedAppUsage
     public static void d(Object caller, String msg) {
         if (!DEBUG) {
             return;
@@ -31,6 +33,7 @@
                 + msg);
     }
 
+    @UnsupportedAppUsage
     public static void d(String caller, String msg) {
         if (!DEBUG) {
             return;
@@ -38,6 +41,7 @@
 
         Rlog.d("CAT", caller + ": " + msg);
     }
+    @UnsupportedAppUsage
     public static void e(Object caller, String msg) {
         String className = caller.getClass().getName();
         Rlog.e("CAT", className.substring(className.lastIndexOf('.') + 1) + ": "
diff --git a/src/java/com/android/internal/telephony/cat/CatResponseMessage.java b/src/java/com/android/internal/telephony/cat/CatResponseMessage.java
index 80025f3..a3f2240 100644
--- a/src/java/com/android/internal/telephony/cat/CatResponseMessage.java
+++ b/src/java/com/android/internal/telephony/cat/CatResponseMessage.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
+
 public class CatResponseMessage {
         CommandDetails mCmdDet = null;
         ResultCode mResCode  = ResultCode.OK;
@@ -44,6 +46,7 @@
             mUsersInput = input;
         }
 
+        @UnsupportedAppUsage
         public void setEventDownload(int event, byte[] addedInfo) {
             this.mEventValue = event;
             this.mAddedInfo = addedInfo;
diff --git a/src/java/com/android/internal/telephony/cat/CatService.java b/src/java/com/android/internal/telephony/cat/CatService.java
index 267d527..76d2e4a 100644
--- a/src/java/com/android/internal/telephony/cat/CatService.java
+++ b/src/java/com/android/internal/telephony/cat/CatService.java
@@ -23,6 +23,7 @@
 import static com.android.internal.telephony.cat.CatCmdMessage.SetupEventListConstants
         .USER_ACTIVITY_EVENT;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.backup.BackupManager;
@@ -58,10 +59,13 @@
 import java.util.Locale;
 
 class RilMessage {
+    @UnsupportedAppUsage
     int mId;
+    @UnsupportedAppUsage
     Object mData;
     ResultCode mResCode;
 
+    @UnsupportedAppUsage
     RilMessage(int msgId, String rawData) {
         mId = msgId;
         mData = rawData;
@@ -89,16 +93,25 @@
 
     // Service members.
     // Protects singleton instance lazy initialization.
+    @UnsupportedAppUsage
     private static final Object sInstanceLock = new Object();
+    @UnsupportedAppUsage
     private static CatService[] sInstance = null;
+    @UnsupportedAppUsage
     private CommandsInterface mCmdIf;
+    @UnsupportedAppUsage
     private Context mContext;
+    @UnsupportedAppUsage
     private CatCmdMessage mCurrntCmd = null;
+    @UnsupportedAppUsage
     private CatCmdMessage mMenuCmd = null;
 
+    @UnsupportedAppUsage
     private RilMessageDecoder mMsgDecoder = null;
+    @UnsupportedAppUsage
     private boolean mStkAppInstalled = false;
 
+    @UnsupportedAppUsage
     private UiccController mUiccController;
     private CardState mCardState = CardState.CARDSTATE_ABSENT;
 
@@ -130,6 +143,7 @@
 
     static final String STK_DEFAULT = "Default Message";
 
+    @UnsupportedAppUsage
     private int mSlotId;
 
     /* For multisim catservice should not be singleton */
@@ -237,6 +251,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public void dispose() {
         synchronized (sInstanceLock) {
             CatLog.d(this, "Disposing CatService object");
@@ -550,6 +565,7 @@
     }
 
 
+    @UnsupportedAppUsage
     private void sendTerminalResponse(CommandDetails cmdDet,
             ResultCode resultCode, boolean includeAdditionalInfo,
             int additionalInfo, ResponseData resp) {
@@ -1092,6 +1108,7 @@
         mCurrntCmd = null;
     }
 
+    @UnsupportedAppUsage
     private boolean isStkAppInstalled() {
         Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
         PackageManager pm = mContext.getPackageManager();
diff --git a/src/java/com/android/internal/telephony/cat/CommandDetails.java b/src/java/com/android/internal/telephony/cat/CommandDetails.java
index aaa9d68..d7c511a 100644
--- a/src/java/com/android/internal/telephony/cat/CommandDetails.java
+++ b/src/java/com/android/internal/telephony/cat/CommandDetails.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -28,9 +29,13 @@
  * {@hide}
  */
 class CommandDetails extends ValueObject implements Parcelable {
+    @UnsupportedAppUsage
     public boolean compRequired;
+    @UnsupportedAppUsage
     public int commandNumber;
+    @UnsupportedAppUsage
     public int typeOfCommand;
+    @UnsupportedAppUsage
     public int commandQualifier;
 
     @Override
@@ -92,6 +97,7 @@
 
 class DeviceIdentities extends ValueObject {
     public int sourceId;
+    @UnsupportedAppUsage
     public int destinationId;
 
     @Override
@@ -102,6 +108,7 @@
 
 // Container class to hold icon identifier value.
 class IconId extends ValueObject {
+    @UnsupportedAppUsage
     int recordNumber;
     boolean selfExplanatory;
 
diff --git a/src/java/com/android/internal/telephony/cat/CommandParams.java b/src/java/com/android/internal/telephony/cat/CommandParams.java
index 59cd414..80e5973 100755
--- a/src/java/com/android/internal/telephony/cat/CommandParams.java
+++ b/src/java/com/android/internal/telephony/cat/CommandParams.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
 
 /**
@@ -23,14 +24,17 @@
  *
  */
 class CommandParams {
+    @UnsupportedAppUsage
     CommandDetails mCmdDet;
     // Variable to track if an optional icon load has failed.
     boolean mLoadIconFailed = false;
 
+    @UnsupportedAppUsage
     CommandParams(CommandDetails cmdDet) {
         mCmdDet = cmdDet;
     }
 
+    @UnsupportedAppUsage
     AppInterface.CommandType getCommandType() {
         return AppInterface.CommandType.fromInt(mCmdDet.typeOfCommand);
     }
@@ -44,8 +48,10 @@
 }
 
 class DisplayTextParams extends CommandParams {
+    @UnsupportedAppUsage
     TextMessage mTextMsg;
 
+    @UnsupportedAppUsage
     DisplayTextParams(CommandDetails cmdDet, TextMessage textMsg) {
         super(cmdDet);
         mTextMsg = textMsg;
@@ -106,6 +112,7 @@
     TextMessage mTextMsg;
     ToneSettings mSettings;
 
+    @UnsupportedAppUsage
     PlayToneParams(CommandDetails cmdDet, TextMessage textMsg,
             Tone tone, Duration duration, boolean vibrate) {
         super(cmdDet);
@@ -163,6 +170,7 @@
     Menu mMenu = null;
     boolean mLoadTitleIcon = false;
 
+    @UnsupportedAppUsage
     SelectItemParams(CommandDetails cmdDet, Menu menu, boolean loadTitleIcon) {
         super(cmdDet);
         mMenu = menu;
@@ -192,6 +200,7 @@
 class GetInputParams extends CommandParams {
     Input mInput = null;
 
+    @UnsupportedAppUsage
     GetInputParams(CommandDetails cmdDet, Input input) {
         super(cmdDet);
         mInput = input;
diff --git a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
index 049e668..bafb8bb 100644
--- a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
+++ b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
 import android.os.Handler;
 import android.os.Message;
@@ -45,6 +46,7 @@
  */
 class CommandParamsFactory extends Handler {
     private static CommandParamsFactory sInstance = null;
+    @UnsupportedAppUsage
     private IconLoader mIconLoader;
     private CommandParams mCmdParams = null;
     private int mIconLoadState = LOAD_NO_ICON;
@@ -289,6 +291,7 @@
      * @return A ComprehensionTlv object that has the tag value of {@code tag}.
      *         If no object is found with the tag, null is returned.
      */
+    @UnsupportedAppUsage
     private ComprehensionTlv searchForTag(ComprehensionTlvTag tag,
             List<ComprehensionTlv> ctlvs) {
         Iterator<ComprehensionTlv> iter = ctlvs.iterator();
@@ -307,6 +310,7 @@
      * @return A ComprehensionTlv object that has the tag value of {@code tag}.
      *         If no object is found with the tag, null is returned.
      */
+    @UnsupportedAppUsage
     private ComprehensionTlv searchForNextTag(ComprehensionTlvTag tag,
             Iterator<ComprehensionTlv> iter) {
         int tagValue = tag.value();
@@ -1101,6 +1105,7 @@
         return false;
     }
 
+    @UnsupportedAppUsage
     public void dispose() {
         mIconLoader.dispose();
         mIconLoader = null;
diff --git a/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java b/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java
index d4ad532..16615a0 100644
--- a/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java
+++ b/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 import java.util.ArrayList;
@@ -57,6 +58,7 @@
         mRawValue = data;
     }
 
+    @UnsupportedAppUsage
     public int getTag() {
         return mTag;
     }
@@ -65,14 +67,17 @@
         return mCr;
     }
 
+    @UnsupportedAppUsage
     public int getLength() {
         return mLength;
     }
 
+    @UnsupportedAppUsage
     public int getValueIndex() {
         return mValueIndex;
     }
 
+    @UnsupportedAppUsage
     public byte[] getRawValue() {
         return mRawValue;
     }
diff --git a/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java b/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
index 973dbc8..1ab18a7 100644
--- a/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
+++ b/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * Enumeration for representing the tag value of COMPREHENSION-TLV objects. If
  * you want to get the actual value, call {@link #value() value} method.
@@ -23,14 +25,22 @@
  * {@hide}
  */
 public enum ComprehensionTlvTag {
+    @UnsupportedAppUsage
     COMMAND_DETAILS(0x01),
+    @UnsupportedAppUsage
     DEVICE_IDENTITIES(0x02),
+    @UnsupportedAppUsage
     RESULT(0x03),
     DURATION(0x04),
+    @UnsupportedAppUsage
     ALPHA_ID(0x05),
+    @UnsupportedAppUsage
     ADDRESS(0x06),
+    @UnsupportedAppUsage
     USSD_STRING(0x0a),
+    @UnsupportedAppUsage
     SMS_TPDU(0x0b),
+    @UnsupportedAppUsage
     TEXT_STRING(0x0d),
     TONE(0x0e),
     ITEM(0x0f),
@@ -40,12 +50,14 @@
     HELP_REQUEST(0x15),
     DEFAULT_TEXT(0x17),
     EVENT_LIST(0x19),
+    @UnsupportedAppUsage
     ICON_ID(0x1e),
     ITEM_ICON_ID_LIST(0x1f),
     IMMEDIATE_RESPONSE(0x2b),
     LANGUAGE(0x2d),
     URL(0x31),
     BROWSER_TERMINATION_CAUSE(0x34),
+    @UnsupportedAppUsage
     TEXT_ATTRIBUTE(0x50);
 
     private int mValue;
@@ -59,6 +71,7 @@
      *
      * @return Actual tag value of this object
      */
+    @UnsupportedAppUsage
     public int value() {
         return mValue;
     }
diff --git a/src/java/com/android/internal/telephony/cat/Duration.java b/src/java/com/android/internal/telephony/cat/Duration.java
index e437f6e..a979c54 100644
--- a/src/java/com/android/internal/telephony/cat/Duration.java
+++ b/src/java/com/android/internal/telephony/cat/Duration.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -26,7 +27,9 @@
  * {@hide}
  */
 public class Duration implements Parcelable {
+    @UnsupportedAppUsage
     public int timeInterval;
+    @UnsupportedAppUsage
     public TimeUnit timeUnit;
 
     public enum TimeUnit {
@@ -40,6 +43,7 @@
             mValue = value;
         }
 
+        @UnsupportedAppUsage
         public int value() {
             return mValue;
         }
diff --git a/src/java/com/android/internal/telephony/cat/IconLoader.java b/src/java/com/android/internal/telephony/cat/IconLoader.java
index 6a668e0..4e5b555 100644
--- a/src/java/com/android/internal/telephony/cat/IconLoader.java
+++ b/src/java/com/android/internal/telephony/cat/IconLoader.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.telephony.uicc.IccFileHandler;
 
+import android.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.os.AsyncResult;
@@ -99,6 +100,7 @@
         startLoadingIcon(recordNumbers[0]);
     }
 
+    @UnsupportedAppUsage
     void loadIcon(int recordNumber, Message msg) {
         if (msg == null) {
             return;
diff --git a/src/java/com/android/internal/telephony/cat/Menu.java b/src/java/com/android/internal/telephony/cat/Menu.java
index a3cbbdf..a93fd1f 100644
--- a/src/java/com/android/internal/telephony/cat/Menu.java
+++ b/src/java/com/android/internal/telephony/cat/Menu.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -29,6 +30,7 @@
  */
 public class Menu implements Parcelable {
     public List<Item> items;
+    @UnsupportedAppUsage
     public List<TextAttribute> titleAttrs;
     public PresentationType presentationType;
     public String title;
diff --git a/src/java/com/android/internal/telephony/cat/ResponseData.java b/src/java/com/android/internal/telephony/cat/ResponseData.java
index 7112bf1..838dd0f 100644
--- a/src/java/com/android/internal/telephony/cat/ResponseData.java
+++ b/src/java/com/android/internal/telephony/cat/ResponseData.java
@@ -25,6 +25,7 @@
 
 import com.android.internal.telephony.cat.AppInterface.CommandType;
 
+import android.annotation.UnsupportedAppUsage;
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
 
@@ -33,6 +34,7 @@
      * Format the data appropriate for TERMINAL RESPONSE and write it into
      * the ByteArrayOutputStream object.
      */
+    @UnsupportedAppUsage
     public abstract void format(ByteArrayOutputStream buf);
 
     public static void writeLength(ByteArrayOutputStream buf, int length) {
diff --git a/src/java/com/android/internal/telephony/cat/ResultCode.java b/src/java/com/android/internal/telephony/cat/ResultCode.java
index f001c7e..346d74a 100644
--- a/src/java/com/android/internal/telephony/cat/ResultCode.java
+++ b/src/java/com/android/internal/telephony/cat/ResultCode.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
+
 
 /**
  * Enumeration for the return code in TERMINAL RESPONSE.
@@ -31,48 +33,62 @@
      */
 
     /** Command performed successfully */
+    @UnsupportedAppUsage
     OK(0x00),
 
     /** Command performed with partial comprehension */
+    @UnsupportedAppUsage
     PRFRMD_WITH_PARTIAL_COMPREHENSION(0x01),
 
     /** Command performed, with missing information */
+    @UnsupportedAppUsage
     PRFRMD_WITH_MISSING_INFO(0x02),
 
     /** REFRESH performed with additional EFs read */
+    @UnsupportedAppUsage
     PRFRMD_WITH_ADDITIONAL_EFS_READ(0x03),
 
     /**
      * Command performed successfully, but requested icon could not be
      * displayed
      */
+    @UnsupportedAppUsage
     PRFRMD_ICON_NOT_DISPLAYED(0x04),
 
     /** Command performed, but modified by call control by NAA */
+    @UnsupportedAppUsage
     PRFRMD_MODIFIED_BY_NAA(0x05),
 
     /** Command performed successfully, limited service */
+    @UnsupportedAppUsage
     PRFRMD_LIMITED_SERVICE(0x06),
 
     /** Command performed with modification */
+    @UnsupportedAppUsage
     PRFRMD_WITH_MODIFICATION(0x07),
 
     /** REFRESH performed but indicated NAA was not active */
+    @UnsupportedAppUsage
     PRFRMD_NAA_NOT_ACTIVE(0x08),
 
     /** Command performed successfully, tone not played */
+    @UnsupportedAppUsage
     PRFRMD_TONE_NOT_PLAYED(0x09),
 
     /** Proactive UICC session terminated by the user */
+    @UnsupportedAppUsage
     UICC_SESSION_TERM_BY_USER(0x10),
 
     /** Backward move in the proactive UICC session requested by the user */
+    @UnsupportedAppUsage
     BACKWARD_MOVE_BY_USER(0x11),
 
     /** No response from user */
+    @UnsupportedAppUsage
     NO_RESPONSE_FROM_USER(0x12),
 
     /** Help information required by the user */
+    @UnsupportedAppUsage
     HELP_INFO_REQUIRED(0x13),
 
     /** USSD or SS transaction terminated by the user */
@@ -85,12 +101,15 @@
      */
 
     /** Terminal currently unable to process command */
+    @UnsupportedAppUsage
     TERMINAL_CRNTLY_UNABLE_TO_PROCESS(0x20),
 
     /** Network currently unable to process command */
+    @UnsupportedAppUsage
     NETWORK_CRNTLY_UNABLE_TO_PROCESS(0x21),
 
     /** User did not accept the proactive command */
+    @UnsupportedAppUsage
     USER_NOT_ACCEPT(0x22),
 
     /** User cleared down call before connection or network release */
@@ -103,6 +122,7 @@
     NAA_CALL_CONTROL_TEMPORARY(0x25),
 
     /** Launch browser generic error code */
+    @UnsupportedAppUsage
     LAUNCH_BROWSER_ERROR(0x26),
 
     /** MMS temporary problem. */
@@ -116,12 +136,14 @@
      */
 
     /** Command beyond terminal's capabilities */
+    @UnsupportedAppUsage
     BEYOND_TERMINAL_CAPABILITY(0x30),
 
     /** Command type not understood by terminal */
     CMD_TYPE_NOT_UNDERSTOOD(0x31),
 
     /** Command data not understood by terminal */
+    @UnsupportedAppUsage
     CMD_DATA_NOT_UNDERSTOOD(0x32),
 
     /** Command number not known by terminal */
@@ -134,6 +156,7 @@
     SMS_RP_ERROR(0x35),
 
     /** Error, required values are missing */
+    @UnsupportedAppUsage
     REQUIRED_VALUES_MISSING(0x36),
 
     /** USSD Return Error */
@@ -146,9 +169,11 @@
      * Interaction with call control by USIM or MO short message control by
      * USIM, permanent problem
      */
+    @UnsupportedAppUsage
     USIM_CALL_CONTROL_PERMANENT(0x39),
 
     /** Bearer Independent Protocol error */
+    @UnsupportedAppUsage
     BIP_ERROR(0x3a),
 
     /** Access Technology unable to process command */
@@ -171,6 +196,7 @@
      * Retrieves the actual result code that this object represents.
      * @return Actual result code
      */
+    @UnsupportedAppUsage
     public int value() {
         return mCode;
     }
diff --git a/src/java/com/android/internal/telephony/cat/ResultException.java b/src/java/com/android/internal/telephony/cat/ResultException.java
index 5175b83..32acae8 100644
--- a/src/java/com/android/internal/telephony/cat/ResultException.java
+++ b/src/java/com/android/internal/telephony/cat/ResultException.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
+
 
 /**
  * Class for errors in the Result object.
@@ -27,6 +29,7 @@
     private int mAdditionalInfo;
     private String mExplanation;
 
+    @UnsupportedAppUsage
     public ResultException(ResultCode result) {
         super();
 
diff --git a/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java b/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java
index 65b958c..2e41dd4 100755
--- a/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java
+++ b/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Handler;
 import android.os.Message;
 import android.telephony.SubscriptionManager;
@@ -38,13 +39,16 @@
     private static final int CMD_PARAMS_READY = 2;
 
     // members
+    @UnsupportedAppUsage
     private CommandParamsFactory mCmdParamsFactory = null;
     private RilMessage mCurrentRilMessage = null;
     private Handler mCaller = null;
     private static int mSimCount = 0;
+    @UnsupportedAppUsage
     private static RilMessageDecoder[] mInstance = null;
 
     // States
+    @UnsupportedAppUsage
     private StateStart mStateStart = new StateStart();
     private StateCmdParamsReady mStateCmdParamsReady = new StateCmdParamsReady();
 
@@ -55,6 +59,7 @@
      * @param fh
      * @return RilMesssageDecoder
      */
+    @UnsupportedAppUsage
     public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh,
             int slotId) {
         if (null == mInstance) {
diff --git a/src/java/com/android/internal/telephony/cat/TextMessage.java b/src/java/com/android/internal/telephony/cat/TextMessage.java
index 926c927..eddca4c 100644
--- a/src/java/com/android/internal/telephony/cat/TextMessage.java
+++ b/src/java/com/android/internal/telephony/cat/TextMessage.java
@@ -16,20 +16,24 @@
 
 package com.android.internal.telephony.cat;
 
+import android.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 public class TextMessage implements Parcelable {
     public String title = "";
+    @UnsupportedAppUsage
     public String text = null;
     public Bitmap icon = null;
+    @UnsupportedAppUsage
     public boolean iconSelfExplanatory = false;
     public boolean isHighPriority = false;
     public boolean responseNeeded = true;
     public boolean userClear = false;
     public Duration duration = null;
 
+    @UnsupportedAppUsage
     TextMessage() {
     }
 
diff --git a/src/java/com/android/internal/telephony/cat/ValueParser.java b/src/java/com/android/internal/telephony/cat/ValueParser.java
index 91a6fd6..4e528b6 100644
--- a/src/java/com/android/internal/telephony/cat/ValueParser.java
+++ b/src/java/com/android/internal/telephony/cat/ValueParser.java
@@ -20,6 +20,7 @@
 import com.android.internal.telephony.cat.Duration.TimeUnit;
 import com.android.internal.telephony.uicc.IccUtils;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import java.io.UnsupportedEncodingException;
@@ -213,6 +214,7 @@
      * @return A list of TextAttribute objects
      * @throws ResultException
      */
+    @UnsupportedAppUsage
     static List<TextAttribute> retrieveTextAttribute(ComprehensionTlv ctlv)
             throws ResultException {
         ArrayList<TextAttribute> lst = new ArrayList<TextAttribute>();
@@ -273,6 +275,7 @@
      * @return String corresponding to the alpha identifier
      * @throws ResultException
      */
+    @UnsupportedAppUsage
     static String retrieveAlphaId(ComprehensionTlv ctlv) throws ResultException {
 
         if (ctlv != null) {
@@ -316,6 +319,7 @@
      * @return A Java String object decoded from the Text object
      * @throws ResultException
      */
+    @UnsupportedAppUsage
     static String retrieveTextString(ComprehensionTlv ctlv) throws ResultException {
         byte[] rawValue = ctlv.getRawValue();
         int valueIndex = ctlv.getValueIndex();
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java b/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
index 81dec16..d1e0881 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cdma;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 import com.android.internal.telephony.PhoneConstants;
 
@@ -26,6 +27,7 @@
  */
 public class CdmaCallWaitingNotification {
     static final String LOG_TAG = "CdmaCallWaitingNotification";
+    @UnsupportedAppUsage
     public String number = null;
     public int numberPresentation = 0;
     public String name = null;
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java b/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
index ab76f98..7600c1a 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
@@ -25,6 +25,7 @@
 import com.android.internal.telephony.MmiCode;
 import com.android.internal.telephony.Phone;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
@@ -65,6 +66,7 @@
     UiccCardApplication mUiccApplication;
 
     String mAction;              // ACTION_REGISTER
+    @UnsupportedAppUsage
     String mSc;                  // Service Code
     String mSia, mSib, mSic;     // Service Info a,b,c
     String mPoundString;         // Entire MMI string up to and including #
@@ -135,6 +137,7 @@
     /** make empty strings be null.
      *  Regexp returns empty strings for empty groups
      */
+    @UnsupportedAppUsage
     private static String
     makeEmptyNull (String s) {
         if (s != null && s.length() == 0) return null;
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index bbaa3ca..04bfbf2 100755
--- a/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cdma;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Message;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
@@ -43,6 +44,7 @@
         Rlog.d(TAG, "CdmaSMSDispatcher created");
     }
 
+    @UnsupportedAppUsage
     @Override
     public String getFormat() {
         return SmsConstants.FORMAT_3GPP2;
@@ -96,6 +98,7 @@
      * Called from parent class to handle status report from {@code CdmaInboundSmsHandler}.
      * @param sms the CDMA SMS message to process
      */
+    @UnsupportedAppUsage
     private void handleCdmaStatusReport(SmsMessage sms) {
         for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
             SmsTracker tracker = deliveryPendingList.get(i);
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java b/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
index 25ad3af..bc09e77 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
@@ -18,6 +18,7 @@
 
 import java.util.concurrent.atomic.AtomicInteger;
 
+import android.annotation.UnsupportedAppUsage;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Phone;
 import android.content.Context;
@@ -74,6 +75,7 @@
      *
      * @return object of type CdmaSubscriptionSourceManager
      */
+    @UnsupportedAppUsage
     public static CdmaSubscriptionSourceManager getInstance(Context context,
             CommandsInterface ci, Handler h, int what, Object obj) {
         synchronized (sReferenceCountMonitor) {
@@ -149,6 +151,7 @@
      * Returns the current CDMA subscription source value
      * @return CDMA subscription source value
      */
+    @UnsupportedAppUsage
     public int getCdmaSubscriptionSource() {
         log("getcdmasubscriptionSource: " + mCdmaSubscriptionSource.get());
         return mCdmaSubscriptionSource.get();
diff --git a/src/java/com/android/internal/telephony/cdma/EriManager.java b/src/java/com/android/internal/telephony/cdma/EriManager.java
index 81bc8fe..b2a1cc3 100644
--- a/src/java/com/android/internal/telephony/cdma/EriManager.java
+++ b/src/java/com/android/internal/telephony/cdma/EriManager.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.cdma;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
@@ -64,6 +65,7 @@
     class EriDisplayInformation {
         int mEriIconIndex;
         int mEriIconMode;
+        @UnsupportedAppUsage
         String mEriIconText;
 
         EriDisplayInformation(int eriIconIndex, int eriIconMode, String eriIconText) {
@@ -308,6 +310,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private EriDisplayInformation getEriDisplayInformation(int roamInd, int defRoamInd){
         EriDisplayInformation ret;
 
diff --git a/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java b/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
index 2e95967..77d8706 100644
--- a/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
@@ -16,16 +16,18 @@
 
 package com.android.internal.telephony.dataconnection;
 
+import android.annotation.NonNull;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
-import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Message;
 import android.os.PersistableBundle;
+import android.os.Registrant;
 import android.os.RegistrantList;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -54,7 +56,7 @@
  * It binds to the vendor's qualified networks service and actively monitors the qualified
  * networks changes.
  */
-public class AccessNetworksManager {
+public class AccessNetworksManager extends Handler {
     private static final String TAG = AccessNetworksManager.class.getSimpleName();
     private static final boolean DBG = false;
 
@@ -68,6 +70,8 @@
             ApnSetting.TYPE_EMERGENCY
     };
 
+    private static final int EVENT_BIND_QUALIFIED_NETWORKS_SERVICE = 1;
+
     private final Phone mPhone;
 
     private final CarrierConfigManager mCarrierConfigManager;
@@ -76,8 +80,7 @@
 
     private AccessNetworksManagerDeathRecipient mDeathRecipient;
 
-    // The bound qualified networks service component name
-    private ComponentName mBoundQualifiedNetworksServiceComponent;
+    private String mTargetBindingPackageName;
 
     private QualifiedNetworksServiceConnection mServiceConnection;
 
@@ -93,10 +96,11 @@
             if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)
                     && mPhone.getPhoneId() == intent.getIntExtra(
                     CarrierConfigManager.EXTRA_SLOT_INDEX, 0)) {
-                // When carrier config changes, we need to evaluate and see if we should unbind
-                // the existing service and bind to a new one.
-                if (DBG) log("Carrier config changed.");
-                bindQualifiedNetworksService();
+                // We should wait for carrier config changed event because the target binding
+                // package name can come from the carrier config. Note that we still get this event
+                // even when SIM is absent.
+                if (DBG) log("Carrier config changed. Try to bind qualified network service.");
+                sendEmptyMessage(EVENT_BIND_QUALIFIED_NETWORKS_SERVICE);
             }
         }
     };
@@ -106,7 +110,7 @@
      */
     public static class QualifiedNetworks {
         public final @ApnType int apnType;
-        // The qualified netowrks in preferred order. Each network is a AccessNetworkType.
+        // The qualified networks in preferred order. Each network is a AccessNetworkType.
         public final int[] qualifiedNetworks;
         public QualifiedNetworks(@ApnType int apnType, int[] qualifiedNetworks) {
             this.apnType = apnType;
@@ -133,15 +137,14 @@
         @Override
         public void binderDied() {
             // TODO: try to rebind the service.
-            loge("QualifiedNetworksService(" + mBoundQualifiedNetworksServiceComponent + ") died.");
+            loge("QualifiedNetworksService(" + mTargetBindingPackageName + ") died.");
         }
     }
 
     private final class QualifiedNetworksServiceConnection implements ServiceConnection {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
-            if (DBG) log("onServiceConnected");
-            mBoundQualifiedNetworksServiceComponent = name;
+            if (DBG) log("onServiceConnected " + name);
             mIQualifiedNetworksService = IQualifiedNetworksService.Stub.asInterface(service);
             mDeathRecipient = new AccessNetworksManagerDeathRecipient();
 
@@ -156,8 +159,9 @@
         }
         @Override
         public void onServiceDisconnected(ComponentName name) {
-            if (DBG) log("onServiceDisconnected");
+            if (DBG) log("onServiceDisconnected " + name);
             mIQualifiedNetworksService.asBinder().unlinkToDeath(mDeathRecipient, 0);
+            mTargetBindingPackageName = null;
         }
     }
 
@@ -191,8 +195,7 @@
             }
 
             if (!qualifiedNetworksList.isEmpty()) {
-                mQualifiedNetworksChangedRegistrants.notifyRegistrants(
-                        new AsyncResult(null, qualifiedNetworksList, null));
+                mQualifiedNetworksChangedRegistrants.notifyResult(qualifiedNetworksList);
             }
         }
     }
@@ -211,11 +214,22 @@
         intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         phone.getContext().registerReceiverAsUser(mConfigChangedReceiver, UserHandle.ALL,
                 intentFilter, null, null);
+        sendEmptyMessage(EVENT_BIND_QUALIFIED_NETWORKS_SERVICE);
+    }
 
-        // Only binds to qualified network service in AP-assisted mode. For legacy mode,
-        // qualified networks service is not needed.
-        if (phone.getTransportManager() != null && !phone.getTransportManager().isInLegacyMode()) {
-            bindQualifiedNetworksService();
+    /**
+     * Handle message events
+     *
+     * @param msg The message to handle
+     */
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case EVENT_BIND_QUALIFIED_NETWORKS_SERVICE:
+                bindQualifiedNetworksService();
+                break;
+            default:
+                loge("Unhandled event " + msg.what);
         }
     }
 
@@ -232,13 +246,13 @@
             return;
         }
 
+        if (TextUtils.equals(packageName, mTargetBindingPackageName)) {
+            if (DBG) log("Service " + packageName + " already bound or being bound.");
+            return;
+        }
+
         if (mIQualifiedNetworksService != null
                 && mIQualifiedNetworksService.asBinder().isBinderAlive()) {
-            if (mBoundQualifiedNetworksServiceComponent.getPackageName().equals(packageName)) {
-                if (DBG) log("Service " + packageName + " already bound.");
-                return;
-            }
-
             // Remove the network availability updater and then unbind the service.
             try {
                 mIQualifiedNetworksService.removeNetworkAvailabilityUpdater(mPhone.getPhoneId());
@@ -258,7 +272,9 @@
                     mServiceConnection,
                     Context.BIND_AUTO_CREATE)) {
                 loge("Cannot bind to the qualified networks service.");
+                return;
             }
+            mTargetBindingPackageName = packageName;
         } catch (Exception e) {
             loge("Cannot bind to the qualified networks service. Exception: " + e);
         }
@@ -290,6 +306,17 @@
         return packageName;
     }
 
+
+    private @NonNull List<QualifiedNetworks> getQualifiedNetworksList() {
+        List<QualifiedNetworks> qualifiedNetworksList = new ArrayList<>();
+        for (int i = 0; i < mAvailableNetworks.size(); i++) {
+            qualifiedNetworksList.add(new QualifiedNetworks(mAvailableNetworks.keyAt(i),
+                    mAvailableNetworks.valueAt(i)));
+        }
+
+        return qualifiedNetworksList;
+    }
+
     /**
      * Register for qualified networks changed event.
      *
@@ -298,7 +325,14 @@
      */
     public void registerForQualifiedNetworksChanged(Handler h, int what) {
         if (h != null) {
-            mQualifiedNetworksChangedRegistrants.addUnique(h, what, null);
+            Registrant r = new Registrant(h, what, null);
+            mQualifiedNetworksChangedRegistrants.add(r);
+
+            // Notify for the first time if there is already something in the available network
+            // list.
+            if (mAvailableNetworks.size() != 0) {
+                r.notifyResult(getQualifiedNetworksList());
+            }
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
index 26d9ec7..d7f0ae3 100644
--- a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
+++ b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
@@ -625,6 +625,10 @@
             if (apnType != ApnSetting.TYPE_NONE) error = true;
             apnType = ApnSetting.TYPE_EMERGENCY;
         }
+        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_MCX)) {
+            if (apnType != ApnSetting.TYPE_NONE) error = true;
+            apnType = ApnSetting.TYPE_MCX;
+        }
         if (error) {
             // TODO: If this error condition is removed, the framework's handling of
             // NET_CAPABILITY_NOT_RESTRICTED will need to be updated so requests for
diff --git a/src/java/com/android/internal/telephony/dataconnection/CellularDataService.java b/src/java/com/android/internal/telephony/dataconnection/CellularDataService.java
index ae69631..41b8dab 100644
--- a/src/java/com/android/internal/telephony/dataconnection/CellularDataService.java
+++ b/src/java/com/android/internal/telephony/dataconnection/CellularDataService.java
@@ -67,7 +67,7 @@
         private CellularDataServiceProvider(int slotId) {
             super(slotId);
 
-            mPhone = PhoneFactory.getPhone(getSlotId());
+            mPhone = PhoneFactory.getPhone(getSlotIndex());
 
             mHandlerThread = new HandlerThread(CellularDataService.class.getSimpleName());
             mHandlerThread.start();
@@ -125,10 +125,10 @@
         }
 
         @Override
-        public void setupDataCall(int radioTechnology, DataProfile dataProfile, boolean isRoaming,
+        public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
                                   boolean allowRoaming, int reason, LinkProperties linkProperties,
                                   DataServiceCallback callback) {
-            if (DBG) log("setupDataCall " + getSlotId());
+            if (DBG) log("setupDataCall " + getSlotIndex());
 
             Message message = null;
             // Only obtain the message when the caller wants a callback. If the caller doesn't care
@@ -138,13 +138,13 @@
                 mCallbackMap.put(message, callback);
             }
 
-            mPhone.mCi.setupDataCall(radioTechnology, dataProfile, isRoaming, allowRoaming, reason,
-                    linkProperties, message);
+            mPhone.mCi.setupDataCall(accessNetworkType, dataProfile, isRoaming, allowRoaming,
+                    reason, linkProperties, message);
         }
 
         @Override
         public void deactivateDataCall(int cid, int reason, DataServiceCallback callback) {
-            if (DBG) log("deactivateDataCall " + getSlotId());
+            if (DBG) log("deactivateDataCall " + getSlotIndex());
 
             Message message = null;
             // Only obtain the message when the caller wants a callback. If the caller doesn't care
@@ -160,7 +160,7 @@
         @Override
         public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming,
                                         DataServiceCallback callback) {
-            if (DBG) log("setInitialAttachApn " + getSlotId());
+            if (DBG) log("setInitialAttachApn " + getSlotIndex());
 
             Message message = null;
             // Only obtain the message when the caller wants a callback. If the caller doesn't care
@@ -176,7 +176,7 @@
         @Override
         public void setDataProfile(List<DataProfile> dps, boolean isRoaming,
                                    DataServiceCallback callback) {
-            if (DBG) log("setDataProfile " + getSlotId());
+            if (DBG) log("setDataProfile " + getSlotIndex());
 
             Message message = null;
             // Only obtain the message when the caller wants a callback. If the caller doesn't care
@@ -191,7 +191,7 @@
 
         @Override
         public void getDataCallList(DataServiceCallback callback) {
-            if (DBG) log("getDataCallList " + getSlotId());
+            if (DBG) log("getDataCallList " + getSlotIndex());
 
             Message message = null;
             // Only obtain the message when the caller wants a callback. If the caller doesn't care
@@ -211,13 +211,13 @@
     }
 
     @Override
-    public DataServiceProvider createDataServiceProvider(int slotId) {
-        log("Cellular data service created for slot " + slotId);
-        if (!SubscriptionManager.isValidSlotIndex(slotId)) {
-            loge("Tried to cellular data service with invalid slotId " + slotId);
+    public DataServiceProvider onCreateDataServiceProvider(int slotIndex) {
+        log("Cellular data service created for slot " + slotIndex);
+        if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
+            loge("Tried to cellular data service with invalid slotId " + slotIndex);
             return null;
         }
-        return new CellularDataServiceProvider(slotId);
+        return new CellularDataServiceProvider(slotIndex);
     }
 
     private void log(String s) {
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 51dc0ee..52fb389 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -41,8 +41,11 @@
 import android.os.Message;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.provider.Telephony;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.DataFailCause;
+import android.telephony.NetworkRegistrationState;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
@@ -72,6 +75,7 @@
 import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType;
 import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
+import com.android.internal.telephony.nano.TelephonyProto.RilDataCall;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Protocol;
@@ -109,6 +113,9 @@
 
     private static final String NETWORK_TYPE = "MOBILE";
 
+    private static final String RAT_NAME_5G = "nr";
+    private static final String RAT_NAME_EVDO = "evdo";
+
     // The data connection providing default Internet connection will have a higher score of 50.
     // Other connections will have a slightly lower score of 45. The intention is other connections
     // will not cause ConnectivityService to tear down default internet connection. For example,
@@ -135,6 +142,8 @@
 
     private String[] mPcscfAddr;
 
+    private final String mTagSuffix;
+
     /**
      * Used internally for saving connecting parameters.
      */
@@ -317,12 +326,13 @@
                                                     DataServiceManager dataServiceManager,
                                                     DcTesterFailBringUpAll failBringUpAll,
                                                     DcController dcc) {
-        String transportType = (dataServiceManager.getTransportType() == TransportType.WWAN)
+        String transportType = (dataServiceManager.getTransportType()
+                == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                 ? "C"   // Cellular
                 : "I";  // IWLAN
-        DataConnection dc = new DataConnection(phone,
-                "DC-" + transportType + "-" + mInstanceNumber.incrementAndGet(), id, dct,
-                dataServiceManager, failBringUpAll, dcc);
+        DataConnection dc = new DataConnection(phone, transportType + "-"
+                + mInstanceNumber.incrementAndGet(), id, dct, dataServiceManager, failBringUpAll,
+                dcc);
         dc.start();
         if (DBG) dc.log("Made " + dc.getName());
         return dc;
@@ -499,10 +509,11 @@
     }
 
     //***** Constructor (NOTE: uses dcc.getHandler() as its Handler)
-    private DataConnection(Phone phone, String name, int id,
+    private DataConnection(Phone phone, String tagSuffix, int id,
                            DcTracker dct, DataServiceManager dataServiceManager,
                            DcTesterFailBringUpAll failBringUpAll, DcController dcc) {
-        super(name, dcc.getHandler());
+        super("DC-" + tagSuffix, dcc.getHandler());
+        mTagSuffix = tagSuffix;
         setLogRecSize(300);
         setLogOnlyTransitions(true);
         if (DBG) log("DataConnection created");
@@ -540,8 +551,9 @@
     private DcTracker getHandoverDcTracker() {
         int transportType = mDataServiceManager.getTransportType();
         // Get the DcTracker from the other transport.
-        return mPhone.getDcTracker(transportType == TransportType.WWAN
-                ? TransportType.WLAN : TransportType.WWAN);
+        return mPhone.getDcTracker(transportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
+                ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
+                : AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
     }
 
     /**
@@ -881,17 +893,25 @@
         return true;
     }
 
+    /**
+     * TCP buffer size config based on the ril technology. There are 6 parameters
+     * read_min, read_default, read_max, write_min, write_default, write_max in the TCP buffer
+     * config string and they are separated by a comma. The unit of these parameters is byte.
+     */
     private static final String TCP_BUFFER_SIZES_GPRS = "4092,8760,48000,4096,8760,48000";
     private static final String TCP_BUFFER_SIZES_EDGE = "4093,26280,70800,4096,16384,70800";
     private static final String TCP_BUFFER_SIZES_UMTS = "58254,349525,1048576,58254,349525,1048576";
-    private static final String TCP_BUFFER_SIZES_1XRTT= "16384,32768,131072,4096,16384,102400";
+    private static final String TCP_BUFFER_SIZES_1XRTT = "16384,32768,131072,4096,16384,102400";
     private static final String TCP_BUFFER_SIZES_EVDO = "4094,87380,262144,4096,16384,262144";
-    private static final String TCP_BUFFER_SIZES_EHRPD= "131072,262144,1048576,4096,16384,524288";
-    private static final String TCP_BUFFER_SIZES_HSDPA= "61167,367002,1101005,8738,52429,262114";
+    private static final String TCP_BUFFER_SIZES_EHRPD = "131072,262144,1048576,4096,16384,524288";
+    private static final String TCP_BUFFER_SIZES_HSDPA = "61167,367002,1101005,8738,52429,262114";
     private static final String TCP_BUFFER_SIZES_HSPA = "40778,244668,734003,16777,100663,301990";
-    private static final String TCP_BUFFER_SIZES_LTE  =
+    private static final String TCP_BUFFER_SIZES_LTE =
             "524288,1048576,2097152,262144,524288,1048576";
-    private static final String TCP_BUFFER_SIZES_HSPAP= "122334,734003,2202010,32040,192239,576717";
+    private static final String TCP_BUFFER_SIZES_HSPAP =
+            "122334,734003,2202010,32040,192239,576717";
+    private static final String TCP_BUFFER_SIZES_NR =
+            "2097152,6291456,16777216,512000,2097152,8388608";
 
     private void updateTcpBufferSizes(int rilRat) {
         String sizes = null;
@@ -906,7 +926,13 @@
         if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 ||
                 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A ||
                 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B) {
-            ratName = "evdo";
+            ratName = RAT_NAME_EVDO;
+        }
+
+        // NR 5G Non-Standalone use LTE cell as the primary cell, the ril technology is LTE in this
+        // case. We use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
+        if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) {
+            ratName = RAT_NAME_5G;
         }
 
         // in the form: "ratname:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
@@ -954,7 +980,12 @@
                     break;
                 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE:
                 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA:
-                    sizes = TCP_BUFFER_SIZES_LTE;
+                    // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
+                    if (isNRConnected()) {
+                        sizes = TCP_BUFFER_SIZES_NR;
+                    } else {
+                        sizes = TCP_BUFFER_SIZES_LTE;
+                    }
                     break;
                 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP:
                     sizes = TCP_BUFFER_SIZES_HSPAP;
@@ -1125,6 +1156,10 @@
                         result.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
                         break;
                     }
+                    case PhoneConstants.APN_TYPE_MCX: {
+                        result.addCapability(NetworkCapabilities.NET_CAPABILITY_MCX);
+                        break;
+                    }
                     default:
                 }
             }
@@ -1191,6 +1226,27 @@
     }
 
     /**
+     * @return {@code True} if 464xlat should be skipped.
+     */
+    @VisibleForTesting
+    public boolean shouldSkip464Xlat() {
+        switch (mApnSetting.getSkip464Xlat()) {
+            case Telephony.Carriers.SKIP_464XLAT_ENABLE:
+                return true;
+            case Telephony.Carriers.SKIP_464XLAT_DISABLE:
+                return false;
+            case Telephony.Carriers.SKIP_464XLAT_DEFAULT:
+            default:
+                break;
+        }
+
+        // As default, return true if ims and no internet
+        final NetworkCapabilities nc = getNetworkCapabilities();
+        return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
+                && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+    }
+
+    /**
      * @return {@code} true iff. {@code address} is a literal IPv4 or IPv6 address.
      */
     @VisibleForTesting
@@ -1358,7 +1414,8 @@
             if (DBG) log("DcDefaultState: enter");
 
             // Register for DRS or RAT change
-            mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(getHandler(),
+            mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
+                    mDataServiceManager.getTransportType(), getHandler(),
                     DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, null);
 
             mPhone.getServiceStateTracker().registerForDataRoamingOn(getHandler(),
@@ -1374,7 +1431,8 @@
             if (DBG) log("DcDefaultState: exit");
 
             // Unregister for DRS or RAT change.
-            mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(getHandler());
+            mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(
+                    mDataServiceManager.getTransportType(), getHandler());
 
             mPhone.getServiceStateTracker().unregisterForDataRoamingOn(getHandler());
             mPhone.getServiceStateTracker().unregisterForDataRoamingOff(getHandler());
@@ -1803,6 +1861,9 @@
             }
             misc.subscriberId = mPhone.getSubscriberId();
 
+            // set skip464xlat if it is not default otherwise
+            misc.skip464xlat = shouldSkip464Xlat();
+
             mRestrictedNetworkOverride = shouldRestrictNetwork();
             mUnmeteredUseOnly = isUnmeteredUseOnly();
 
@@ -1822,6 +1883,8 @@
                 if (dc != null) {
                     mNetworkAgent = dc.getNetworkAgent();
                     if (mNetworkAgent != null) {
+                        mNetworkAgent.setTransportType(mDataServiceManager.getTransportType());
+                        log("Transfer the network agent from " + dc.getName() + " successfully.");
                         mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities());
                         mNetworkAgent.sendLinkProperties(mLinkProperties);
                     } else {
@@ -1833,15 +1896,18 @@
             } else {
                 mScore = calculateScore();
                 mNetworkAgent = new DcNetworkAgent(getHandler().getLooper(), mPhone.getContext(),
-                        "DcNetworkAgent", mNetworkInfo, getNetworkCapabilities(), mLinkProperties,
-                        mScore, misc);
+                        "DcNetworkAgent" + mTagSuffix, mNetworkInfo, getNetworkCapabilities(),
+                        mLinkProperties, mScore, misc);
             }
-            if (mDataServiceManager.getTransportType() == TransportType.WWAN) {
+            if (mDataServiceManager.getTransportType()
+                    == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                 mPhone.mCi.registerForNattKeepaliveStatus(
                         getHandler(), DataConnection.EVENT_KEEPALIVE_STATUS, null);
                 mPhone.mCi.registerForLceInfo(
                         getHandler(), DataConnection.EVENT_LINK_CAPACITY_CHANGED, null);
             }
+            TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(),
+                    mCid, mApnSetting.getApnTypeBitmask(), RilDataCall.State.CONNECTED);
         }
 
         @Override
@@ -1861,21 +1927,17 @@
             mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
                     reason, mNetworkInfo.getExtraInfo());
 
-            if (mDataServiceManager.getTransportType() == TransportType.WWAN) {
+            if (mDataServiceManager.getTransportType()
+                    == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                 mPhone.mCi.unregisterForNattKeepaliveStatus(getHandler());
                 mPhone.mCi.unregisterForLceInfo(getHandler());
             }
             if (mNetworkAgent != null) {
-                // We do not want to update the network info if this is a handover. For all other
-                // cases we need to update connectivity service with the latest network info.
-                //
-                // For handover, the network agent is transferred to the other data connection.
-                if (mDisconnectParams == null
-                        || mDisconnectParams.mReleaseType != DcTracker.RELEASE_TYPE_HANDOVER) {
-                    mNetworkAgent.sendNetworkInfo(mNetworkInfo);
-                }
+                mNetworkAgent.sendNetworkInfo(mNetworkInfo);
                 mNetworkAgent = null;
             }
+            TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(),
+                    mCid, mApnSetting.getApnTypeBitmask(), RilDataCall.State.DISCONNECTED);
         }
 
         @Override
@@ -2001,7 +2063,8 @@
                     KeepalivePacketData pkt = (KeepalivePacketData) msg.obj;
                     int slotId = msg.arg1;
                     int intervalMillis = msg.arg2 * 1000;
-                    if (mDataServiceManager.getTransportType() == TransportType.WWAN) {
+                    if (mDataServiceManager.getTransportType()
+                            == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                         mPhone.mCi.startNattKeepalive(
                                 DataConnection.this.mCid, pkt, intervalMillis,
                                 DataConnection.this.obtainMessage(
@@ -2274,6 +2337,8 @@
 
     private class DcNetworkAgent extends NetworkAgent {
 
+        private final AtomicInteger mTransportType;
+
         private NetworkCapabilities mNetworkCapabilities;
 
         public final DcKeepaliveTracker keepaliveTracker = new DcKeepaliveTracker();
@@ -2283,6 +2348,11 @@
             super(l, c, TAG, ni, nc, lp, score, misc);
             mNetCapsLocalLog.log("New network agent created. capabilities=" + nc);
             mNetworkCapabilities = nc;
+            mTransportType = new AtomicInteger(mDataServiceManager.getTransportType());
+        }
+
+        public void setTransportType(@TransportType int transportType) {
+            mTransportType.set(transportType);
         }
 
         @Override
@@ -2310,7 +2380,8 @@
         @Override
         protected void pollLceData() {
             if (mPhone.getLceStatus() == RILConstants.LCE_ACTIVE     // active LCE service
-                    && mDataServiceManager.getTransportType() == TransportType.WWAN) {
+                    && mDataServiceManager.getTransportType()
+                    == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                 mPhone.mCi.pullLceData(
                         DataConnection.this.obtainMessage(EVENT_BW_REFRESH_RESPONSE));
             }
@@ -2326,6 +2397,11 @@
 
         @Override
         public void sendNetworkCapabilities(NetworkCapabilities networkCapabilities) {
+            if (mTransportType.get() != mDataServiceManager.getTransportType()) {
+                log("sendNetworkCapabilities: Data connection has been handover to transport "
+                        + AccessNetworkConstants.transportTypeToString(mTransportType.get()));
+                return;
+            }
             if (!networkCapabilities.equals(mNetworkCapabilities)) {
                 String logStr = "Changed from " + mNetworkCapabilities + " to "
                         + networkCapabilities + ", Data RAT="
@@ -2339,6 +2415,36 @@
         }
 
         @Override
+        public void sendLinkProperties(LinkProperties linkProperties) {
+            if (mTransportType.get() != mDataServiceManager.getTransportType()) {
+                log("sendLinkProperties: Data connection has been handover to transport "
+                        + AccessNetworkConstants.transportTypeToString(mTransportType.get()));
+                return;
+            }
+            super.sendLinkProperties(linkProperties);
+        }
+
+        @Override
+        public void sendNetworkScore(int score) {
+            if (mTransportType.get() != mDataServiceManager.getTransportType()) {
+                log("sendNetworkScore: Data connection has been handover to transport "
+                        + AccessNetworkConstants.transportTypeToString(mTransportType.get()));
+                return;
+            }
+            super.sendNetworkScore(score);
+        }
+
+        @Override
+        public void sendNetworkInfo(NetworkInfo networkInfo) {
+            if (mTransportType.get() != mDataServiceManager.getTransportType()) {
+                log("sendNetworkScore: Data connection has been handover to transport "
+                        + AccessNetworkConstants.transportTypeToString(mTransportType.get()));
+                return;
+            }
+            super.sendNetworkInfo(networkInfo);
+        }
+
+        @Override
         protected void startSocketKeepalive(Message msg) {
             if (msg.obj instanceof NattKeepalivePacketData) {
                 DataConnection.this.obtainMessage(EVENT_KEEPALIVE_START_REQUEST,
@@ -2538,7 +2644,7 @@
      */
     public void tearDownAll(String reason, @ReleaseNetworkType int releaseType,
                             Message onCompletedMsg) {
-        if (DBG) log("tearDownAll: reason=" + reason + " onCompletedMsg=" + onCompletedMsg);
+        if (DBG) log("tearDownAll: reason=" + reason + ", releaseType=" + releaseType);
         sendMessage(DataConnection.EVENT_DISCONNECT_ALL,
                 new DisconnectParams(null, reason, releaseType, onCompletedMsg));
     }
@@ -2763,6 +2869,12 @@
         return "{" + toStringSimple() + " mApnContexts=" + mApnContexts + "}";
     }
 
+    /** Check if the device is connected to NR 5G Non-Standalone network. */
+    private boolean isNRConnected() {
+        return mPhone.getServiceState().getNrStatus()
+                == NetworkRegistrationState.NR_STATUS_CONNECTED;
+    }
+
     private void dumpToLog() {
         dump(null, new PrintWriter(new StringWriter(0)) {
             @Override
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
index be6892b..00d44e6 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
@@ -24,12 +24,14 @@
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.telephony.Rlog;
+import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.LocalLog;
 import android.util.Pair;
 
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.SubscriptionController;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -126,13 +128,28 @@
     }
 
     public synchronized void setUserDataEnabled(boolean enabled) {
+        // Can't disable data for opportunistic subscription.
+        if (isSubOpportunistic() && !enabled) return;
+        // Can't enable data for non-default data subscription.
+        if (!isDefaultDataSub() && enabled) return;
+
         localLog("UserDataEnabled", enabled);
-        Settings.Global.putInt(mResolver, getMobileDataSettingName(), enabled ? 1 : 0);
-        mPhone.notifyUserMobileDataStateChanged(enabled);
-        updateDataEnabledAndNotify(REASON_USER_DATA_ENABLED);
+        // Make sure if value is not initialized, it gets overwritten by the target value.
+        int uninitializedValue = -1;
+        int currentValue = Settings.Global.getInt(
+                mResolver, getMobileDataSettingName(), uninitializedValue);
+        int targetValue = (enabled ? 1 : 0);
+        if (currentValue != targetValue) {
+            Settings.Global.putInt(mResolver, getMobileDataSettingName(), targetValue);
+            mPhone.notifyUserMobileDataStateChanged(enabled);
+            updateDataEnabledAndNotify(REASON_USER_DATA_ENABLED);
+        }
     }
 
     public synchronized boolean isUserDataEnabled() {
+        // User data should always be true for opportunistic subscription.
+        if (isSubOpportunistic()) return true;
+
         boolean defaultVal = "true".equalsIgnoreCase(SystemProperties.get(
                 "ro.com.android.mobiledata", "true"));
 
@@ -244,6 +261,16 @@
         mOverallDataEnabledChangedRegistrants.remove(h);
     }
 
+    private boolean isSubOpportunistic() {
+        SubscriptionInfo info = SubscriptionController.getInstance().getActiveSubscriptionInfo(
+                mPhone.getSubId(), mPhone.getContext().getOpPackageName());
+        return (info != null) && info.isOpportunistic();
+    }
+
+    private boolean isDefaultDataSub() {
+        return SubscriptionController.getInstance().getDefaultDataSubId() == mPhone.getSubId();
+    }
+
     private void log(String s) {
         Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
     }
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
index 72be25e..a1332b2 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
@@ -16,14 +16,13 @@
 
 package com.android.internal.telephony.dataconnection;
 
-import static android.telephony.AccessNetworkConstants.TransportType.WLAN;
-import static android.telephony.AccessNetworkConstants.TransportType.WWAN;
-
 import android.annotation.NonNull;
 import android.app.AppOpsManager;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
@@ -37,6 +36,9 @@
 import android.os.RegistrantList;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.Rlog;
 import android.telephony.data.DataCallResponse;
@@ -59,14 +61,17 @@
  * Data service manager manages handling data requests and responses on data services (e.g.
  * Cellular data service, IWLAN data service).
  */
-public class DataServiceManager {
-    private static final String TAG = DataServiceManager.class.getSimpleName();
-    private static final boolean DBG = false;
+public class DataServiceManager extends Handler {
+    private static final boolean DBG = true;
 
     static final String DATA_CALL_RESPONSE = "data_call_response";
 
+    private static final int EVENT_BIND_DATA_SERVICE = 1;
+
     private final Phone mPhone;
 
+    private final String mTag;
+
     private final CarrierConfigManager mCarrierConfigManager;
     private final AppOpsManager mAppOps;
     private final IPackageManager mPackageManager;
@@ -85,15 +90,32 @@
 
     private final RegistrantList mDataCallListChangedRegistrants = new RegistrantList();
 
-    // not final because it is set by the onServiceConnected method
-    private ComponentName mComponentName;
+    private String mTargetBindingPackageName;
+
+    private CellularDataServiceConnection mServiceConnection;
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)
+                    && mPhone.getPhoneId() == intent.getIntExtra(
+                    CarrierConfigManager.EXTRA_SLOT_INDEX, 0)) {
+                // We should wait for carrier config changed event because the target binding
+                // package name can come from the carrier config. Note that we still get this event
+                // even when SIM is absent.
+                if (DBG) log("Carrier config changed. Try to bind data service.");
+                sendEmptyMessage(EVENT_BIND_DATA_SERVICE);
+            }
+        }
+    };
 
     private class DataServiceManagerDeathRecipient implements IBinder.DeathRecipient {
         @Override
         public void binderDied() {
             // TODO: try to rebind the service.
-            loge("DataService(" + mComponentName +  " transport type " + mTransportType
-                    + ") died.");
+            loge("DataService " + mTargetBindingPackageName +  ", transport type " + mTransportType
+                    + " died.");
         }
     }
 
@@ -117,7 +139,7 @@
     private void revokePermissionsFromUnusedDataServices() {
         // Except the current data services from having their permissions removed.
         Set<String> dataServices = getAllDataServicePackageNames();
-        for (int transportType : new int[] {WWAN, WLAN}) {
+        for (int transportType : mPhone.getTransportManager().getAvailableTransports()) {
             dataServices.remove(getDataServicePackageName(transportType));
         }
 
@@ -141,7 +163,6 @@
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             if (DBG) log("onServiceConnected");
-            mComponentName = name;
             mIDataService = IDataService.Stub.asInterface(service);
             mDeathRecipient = new DataServiceManagerDeathRecipient();
             mBound = true;
@@ -166,6 +187,7 @@
             mIDataService = null;
             mBound = false;
             mServiceBindingChangedRegistrants.notifyResult(false);
+            mTargetBindingPackageName = null;
         }
     }
 
@@ -226,39 +248,81 @@
      * Constructor
      *
      * @param phone The phone object
-     * @param transportType The transport type. Must be a
-     *        {@link AccessNetworkConstants.TransportType}.
+     * @param transportType The transport type
+     * @param tagSuffix Logging tag suffix
      */
-    public DataServiceManager(Phone phone, int transportType) {
+    public DataServiceManager(Phone phone, @TransportType int transportType, String tagSuffix) {
         mPhone = phone;
+        mTag = "DSM" + tagSuffix;
         mTransportType = transportType;
         mBound = false;
         mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService(
                 Context.CARRIER_CONFIG_SERVICE);
         mPackageManager = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
         mAppOps = (AppOpsManager) phone.getContext().getSystemService(Context.APP_OPS_SERVICE);
-        bindDataService();
+
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        phone.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+                intentFilter, null, null);
+        sendEmptyMessage(EVENT_BIND_DATA_SERVICE);
+    }
+
+    /**
+     * Handle message events
+     *
+     * @param msg The message to handle
+     */
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case EVENT_BIND_DATA_SERVICE:
+                bindDataService();
+                break;
+            default:
+                loge("Unhandled event " + msg.what);
+        }
     }
 
     private void bindDataService() {
-        // Start by cleaning up all packages that *shouldn't* have permissions.
-        revokePermissionsFromUnusedDataServices();
-
         String packageName = getDataServicePackageName();
         if (TextUtils.isEmpty(packageName)) {
             loge("Can't find the binding package");
             return;
         }
+
+        if (TextUtils.equals(packageName, mTargetBindingPackageName)) {
+            if (DBG) log("Service " + packageName + " already bound or being bound.");
+            return;
+        }
+
+        // Start by cleaning up all packages that *shouldn't* have permissions.
+        revokePermissionsFromUnusedDataServices();
+
+        if (mIDataService != null && mIDataService.asBinder().isBinderAlive()) {
+            // Remove the network availability updater and then unbind the service.
+            try {
+                mIDataService.removeDataServiceProvider(mPhone.getPhoneId());
+            } catch (RemoteException e) {
+                loge("Cannot remove data service provider. " + e);
+            }
+
+            mPhone.getContext().unbindService(mServiceConnection);
+        }
+
         // Then pre-emptively grant the permissions to the package we will bind.
         grantPermissionsToService(packageName);
 
         try {
+            mServiceConnection = new CellularDataServiceConnection();
             if (!mPhone.getContext().bindService(
                     new Intent(DataService.DATA_SERVICE_INTERFACE).setPackage(packageName),
-                    new CellularDataServiceConnection(),
+                    mServiceConnection,
                     Context.BIND_AUTO_CREATE)) {
                 loge("Cannot bind to the data service.");
+                return;
             }
+            mTargetBindingPackageName = packageName;
         } catch (Exception e) {
             loge("Cannot bind to the data service. Exception: " + e);
         }
@@ -298,28 +362,28 @@
      * packages; we need to exclude data packages for all transport types, so we need to
      * to be able to query by transport type.
      *
-     * @param transportType either WWAN or WLAN
+     * @param transportType The transport type
      * @return package name of the data service package for the specified transportType.
      */
-    private String getDataServicePackageName(int transportType) {
+    private String getDataServicePackageName(@TransportType int transportType) {
         String packageName;
         int resourceId;
         String carrierConfig;
 
         switch (transportType) {
-            case WWAN:
+            case AccessNetworkConstants.TRANSPORT_TYPE_WWAN:
                 resourceId = com.android.internal.R.string.config_wwan_data_service_package;
                 carrierConfig = CarrierConfigManager
                         .KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING;
                 break;
-            case WLAN:
+            case AccessNetworkConstants.TRANSPORT_TYPE_WLAN:
                 resourceId = com.android.internal.R.string.config_wlan_data_service_package;
                 carrierConfig = CarrierConfigManager
                         .KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING;
                 break;
             default:
                 throw new IllegalStateException("Transport type not WWAN or WLAN. type="
-                        + mTransportType);
+                        + AccessNetworkConstants.transportTypeToString(mTransportType));
         }
 
         // Read package name from resource overlay
@@ -571,7 +635,7 @@
     }
 
     /**
-     * Get the transport type. Must be a {@link AccessNetworkConstants.TransportType}.
+     * Get the transport type. Must be a {@link TransportType}.
      *
      * @return
      */
@@ -580,11 +644,11 @@
     }
 
     private void log(String s) {
-        Rlog.d(TAG, s);
+        Rlog.d(mTag, s);
     }
 
     private void loge(String s) {
-        Rlog.e(TAG, s);
+        Rlog.e(mTag, s);
     }
 
 }
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcController.java b/src/java/com/android/internal/telephony/dataconnection/DcController.java
index f1790a3..fa3f537 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcController.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcController.java
@@ -27,7 +27,7 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
-import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.DataFailCause;
 import android.telephony.PhoneStateListener;
 import android.telephony.Rlog;
@@ -121,9 +121,9 @@
     }
 
     public static DcController makeDcc(Phone phone, DcTracker dct,
-                                       DataServiceManager dataServiceManager, Handler handler) {
-        DcController dcc = new DcController("Dcc", phone, dct, dataServiceManager, handler);
-        return dcc;
+                                       DataServiceManager dataServiceManager, Handler handler,
+                                       String tagSuffix) {
+        return new DcController("Dcc" + tagSuffix, phone, dct, dataServiceManager, handler);
     }
 
     void dispose() {
@@ -192,7 +192,7 @@
         @Override
         public void enter() {
             if (mPhone != null && mDataServiceManager.getTransportType()
-                    == TransportType.WWAN) {
+                    == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                 mPhone.mCi.registerForRilConnected(getHandler(),
                         DataConnection.EVENT_RIL_CONNECTED, null);
             }
@@ -208,7 +208,7 @@
         @Override
         public void exit() {
             if (mPhone != null & mDataServiceManager.getTransportType()
-                    == TransportType.WWAN) {
+                    == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                 mPhone.mCi.unregisterForRilConnected(getHandler());
             }
             mDataServiceManager.unregisterForDataCallListChanged(getHandler());
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 7411e0e..226a914 100755
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -17,6 +17,9 @@
 package com.android.internal.telephony.dataconnection;
 
 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE_CA;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_NR;
 
 import static com.android.internal.telephony.RILConstants.DATA_PROFILE_DEFAULT;
 import static com.android.internal.telephony.RILConstants.DATA_PROFILE_INVALID;
@@ -62,10 +65,12 @@
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.provider.Telephony;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellLocation;
 import android.telephony.DataFailCause;
+import android.telephony.NetworkRegistrationState;
 import android.telephony.PcoData;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
@@ -74,6 +79,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.cdma.CdmaCellLocation;
 import android.telephony.data.ApnSetting;
+import android.telephony.data.ApnSetting.ApnType;
 import android.telephony.data.DataProfile;
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
@@ -91,6 +97,7 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.PhoneSwitcher;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.SettingsObserver;
 import com.android.internal.telephony.TelephonyIntents;
@@ -128,6 +135,25 @@
     private static final boolean VDBG_STALL = false; // STOPSHIP if true
     private static final boolean RADIO_TESTS = false;
 
+    /**
+     * These constants exist here because ConnectivityManager.TYPE_xxx constants are deprecated and
+     * new ones will not be added (for instance NETWORK_TYPE_MCX below).
+     * For backward compatibility, the values here need to be the same as
+     * ConnectivityManager.TYPE_xxx because networkAttributes overlay uses those values.
+     */
+    private static final int NETWORK_TYPE_DEFAULT = ConnectivityManager.TYPE_MOBILE;
+    private static final int NETWORK_TYPE_MMS = ConnectivityManager.TYPE_MOBILE_MMS;
+    private static final int NETWORK_TYPE_SUPL = ConnectivityManager.TYPE_MOBILE_SUPL;
+    private static final int NETWORK_TYPE_DUN = ConnectivityManager.TYPE_MOBILE_DUN;
+    private static final int NETWORK_TYPE_HIPRI = ConnectivityManager.TYPE_MOBILE_HIPRI;
+    private static final int NETWORK_TYPE_FOTA = ConnectivityManager.TYPE_MOBILE_FOTA;
+    private static final int NETWORK_TYPE_IMS = ConnectivityManager.TYPE_MOBILE_IMS;
+    private static final int NETWORK_TYPE_CBS = ConnectivityManager.TYPE_MOBILE_CBS;
+    private static final int NETWORK_TYPE_IA = ConnectivityManager.TYPE_MOBILE_IA;
+    private static final int NETWORK_TYPE_EMERGENCY = ConnectivityManager.TYPE_MOBILE_EMERGENCY;
+    private static final int NETWORK_TYPE_MCX = 1001;  // far away from ConnectivityManager.TYPE_xxx
+                                                       // constants as MCX isn't defined there.
+
     @IntDef(value = {
             REQUEST_TYPE_NORMAL,
             REQUEST_TYPE_HANDOVER,
@@ -558,7 +584,7 @@
 
     // When false we will not auto attach and manually attaching is required.
     private boolean mAutoAttachOnCreationConfig = false;
-    private AtomicBoolean mAutoAttachOnCreation = new AtomicBoolean(false);
+    private AtomicBoolean mAutoAttachEnabled = new AtomicBoolean(false);
 
     // State of screen
     // (TODO: Reconsider tying directly to screen, maybe this is
@@ -642,7 +668,7 @@
     private final Map<Integer, List<Message>> mRequestNetworkCompletionMsgs = new HashMap<>();
 
     //***** Constructor
-    public DcTracker(Phone phone, int transportType) {
+    public DcTracker(Phone phone, @TransportType int transportType) {
         super();
         mPhone = phone;
         if (DBG) log("DCT.constructor");
@@ -650,14 +676,15 @@
                 .createForSubscriptionId(phone.getSubId());
         // The 'C' in tag indicates cellular, and 'I' indicates IWLAN. This is to distinguish
         // between two DcTrackers, one for each.
-        String tag = "DCT-" + ((transportType == TransportType.WWAN) ? "C" : "I");
+        String tagSuffix = "-" + ((transportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                ? "C" : "I");
         if (mTelephonyManager.getPhoneCount() > 1) {
-            tag += "-" + mPhone.getPhoneId();
+            tagSuffix += "-" + mPhone.getPhoneId();
         }
-        mLogTag = tag;
+        mLogTag = "DCT" + tagSuffix;
 
         mTransportType = transportType;
-        mDataServiceManager = new DataServiceManager(phone, transportType);
+        mDataServiceManager = new DataServiceManager(phone, transportType, tagSuffix);
 
         mResolver = mPhone.getContext().getContentResolver();
         mUiccController = UiccController.getInstance();
@@ -682,7 +709,7 @@
         mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
 
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
-        mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
+        mAutoAttachEnabled.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
 
         mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
         mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
@@ -690,7 +717,7 @@
         HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
         dcHandlerThread.start();
         Handler dcHandler = new Handler(dcHandlerThread.getLooper());
-        mDcc = DcController.makeDcc(mPhone, this, mDataServiceManager, dcHandler);
+        mDcc = DcController.makeDcc(mPhone, this, mDataServiceManager, dcHandler, tagSuffix);
         mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
 
         mDataConnectionTracker = this;
@@ -733,9 +760,9 @@
     }
 
     public void registerServiceStateTrackerEvents() {
-        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
+        mPhone.getServiceStateTracker().registerForDataConnectionAttached(mTransportType, this,
                 DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
-        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
+        mPhone.getServiceStateTracker().registerForDataConnectionDetached(mTransportType, this,
                 DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
         mPhone.getServiceStateTracker().registerForDataRoamingOn(this,
                 DctConstants.EVENT_ROAMING_ON, null);
@@ -745,22 +772,23 @@
                 DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
         mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
                 DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
-        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
+        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(mTransportType, this,
                 DctConstants.EVENT_DATA_RAT_CHANGED, null);
     }
 
     public void unregisterServiceStateTrackerEvents() {
-        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
-        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
+        mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(mTransportType, this);
+        mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(mTransportType, this);
         mPhone.getServiceStateTracker().unregisterForDataRoamingOn(this);
         mPhone.getServiceStateTracker().unregisterForDataRoamingOff(this);
         mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
         mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
-        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(this);
+        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(mTransportType,
+                this);
     }
 
     private void registerForAllEvents() {
-        if (mTransportType == TransportType.WWAN) {
+        if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
             mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
             mPhone.mCi.registerForOffOrNotAvailable(this,
                     DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
@@ -816,7 +844,7 @@
 
     private void unregisterForAllEvents() {
          //Unregister for all events
-        if (mTransportType == TransportType.WWAN) {
+        if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
             mPhone.mCi.unregisterForAvailable(this);
             mPhone.mCi.unregisterForOffOrNotAvailable(this);
             mPhone.mCi.unregisterForPcoData(this);
@@ -969,42 +997,45 @@
                 com.android.internal.R.array.networkAttributes);
         for (String networkConfigString : networkConfigStrings) {
             NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
-            ApnContext apnContext = null;
+            ApnContext apnContext;
 
             switch (networkConfig.type) {
-            case ConnectivityManager.TYPE_MOBILE:
-                apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_MMS:
-                apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_SUPL:
-                apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_DUN:
-                apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_HIPRI:
-                apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_FOTA:
-                apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_IMS:
-                apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_CBS:
-                apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_IA:
-                apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
-                break;
-            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
-                apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
-                break;
-            default:
-                log("initApnContexts: skipping unknown type=" + networkConfig.type);
-                continue;
+                case NETWORK_TYPE_DEFAULT:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
+                    break;
+                case NETWORK_TYPE_MMS:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
+                    break;
+                case NETWORK_TYPE_SUPL:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
+                    break;
+                case NETWORK_TYPE_DUN:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
+                    break;
+                case NETWORK_TYPE_HIPRI:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
+                    break;
+                case NETWORK_TYPE_FOTA:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
+                    break;
+                case NETWORK_TYPE_IMS:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
+                    break;
+                case NETWORK_TYPE_CBS:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
+                    break;
+                case NETWORK_TYPE_IA:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
+                    break;
+                case NETWORK_TYPE_EMERGENCY:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
+                    break;
+                case NETWORK_TYPE_MCX:
+                    apnContext = addApnContext(PhoneConstants.APN_TYPE_MCX, networkConfig);
+                    break;
+                default:
+                    log("initApnContexts: skipping unknown type=" + networkConfig.type);
+                    continue;
             }
             log("initApnContexts: apnContext=" + apnContext);
         }
@@ -1162,7 +1193,7 @@
         if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
         stopNetStatPoll();
         stopDataStallAlarm();
-        notifyDataConnection();
+        mPhone.notifyDataConnection();
         mAttached.set(false);
     }
 
@@ -1173,13 +1204,10 @@
             if (DBG) log("onDataConnectionAttached: start polling notify attached");
             startNetStatPoll();
             startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
-            notifyDataConnection();
-        } else {
-            // update APN availability so that APN can be enabled.
-            notifyOffApnsOfAvailability();
+            mPhone.notifyDataConnection();
         }
         if (mAutoAttachOnCreationConfig) {
-            mAutoAttachOnCreation.set(true);
+            mAutoAttachEnabled.set(true);
         }
         setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED, RetryFailures.ALWAYS);
     }
@@ -1222,7 +1250,7 @@
         boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
         boolean radioStateFromCarrier = mPhone.getServiceStateTracker().getPowerStateFromCarrier();
         // TODO: Remove this hack added by ag/641832.
-        int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
+        int radioTech = getDataRat();
         if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
             desiredPowerState = true;
             radioStateFromCarrier = true;
@@ -1278,7 +1306,7 @@
             reasons.add(DataDisallowedReasonType.IN_ECBM);
         }
 
-        if (!(attachedState || mAutoAttachOnCreation.get())) {
+        if (!(attachedState || mAutoAttachEnabled.get())) {
             reasons.add(DataDisallowedReasonType.NOT_ATTACHED);
         }
         if (!recordsLoaded) {
@@ -1430,7 +1458,7 @@
                 apnContext.requestLog(str);
                 apnContext.setState(DctConstants.State.IDLE);
             }
-            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
+            int radioTech = getDataRat();
             apnContext.setConcurrentVoiceAndDataAllowed(mPhone.getServiceStateTracker()
                     .isConcurrentVoiceAndDataAllowed());
             if (apnContext.getState() == DctConstants.State.IDLE) {
@@ -1438,7 +1466,6 @@
                         buildWaitingApns(apnContext.getApnType(), radioTech);
                 if (waitingApns.isEmpty()) {
                     notifyNoData(DataFailCause.MISSING_UNKNOWN_APN, apnContext);
-                    notifyOffApnsOfAvailability();
                     String str = "trySetupData: X No APN found retValue=false";
                     if (DBG) log(str);
                     apnContext.requestLog(str);
@@ -1453,7 +1480,6 @@
             }
 
             boolean retValue = setupData(apnContext, radioTech, requestType);
-            notifyOffApnsOfAvailability();
 
             if (DBG) log("trySetupData: X retValue=" + retValue);
             return retValue;
@@ -1462,7 +1488,6 @@
                     && apnContext.isConnectable()) {
                 mPhone.notifyDataConnectionFailed(apnContext.getApnType());
             }
-            notifyOffApnsOfAvailability();
 
             StringBuilder str = new StringBuilder();
 
@@ -1488,22 +1513,6 @@
         }
     }
 
-    // Disabled apn's still need avail/unavail notifications - send them out
-    private void notifyOffApnsOfAvailability() {
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (!mAttached.get() || !apnContext.isReady()) {
-                if (DBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
-                mPhone.notifyDataConnection(apnContext.getApnType(),
-                                            PhoneConstants.DataState.DISCONNECTED);
-            } else {
-                if (VDBG) {
-                    log("notifyOffApnsOfAvailability skipped apn due to attached && isReady " +
-                            apnContext.toString());
-                }
-            }
-        }
-    }
-
     /**
      * Clean up all data connections. Note this is just detach the APN context from the data
      * connection. After all APN contexts are detached from the data connection, the data
@@ -1696,7 +1705,7 @@
             log("fetchDunApns: net.tethering.noprovisioning=true ret: empty list");
             return new ArrayList<ApnSetting>(0);
         }
-        int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
+        int bearer = getDataRat();
         ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
         ArrayList<ApnSetting> retDunSettings = new ArrayList<ApnSetting>();
 
@@ -1787,7 +1796,7 @@
      */
     private boolean teardownForDun() {
         // CDMA always needs to do this the profile id is correct
-        final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
+        final int rilRat = getDataRat();
         if (ServiceState.isCdma(rilRat)) return true;
 
         ArrayList<ApnSetting> apns = fetchDunApns();
@@ -1877,7 +1886,7 @@
         // On GSM/LTE we can share existing apn connections provided they support
         // this type.
         if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DUN)
-                || ServiceState.isGsm(mPhone.getServiceState().getRilDataRadioTechnology())) {
+                || ServiceState.isGsm(getDataRat())) {
             dataConnection = checkForCompatibleConnectedApnContext(apnContext);
             if (dataConnection != null) {
                 // Get the apn setting used by the data connection
@@ -2129,9 +2138,8 @@
         boolean retry = true;
         String reason = apnContext.getReason();
 
-        if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
-                (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
-                 && isHigherPriorityApnContextActive(apnContext))) {
+        if (Phone.REASON_RADIO_TURNED_OFF.equals(reason) || (isOnlySingleDcAllowed(getDataRat())
+                && isHigherPriorityApnContextActive(apnContext))) {
             retry = false;
         }
         return retry;
@@ -2173,8 +2181,8 @@
         }
     }
 
-    public boolean getAutoAttachOnCreation() {
-        return mAutoAttachOnCreation.get();
+    public boolean getAutoAttachEnabled() {
+        return mAutoAttachEnabled.get();
     }
 
     private void onRecordsLoadedOrSubIdChanged() {
@@ -2185,10 +2193,7 @@
         createAllApnList();
         setDataProfilesAsNeeded();
         setInitialAttachApn();
-        if (mPhone.mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) {
-            if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
-            notifyOffApnsOfAvailability();
-        }
+        mPhone.notifyDataConnection();
         setupDataOnConnectableApns(Phone.REASON_SIM_LOADED, RetryFailures.ALWAYS);
     }
 
@@ -2199,7 +2204,7 @@
         mAllApnSettings.clear();
         mAutoAttachOnCreationConfig = false;
         // Clear auto attach as modem is expected to do a new attach once SIM is ready
-        mAutoAttachOnCreation.set(false);
+        mAutoAttachEnabled.set(false);
         mOnSubscriptionsChangedListener.mPreviousSubId.set(
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         // In no-sim case, we should still send the emergency APN to the modem, if there is any.
@@ -2283,7 +2288,7 @@
     }
 
     private void addRequestNetworkCompleteMsg(Message onCompleteMsg,
-                                              @ApnSetting.ApnType int apnType) {
+                                              @ApnType int apnType) {
         if (onCompleteMsg != null) {
             List<Message> messageList = mRequestNetworkCompletionMsgs.get(apnType);
             if (messageList == null) messageList = new ArrayList<>();
@@ -2292,7 +2297,8 @@
         }
     }
 
-    private void sendRequestNetworkCompleteMsg(Message message, boolean success, int transport,
+    private void sendRequestNetworkCompleteMsg(Message message, boolean success,
+                                               @TransportType int transport,
                                                @RequestNetworkType int requestType) {
         if (message == null) return;
 
@@ -2303,13 +2309,13 @@
         message.sendToTarget();
     }
 
-    public void enableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType,
+    public void enableApn(@ApnType int apnType, @RequestNetworkType int requestType,
                           Message onCompleteMsg) {
         sendMessage(obtainMessage(DctConstants.EVENT_ENABLE_APN, apnType, requestType,
                 onCompleteMsg));
     }
 
-    private void onEnableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType,
+    private void onEnableApn(@ApnType int apnType, @RequestNetworkType int requestType,
                              Message onCompleteMsg) {
         ApnContext apnContext = mApnContextsByType.get(apnType);
         if (apnContext == null) {
@@ -2383,11 +2389,11 @@
         }
     }
 
-    public void disableApn(@ApnSetting.ApnType int apnType, @ReleaseNetworkType int releaseType) {
+    public void disableApn(@ApnType int apnType, @ReleaseNetworkType int releaseType) {
         sendMessage(obtainMessage(DctConstants.EVENT_DISABLE_APN, apnType, releaseType));
     }
 
-    private void onDisableApn(@ApnSetting.ApnType int apnType,
+    private void onDisableApn(@ApnType int apnType,
                               @ReleaseNetworkType int releaseType) {
         ApnContext apnContext = mApnContextsByType.get(apnType);
         if (apnContext == null) {
@@ -2434,8 +2440,7 @@
             cleanUpConnectionInternal(true, releaseType, apnContext);
         }
 
-        if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
-                && !isHigherPriorityApnContextActive(apnContext)) {
+        if (isOnlySingleDcAllowed(getDataRat()) && !isHigherPriorityApnContextActive(apnContext)) {
             if (DBG) log("disableApn: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.
@@ -2580,10 +2585,9 @@
             // 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();
             setupDataOnConnectableApns(Phone.REASON_ROAMING_OFF, RetryFailures.ALWAYS);
         } else {
-            notifyDataConnection();
+            mPhone.notifyDataConnection();
         }
     }
 
@@ -2614,14 +2618,13 @@
             if (DBG) log("onDataRoamingOnOrSettingsChanged: setup data on roaming");
 
             setupDataOnConnectableApns(Phone.REASON_ROAMING_ON, RetryFailures.ALWAYS);
-            notifyDataConnection();
+            mPhone.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();
         }
     }
 
@@ -2647,16 +2650,11 @@
             // Assume data is connected on the simulator
             // FIXME  this can be improved
             // setState(DctConstants.State.CONNECTED);
-            notifyDataConnection();
+            mPhone.notifyDataConnection();
 
             log("onRadioAvailable: We're on the simulator; assuming data is connected");
         }
 
-        IccRecords r = mIccRecords.get();
-        if (r != null && r.getRecordsLoaded()) {
-            notifyOffApnsOfAvailability();
-        }
-
         if (getOverallState() != DctConstants.State.IDLE) {
             cleanUpConnectionInternal(true, RELEASE_TYPE_DETACH, null);
         }
@@ -2669,7 +2667,7 @@
         mReregisterOnReconnectFailure = false;
 
         // Clear auto attach as modem is expected to do a new attach
-        mAutoAttachOnCreation.set(false);
+        mAutoAttachEnabled.set(false);
 
         if (mPhone.getSimulatedRadioControl() != null) {
             // Assume data is connected on the simulator
@@ -2679,10 +2677,9 @@
             if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
             cleanUpAllConnectionsInternal(false, Phone.REASON_RADIO_TURNED_OFF);
         }
-        notifyOffApnsOfAvailability();
     }
 
-    private void completeConnection(ApnContext apnContext) {
+    private void completeConnection(ApnContext apnContext, @RequestNetworkType int type) {
 
         if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
 
@@ -2709,7 +2706,10 @@
                     mProvisioningSpinner));
         }
 
-        mPhone.notifyDataConnection(apnContext.getApnType());
+        // Notify data is connected except for handover case.
+        if (type != REQUEST_TYPE_HANDOVER) {
+            mPhone.notifyDataConnection(apnContext.getApnType());
+        }
         startNetStatPoll();
         startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
     }
@@ -2813,7 +2813,7 @@
                     // Complete the connection normally notifying the world we're connected.
                     // We do this if this isn't a special provisioning apn or if we've been
                     // told its time to provision.
-                    completeConnection(apnContext);
+                    completeConnection(apnContext, requestType);
                 } else {
                     // This is a provisioning APN that we're reporting as connected. Later
                     // when the user desires to upgrade this to a "default" connection,
@@ -2875,9 +2875,8 @@
                         cause, cid, mTelephonyManager.getNetworkType());
             }
             ApnSetting apn = apnContext.getApnSetting();
-            mPhone.notifyPreciseDataConnectionFailed(
-                    apnContext.getApnType(), apn != null ? apn.getApnName()
-                    : "unknown", cause);
+            mPhone.notifyPreciseDataConnectionFailed(apnContext.getApnType(),
+                    apn != null ? apn.getApnName() : null, cause);
 
             // Compose broadcast intent send to the specific carrier signaling receivers
             Intent intent = new Intent(TelephonyIntents
@@ -2952,7 +2951,7 @@
                 if (DBG) log("Skip data stall recovery on network status change with in threshold");
                 return;
             }
-            if (mTransportType != TransportType.WWAN) {
+            if (mTransportType != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                 if (DBG) log("Skip data stall recovery on non WWAN");
                 return;
             }
@@ -3017,7 +3016,7 @@
             }
             apnContext.setApnSetting(null);
             apnContext.setDataConnection(null);
-            if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
+            if (isOnlySingleDcAllowed(getDataRat())) {
                 if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
                 setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION,
                         RetryFailures.ALWAYS);
@@ -3044,7 +3043,7 @@
             if (DBG) log("onVoiceCallStarted stop polling");
             stopNetStatPoll();
             stopDataStallAlarm();
-            notifyDataConnection();
+            mPhone.notifyDataConnection();
         }
     }
 
@@ -3055,7 +3054,7 @@
             if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
                 startNetStatPoll();
                 startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
-                notifyDataConnection();
+                mPhone.notifyDataConnection();
             } else {
                 // clean slate after call end.
                 resetPollStats();
@@ -3087,16 +3086,6 @@
         return true;
     }
 
-    private void notifyDataConnection() {
-        for (ApnContext apnContext : mApnContexts.values()) {
-            if (mAttached.get() && apnContext.isReady()) {
-                if (DBG) log("notifyDataConnection: type:" + apnContext.getApnType());
-                mPhone.notifyDataConnection(apnContext.getApnType());
-            }
-        }
-        notifyOffApnsOfAvailability();
-    }
-
     private void setDataProfilesAsNeeded() {
         if (DBG) log("setDataProfilesAsNeeded");
 
@@ -3223,7 +3212,8 @@
             dest.isEnabled(), networkTypeBitmask, dest.getProfileId(),
             (dest.isPersistent() || src.isPersistent()), dest.getMaxConns(),
             dest.getWaitTime(), dest.getMaxConnsTime(), dest.getMtu(), dest.getMvnoType(),
-            dest.getMvnoMatchData(), dest.getApnSetId(), dest.getCarrierId());
+            dest.getMvnoMatchData(), dest.getApnSetId(), dest.getCarrierId(),
+            dest.getSkip464Xlat());
     }
 
     private DataConnection createDataConnection() {
@@ -3546,8 +3536,7 @@
                 break;
 
             case DctConstants.EVENT_DATA_RAT_CHANGED:
-                if (mPhone.getServiceState().getRilDataRadioTechnology()
-                        == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
+                if (getDataRat() == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
                     // unknown rat is an exception for data rat change. It's only received when out
                     // of service and is not applicable for apn bearer bitmask. We should bypass the
                     // check of waiting apn list and keep the data connection on, and no need to
@@ -3887,11 +3876,34 @@
         log("update(): Active DDS, register for all events now!");
         onUpdateIcc();
 
-        mAutoAttachOnCreation.set(false);
+        updateAutoAttachOnCreation();
 
         mPhone.updateCurrentCarrierInProvider();
     }
 
+    /**
+     * For non DDS phone, mAutoAttachEnabled should be true because it may be detached
+     * automatically from network only because it's idle for too long. In this case, we should
+     * try setting up data call even if it's not attached for 2G or 3G networks. And doing so will
+     * trigger PS attach if possible.
+     */
+    public void updateAutoAttachOnCreation() {
+        PhoneSwitcher phoneSwitcher = PhoneSwitcher.getInstance();
+        ServiceState serviceState = mPhone.getServiceState();
+        if (PhoneSwitcher.getInstance() == null || serviceState == null) {
+            mAutoAttachEnabled.set(false);
+            return;
+        }
+
+        // If it's non DDS phone, and voice is registered on 2G or 3G network, we set
+        // mAutoAttachEnabled to true.
+        mAutoAttachEnabled.set(mPhone.getPhoneId() != phoneSwitcher.getPreferredDataPhoneId()
+                && serviceState.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
+                && serviceState.getVoiceNetworkType() != NETWORK_TYPE_LTE
+                && serviceState.getVoiceNetworkType() != NETWORK_TYPE_LTE_CA
+                && serviceState.getVoiceNetworkType() != NETWORK_TYPE_NR);
+    }
+
     private void notifyAllDataDisconnected() {
         sEnableFailFastRefCounter = 0;
         mFailFast = false;
@@ -3972,7 +3984,7 @@
         pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
         pw.println(" mResolver=" + mResolver);
         pw.println(" mReconnectIntent=" + mReconnectIntent);
-        pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation.get());
+        pw.println(" mAutoAttachEnabled=" + mAutoAttachEnabled.get());
         pw.println(" mIsScreenOn=" + mIsScreenOn);
         pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
         pw.println(" mDataServiceBound=" + mDataServiceBound);
@@ -4157,8 +4169,7 @@
         if (mAllApnSettings.isEmpty()) {
             cleanUpAllConnectionsInternal(detach, Phone.REASON_APN_CHANGED);
         } else {
-            int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
-            if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
+            if (getDataRat() == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
                 // unknown rat is an exception for data rat change. Its only received when out of
                 // service and is not applicable for apn bearer bitmask. We should bypass the check
                 // of waiting apn list and keep the data connection on.
@@ -4167,8 +4178,7 @@
             for (ApnContext apnContext : mApnContexts.values()) {
                 ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
                 ArrayList<ApnSetting> waitingApns = buildWaitingApns(
-                        apnContext.getApnType(),
-                        mPhone.getServiceState().getRilDataRadioTechnology());
+                        apnContext.getApnType(), getDataRat());
                 if (VDBG) log("new waitingApns:" + waitingApns);
                 if ((currentWaitingApns != null)
                         && ((waitingApns.size() != currentWaitingApns.size())
@@ -4781,4 +4791,14 @@
         }
         return "UNKNOWN";
     }
+
+    private int getDataRat() {
+        ServiceState ss = mPhone.getServiceState();
+        NetworkRegistrationState nrs = ss.getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_PS, mTransportType);
+        if (nrs != null) {
+            return ServiceState.networkTypeToRilRadioTechnology(nrs.getAccessNetworkTechnology());
+        }
+        return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
+    }
 }
diff --git a/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
index cd64d1d..896dea1 100644
--- a/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
+++ b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
@@ -27,7 +27,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.Rlog;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.ApnSetting.ApnType;
@@ -63,7 +63,7 @@
     private final LocalLog mLocalLog = new LocalLog(REQUEST_LOG_SIZE);
 
     // Key: network request. Value: the transport of DcTracker it applies to,
-    // TransportType.INVALID if not applied.
+    // AccessNetworkConstants.TRANSPORT_TYPE_INVALID if not applied.
     private final Map<NetworkRequest, Integer> mNetworkRequests = new HashMap<>();
 
     private final Phone mPhone;
@@ -219,9 +219,16 @@
 
     // apply or revoke requests if our active-ness changes
     private void onActivePhoneSwitch() {
+        // For non DDS phone, mAutoAttachOnCreation should be true because it may be detached
+        // automatically from network only because it's idle for too long. In this case, we should
+        // try setting up data call even if it's not attached. And doing so will trigger PS attach
+        // if possible.
+        mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                .updateAutoAttachOnCreation();
+
         for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
             NetworkRequest networkRequest = entry.getKey();
-            boolean applied = entry.getValue() != TransportType.INVALID;
+            boolean applied = entry.getValue() != AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
 
             boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest(
                     networkRequest, mPhone.getPhoneId());
@@ -242,7 +249,7 @@
             }
 
             mNetworkRequests.put(networkRequest,
-                    shouldApply ? transportType : TransportType.INVALID);
+                    shouldApply ? transportType : AccessNetworkConstants.TRANSPORT_TYPE_INVALID);
         }
     }
 
@@ -271,7 +278,8 @@
                 networkRequest, mPhone.getPhoneId());
 
         mNetworkRequests.put(networkRequest, shouldApply
-                ? getTransportTypeFromNetworkRequest(networkRequest) : TransportType.INVALID);
+                ? getTransportTypeFromNetworkRequest(networkRequest)
+                : AccessNetworkConstants.TRANSPORT_TYPE_INVALID);
 
         String s = "onNeedNetworkFor " + networkRequest + " shouldApply " + shouldApply;
         log(s);
@@ -292,7 +300,8 @@
 
     private void onReleaseNetworkFor(Message msg) {
         NetworkRequest networkRequest = (NetworkRequest)msg.obj;
-        boolean applied = mNetworkRequests.get(networkRequest) != TransportType.INVALID;
+        boolean applied = mNetworkRequests.get(networkRequest)
+                != AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
 
         mNetworkRequests.remove(networkRequest);
 
@@ -308,17 +317,19 @@
 
     private void onDataHandoverNeeded(@ApnType int apnType, int targetTransport) {
         log("onDataHandoverNeeded: apnType=" + ApnSetting.getApnTypeString(apnType)
-                + ", target transport=" + TransportType.toString(targetTransport));
+                + ", target transport="
+                + AccessNetworkConstants.transportTypeToString(targetTransport));
         if (mTransportManager.getCurrentTransport(apnType) == targetTransport) {
-            log("apnType " + ApnSetting.getApnTypeString(apnType) + " is already on "
-                    + TransportType.toString(targetTransport));
+            log("APN type " + ApnSetting.getApnTypeString(apnType) + " is already on "
+                    + AccessNetworkConstants.transportTypeToString(targetTransport));
             return;
         }
 
+        boolean handoverPending = false;
         for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
             NetworkRequest networkRequest = entry.getKey();
             int currentTransport = entry.getValue();
-            boolean applied = currentTransport != TransportType.INVALID;
+            boolean applied = currentTransport != AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
             if (ApnContext.getApnTypeFromNetworkRequest(networkRequest) == apnType
                     && applied
                     && currentTransport != targetTransport) {
@@ -326,16 +337,27 @@
                         EVENT_DATA_HANDOVER_COMPLETED);
                 onCompleteMsg.getData().putParcelable(
                         DcTracker.DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST, networkRequest);
+                // TODO: Need to handle the case that the request is there, but there is no actual
+                // data connections established.
                 requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_HANDOVER,
                         targetTransport, onCompleteMsg);
+                handoverPending = true;
             }
         }
+
+        if (!handoverPending) {
+            log("No handover request pending. Update the transport type to "
+                    + AccessNetworkConstants.transportTypeToString(targetTransport)
+                    + " for APN type " + ApnSetting.getApnTypeString(apnType));
+            mTransportManager.setCurrentTransport(apnType, targetTransport);
+        }
     }
 
     private void onDataHandoverSetupCompleted(NetworkRequest networkRequest, boolean success,
                                               int targetTransport) {
         log("onDataHandoverSetupCompleted: " + networkRequest + ", success=" + success
-                + ", targetTransport=" + TransportType.toString(targetTransport));
+                + ", targetTransport="
+                + AccessNetworkConstants.transportTypeToString(targetTransport));
 
         // At this point, handover setup has been completed on the target transport. If succeeded,
         // we can release the data connection on the original transport. If failed, then we also
@@ -344,8 +366,9 @@
         if (success) {
             // Handover setup succeeded on targeting transport. Now we can release the network
             // request on the original transport.
-            int originTransport = (targetTransport == TransportType.WWAN)
-                    ? TransportType.WLAN : TransportType.WWAN;
+            int originTransport = (targetTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                    ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
+                    : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
             int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
             releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_HANDOVER,
                     originTransport);
@@ -369,7 +392,7 @@
         for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
             NetworkRequest nr = entry.getKey();
             int transport = entry.getValue();
-            pw.println(nr + (transport != TransportType.INVALID
+            pw.println(nr + (transport != AccessNetworkConstants.TRANSPORT_TYPE_INVALID
                     ? (" applied on " + transport) : " not applied"));
         }
         mLocalLog.dump(fd, pw, args);
diff --git a/src/java/com/android/internal/telephony/TransportManager.java b/src/java/com/android/internal/telephony/dataconnection/TransportManager.java
similarity index 68%
rename from src/java/com/android/internal/telephony/TransportManager.java
rename to src/java/com/android/internal/telephony/dataconnection/TransportManager.java
index 9e1379b..bb478e8 100644
--- a/src/java/com/android/internal/telephony/TransportManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/TransportManager.java
@@ -16,20 +16,24 @@
 
 package com.android.internal.telephony.dataconnection;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.StringDef;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.os.RegistrantList;
+import android.os.SystemProperties;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.Rlog;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.ApnSetting.ApnType;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.RIL;
 import com.android.internal.telephony.dataconnection.AccessNetworksManager.QualifiedNetworks;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
@@ -47,8 +51,43 @@
 
 /**
  * This class represents the transport manager which manages available transports (i.e. WWAN or
- * WLAN)and determine the correct transport for {@link TelephonyNetworkFactory} to handle the data
+ * WLAN) and determine the correct transport for {@link TelephonyNetworkFactory} to handle the data
  * requests.
+ *
+ * The device can operate in the following modes, which is stored in the system properties
+ * ro.telephony.iwlan_operation_mode. If the system properties is missing, then it's tied to
+ * IRadio version. For 1.4 or above, it's legacy mode. For 1.3 or below, it's
+ *
+ * Legacy mode:
+ *      Frameworks send all data requests to the default data service, which is the cellular data
+ *      service. IWLAN should be still reported as a RAT on cellular network service.
+ *
+ * AP-assisted mode:
+ *      IWLAN is handled by IWLAN data service extending {@link android.telephony.data.DataService},
+ *      IWLAN network service extending {@link android.telephony.NetworkService}, and qualified
+ *      network service extending {@link android.telephony.data.QualifiedNetworksService}.
+ *
+ *      The following settings for service package name need to be configured properly for
+ *      frameworks to bind.
+ *
+ *      Package name of data service:
+ *          The resource overlay 'config_wwan_data_service_package' or,
+ *          the carrier config
+ *          {@link CarrierConfigManager#KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING}.
+ *          The carrier config takes precedence over the resource overlay if both exist.
+ *
+ *      Package name of network service
+ *          The resource overlay 'config_wwan_network_service_package' or
+ *          the carrier config
+ *          {@link CarrierConfigManager#KEY_CARRIER_NETWORK_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING}.
+ *          The carrier config takes precedence over the resource overlay if both exist.
+ *
+ *      Package name of qualified network service
+ *          The resource overlay 'config_qualified_networks_service_package' or
+ *          the carrier config
+ *          {@link CarrierConfigManager#
+ *          KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING}.
+ *          The carrier config takes precedence over the resource overlay if both exist.
  */
 public class TransportManager extends Handler {
     private static final String TAG = TransportManager.class.getSimpleName();
@@ -58,12 +97,18 @@
 
     static {
         ACCESS_NETWORK_TRANSPORT_TYPE_MAP = new HashMap<>();
-        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.UNKNOWN, TransportType.WWAN);
-        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.GERAN, TransportType.WWAN);
-        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.UTRAN, TransportType.WWAN);
-        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.EUTRAN, TransportType.WWAN);
-        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.CDMA2000, TransportType.WWAN);
-        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.IWLAN, TransportType.WLAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.UNKNOWN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.GERAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.UTRAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.EUTRAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.CDMA2000,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.IWLAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
     }
 
     private static final int EVENT_QUALIFIED_NETWORKS_CHANGED = 1;
@@ -72,7 +117,7 @@
             "ro.telephony.iwlan_operation_mode";
 
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"IWLAN_OPERATION_MODE_"},
+    @StringDef(prefix = {"IWLAN_OPERATION_MODE_"},
             value = {
                     IWLAN_OPERATION_MODE_DEFAULT,
                     IWLAN_OPERATION_MODE_LEGACY,
@@ -84,26 +129,27 @@
      * {@link #IWLAN_OPERATION_MODE_AP_ASSISTED}. On device that has IRadio 1.2 or below, it means
      * {@link #IWLAN_OPERATION_MODE_LEGACY}.
      */
-    public static final int IWLAN_OPERATION_MODE_DEFAULT = 0;
+    public static final String IWLAN_OPERATION_MODE_DEFAULT = "default";
 
     /**
      * IWLAN legacy mode. IWLAN is completely handled by the modem, and when the device is on
      * IWLAN, modem reports IWLAN as a RAT.
      */
-    public static final int IWLAN_OPERATION_MODE_LEGACY = 1;
+    public static final String IWLAN_OPERATION_MODE_LEGACY = "legacy";
 
     /**
      * IWLAN application processor assisted mode. IWLAN is handled by the bound IWLAN data service
      * and network service separately.
      */
-    public static final int IWLAN_OPERATION_MODE_AP_ASSISTED = 2;
+    public static final String IWLAN_OPERATION_MODE_AP_ASSISTED = "AP-assisted";
 
     private final Phone mPhone;
 
     /** The available transports. Must be one or more of AccessNetworkConstants.TransportType.XXX */
     private final int[] mAvailableTransports;
 
-    private final AccessNetworksManager mAccessNetworksManager;
+    @Nullable
+    private AccessNetworksManager mAccessNetworksManager;
 
     /**
      * Available networks. The key is the APN type, and the value is the available network list in
@@ -122,7 +168,11 @@
      */
     private final RegistrantList mHandoverNeededEventRegistrants;
 
-    static final class HandoverParams {
+    /**
+     * Handover parameters
+     */
+    @VisibleForTesting
+    public static final class HandoverParams {
         public final @ApnType int apnType;
         public final int targetTransport;
         HandoverParams(int apnType, int targetTransport) {
@@ -133,21 +183,22 @@
 
     public TransportManager(Phone phone) {
         mPhone = phone;
-        mAccessNetworksManager = new AccessNetworksManager(phone);
-
-        mAccessNetworksManager.registerForQualifiedNetworksChanged(this,
-                EVENT_QUALIFIED_NETWORKS_CHANGED);
-
         mCurrentAvailableNetworks = new ConcurrentHashMap<>();
         mCurrentTransports = new ConcurrentHashMap<>();
         mHandoverNeededEventRegistrants = new RegistrantList();
 
         if (isInLegacyMode()) {
+            log("operates in legacy mode.");
             // For legacy mode, WWAN is the only transport to handle all data connections, even
             // the IWLAN ones.
-            mAvailableTransports = new int[]{TransportType.WWAN};
+            mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN};
         } else {
-            mAvailableTransports = new int[]{TransportType.WWAN, TransportType.WLAN};
+            log("operates in AP-assisted mode.");
+            mAccessNetworksManager = new AccessNetworksManager(phone);
+            mAccessNetworksManager.registerForQualifiedNetworksChanged(this,
+                    EVENT_QUALIFIED_NETWORKS_CHANGED);
+            mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                    AccessNetworkConstants.TRANSPORT_TYPE_WLAN};
         }
     }
 
@@ -211,14 +262,17 @@
         log("updateAvailableNetworks: " + networksList);
         for (QualifiedNetworks networks : networksList) {
             if (areNetworksValid(networks)) {
-                mCurrentAvailableNetworks.put(networks.apnType, networks.qualifiedNetworks);
                 if (isHandoverNeeded(networks)) {
+                    mCurrentAvailableNetworks.put(networks.apnType, networks.qualifiedNetworks);
                     // If handover is needed, perform the handover works. For now we only pick the
                     // first element because it's the most preferred. In the future we should also
                     // consider the rest in the list, for example, the first one violates
                     // carrier/user policy.
                     int targetTransport = ACCESS_NETWORK_TRANSPORT_TYPE_MAP.get(
                             networks.qualifiedNetworks[0]);
+                    log("Handover needed for APN type: "
+                            + ApnSetting.getApnTypeString(networks.apnType) + ", target transport: "
+                            + AccessNetworkConstants.transportTypeToString(targetTransport));
                     mHandoverNeededEventRegistrants.notifyResult(
                             new HandoverParams(networks.apnType, targetTransport));
 
@@ -227,7 +281,8 @@
                     // transport.
                     log("Handover not needed for APN type: "
                             + ApnSetting.getApnTypeString(networks.apnType));
-                    int transport = TransportType.WWAN;
+                    mCurrentAvailableNetworks.put(networks.apnType, networks.qualifiedNetworks);
+                    int transport = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
                     if (!ArrayUtils.isEmpty(networks.qualifiedNetworks)
                             && ACCESS_NETWORK_TRANSPORT_TYPE_MAP.containsKey(
                                     networks.qualifiedNetworks[0])) {
@@ -254,20 +309,17 @@
     }
 
     /**
-     * @return True if in IWLAN legacy mode. Operating in legacy mode means telephony will send
-     * all data requests to the default data service, which is the cellular data service.
-     * AP-assisted mode requires properly configuring the resource overlay
-     * 'config_wwan_data_service_package' (or the carrier config
-     * {@link CarrierConfigManager#KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING }) to
-     * the IWLAN data service package, 'config_wwan_network_service_package' (or the carrier config
-     * {@link CarrierConfigManager#KEY_CARRIER_NETWORK_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING })
-     * to the IWLAN network service package, and 'config_qualified_networks_service_package' (or the
-     * carrier config
-     * {@link CarrierConfigManager#KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING})
-     * to the qualified networks service package.
+     * @return {@code true} if the device operates in legacy mode, otherwise {@code false}.
      */
     public boolean isInLegacyMode() {
-        return (mPhone.mCi.getIwlanOperationMode() == IWLAN_OPERATION_MODE_LEGACY);
+        // Get IWLAN operation mode from the system property. If the system property is missing or
+        // misconfiged the default behavior is tied to the IRadio version. For 1.4 or above, it's
+        // AP-assisted mode, for 1.3 or below, it's legacy mode. For IRadio 1.3 or below, no matter
+        // what the configuration is, it will always be legacy mode.
+        String mode = SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE);
+
+        return mode.equals(IWLAN_OPERATION_MODE_LEGACY)
+                || mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_4);
     }
 
     /**
@@ -279,12 +331,12 @@
     public int getCurrentTransport(@ApnType int apnType) {
         // In legacy mode, always route to cellular.
         if (isInLegacyMode()) {
-            return TransportType.WWAN;
+            return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
         }
 
         // If we can't find the corresponding transport, always route to cellular.
         return mCurrentTransports.get(apnType) == null
-                ? TransportType.WWAN : mCurrentTransports.get(apnType);
+                ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mCurrentTransports.get(apnType);
     }
 
     /**
@@ -320,13 +372,16 @@
         pw.println("TransportManager:");
         pw.increaseIndent();
         pw.println("mAvailableTransports=[" + Arrays.stream(mAvailableTransports)
-                .mapToObj(type -> TransportType.toString(type))
+                .mapToObj(type -> AccessNetworkConstants.transportTypeToString(type))
                 .collect(Collectors.joining(",")) + "]");
         pw.println("mCurrentAvailableNetworks=" + mCurrentAvailableNetworks);
         pw.println("mCurrentTransports=" + mCurrentTransports);
         pw.println("isInLegacy=" + isInLegacyMode());
-        pw.println("IWLAN operation mode=" + mPhone.mCi.getIwlanOperationMode());
-        mAccessNetworksManager.dump(fd, pw, args);
+        pw.println("IWLAN operation mode="
+                + SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE));
+        if (mAccessNetworksManager != null) {
+            mAccessNetworksManager.dump(fd, pw, args);
+        }
         pw.decreaseIndent();
         pw.flush();
     }
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
index 303f6a9..c5d74a1 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
@@ -366,6 +366,9 @@
      * @return {@code true} if it is; {@code false} otherwise.
      */
     public boolean isEmergencyNumber(String number, boolean exactMatch) {
+        if (number == null) {
+            return false;
+        }
         if (!mEmergencyNumberListFromRadio.isEmpty()) {
             for (EmergencyNumber num : mEmergencyNumberList) {
                 // According to com.android.i18n.phonenumbers.ShortNumberInfo, in
@@ -467,18 +470,12 @@
             // 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,
-                        new ArrayList<String>(), 0,
-                        EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
+                emergencyNumberList.add(getLabeledEmergencyNumberForEcclist(emergencyNum));
             }
         }
         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,
-                    new ArrayList<String>(), 0,
-                    EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
+            emergencyNumberList.add(getLabeledEmergencyNumberForEcclist(emergencyNum));
         }
         EmergencyNumber.mergeSameNumbersInEmergencyNumberList(emergencyNumberList);
         return emergencyNumberList;
@@ -493,6 +490,21 @@
         return false;
     }
 
+    private EmergencyNumber getLabeledEmergencyNumberForEcclist(String number) {
+        for (EmergencyNumber num : mEmergencyNumberListFromDatabase) {
+            if (num.getNumber().equals(number)) {
+                return new EmergencyNumber(number, mCountryIso.toLowerCase(), "",
+                        num.getEmergencyServiceCategoryBitmask(),
+                        new ArrayList<String>(), EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                        EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+            }
+        }
+        return new EmergencyNumber(number, "", "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                new ArrayList<String>(), 0,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+    }
+
     /**
      * Back-up old logics for {@link PhoneNumberUtils#isEmergencyNumberInternal} for legacy
      * and deprecate purpose.
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccConnector.java b/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
index c854e6f..0c6300b 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
@@ -953,7 +953,8 @@
      * Gets the slot ID from the card ID.
      */
     private int getSlotIdFromCardId(int cardId) {
-        if (cardId == TelephonyManager.UNSUPPORTED_CARD_ID) {
+        if (cardId == TelephonyManager.UNSUPPORTED_CARD_ID
+                || cardId == TelephonyManager.UNINITIALIZED_CARD_ID) {
             return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
         }
         TelephonyManager tm = (TelephonyManager)
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccController.java b/src/java/com/android/internal/telephony/euicc/EuiccController.java
index 5d5f57f..083f9ee 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccController.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccController.java
@@ -169,14 +169,17 @@
      */
     @Override
     public String getEid(int cardId, String callingPackage) {
-        if (!callerCanReadPhoneStatePrivileged()
-                && !canManageActiveSubscriptionOnTargetSim(cardId, callingPackage)) {
-            throw new SecurityException(
-                    "Must have carrier privileges on active subscription to read EID for cardId="
-                    + cardId);
-        }
+        boolean callerCanReadPhoneStatePrivileged = callerCanReadPhoneStatePrivileged();
         long token = Binder.clearCallingIdentity();
         try {
+            if (!callerCanReadPhoneStatePrivileged
+                    && !canManageActiveSubscriptionOnTargetSim(cardId, callingPackage)) {
+                throw new SecurityException(
+                        "Must have carrier privileges on active subscription to read EID for "
+                                + "cardId="
+                                + cardId);
+            }
+
             return blockingGetEidFromEuiccService(cardId);
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -575,6 +578,7 @@
         try {
             latch.await();
         } catch (InterruptedException e) {
+            Log.e(TAG, "blockingGetEuiccInfoFromEuiccService got InterruptedException e: " + e);
             Thread.currentThread().interrupt();
         }
         return resultRef.get();
@@ -1159,13 +1163,19 @@
     // Checks whether the caller can manage the active embedded subscription on the SIM with the
     // given cardId.
     private boolean canManageActiveSubscriptionOnTargetSim(int cardId, String callingPackage) {
-        List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
+        List<SubscriptionInfo> subInfoList = mSubscriptionManager
+                .getActiveSubscriptionInfoList(/* userVisibleonly */false);
         if (subInfoList == null || subInfoList.size() == 0) {
             // No active subscription on any SIM.
             return false;
         }
         for (SubscriptionInfo subInfo : subInfoList) {
-            if (subInfo.getCardId() == cardId && subInfo.isEmbedded()
+            // If cardId == TelephonyManager.UNSUPPORTED_CARD_ID, we assume it does not support
+            // multiple eSIMs. There are older multi-active SIM devices which do not implement HAL
+            // 1.2 and if they have multiple eSIMs, we let it pass if the app can manage an active
+            // subscription on any eSIM. That's the best we can do here.
+            if ((cardId == TelephonyManager.UNSUPPORTED_CARD_ID || subInfo.getCardId() == cardId)
+                    && subInfo.isEmbedded()
                     && mSubscriptionManager.canManageSubscription(subInfo, callingPackage)) {
                 return true;
             }
@@ -1181,11 +1191,16 @@
     // For a single-active subscription phone, checks whether the caller can manage any active
     // embedded subscription.
     private boolean canManageSubscriptionOnTargetSim(int cardId, String callingPackage) {
-        List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
+        List<SubscriptionInfo> subInfoList = mSubscriptionManager
+                .getActiveSubscriptionInfoList(/* userVisibleonly */false);
         // No active subscription on any SIM.
         if (subInfoList == null || subInfoList.size() == 0) {
             return false;
         }
+        // If it's a multi-active SIM device, we assume it's above HAL 1.2 which supports cardId.
+        // There are older multi-active SIM devices but don't implement HAL 1.2. In this case,
+        // platform can't even detect UiccCardInfo#isEuicc as true for eSIM, which won't let the
+        // below check pass. That's the best we can do here.
         if (supportMultiActiveSlots()) {
             // The target card should be an eUICC.
             List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo();
diff --git a/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java b/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java
index db742be..7b0619b 100644
--- a/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java
+++ b/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java
@@ -42,7 +42,6 @@
 import com.android.ims.internal.IImsUt;
 
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -81,15 +80,6 @@
     public static final int FEATURE_DISABLED = 0;
     public static final int FEATURE_ENABLED = 1;
 
-    private static final CapabilityChangeRequest.CapabilityPair VOLTE_CAPABILITY_PAIR =
-            new CapabilityChangeRequest.CapabilityPair(
-                    MmTelCapabilities.CAPABILITY_TYPE_VOICE,
-                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
-    private static final CapabilityChangeRequest.CapabilityPair VT_CAPABILITY_PAIR =
-            new CapabilityChangeRequest.CapabilityPair(
-                    MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
-                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
-
     private static class ConfigListener extends ImsConfigListener.Stub {
 
         private final int mCapability;
@@ -358,20 +348,6 @@
                         });
                 latch.await(WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
             }
-            // Hack For compatibility purposes: older implementations would ignore the VT feature
-            // enabled flag when VoLTE was also enabled on the first time after sub loaded. If we
-            // did not ignore the VT feature, it would send multiple registrations to the network
-            // (first voice, then voice+video). So, we should only send voice if voice+vt is enabled
-            // because they will check to see if VT is enabled separately.
-            List<CapabilityChangeRequest.CapabilityPair> enableRequest =
-                    request.getCapabilitiesToEnable();
-            if (enableRequest.contains(VT_CAPABILITY_PAIR)
-                    && enableRequest.contains(VOLTE_CAPABILITY_PAIR)) {
-                Log.i(TAG, "changeEnabledCapabilities: VT + VoLTE enable requested - removing VT "
-                        + "request");
-                enableRequest.remove(VT_CAPABILITY_PAIR);
-            }
-
             // Enable Capabilities
             for (CapabilityChangeRequest.CapabilityPair cap : request.getCapabilitiesToEnable()) {
                 CountDownLatch latch = new CountDownLatch(1);
diff --git a/src/java/com/android/internal/telephony/ims/RcsEventQueryHelper.java b/src/java/com/android/internal/telephony/ims/RcsEventQueryHelper.java
index 995b413..fcd69fa 100644
--- a/src/java/com/android/internal/telephony/ims/RcsEventQueryHelper.java
+++ b/src/java/com/android/internal/telephony/ims/RcsEventQueryHelper.java
@@ -21,7 +21,6 @@
 import static android.provider.Telephony.RcsColumns.RcsEventTypes.PARTICIPANT_JOINED_EVENT_TYPE;
 import static android.provider.Telephony.RcsColumns.RcsEventTypes.PARTICIPANT_LEFT_EVENT_TYPE;
 import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.RCS_GROUP_THREAD_URI;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_ID_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_URI;
 import static android.provider.Telephony.RcsColumns.RcsParticipantEventColumns.ALIAS_CHANGE_EVENT_URI_PART;
 import static android.provider.Telephony.RcsColumns.RcsParticipantEventColumns.NEW_ALIAS_COLUMN;
@@ -46,13 +45,13 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.telephony.Rlog;
-import android.telephony.ims.RcsEvent;
-import android.telephony.ims.RcsEventQueryResult;
-import android.telephony.ims.RcsGroupThreadIconChangedEvent;
-import android.telephony.ims.RcsGroupThreadNameChangedEvent;
-import android.telephony.ims.RcsGroupThreadParticipantJoinedEvent;
-import android.telephony.ims.RcsGroupThreadParticipantLeftEvent;
-import android.telephony.ims.RcsParticipantAliasChangedEvent;
+import android.telephony.ims.RcsEventDescriptor;
+import android.telephony.ims.RcsEventQueryResultDescriptor;
+import android.telephony.ims.RcsGroupThreadIconChangedEventDescriptor;
+import android.telephony.ims.RcsGroupThreadNameChangedEventDescriptor;
+import android.telephony.ims.RcsGroupThreadParticipantJoinedEventDescriptor;
+import android.telephony.ims.RcsGroupThreadParticipantLeftEventDescriptor;
+import android.telephony.ims.RcsParticipantAliasChangedEventDescriptor;
 import android.telephony.ims.RcsQueryContinuationToken;
 
 import java.util.ArrayList;
@@ -70,9 +69,9 @@
                 .appendPath(ALIAS_CHANGE_EVENT_URI_PART).build();
     }
 
-    RcsEventQueryResult performEventQuery(Bundle bundle) throws RemoteException {
+    RcsEventQueryResultDescriptor performEventQuery(Bundle bundle) throws RemoteException {
         RcsQueryContinuationToken continuationToken = null;
-        List<RcsEvent> eventList = new ArrayList<>();
+        List<RcsEventDescriptor> eventList = new ArrayList<>();
 
         try (Cursor cursor = mContentResolver.query(RCS_EVENT_QUERY_URI, null, bundle, null)) {
             if (cursor == null) {
@@ -109,7 +108,7 @@
             }
         }
 
-        return new RcsEventQueryResult(continuationToken, eventList);
+        return new RcsEventQueryResultDescriptor(continuationToken, eventList);
     }
 
     int createGroupThreadEvent(int eventType, long timestamp, int threadId,
@@ -151,44 +150,47 @@
         }
     }
 
-    private RcsGroupThreadIconChangedEvent createNewGroupIconChangedEvent(Cursor cursor) {
+    private RcsGroupThreadIconChangedEventDescriptor createNewGroupIconChangedEvent(Cursor cursor) {
         String newIcon = cursor.getString(cursor.getColumnIndex(NEW_ICON_URI_COLUMN));
 
-        return new RcsGroupThreadIconChangedEvent(
+        return new RcsGroupThreadIconChangedEventDescriptor(
                 cursor.getLong(cursor.getColumnIndex(TIMESTAMP_COLUMN)),
                 cursor.getInt(cursor.getColumnIndex(RCS_THREAD_ID_COLUMN)),
                 cursor.getInt(cursor.getColumnIndex(SOURCE_PARTICIPANT_ID_COLUMN)),
                 newIcon == null ? null : Uri.parse(newIcon));
     }
 
-    private RcsGroupThreadNameChangedEvent createNewGroupNameChangedEvent(Cursor cursor) {
-        return new RcsGroupThreadNameChangedEvent(
+    private RcsGroupThreadNameChangedEventDescriptor createNewGroupNameChangedEvent(Cursor cursor) {
+        return new RcsGroupThreadNameChangedEventDescriptor(
                 cursor.getLong(cursor.getColumnIndex(TIMESTAMP_COLUMN)),
                 cursor.getInt(cursor.getColumnIndex(RCS_THREAD_ID_COLUMN)),
                 cursor.getInt(cursor.getColumnIndex(SOURCE_PARTICIPANT_ID_COLUMN)),
                 cursor.getString(cursor.getColumnIndex(NEW_NAME_COLUMN)));
     }
 
-    private RcsGroupThreadParticipantLeftEvent createNewParticipantLeftEvent(Cursor cursor) {
-        return new RcsGroupThreadParticipantLeftEvent(
+    private RcsGroupThreadParticipantLeftEventDescriptor
+            createNewParticipantLeftEvent(Cursor cursor) {
+        return new RcsGroupThreadParticipantLeftEventDescriptor(
                 cursor.getLong(cursor.getColumnIndex(TIMESTAMP_COLUMN)),
                 cursor.getInt(cursor.getColumnIndex(RCS_THREAD_ID_COLUMN)),
                 cursor.getInt(cursor.getColumnIndex(SOURCE_PARTICIPANT_ID_COLUMN)),
                 cursor.getInt(cursor.getColumnIndex(DESTINATION_PARTICIPANT_ID_COLUMN)));
     }
 
-    private RcsGroupThreadParticipantJoinedEvent createNewParticipantJoinedEvent(Cursor cursor) {
-        return new RcsGroupThreadParticipantJoinedEvent(
+    private RcsGroupThreadParticipantJoinedEventDescriptor
+            createNewParticipantJoinedEvent(Cursor cursor) {
+        return new RcsGroupThreadParticipantJoinedEventDescriptor(
                 cursor.getLong(cursor.getColumnIndex(TIMESTAMP_COLUMN)),
                 cursor.getInt(cursor.getColumnIndex(RCS_THREAD_ID_COLUMN)),
                 cursor.getInt(cursor.getColumnIndex(SOURCE_PARTICIPANT_ID_COLUMN)),
                 cursor.getInt(cursor.getColumnIndex(DESTINATION_PARTICIPANT_ID_COLUMN)));
     }
 
-    private RcsParticipantAliasChangedEvent createNewParticipantAliasChangedEvent(Cursor cursor) {
-        return new RcsParticipantAliasChangedEvent(
+    private RcsParticipantAliasChangedEventDescriptor
+            createNewParticipantAliasChangedEvent(Cursor cursor) {
+        return new RcsParticipantAliasChangedEventDescriptor(
                 cursor.getLong(cursor.getColumnIndex(TIMESTAMP_COLUMN)),
-                cursor.getInt(cursor.getColumnIndex(RCS_PARTICIPANT_ID_COLUMN)),
+                cursor.getInt(cursor.getColumnIndex(SOURCE_PARTICIPANT_ID_COLUMN)),
                 cursor.getString(cursor.getColumnIndex(NEW_ALIAS_COLUMN)));
     }
 }
diff --git a/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java b/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java
index 9edec9a..fd00dff 100644
--- a/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java
+++ b/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java
@@ -57,12 +57,12 @@
 import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_ALIAS_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_ID_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_URI;
-import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_URI_PART;
 import static android.provider.Telephony.RcsColumns.RcsParticipantEventColumns.NEW_ALIAS_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsThreadColumns.RCS_THREAD_ID_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.DESTINATION_PARTICIPANT_ID_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.NEW_ICON_URI_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.NEW_NAME_COLUMN;
+import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.SOURCE_PARTICIPANT_ID_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsThreadEventColumns.TIMESTAMP_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsUnifiedThreadColumns.THREAD_TYPE_GROUP;
 import static android.provider.Telephony.RcsColumns.TRANSACTION_FAILED;
@@ -90,7 +90,7 @@
 import android.provider.Telephony;
 import android.telephony.Rlog;
 import android.telephony.ims.RcsEventQueryParams;
-import android.telephony.ims.RcsEventQueryResult;
+import android.telephony.ims.RcsEventQueryResultDescriptor;
 import android.telephony.ims.RcsFileTransferCreationParams;
 import android.telephony.ims.RcsIncomingMessageCreationParams;
 import android.telephony.ims.RcsMessageQueryParams;
@@ -98,7 +98,6 @@
 import android.telephony.ims.RcsMessageSnippet;
 import android.telephony.ims.RcsMessageStore;
 import android.telephony.ims.RcsOutgoingMessageCreationParams;
-import android.telephony.ims.RcsParticipant;
 import android.telephony.ims.RcsParticipantQueryParams;
 import android.telephony.ims.RcsParticipantQueryResult;
 import android.telephony.ims.RcsQueryContinuationToken;
@@ -132,6 +131,9 @@
         synchronized (RcsMessageStoreController.class) {
             if (sInstance == null) {
                 sInstance = new RcsMessageStoreController(context.getContentResolver());
+                if (ServiceManager.getService(RCS_SERVICE_NAME) == null) {
+                    ServiceManager.addService(RCS_SERVICE_NAME, sInstance);
+                }
             } else {
                 Rlog.e(TAG, "init() called multiple times! sInstance = " + sInstance);
             }
@@ -139,20 +141,8 @@
         return sInstance;
     }
 
-    private RcsMessageStoreController(ContentResolver contentResolver) {
-        mContentResolver = contentResolver;
-        mParticipantQueryHelper = new RcsParticipantQueryHelper(contentResolver);
-        mMessageQueryHelper = new RcsMessageQueryHelper(contentResolver);
-        mThreadQueryHelper = new RcsThreadQueryHelper(contentResolver, mParticipantQueryHelper);
-        mEventQueryHelper = new RcsEventQueryHelper(contentResolver);
-        mMessageStoreUtil = new RcsMessageStoreUtil(contentResolver);
-        if (ServiceManager.getService(RCS_SERVICE_NAME) == null) {
-            ServiceManager.addService(RCS_SERVICE_NAME, this);
-        }
-    }
-
     @VisibleForTesting
-    public RcsMessageStoreController(ContentResolver contentResolver, Void unused) {
+    public RcsMessageStoreController(ContentResolver contentResolver) {
         mContentResolver = contentResolver;
         mParticipantQueryHelper = new RcsParticipantQueryHelper(contentResolver);
         mMessageQueryHelper = new RcsMessageQueryHelper(contentResolver);
@@ -210,10 +200,10 @@
     }
 
     @Override
-    public RcsMessageQueryResult getMessages(RcsMessageQueryParams queryParameters)
+    public RcsMessageQueryResult getMessages(RcsMessageQueryParams queryParams)
             throws RemoteException {
         Bundle bundle = new Bundle();
-        bundle.putParcelable(MESSAGE_QUERY_PARAMETERS_KEY, queryParameters);
+        bundle.putParcelable(MESSAGE_QUERY_PARAMETERS_KEY, queryParams);
         return mMessageQueryHelper.performMessageQuery(bundle);
     }
 
@@ -226,7 +216,7 @@
     }
 
     @Override
-    public RcsEventQueryResult getEvents(RcsEventQueryParams queryParameters)
+    public RcsEventQueryResultDescriptor getEvents(RcsEventQueryParams queryParameters)
             throws RemoteException {
         Bundle bundle = new Bundle();
         bundle.putParcelable(EVENT_QUERY_PARAMETERS_KEY, queryParameters);
@@ -234,7 +224,7 @@
     }
 
     @Override
-    public RcsEventQueryResult getEventsWithToken(
+    public RcsEventQueryResultDescriptor getEventsWithToken(
             RcsQueryContinuationToken continuationToken) throws RemoteException {
         Bundle bundle = new Bundle();
         bundle.putParcelable(QUERY_CONTINUATION_TOKEN, continuationToken);
@@ -243,35 +233,7 @@
 
     @Override
     public int createRcs1To1Thread(int recipientId) throws RemoteException {
-        // Look up if a similar thread exists. Fail the call if it does
-        RcsParticipant participant = mParticipantQueryHelper.getParticipantFromId(recipientId);
-        if (participant == null) {
-            throw new RemoteException(
-                    "RcsParticipant with id: " + recipientId + " does not exist.");
-        }
-
-        RcsThreadQueryParams queryParameters = new RcsThreadQueryParams.Builder()
-                .setThreadType(RcsThreadQueryParams.THREAD_TYPE_1_TO_1).setParticipant(
-                        participant).build();
-        RcsThreadQueryResult queryResult = getRcsThreads(queryParameters);
-        if (queryResult.getThreads().size() > 0) {
-            throw new RemoteException(
-                    "Rcs1To1Thread with recipient " + recipientId + " already exists.");
-        }
-
-        int rcs1To1ThreadId = mThreadQueryHelper.create1To1Thread();
-        // add the recipient
-        Uri recipientUri = RCS_1_TO_1_THREAD_URI.buildUpon().appendPath(
-                Integer.toString(rcs1To1ThreadId)).appendPath(
-                RCS_PARTICIPANT_URI_PART).appendPath(Integer.toString(recipientId)).build();
-        Uri insertionResult = mContentResolver.insert(recipientUri, null);
-
-        if (insertionResult.equals(recipientUri)) {
-            // insertion successful, return the created thread
-            return rcs1To1ThreadId;
-        }
-
-        throw new RemoteException("Creating Rcs1To1Thread failed");
+        return mThreadQueryHelper.create1To1Thread(recipientId);
     }
 
     @Override
@@ -910,7 +872,7 @@
             String newAlias) throws RemoteException {
         ContentValues contentValues = new ContentValues(4);
         contentValues.put(TIMESTAMP_COLUMN, timestamp);
-        contentValues.put(RCS_PARTICIPANT_ID_COLUMN, participantId);
+        contentValues.put(SOURCE_PARTICIPANT_ID_COLUMN, participantId);
         contentValues.put(NEW_ALIAS_COLUMN, newAlias);
 
         Uri uri = mContentResolver.insert(
diff --git a/src/java/com/android/internal/telephony/ims/RcsParticipantQueryHelper.java b/src/java/com/android/internal/telephony/ims/RcsParticipantQueryHelper.java
index 92fc459..29be536 100644
--- a/src/java/com/android/internal/telephony/ims/RcsParticipantQueryHelper.java
+++ b/src/java/com/android/internal/telephony/ims/RcsParticipantQueryHelper.java
@@ -43,8 +43,8 @@
         RcsParticipant participant = null;
         try (Cursor cursor = mContentResolver.query(
                 Uri.withAppendedPath(RCS_PARTICIPANT_URI, Integer.toString(participantId)),
-                null, null, null)) {
-            if (cursor == null && !cursor.moveToNext()) {
+                new String[]{RCS_PARTICIPANT_ID_COLUMN}, null, null)) {
+            if (cursor == null || !cursor.moveToNext()) {
                 throw new RemoteException("Could not find participant with id: " + participantId);
             }
 
diff --git a/src/java/com/android/internal/telephony/ims/RcsThreadQueryHelper.java b/src/java/com/android/internal/telephony/ims/RcsThreadQueryHelper.java
index 3df1c2c..596ee22 100644
--- a/src/java/com/android/internal/telephony/ims/RcsThreadQueryHelper.java
+++ b/src/java/com/android/internal/telephony/ims/RcsThreadQueryHelper.java
@@ -19,6 +19,7 @@
 import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.GROUP_ICON_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.GROUP_NAME_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsGroupThreadColumns.RCS_GROUP_THREAD_URI;
+import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_ID_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsParticipantColumns.RCS_PARTICIPANT_URI_PART;
 import static android.provider.Telephony.RcsColumns.RcsThreadColumns.RCS_THREAD_ID_COLUMN;
 import static android.provider.Telephony.RcsColumns.RcsThreadColumns.RCS_THREAD_URI;
@@ -89,16 +90,16 @@
         return new RcsThreadQueryResult(continuationToken, rcsThreadIdList);
     }
 
-    int create1To1Thread() throws RemoteException {
-        ContentValues contentValues = new ContentValues(0);
-        Uri insertionUri = mContentResolver.insert(RCS_THREAD_URI, contentValues);
+    int create1To1Thread(int participantId) throws RemoteException {
+        ContentValues contentValues = new ContentValues(1);
+        contentValues.put(RCS_PARTICIPANT_ID_COLUMN, participantId);
+        Uri insertionUri = mContentResolver.insert(RCS_1_TO_1_THREAD_URI, contentValues);
 
         if (insertionUri == null) {
             throw new RemoteException("Rcs1To1Thread creation failed");
         }
 
-        String threadIdAsString = insertionUri.getPathSegments().get(
-                THREAD_ID_INDEX_IN_INSERTION_URI);
+        String threadIdAsString = insertionUri.getLastPathSegment();
         int threadId = Integer.parseInt(threadIdAsString);
 
         if (threadId <= 0) {
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java b/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java
index 03ea1c8..7b6162d 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.imsphone;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.ims.ImsExternalCallState;
 
 import com.android.internal.telephony.Call;
@@ -33,6 +34,7 @@
 
     private Phone mPhone;
 
+    @UnsupportedAppUsage
     public ImsExternalCall(Phone phone, ImsExternalConnection connection) {
         mPhone = phone;
         mConnections.add(connection);
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java
index 6de4e80..cd5c83d 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java
@@ -24,6 +24,7 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.UUSInfo;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.net.Uri;
 import android.telecom.PhoneAccount;
@@ -189,6 +190,7 @@
     /**
      * Sets this external call as active.
      */
+    @UnsupportedAppUsage
     public void setActive() {
         if (mCall == null) {
             return;
@@ -269,6 +271,7 @@
     /**
      * Rebuilds the connection capabilities.
      */
+    @UnsupportedAppUsage
     private void rebuildCapabilities() {
         int capabilities = Capability.IS_EXTERNAL_CONNECTION;
         if (mIsPullable) {
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index ab39212..cf3f679 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -37,6 +37,7 @@
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_NONE;
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.Notification;
@@ -182,9 +183,12 @@
 
     // Instance Variables
     Phone mDefaultPhone;
+    @UnsupportedAppUsage
     ImsPhoneCallTracker mCT;
     ImsExternalCallTracker mExternalCallTracker;
+    @UnsupportedAppUsage
     private ArrayList <ImsPhoneMmiCode> mPendingMMIs = new ArrayList<ImsPhoneMmiCode>();
+    @UnsupportedAppUsage
     private ServiceState mSS = new ServiceState();
 
     // To redial silently through GSM or CDMA when dialing through IMS fails
@@ -233,6 +237,7 @@
         final Message mOnComplete;
         final boolean mIsCfu;
 
+        @UnsupportedAppUsage
         Cf(String cfNumber, boolean isCfu, Message onComplete) {
             mSetCfNumber = cfNumber;
             mIsCfu = isCfu;
@@ -272,10 +277,13 @@
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
         mWakeLock.setReferenceCounted(false);
 
-        if (mDefaultPhone.getServiceStateTracker() != null) {
-            mDefaultPhone.getServiceStateTracker()
-                    .registerForDataRegStateOrRatChanged(this,
-                            EVENT_DEFAULT_PHONE_DATA_STATE_CHANGED, null);
+        if (mDefaultPhone.getServiceStateTracker() != null
+                && mDefaultPhone.getTransportManager() != null) {
+            for (int transport : mDefaultPhone.getTransportManager().getAvailableTransports()) {
+                mDefaultPhone.getServiceStateTracker()
+                        .registerForDataRegStateOrRatChanged(transport, this,
+                                EVENT_DEFAULT_PHONE_DATA_STATE_CHANGED, null);
+            }
         }
         // Sets the Voice reg state to STATE_OUT_OF_SERVICE and also queries the data service
         // state. We don't ever need the voice reg state to be anything other than in or out of
@@ -301,17 +309,21 @@
 
         //Force all referenced classes to unregister their former registered events
         if (mDefaultPhone != null && mDefaultPhone.getServiceStateTracker() != null) {
-            mDefaultPhone.getServiceStateTracker().
-                    unregisterForDataRegStateOrRatChanged(this);
+            for (int transport : mDefaultPhone.getTransportManager().getAvailableTransports()) {
+                mDefaultPhone.getServiceStateTracker()
+                        .unregisterForDataRegStateOrRatChanged(transport, this);
+            }
             mDefaultPhone.unregisterForServiceStateChanged(this);
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public ServiceState getServiceState() {
         return mSS;
     }
 
+    @UnsupportedAppUsage
     @VisibleForTesting
     public void setServiceState(int state) {
         boolean isVoiceRegStateChanged = false;
@@ -396,18 +408,21 @@
         mCT.explicitCallTransfer();
     }
 
+    @UnsupportedAppUsage
     @Override
     public ImsPhoneCall
     getForegroundCall() {
         return mCT.mForegroundCall;
     }
 
+    @UnsupportedAppUsage
     @Override
     public ImsPhoneCall
     getBackgroundCall() {
         return mCT.mBackgroundCall;
     }
 
+    @UnsupportedAppUsage
     @Override
     public ImsPhoneCall
     getRingingCall() {
@@ -601,6 +616,7 @@
         mSsnRegistrants.notifyRegistrants(ar);
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean handleInCallMmiCommands(String dialString) {
         if (!isInCall()) {
@@ -665,6 +681,7 @@
         mDefaultPhone.notifyNewRingingConnectionP(c);
     }
 
+    @UnsupportedAppUsage
     void notifyUnknownConnection(Connection c) {
         mDefaultPhone.notifyUnknownConnectionP(c);
     }
@@ -803,11 +820,13 @@
         return mCT.getMute();
     }
 
+    @UnsupportedAppUsage
     @Override
     public PhoneConstants.State getState() {
         return mCT.getState();
     }
 
+    @UnsupportedAppUsage
     private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) {
         switch (commandInterfaceCFReason) {
         case CF_REASON_UNCONDITIONAL:
@@ -822,6 +841,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private boolean isValidCommandInterfaceCFAction (int commandInterfaceCFAction) {
         switch (commandInterfaceCFAction) {
         case CF_ACTION_DISABLE:
@@ -834,10 +854,12 @@
         }
     }
 
+    @UnsupportedAppUsage
     private  boolean isCfEnable(int action) {
         return (action == CF_ACTION_ENABLE) || (action == CF_ACTION_REGISTRATION);
     }
 
+    @UnsupportedAppUsage
     private int getConditionFromCFReason(int reason) {
         switch(reason) {
             case CF_REASON_UNCONDITIONAL: return ImsUtInterface.CDIV_CF_UNCONDITIONAL;
@@ -868,6 +890,7 @@
         return CF_REASON_NOT_REACHABLE;
     }
 
+    @UnsupportedAppUsage
     private int getActionFromCFAction(int action) {
         switch(action) {
             case CF_ACTION_DISABLE: return ImsUtInterface.ACTION_DEACTIVATION;
@@ -911,6 +934,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public void getCallForwardingOption(int commandInterfaceCFReason,
             Message onComplete) {
@@ -941,6 +965,7 @@
                 CommandsInterface.SERVICE_CLASS_VOICE, timerSeconds, onComplete);
     }
 
+    @UnsupportedAppUsage
     public void setCallForwardingOption(int commandInterfaceCFAction,
             int commandInterfaceCFReason,
             String dialingNumber,
@@ -975,6 +1000,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public void getCallWaiting(Message onComplete) {
         if (DBG) logd("getCallWaiting");
@@ -989,6 +1015,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public void setCallWaiting(boolean enable, Message onComplete) {
         setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
@@ -1105,6 +1132,7 @@
         mCT.cancelUSSD();
     }
 
+    @UnsupportedAppUsage
     private void sendErrorResponse(Message onComplete) {
         logd("sendErrorResponse");
         if (onComplete != null) {
@@ -1114,6 +1142,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @VisibleForTesting
     public void sendErrorResponse(Message onComplete, Throwable e) {
         logd("sendErrorResponse");
@@ -1226,6 +1255,7 @@
      * registrants that it is complete.
      * @param mmi MMI that is done
      */
+    @UnsupportedAppUsage
     public void onMMIDone(ImsPhoneMmiCode mmi) {
         /* Only notify complete if it's on the pending list.
          * Otherwise, it's already been handled (eg, previously canceled).
@@ -1543,6 +1573,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void handleEnterEmergencyCallbackMode() {
         if (DBG) logd("handleEnterEmergencyCallbackMode,mIsPhoneInEcmState= " + isInEcm());
         // if phone is not in Ecm mode, and it's changed to Ecm mode
@@ -1561,6 +1592,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     protected void handleExitEmergencyCallbackMode() {
         if (DBG) logd("handleExitEmergencyCallbackMode: mIsPhoneInEcmState = " + isInEcm());
@@ -1608,6 +1640,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public void setOnEcbModeExitResponse(Handler h, int what, Object obj) {
         mEcmExitRespRegistrant = new Registrant(h, what, obj);
@@ -1627,6 +1660,7 @@
         return mCT.isImsCapabilityAvailable(capability, regTech);
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean isVolteEnabled() {
         return mCT.isVolteEnabled();
@@ -1657,6 +1691,7 @@
         return mImsRegistered;
     }
 
+    @UnsupportedAppUsage
     public void setImsRegistered(boolean value) {
         mImsRegistered = value;
     }
@@ -1821,6 +1856,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean isUtEnabled() {
         return mCT.isUtEnabled();
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
index f0d38a8..5e670f4 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
@@ -135,8 +135,8 @@
         mTtyModeReceivedRegistrants.notifyRegistrants(result);
     }
 
-    public void onCallQualityChanged(CallQuality callQuality) {
-        mNotifier.notifyCallQualityChanged(this, callQuality);
+    public void onCallQualityChanged(CallQuality callQuality, int callNetworkType) {
+        mNotifier.notifyCallQualityChanged(this, callQuality, callNetworkType);
     }
 
     @Override
@@ -184,11 +184,6 @@
     }
 
     @Override
-    public PhoneConstants.DataState getDataConnectionState(String apnType) {
-        return PhoneConstants.DataState.DISCONNECTED;
-    }
-
-    @Override
     public DataActivityState getDataActivityState() {
         return DataActivityState.NONE;
     }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
index cb5917d..f45bdfe 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.imsphone;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telecom.ConferenceParticipant;
 import android.telephony.Rlog;
 import android.telephony.DisconnectCause;
@@ -53,7 +54,7 @@
 
     /*package*/ ImsPhoneCallTracker mOwner;
 
-    private boolean mRingbackTonePlayed = false;
+    private boolean mIsRingbackTonePlaying = false;
 
     // Determines what type of ImsPhoneCall this is.  ImsPhoneCallTracker uses instances of
     // ImsPhoneCall to for fg, bg, etc calls.  This is used as a convenience for logging so that it
@@ -87,6 +88,7 @@
 
     /************************** Overridden from Call *************************/
 
+    @UnsupportedAppUsage
     @Override
     public List<Connection>
     getConnections() {
@@ -96,7 +98,7 @@
     @Override
     public Phone
     getPhone() {
-        return mOwner.mPhone;
+        return mOwner.getPhone();
     }
 
     @Override
@@ -113,6 +115,7 @@
     /** Please note: if this is the foreground call and a
      *  background call exists, the background call will be resumed.
      */
+    @UnsupportedAppUsage
     @Override
     public void
     hangup() throws CallStateException {
@@ -160,6 +163,7 @@
         mOwner.logState();
     }
 
+    @UnsupportedAppUsage
     public void attach(Connection conn, State state) {
         if (VDBG) {
             Rlog.v(LOG_TAG, "attach : " + mCallContext + " state = " +
@@ -169,6 +173,7 @@
         mState = state;
     }
 
+    @UnsupportedAppUsage
     public void attachFake(Connection conn, State state) {
         attach(conn, state);
     }
@@ -225,6 +230,7 @@
     /**
      * Called when this Call is being hung up locally (eg, user pressed "end")
      */
+    @UnsupportedAppUsage
     void
     onHangupLocal() {
         for (int i = 0, s = mConnections.size(); i < s; i++) {
@@ -257,6 +263,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     /* package */ void
     merge(ImsPhoneCall that, State state) {
         // This call is the conference host and the "that" call is the one being merged in.
@@ -314,17 +321,17 @@
         //ImsCall.Listener.onCallProgressing can be invoked several times
         //and ringback tone mode can be changed during the call setup procedure
         if (state == State.ALERTING) {
-            if (mRingbackTonePlayed && !isLocalTone(imsCall)) {
-                mOwner.mPhone.stopRingbackTone();
-                mRingbackTonePlayed = false;
-            } else if (!mRingbackTonePlayed && isLocalTone(imsCall)) {
-                mOwner.mPhone.startRingbackTone();
-                mRingbackTonePlayed = true;
+            if (mIsRingbackTonePlaying && !isLocalTone(imsCall)) {
+                getPhone().stopRingbackTone();
+                mIsRingbackTonePlaying = false;
+            } else if (!mIsRingbackTonePlaying && isLocalTone(imsCall)) {
+                getPhone().startRingbackTone();
+                mIsRingbackTonePlaying = true;
             }
         } else {
-            if (mRingbackTonePlayed) {
-                mOwner.mPhone.stopRingbackTone();
-                mRingbackTonePlayed = false;
+            if (mIsRingbackTonePlaying) {
+                getPhone().stopRingbackTone();
+                mIsRingbackTonePlaying = false;
             }
         }
 
@@ -360,6 +367,16 @@
         mOwner.logState();
     }
 
+    /**
+     * Stops ringback tone playing if it is playing.
+     */
+    public void maybeStopRingback() {
+        if (mIsRingbackTonePlaying) {
+            getPhone().stopRingbackTone();
+            mIsRingbackTonePlaying = false;
+        }
+    }
+
     private void takeOver(ImsPhoneCall that) {
         mConnections = that.mConnections;
         mState = that.mState;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index d284a74..11ae399 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -19,6 +19,7 @@
 import static com.android.internal.telephony.Phone.CS_FALLBACK;
 
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -113,6 +114,7 @@
 import java.util.Map;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Pattern;
@@ -316,15 +318,20 @@
     }
 
     //***** Instance Variables
+    @UnsupportedAppUsage
     private ArrayList<ImsPhoneConnection> mConnections = new ArrayList<ImsPhoneConnection>();
     private RegistrantList mVoiceCallEndedRegistrants = new RegistrantList();
     private RegistrantList mVoiceCallStartedRegistrants = new RegistrantList();
 
+    @UnsupportedAppUsage
     public ImsPhoneCall mRingingCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_RINGING);
+    @UnsupportedAppUsage
     public ImsPhoneCall mForegroundCall = new ImsPhoneCall(this,
             ImsPhoneCall.CONTEXT_FOREGROUND);
+    @UnsupportedAppUsage
     public ImsPhoneCall mBackgroundCall = new ImsPhoneCall(this,
             ImsPhoneCall.CONTEXT_BACKGROUND);
+    @UnsupportedAppUsage
     public ImsPhoneCall mHandoverCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_HANDOVER);
 
     // Hold aggregated video call data usage for each video call since boot.
@@ -350,17 +357,23 @@
 
     private final AtomicInteger mDefaultDialerUid = new AtomicInteger(NetworkStats.UID_ALL);
 
+    @UnsupportedAppUsage
     private ImsPhoneConnection mPendingMO;
     private int mClirMode = CommandsInterface.CLIR_DEFAULT;
+    @UnsupportedAppUsage
     private Object mSyncHold = new Object();
 
     private ImsCall mUssdSession = null;
+    @UnsupportedAppUsage
     private Message mPendingUssd = null;
 
+    @UnsupportedAppUsage
     ImsPhone mPhone;
 
     private boolean mDesiredMute = false;    // false = mute off
+    @UnsupportedAppUsage
     private boolean mOnHoldToneStarted = false;
+    @UnsupportedAppUsage
     private int mOnHoldToneId = -1;
 
     private PhoneConstants.State mState = PhoneConstants.State.IDLE;
@@ -377,8 +390,10 @@
     private int mPendingCallVideoState;
     private Bundle mPendingIntentExtras;
     private boolean pendingCallInEcm = false;
+    @UnsupportedAppUsage
     private boolean mSwitchingFgAndBgCalls = false;
     private ImsCall mCallExpectedToResume = null;
+    @UnsupportedAppUsage
     private boolean mAllowEmergencyVideoCalls = false;
     private boolean mIgnoreDataEnabledChangedForVideoCalls = false;
     private boolean mIsViLteDataMetered = false;
@@ -499,8 +514,12 @@
 
 
     //***** Constructors
-
     public ImsPhoneCallTracker(ImsPhone phone) {
+        this(phone, phone.getContext().getMainExecutor());
+    }
+
+    @VisibleForTesting
+    public ImsPhoneCallTracker(ImsPhone phone, Executor executor) {
         this.mPhone = phone;
 
         mMetrics = TelephonyMetrics.getInstance();
@@ -523,6 +542,7 @@
         mVtDataUsageSnapshot = new NetworkStats(currentTime, 1);
         mVtDataUsageUidSnapshot = new NetworkStats(currentTime, 1);
 
+        // Allow the executor to be specified for testing.
         mImsManagerConnector = new ImsManager.Connector(phone.getContext(), phone.getPhoneId(),
                 new ImsManager.Connector.Listener() {
                     @Override
@@ -535,7 +555,7 @@
                     public void connectionUnavailable() {
                         stopListeningForCalls();
                     }
-                });
+                }, executor);
         mImsManagerConnector.connect();
     }
 
@@ -694,6 +714,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public Connection dial(String dialString, int videoState, Bundle intentExtras) throws
             CallStateException {
         ImsPhone.ImsDialArgs dialArgs =  new ImsPhone.ImsDialArgs.Builder()
@@ -791,6 +812,12 @@
             mPendingMO = new ImsPhoneConnection(mPhone,
                     checkForTestEmergencyNumber(dialString), this, mForegroundCall,
                     isEmergencyNumber);
+            if (isEmergencyNumber && dialArgs != null && dialArgs.intentExtras != null) {
+                Rlog.i(LOG_TAG, "dial ims emergency dialer: " + dialArgs.intentExtras.getBoolean(
+                        TelecomManager.EXTRA_IS_USER_INTENT_EMERGENCY_CALL));
+                mPendingMO.setHasKnownUserIntentEmergency(dialArgs.intentExtras.getBoolean(
+                        TelecomManager.EXTRA_IS_USER_INTENT_EMERGENCY_CALL));
+            }
             mPendingMO.setVideoState(videoState);
             if (dialArgs.rttTextStream != null) {
                 log("dial: setting RTT stream on mPendingMO");
@@ -961,6 +988,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void handleEcmTimer(int action) {
         mPhone.handleTimerInEmergencyCallbackMode(action);
         switch (action) {
@@ -1134,10 +1162,11 @@
     private void setEmergencyCallInfo(ImsCallProfile profile, Connection conn) {
         EmergencyNumber num = conn.getEmergencyNumberInfo();
         if (num != null) {
-            profile.setEmergencyCallInfo(num);
+            profile.setEmergencyCallInfo(num, conn.hasKnownUserIntentEmergency());
         }
     }
 
+    @UnsupportedAppUsage
     private void switchAfterConferenceSuccess() {
         if (DBG) log("switchAfterConferenceSuccess fg =" + mForegroundCall.getState() +
                 ", bg = " + mBackgroundCall.getState());
@@ -1411,6 +1440,7 @@
         //TODO : implement
     }
 
+    @UnsupportedAppUsage
     public void
     clearDisconnected() {
         if (DBG) log("clearDisconnected");
@@ -1471,6 +1501,7 @@
         mHandoverCall.clearDisconnected();
     }
 
+    @UnsupportedAppUsage
     private void
     updatePhoneState() {
         PhoneConstants.State oldState = mState;
@@ -1769,6 +1800,7 @@
         return null;
     }
 
+    @UnsupportedAppUsage
     private synchronized void removeConnection(ImsPhoneConnection conn) {
         mConnections.remove(conn);
         // If not emergency call is remaining, notify emergency call registrants
@@ -1789,6 +1821,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private synchronized void addConnection(ImsPhoneConnection conn) {
         mConnections.add(conn);
         if (conn.isEmergency()) {
@@ -2092,6 +2125,7 @@
      * Before dialing pending MO request, check for the Emergency Callback mode.
      * If device is in Emergency callback mode, then exit the mode before dialing pending MO.
      */
+    @UnsupportedAppUsage
     private void dialPendingMO() {
         boolean isPhoneInEcmMode = isPhoneInEcbMode();
         boolean isEmergencyNumber = mPendingMO.isEmergency();
@@ -2350,8 +2384,7 @@
                         || mPendingMO.getDisconnectCause() != DisconnectCause.NOT_DISCONNECTED) {
                     mHoldSwitchingState = HoldSwapState.INACTIVE;
                     logHoldSwapState("onCallTerminated hold to dial but no pendingMo");
-                }
-                if (imsCall != mPendingMO.getImsCall()) {
+                } else if (imsCall != mPendingMO.getImsCall()) {
                     sendEmptyMessage(EVENT_DIAL_PENDINGMO);
                     mHoldSwitchingState = HoldSwapState.INACTIVE;
                     logHoldSwapState("onCallTerminated hold to dial, dial pendingMo");
@@ -2436,6 +2469,9 @@
                     // disconnected while processing hold
                     if (mPendingMO != null) {
                         dialPendingMO();
+                    } else if (mRingingCall.getState() == ImsPhoneCall.State.WAITING
+                            && mHoldSwitchingState == HoldSwapState.HOLDING_TO_ANSWER_INCOMING) {
+                        sendEmptyMessage(EVENT_ANSWER_WAITING_CALL);
                     }
                     mHoldSwitchingState = HoldSwapState.INACTIVE;
                 } else if (mPendingMO != null && mPendingMO.isEmergency()) {
@@ -2447,6 +2483,13 @@
                     }
                     // Leave mHoldSwitchingState as is for now -- we'll reset it
                     // in onCallTerminated, which will also dial the outgoing emergency call.
+                } else if (mRingingCall.getState() == ImsPhoneCall.State.WAITING
+                        && mHoldSwitchingState == HoldSwapState.HOLDING_TO_ANSWER_INCOMING) {
+                    // If we issued a hold request in order to answer an incoming call, we need
+                    // to tell Telecom that we can't actually answer the incoming call.
+                    mHoldSwitchingState = HoldSwapState.INACTIVE;
+                    mForegroundCall.switchWith(mBackgroundCall);
+                    logHoldSwapState("onCallHoldFailed unable to answer waiting call");
                 } else if (bgState == ImsPhoneCall.State.ACTIVE) {
                     mForegroundCall.switchWith(mBackgroundCall);
 
@@ -2459,6 +2502,10 @@
                     }
                     mHoldSwitchingState = HoldSwapState.INACTIVE;
                 }
+                ImsPhoneConnection conn = findConnection(imsCall);
+                if (conn != null) {
+                    conn.onConnectionEvent(android.telecom.Connection.EVENT_CALL_HOLD_FAILED, null);
+                }
                 mPhone.notifySuppServiceFailed(Phone.SuppService.HOLD);
             }
             mMetrics.writeOnImsCallHoldFailed(mPhone.getPhoneId(), imsCall.getCallSession(),
@@ -2714,6 +2761,12 @@
 
             ImsPhoneConnection conn = findConnection(imsCall);
             if (conn != null) {
+                ImsPhoneCall imsPhoneCall = conn.getCall();
+                if (imsPhoneCall != null) {
+                    // We might be playing ringback on the handover connection; we should stop
+                    // playing it at this point (otherwise it could play indefinitely).
+                    imsPhoneCall.maybeStopRingback();
+                }
                 if (conn.getDisconnectCause() == DisconnectCause.NOT_DISCONNECTED) {
                     if (isHandoverToWifi) {
                         removeMessages(EVENT_CHECK_FOR_WIFI_HANDOVER);
@@ -2869,7 +2922,7 @@
          */
         @Override
         public void onCallQualityChanged(ImsCall imsCall, CallQuality callQuality) {
-            mPhone.onCallQualityChanged(callQuality);
+            mPhone.onCallQualityChanged(callQuality, imsCall.getRadioTechnology());
         }
     };
 
@@ -2962,7 +3015,7 @@
                 }
 
                 @Override
-                public void onDeregistered(ImsReasonInfo imsReasonInfo) {
+                public void onUnregistered(ImsReasonInfo imsReasonInfo) {
                     if (DBG) log("onImsDisconnected imsReasonInfo=" + imsReasonInfo);
                     mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
                     mPhone.setImsRegistered(false);
@@ -3054,6 +3107,7 @@
         mPhone.notifyImsReason(reasonInfo);
     }
 
+    @UnsupportedAppUsage
     public ImsUtInterface getUtInterface() throws ImsException {
         if (mImsManager == null) {
             throw getImsManagerIsNullException();
@@ -3246,6 +3300,7 @@
                 ImsPhoneConnection oldConnection = findConnection(callInfo.first);
                 if (oldConnection == null) {
                     sendCallStartFailedDisconnect(callInfo.first, callInfo.second);
+                    break;
                 }
                 mForegroundCall.detach(oldConnection);
                 removeConnection(oldConnection);
@@ -3325,11 +3380,13 @@
         mVtDataUsageUidSnapshot = vtDataUsageUidSnapshot;
     }
 
+    @UnsupportedAppUsage
     @Override
     protected void log(String msg) {
         Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + msg);
     }
 
+    @UnsupportedAppUsage
     protected void loge(String msg) {
         Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + msg);
     }
@@ -4066,4 +4123,8 @@
     public void setAlwaysPlayRemoteHoldTone(boolean shouldPlayRemoteHoldTone) {
         mAlwaysPlayRemoteHoldTone = shouldPlayRemoteHoldTone;
     }
+
+    public ImsPhone getPhone() {
+        return mPhone;
+    }
 }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
index 5cf3f7c..5ebd904 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
@@ -104,12 +104,13 @@
 
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-                     int clirMode, Message result) {
+                     boolean hasKnownUserIntentEmergency, int clirMode, Message result) {
     }
 
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-                     int clirMode, UUSInfo uusInfo, Message result) {
+                     boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
+                     Message result) {
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index 8dc9143..69682ee 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.imsphone;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.net.Uri;
 import android.os.AsyncResult;
@@ -61,12 +62,15 @@
 
     //***** Instance Variables
 
+    @UnsupportedAppUsage
     private ImsPhoneCallTracker mOwner;
+    @UnsupportedAppUsage
     private ImsPhoneCall mParent;
     private ImsCall mImsCall;
     private Bundle mExtras = new Bundle();
     private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
 
+    @UnsupportedAppUsage
     private boolean mDisconnected;
 
     /*
@@ -242,6 +246,9 @@
         parent.attachFake(this, ImsPhoneCall.State.DIALING);
 
         mIsEmergency = isEmergency;
+        if (isEmergency) {
+            setEmergencyCallInfo();
+        }
 
         fetchDtmfToneDelay(phone);
 
@@ -305,6 +312,7 @@
         return mDialString;
     }
 
+    @UnsupportedAppUsage
     @Override
     public ImsPhoneCall getCall() {
         return mParent;
@@ -339,6 +347,7 @@
       return null;
     }
 
+    @UnsupportedAppUsage
     public ImsPhoneCallTracker getOwner () {
         return mOwner;
     }
@@ -444,6 +453,7 @@
         return onDisconnect();
     }
 
+    @UnsupportedAppUsage
     public boolean onDisconnect() {
         boolean changed = false;
 
@@ -618,12 +628,14 @@
         notifyPostDialListeners();
     }
 
+    @UnsupportedAppUsage
     private void
     createWakeLock(Context context) {
         PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
     }
 
+    @UnsupportedAppUsage
     private void
     acquireWakeLock() {
         Rlog.d(LOG_TAG, "acquireWakeLock");
@@ -666,6 +678,7 @@
         return null;
     }
 
+    @UnsupportedAppUsage
     @Override
     public synchronized boolean isMultiparty() {
         return mImsCall != null && mImsCall.isMultiparty();
@@ -1055,7 +1068,7 @@
     public void onRttAudioIndicatorChanged(ImsStreamMediaProfile profile) {
         Bundle extras = new Bundle();
         extras.putBoolean(android.telecom.Connection.EXTRA_IS_RTT_AUDIO_PRESENT,
-                profile.getRttAudioSpeech());
+                profile.isReceivingRttAudio());
         onConnectionEvent(android.telecom.Connection.EVENT_RTT_AUDIO_INDICATION_CHANGED,
                 extras);
     }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
index 72f3a38..dcc6ca55 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
@@ -29,6 +29,7 @@
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_SMS;
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.AsyncResult;
@@ -38,6 +39,7 @@
 import android.os.ResultReceiver;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.Rlog;
+import android.telephony.ims.ImsCallForwardInfo;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsSsData;
 import android.telephony.ims.ImsSsInfo;
@@ -54,6 +56,7 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.uicc.IccRecords;
 
+import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -158,7 +161,9 @@
 
     //***** Instance Variables
 
+    @UnsupportedAppUsage
     private ImsPhone mPhone;
+    @UnsupportedAppUsage
     private Context mContext;
     private IccRecords mIccRecords;
 
@@ -228,6 +233,7 @@
      * Please see flow chart in TS 22.030 6.5.3.2
      */
 
+    @UnsupportedAppUsage
     static ImsPhoneMmiCode newFromDialString(String dialString, ImsPhone phone) {
        return newFromDialString(dialString, phone, null);
     }
@@ -365,6 +371,7 @@
     }
 
     /** returns true of the string is empty or null */
+    @UnsupportedAppUsage
     private static boolean
     isEmptyOrNull(CharSequence s) {
         return s == null || (s.length() == 0);
@@ -542,6 +549,7 @@
 
     //***** Instance Methods
 
+    @UnsupportedAppUsage
     String getDialingNumber() {
         return mDialingNumber;
     }
@@ -657,6 +665,7 @@
      *  In temporary mode, to invoke CLIR for a single call enter:
      *       " # 31 # [called number] SEND "
      */
+    @UnsupportedAppUsage
     boolean
     isTemporaryModeCLIR() {
         return mSc != null && mSc.equals(SC_CLIR) && mDialingNumber != null
@@ -667,6 +676,7 @@
      * returns CommandsInterface.CLIR_*
      * See also isTemporaryModeCLIR()
      */
+    @UnsupportedAppUsage
     int
     getCLIRMode() {
         if (mSc != null && mSc.equals(SC_CLIR)) {
@@ -680,10 +690,12 @@
         return CommandsInterface.CLIR_DEFAULT;
     }
 
+    @UnsupportedAppUsage
     boolean isActivate() {
         return mAction != null && mAction.equals(ACTION_ACTIVATE);
     }
 
+    @UnsupportedAppUsage
     boolean isDeactivate() {
         return mAction != null && mAction.equals(ACTION_DEACTIVATE);
     }
@@ -692,10 +704,12 @@
         return mAction != null && mAction.equals(ACTION_INTERROGATE);
     }
 
+    @UnsupportedAppUsage
     boolean isRegister() {
         return mAction != null && mAction.equals(ACTION_REGISTER);
     }
 
+    @UnsupportedAppUsage
     boolean isErasure() {
         return mAction != null && mAction.equals(ACTION_ERASURE);
     }
@@ -713,6 +727,7 @@
         return mIsUssdRequest;
     }
 
+    @UnsupportedAppUsage
     boolean
     isSupportedOverImsPhone() {
         if (isShortCode()) return true;
@@ -772,6 +787,7 @@
     }
 
     /** Process a MMI code or short code...anything that isn't a dialing number */
+    @UnsupportedAppUsage
     public void
     processCode () throws CallStateException {
         try {
@@ -1178,6 +1194,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private CharSequence getErrorMessage(AsyncResult ar) {
         CharSequence errorMessage;
         return ((errorMessage = getMmiErrorMessage(ar)) != null) ? errorMessage :
@@ -1217,6 +1234,7 @@
         return null;
     }
 
+    @UnsupportedAppUsage
     private CharSequence getScString() {
         if (mSc != null) {
             if (isServiceCodeCallBarring(mSc)) {
@@ -1315,6 +1333,7 @@
      *        Returns null if unrecognized
      */
 
+    @UnsupportedAppUsage
     private CharSequence
     serviceClassToCFString (int serviceClass) {
         switch (serviceClass) {
@@ -1531,15 +1550,17 @@
                 sb.append(getErrorMessage(ar));
             }
         } else {
-            ImsSsInfo[] infos = (ImsSsInfo[])ar.result;
-            if (infos.length == 0) {
+            List<ImsSsInfo> infos = (List<ImsSsInfo>) ar.result;
+            if (infos.size() == 0) {
                 sb.append(mContext.getText(com.android.internal.R.string.serviceDisabled));
             } else {
-                for (int i = 0, s = infos.length; i < s ; i++) {
-                    if (infos[i].getIncomingCommunicationBarringNumber() != null) {
-                        sb.append("Num: " + infos[i].getIncomingCommunicationBarringNumber()
-                                + " status: " + infos[i].getStatus() + "\n");
-                    } else if (infos[i].getStatus() == 1) {
+                ImsSsInfo info;
+                for (int i = 0, s = infos.size(); i < s; i++) {
+                    info = infos.get(i);
+                    if (info.getIncomingCommunicationBarringNumber() != null) {
+                        sb.append("Num: " + info.getIncomingCommunicationBarringNumber()
+                                + " status: " + info.getStatus() + "\n");
+                    } else if (info.getStatus() == 1) {
                         sb.append(mContext.getText(com.android.internal
                                 .R.string.serviceEnabled));
                     } else {
@@ -1772,8 +1793,16 @@
                     onQueryClirComplete(new AsyncResult(null, clirInfo, ex));
                 } else if (ssData.isTypeCF()) {
                     Rlog.d(LOG_TAG, "CALL FORWARD INTERROGATION");
-                    onQueryCfComplete(new AsyncResult(null, mPhone
-                            .handleCfQueryResult(ssData.getCallForwardInfo()), ex));
+                    // Have to translate to an array, since the modem still returns it in the
+                    // ImsCallForwardInfo[] format.
+                    List<ImsCallForwardInfo> mCfInfos = ssData.getCallForwardInfo();
+                    ImsCallForwardInfo[] mCfInfosCompat = null;
+                    if (mCfInfos != null) {
+                        mCfInfosCompat = new ImsCallForwardInfo[mCfInfos.size()];
+                        mCfInfosCompat = mCfInfos.toArray(mCfInfosCompat);
+                    }
+                    onQueryCfComplete(new AsyncResult(null, mPhone.handleCfQueryResult(
+                            mCfInfosCompat), ex));
                 } else if (ssData.isTypeBarring()) {
                     onSuppSvcQueryComplete(new AsyncResult(null, ssData.getSuppServiceInfoCompat(),
                             ex));
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyEventBuilder.java b/src/java/com/android/internal/telephony/metrics/TelephonyEventBuilder.java
index 56db4ba..8a97579 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyEventBuilder.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyEventBuilder.java
@@ -19,6 +19,7 @@
 import static com.android.internal.telephony.nano.TelephonyProto.ImsCapabilities;
 import static com.android.internal.telephony.nano.TelephonyProto.ImsConnectionState;
 import static com.android.internal.telephony.nano.TelephonyProto.RilDataCall;
+import static com.android.internal.telephony.nano.TelephonyProto.SimState;
 import static com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent;
 import static com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.CarrierIdMatching;
 import static com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.CarrierKeyChange;
@@ -30,10 +31,16 @@
 import static com.android.internal.telephony.nano.TelephonyProto.TelephonySettings;
 
 import android.os.SystemClock;
+import android.telephony.TelephonyManager;
+import android.util.SparseArray;
 
-import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.PhoneStatus;
+import com.android.internal.telephony.nano.TelephonyProto.ActiveSubscriptionInfo;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.DataSwitch;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.Type;
 
+import java.util.Arrays;
+
 public class TelephonyEventBuilder {
     private final TelephonyEvent mEvent = new TelephonyEvent();
 
@@ -41,6 +48,11 @@
         return mEvent;
     }
 
+    /** The event is not related to any phone id. */
+    public TelephonyEventBuilder() {
+        this(-1 /* phoneId */);
+    }
+
     public TelephonyEventBuilder(int phoneId) {
         this(SystemClock.elapsedRealtime(), phoneId);
     }
@@ -137,12 +149,53 @@
         return this;
     }
 
-    /**
-     * Set and build phone status changed event.
-     */
-    public TelephonyEventBuilder setPhoneStatusChange(PhoneStatus phoneStatus) {
-        mEvent.type = Type.PHONE_STATUS_CHANGED;
-        mEvent.phoneStatus = phoneStatus;
+    /** Set and build SIM state change event. */
+    public TelephonyEventBuilder setSimStateChange(SparseArray<Integer> simStates) {
+        int phoneCount = TelephonyManager.getDefault().getPhoneCount();
+        mEvent.simState = new int[phoneCount];
+        Arrays.fill(mEvent.simState, SimState.SIM_STATE_UNKNOWN);
+        mEvent.type = Type.SIM_STATE_CHANGED;
+        for (int i = 0; i < simStates.size(); i++) {
+            int key = simStates.keyAt(i);
+            if (0 <= key && key < phoneCount) {
+                mEvent.simState[key] = simStates.get(key);
+            }
+        }
+        return this;
+    }
+
+    /** Set and build subscription info change event. */
+    public TelephonyEventBuilder setActiveSubscriptionInfoChange(ActiveSubscriptionInfo info) {
+        mEvent.type = Type.ACTIVE_SUBSCRIPTION_INFO_CHANGED;
+        mEvent.activeSubscriptionInfo = info;
+        return this;
+    }
+
+    /** Set and build enabled modem bitmap change event. */
+    public TelephonyEventBuilder setEnabledModemBitmap(int enabledModemBitmap) {
+        mEvent.type = Type.ENABLED_MODEM_CHANGED;
+        mEvent.enabledModemBitmap = enabledModemBitmap;
+        return this;
+    }
+
+    /** Set and build data switch event. */
+    public TelephonyEventBuilder setDataSwitch(DataSwitch dataSwitch) {
+        mEvent.type = TelephonyEvent.Type.DATA_SWITCH;
+        mEvent.dataSwitch = dataSwitch;
+        return this;
+    }
+
+    /** Set and build network validation event. */
+    public TelephonyEventBuilder setNetworkValidate(int networkValidationState) {
+        mEvent.type = TelephonyEvent.Type.NETWORK_VALIDATE;
+        mEvent.networkValidationState = networkValidationState;
+        return this;
+    }
+
+    /** Set and build on demand data switch event. */
+    public TelephonyEventBuilder setOnDemandDataSwitch(OnDemandDataSwitch onDemandDataSwitch) {
+        mEvent.type = TelephonyEvent.Type.ON_DEMAND_DATA_SWITCH;
+        mEvent.onDemandDataSwitch = onDemandDataSwitch;
         return this;
     }
 }
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
index fa7f18c..c4d2d2e 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
@@ -86,8 +86,9 @@
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.CarrierIdMatching;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.CarrierIdMatchingResult;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.CarrierKeyChange;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.DataSwitch;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.ModemRestart;
-import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.PhoneStatus;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.RilDeactivateDataCall;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.RilDeactivateDataCall.DeactivateReason;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.RilSetupDataCall;
@@ -97,6 +98,7 @@
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyServiceState;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonySettings;
 import com.android.internal.telephony.nano.TelephonyProto.TimeInterval;
+import com.android.internal.telephony.protobuf.nano.MessageNano;
 import com.android.internal.util.IndentingPrintWriter;
 
 import java.io.FileDescriptor;
@@ -197,6 +199,12 @@
      */
     private final SparseArray<CarrierIdMatching> mLastCarrierId = new SparseArray<>();
 
+    /**
+     * Last RilDataCall Events (indexed by cid), indexed by phone id
+     */
+    private final SparseArray<SparseArray<RilDataCall>> mLastRilDataCallEvents =
+            new SparseArray<>();
+
     /** The start system time of the TelephonyLog in milliseconds*/
     private long mStartSystemTimeMs;
 
@@ -598,7 +606,28 @@
             addTelephonyEvent(event);
         }
 
-        writePhoneStatusChangedEvent();
+        for (int i = 0; i < mLastActiveSubscriptionInfos.size(); i++) {
+            final int key = mLastActiveSubscriptionInfos.keyAt(i);
+            TelephonyEvent event = new TelephonyEventBuilder(mStartElapsedTimeMs, key)
+                    .setActiveSubscriptionInfoChange(mLastActiveSubscriptionInfos.get(key)).build();
+            addTelephonyEvent(event);
+        }
+
+        for (int i = 0; i < mLastRilDataCallEvents.size(); i++) {
+            final int key = mLastRilDataCallEvents.keyAt(i);
+            for (int j = 0; j < mLastRilDataCallEvents.get(key).size(); j++) {
+                final int cidKey = mLastRilDataCallEvents.get(key).keyAt(j);
+                RilDataCall[] dataCalls = new RilDataCall[1];
+                dataCalls[0] = mLastRilDataCallEvents.get(key).get(cidKey);
+                addTelephonyEvent(new TelephonyEventBuilder(mStartElapsedTimeMs, key)
+                        .setDataCalls(dataCalls).build());
+            }
+        }
+        addTelephonyEvent(new TelephonyEventBuilder(mStartElapsedTimeMs, -1 /* phoneId */)
+                .setSimStateChange(mLastSimState).build());
+
+        addTelephonyEvent(new TelephonyEventBuilder(mStartElapsedTimeMs, -1 /* phoneId */)
+                .setEnabledModemBitmap(mLastEnabledModemBitmap).build());
     }
 
     /**
@@ -655,6 +684,22 @@
         log.endTime = new TelephonyProto.Time();
         log.endTime.systemTimestampMillis = System.currentTimeMillis();
         log.endTime.elapsedTimestampMillis = SystemClock.elapsedRealtime();
+
+        // Log the last active subscription information.
+        int phoneCount = TelephonyManager.getDefault().getPhoneCount();
+        ActiveSubscriptionInfo[] activeSubscriptionInfo =
+                new ActiveSubscriptionInfo[phoneCount];
+        for (int i = 0; i < mLastActiveSubscriptionInfos.size(); i++) {
+            int key = mLastActiveSubscriptionInfos.keyAt(i);
+            activeSubscriptionInfo[key] = mLastActiveSubscriptionInfos.get(key);
+        }
+        for (int i = 0; i < phoneCount; i++) {
+            if (activeSubscriptionInfo[i] == null) {
+                activeSubscriptionInfo[i] = makeInvalidSubscriptionInfo(i);
+            }
+        }
+        log.lastActiveSubscriptionInfo = activeSubscriptionInfo;
+
         return log;
     }
 
@@ -664,19 +709,37 @@
         Integer lastSimState = mLastSimState.get(phoneId);
         if (lastSimState == null || !lastSimState.equals(state)) {
             mLastSimState.put(phoneId, state);
-            writePhoneStatusChangedEvent();
+            addTelephonyEvent(new TelephonyEventBuilder().setSimStateChange(mLastSimState).build());
         }
     }
 
     /** Update active subscription info list. */
     public void updateActiveSubscriptionInfoList(List<SubscriptionInfo> subInfos) {
-        mLastActiveSubscriptionInfos.clear();
+        List<Integer> inActivePhoneList = new ArrayList<>();
+        for (int i = 0; i < mLastActiveSubscriptionInfos.size(); i++) {
+            inActivePhoneList.add(mLastActiveSubscriptionInfos.keyAt(i));
+        }
+
         for (SubscriptionInfo info : subInfos) {
             int phoneId = SubscriptionManager.getPhoneId(info.getSubscriptionId());
+            inActivePhoneList.removeIf(value -> value.equals(phoneId));
             ActiveSubscriptionInfo activeSubscriptionInfo = new ActiveSubscriptionInfo();
-            activeSubscriptionInfo.isOpportunistic = info.isOpportunistic();
+            activeSubscriptionInfo.slotIndex = phoneId;
+            activeSubscriptionInfo.isOpportunistic = info.isOpportunistic() ? 1 : 0;
             activeSubscriptionInfo.carrierId = info.getCarrierId();
-            mLastActiveSubscriptionInfos.put(phoneId, activeSubscriptionInfo);
+            if (!MessageNano.messageNanoEquals(
+                    mLastActiveSubscriptionInfos.get(phoneId), activeSubscriptionInfo)) {
+                addTelephonyEvent(new TelephonyEventBuilder(phoneId)
+                        .setActiveSubscriptionInfoChange(activeSubscriptionInfo).build());
+
+                mLastActiveSubscriptionInfos.put(phoneId, activeSubscriptionInfo);
+            }
+        }
+
+        for (int phoneId : inActivePhoneList) {
+            mLastActiveSubscriptionInfos.remove(phoneId);
+            addTelephonyEvent(new TelephonyEventBuilder(phoneId)
+                    .setActiveSubscriptionInfoChange(makeInvalidSubscriptionInfo(phoneId)).build());
         }
     }
 
@@ -684,28 +747,16 @@
     public void updateEnabledModemBitmap(int enabledModemBitmap) {
         if (mLastEnabledModemBitmap == enabledModemBitmap) return;
         mLastEnabledModemBitmap = enabledModemBitmap;
-        writePhoneStatusChangedEvent();
+        addTelephonyEvent(new TelephonyEventBuilder()
+                .setEnabledModemBitmap(mLastEnabledModemBitmap).build());
     }
 
-    /** Write the event of phone status changed. */
-    public void writePhoneStatusChangedEvent() {
-        int phoneCount = TelephonyManager.getDefault().getPhoneCount();
-        PhoneStatus phoneStatus = new PhoneStatus();
-        phoneStatus.enabledModemBitmap = mLastEnabledModemBitmap;
-        phoneStatus.simState = new int[phoneCount];
-        Arrays.fill(phoneStatus.simState, SimState.SIM_STATE_ABSENT);
-        for (int i = 0; i < mLastSimState.size(); i++) {
-            int phoneId = mLastSimState.keyAt(i);
-            if (SubscriptionManager.isValidPhoneId(phoneId)) {
-                phoneStatus.simState[phoneId] = mLastSimState.get(phoneId);
-            }
-        }
-
-        // Phone status is not associated with any phone id, so set the phone id to -1 for the phone
-        // status changed event.
-        addTelephonyEvent(new TelephonyEventBuilder(-1 /* phoneId */)
-                .setPhoneStatusChange(phoneStatus)
-                .build());
+    private static ActiveSubscriptionInfo makeInvalidSubscriptionInfo(int phoneId) {
+        ActiveSubscriptionInfo invalidSubscriptionInfo = new ActiveSubscriptionInfo();
+        invalidSubscriptionInfo.slotIndex = phoneId;
+        invalidSubscriptionInfo.carrierId = -1;
+        invalidSubscriptionInfo.isOpportunistic = -1;
+        return invalidSubscriptionInfo;
     }
 
     /**
@@ -1308,25 +1359,36 @@
     }
 
     /**
-     * Write get data call list event
-     *
-     * @param phoneId Phone id
-     * @param dcsList Data call list
+     * Write data call list event when connected
+     * @param phoneId          Phone id
+     * @param cid              Context Id, uniquely identifies the call
+     * @param apnTypeBitmask   Bitmask of supported APN types
+     * @param state            State of the data call event
      */
-    public void writeRilDataCallList(int phoneId, ArrayList<DataCallResponse> dcsList) {
+    public void writeRilDataCallEvent(int phoneId, int cid,
+            int apnTypeBitmask, int state) {
+        RilDataCall[] dataCalls = new RilDataCall[1];
+        dataCalls[0] = new RilDataCall();
+        dataCalls[0].cid = cid;
+        dataCalls[0].apnTypeBitmask = apnTypeBitmask;
+        dataCalls[0].state = state;
 
-        RilDataCall[] dataCalls = new RilDataCall[dcsList.size()];
-
-        for (int i = 0; i < dcsList.size(); i++) {
-            dataCalls[i] = new RilDataCall();
-            dataCalls[i].cid = dcsList.get(i).getCallId();
-            if (!TextUtils.isEmpty(dcsList.get(i).getIfname())) {
-                dataCalls[i].iframe = dcsList.get(i).getIfname();
+        SparseArray<RilDataCall> dataCallList;
+        if (mLastRilDataCallEvents.get(phoneId) != null) {
+            // If the Data call event does not change, do not log it.
+            if (mLastRilDataCallEvents.get(phoneId).get(cid) != null
+                    && Arrays.equals(
+                        RilDataCall.toByteArray(mLastRilDataCallEvents.get(phoneId).get(cid)),
+                        RilDataCall.toByteArray(dataCalls[0]))) {
+                return;
             }
-
-            dataCalls[i].type = dcsList.get(i).getProtocolType() + 1;
+            dataCallList =  mLastRilDataCallEvents.get(phoneId);
+        } else {
+            dataCallList = new SparseArray<>();
         }
 
+        dataCallList.put(cid, dataCalls[0]);
+        mLastRilDataCallEvents.put(phoneId, dataCallList);
         addTelephonyEvent(new TelephonyEventBuilder(phoneId).setDataCalls(dataCalls).build());
     }
 
@@ -1709,6 +1771,32 @@
     }
 
     /**
+     * Write network validation event.
+     * @param networkValidationState the network validation state.
+     */
+    public void writeNetworkValidate(int networkValidationState) {
+        addTelephonyEvent(
+                new TelephonyEventBuilder().setNetworkValidate(networkValidationState).build());
+    }
+
+    /**
+     * Write data switch event.
+     * @param dataSwitch the reason and state of data switch.
+     */
+    public void writeDataSwitch(DataSwitch dataSwitch) {
+        addTelephonyEvent(new TelephonyEventBuilder().setDataSwitch(dataSwitch).build());
+    }
+
+    /**
+     * Write on demand data switch event.
+     * @param onDemandDataSwitch the apn and state of on demand data switch.
+     */
+    public void writeOnDemandDataSwitch(OnDemandDataSwitch onDemandDataSwitch) {
+        addTelephonyEvent(
+                new TelephonyEventBuilder().setOnDemandDataSwitch(onDemandDataSwitch).build());
+    }
+
+    /**
      * Write phone state changed event
      *
      * @param phoneId Phone id
diff --git a/src/java/com/android/internal/telephony/sip/SipCommandInterface.java b/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
index 9ae8981..075b4d6 100644
--- a/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
+++ b/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
@@ -103,12 +103,13 @@
 
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-                     int clirMode, Message result) {
+                     boolean hasKnownUserIntentEmergency, int clirMode, Message result) {
     }
 
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-                     int clirMode, UUSInfo uusInfo, Message result) {
+                     boolean hasKnownUserIntentEmergency, 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 ee89638..a87fb2b 100755
--- a/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -135,11 +135,6 @@
     }
 
     @Override
-    public PhoneConstants.DataState getDataConnectionState(String apnType) {
-        return PhoneConstants.DataState.DISCONNECTED;
-    }
-
-    @Override
     public DataActivityState getDataActivityState() {
         return DataActivityState.NONE;
     }
diff --git a/src/java/com/android/internal/telephony/test/SimulatedCommands.java b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
index 879d70e..5bdf169 100644
--- a/src/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -563,9 +563,9 @@
      */
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-                     int clirMode, Message result) {
+                     boolean hasKnownUserIntentEmergency, int clirMode, Message result) {
         SimulatedCommandsVerifier.getInstance().dial(address, isEmergencyCall,
-                emergencyNumberInfo, clirMode, result);
+                emergencyNumberInfo, hasKnownUserIntentEmergency, clirMode, result);
         simulatedCallState.onDial(address);
 
         resultSuccess(result, null);
@@ -584,9 +584,10 @@
      */
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-                     int clirMode, UUSInfo uusInfo, Message result) {
+                     boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
+                     Message result) {
         SimulatedCommandsVerifier.getInstance().dial(address, isEmergencyCall,
-                emergencyNumberInfo, clirMode, uusInfo, result);
+                emergencyNumberInfo, hasKnownUserIntentEmergency, clirMode, uusInfo, result);
         simulatedCallState.onDial(address);
 
         resultSuccess(result, null);
diff --git a/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java b/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java
index cacf278..722d1e8 100644
--- a/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java
+++ b/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java
@@ -674,12 +674,13 @@
 
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-                     int clirMode, Message result) {
+                     boolean hasKnownUserIntentEmergency, int clirMode, Message result) {
     }
 
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-                     int clirMode, UUSInfo uusInfo, Message result) {
+                     boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
+                     Message result) {
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/uicc/AdnRecord.java b/src/java/com/android/internal/telephony/uicc/AdnRecord.java
index 4414caf..7aa6a11 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnRecord.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnRecord.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.PhoneNumberUtils;
@@ -39,11 +40,17 @@
 
     //***** Instance Variables
 
+    @UnsupportedAppUsage
     String mAlphaTag = null;
+    @UnsupportedAppUsage
     String mNumber = null;
+    @UnsupportedAppUsage
     String[] mEmails;
+    @UnsupportedAppUsage
     int mExtRecord = 0xff;
+    @UnsupportedAppUsage
     int mEfid;                   // or 0 if none
+    @UnsupportedAppUsage
     int mRecordNumber;           // or 0 if none
 
 
@@ -71,6 +78,7 @@
 
     //***** Static Methods
 
+    @UnsupportedAppUsage
     public static final Parcelable.Creator<AdnRecord> CREATOR
             = new Parcelable.Creator<AdnRecord>() {
         @Override
@@ -98,24 +106,29 @@
 
 
     //***** Constructor
+    @UnsupportedAppUsage
     public AdnRecord (byte[] record) {
         this(0, 0, record);
     }
 
+    @UnsupportedAppUsage
     public AdnRecord (int efid, int recordNumber, byte[] record) {
         this.mEfid = efid;
         this.mRecordNumber = recordNumber;
         parseRecord(record);
     }
 
+    @UnsupportedAppUsage
     public AdnRecord (String alphaTag, String number) {
         this(0, 0, alphaTag, number);
     }
 
+    @UnsupportedAppUsage
     public AdnRecord (String alphaTag, String number, String[] emails) {
         this(0, 0, alphaTag, number, emails);
     }
 
+    @UnsupportedAppUsage
     public AdnRecord (int efid, int recordNumber, String alphaTag, String number, String[] emails) {
         this.mEfid = efid;
         this.mRecordNumber = recordNumber;
@@ -124,6 +137,7 @@
         this.mEmails = emails;
     }
 
+    @UnsupportedAppUsage
     public AdnRecord(int efid, int recordNumber, String alphaTag, String number) {
         this.mEfid = efid;
         this.mRecordNumber = recordNumber;
@@ -146,6 +160,7 @@
         return mRecordNumber;
     }
 
+    @UnsupportedAppUsage
     public String getNumber() {
         return mNumber;
     }
@@ -154,10 +169,12 @@
         mNumber = number;
     }
 
+    @UnsupportedAppUsage
     public String[] getEmails() {
         return mEmails;
     }
 
+    @UnsupportedAppUsage
     public void setEmails(String[] emails) {
         this.mEmails = emails;
     }
@@ -168,6 +185,7 @@
                 + Rlog.pii(LOG_TAG, mEmails) + "'";
     }
 
+    @UnsupportedAppUsage
     public boolean isEmpty() {
         return TextUtils.isEmpty(mAlphaTag) && TextUtils.isEmpty(mNumber) && mEmails == null;
     }
@@ -219,6 +237,7 @@
      * @return hex byte[recordSize] to be written to EF record
      *          return null for wrong format of dialing number or tag
      */
+    @UnsupportedAppUsage
     public byte[] buildAdnString(int recordSize) {
         byte[] bcdNumber;
         byte[] byteTag;
diff --git a/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java b/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
index ce3545a..959984b 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
@@ -32,7 +33,9 @@
 public class AdnRecordCache extends Handler implements IccConstants {
     //***** Instance Variables
 
+    @UnsupportedAppUsage
     private IccFileHandler mFh;
+    @UnsupportedAppUsage
     private UsimPhoneBookManager mUsimPhoneBookManager;
 
     // Indexed by EF ID
@@ -40,10 +43,12 @@
         = new SparseArray<ArrayList<AdnRecord>>();
 
     // People waiting for ADN-like files to be loaded
+    @UnsupportedAppUsage
     SparseArray<ArrayList<Message>> mAdnLikeWaiters
         = new SparseArray<ArrayList<Message>>();
 
     // People waiting for adn record to be updated
+    @UnsupportedAppUsage
     SparseArray<Message> mUserWriteResponse = new SparseArray<Message>();
 
     //***** Event Constants
@@ -65,6 +70,7 @@
     /**
      * Called from SIMRecords.onRadioNotAvailable and SIMRecords.handleSimRefresh.
      */
+    @UnsupportedAppUsage
     public void reset() {
         mAdnLikeFiles.clear();
         mUsimPhoneBookManager.reset();
@@ -96,6 +102,7 @@
      * @return List of AdnRecords for efid if we've already loaded them this
      * radio session, or null if we haven't
      */
+    @UnsupportedAppUsage
     public ArrayList<AdnRecord>
     getRecordsIfLoaded(int efid) {
         return mAdnLikeFiles.get(efid);
@@ -107,6 +114,7 @@
      *
      * See 3GPP TS 51.011 for this mapping
      */
+    @UnsupportedAppUsage
     public int extensionEfForEf(int efid) {
         switch (efid) {
             case EF_MBDN: return EF_EXT6;
@@ -119,6 +127,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void sendErrorResponse(Message response, String errString) {
         if (response != null) {
             Exception e = new RuntimeException(errString);
@@ -137,6 +146,7 @@
      * @param response message to be posted when done
      *        response.exception hold the exception in error
      */
+    @UnsupportedAppUsage
     public void updateAdnByIndex(int efid, AdnRecord adn, int recordIndex, String pin2,
             Message response) {
 
diff --git a/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java b/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
index eb5e9ce..391b8fc 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
@@ -18,6 +18,7 @@
 
 import java.util.ArrayList;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Looper;
@@ -32,6 +33,7 @@
 
     //***** Instance Variables
 
+    @UnsupportedAppUsage
     private IccFileHandler mFh;
     int mEf;
     int mExtensionEF;
@@ -59,6 +61,7 @@
 
     //***** Constructor
 
+    @UnsupportedAppUsage
     AdnRecordLoader(IccFileHandler fh) {
         // The telephony unit-test cases may create AdnRecords
         // in secondary threads
@@ -66,6 +69,7 @@
         mFh = fh;
     }
 
+    @UnsupportedAppUsage
     private String getEFPath(int efid) {
         if (efid == IccConstants.EF_ADN) {
             return IccConstants.MF_SIM + IccConstants.DF_TELECOM;
@@ -78,6 +82,7 @@
      * Resulting AdnRecord is placed in response.obj.result
      * or response.obj.exception is set
      */
+    @UnsupportedAppUsage
     public void
     loadFromEF(int ef, int extensionEF, int recordNumber,
                 Message response) {
@@ -124,6 +129,7 @@
      * @param pin2 for CHV2 operations, must be null if pin2 is not needed
      * @param response will be sent to its handler when completed
      */
+    @UnsupportedAppUsage
     public void
     updateEF(AdnRecord adn, int ef, int extensionEF, int recordNumber,
             String pin2, Message response) {
diff --git a/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java b/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java
index f1b0e43..76242c4 100644
--- a/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java
+++ b/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 import com.android.internal.telephony.uicc.IccCardStatus.PinState;
@@ -29,20 +30,32 @@
 public class IccCardApplicationStatus {
     // TODO: Replace with constants from PhoneConstants.APPTYPE_xxx
     public enum AppType{
+        @UnsupportedAppUsage
         APPTYPE_UNKNOWN,
+        @UnsupportedAppUsage
         APPTYPE_SIM,
+        @UnsupportedAppUsage
         APPTYPE_USIM,
+        @UnsupportedAppUsage
         APPTYPE_RUIM,
+        @UnsupportedAppUsage
         APPTYPE_CSIM,
+        @UnsupportedAppUsage
         APPTYPE_ISIM
     }
 
     public enum AppState{
+        @UnsupportedAppUsage
         APPSTATE_UNKNOWN,
+        @UnsupportedAppUsage
         APPSTATE_DETECTED,
+        @UnsupportedAppUsage
         APPSTATE_PIN,
+        @UnsupportedAppUsage
         APPSTATE_PUK,
+        @UnsupportedAppUsage
         APPSTATE_SUBSCRIPTION_PERSO,
+        @UnsupportedAppUsage
         APPSTATE_READY;
 
         boolean isPinRequired() {
@@ -68,17 +81,23 @@
     }
 
     public enum PersoSubState{
+        @UnsupportedAppUsage
         PERSOSUBSTATE_UNKNOWN,
         PERSOSUBSTATE_IN_PROGRESS,
         PERSOSUBSTATE_READY,
+        @UnsupportedAppUsage
         PERSOSUBSTATE_SIM_NETWORK,
+        @UnsupportedAppUsage
         PERSOSUBSTATE_SIM_NETWORK_SUBSET,
         PERSOSUBSTATE_SIM_CORPORATE,
+        @UnsupportedAppUsage
         PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
         PERSOSUBSTATE_SIM_SIM,
         PERSOSUBSTATE_SIM_NETWORK_PUK,
+        @UnsupportedAppUsage
         PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK,
         PERSOSUBSTATE_SIM_CORPORATE_PUK,
+        @UnsupportedAppUsage
         PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK,
         PERSOSUBSTATE_SIM_SIM_PUK,
         PERSOSUBSTATE_RUIM_NETWORK1,
@@ -99,6 +118,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public AppType        app_type;
     public AppState       app_state;
     // applicable only if app_state == RIL_APPSTATE_SUBSCRIPTION_PERSO
@@ -112,6 +132,7 @@
     public PinState       pin1;
     public PinState       pin2;
 
+    @UnsupportedAppUsage
     public AppType AppTypeFromRILInt(int type) {
         AppType newType;
         /* RIL_AppType ril.h */
diff --git a/src/java/com/android/internal/telephony/uicc/IccCardStatus.java b/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
index 5e7abfd..29bd6cc 100644
--- a/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
+++ b/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.SubscriptionInfo;
 
 /**
@@ -27,11 +28,15 @@
     public static final int CARD_MAX_APPS = 8;
 
     public enum CardState {
+        @UnsupportedAppUsage
         CARDSTATE_ABSENT,
+        @UnsupportedAppUsage
         CARDSTATE_PRESENT,
+        @UnsupportedAppUsage
         CARDSTATE_ERROR,
         CARDSTATE_RESTRICTED;
 
+        @UnsupportedAppUsage
         boolean isCardPresent() {
             return this == CARDSTATE_PRESENT ||
                 this == CARDSTATE_RESTRICTED;
@@ -42,8 +47,11 @@
         PINSTATE_UNKNOWN,
         PINSTATE_ENABLED_NOT_VERIFIED,
         PINSTATE_ENABLED_VERIFIED,
+        @UnsupportedAppUsage
         PINSTATE_DISABLED,
+        @UnsupportedAppUsage
         PINSTATE_ENABLED_BLOCKED,
+        @UnsupportedAppUsage
         PINSTATE_ENABLED_PERM_BLOCKED;
 
         boolean isPermBlocked() {
@@ -59,16 +67,22 @@
         }
     }
 
+    @UnsupportedAppUsage
     public CardState  mCardState;
+    @UnsupportedAppUsage
     public PinState   mUniversalPinState;
+    @UnsupportedAppUsage
     public int        mGsmUmtsSubscriptionAppIndex;
+    @UnsupportedAppUsage
     public int        mCdmaSubscriptionAppIndex;
+    @UnsupportedAppUsage
     public int        mImsSubscriptionAppIndex;
     public int        physicalSlotIndex = UiccController.INVALID_SLOT_ID;
     public String     atr;
     public String     iccid;
     public String     eid;
 
+    @UnsupportedAppUsage
     public IccCardApplicationStatus[] mApplications;
 
     public void setCardState(int state) {
diff --git a/src/java/com/android/internal/telephony/uicc/IccFileHandler.java b/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
index 33dd381..1c4123d 100644
--- a/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
+++ b/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.*;
 
 import com.android.internal.telephony.CommandsInterface;
@@ -95,21 +96,27 @@
     static protected final int EVENT_GET_RECORD_SIZE_IMG_DONE = 11;
 
      // member variables
+    @UnsupportedAppUsage
     protected final CommandsInterface mCi;
+    @UnsupportedAppUsage
     protected final UiccCardApplication mParentApp;
+    @UnsupportedAppUsage
     protected final String mAid;
 
     static class LoadLinearFixedContext {
 
         int mEfid;
+        @UnsupportedAppUsage
         int mRecordNum, mRecordSize, mCountRecords;
         boolean mLoadAll;
         String mPath;
 
         Message mOnLoaded;
 
+        @UnsupportedAppUsage
         ArrayList<byte[]> results;
 
+        @UnsupportedAppUsage
         LoadLinearFixedContext(int efid, int recordNum, Message onLoaded) {
             mEfid = efid;
             mRecordNum = recordNum;
@@ -168,6 +175,7 @@
      * ((AsyncResult)(onLoaded.obj)).result is the byte[]
      *
      */
+    @UnsupportedAppUsage
     public void loadEFLinearFixed(int fileid, String path, int recordNum, Message onLoaded) {
         String efPath = (path == null) ? getEFPath(fileid) : path;
         Message response
@@ -188,6 +196,7 @@
      * ((AsyncResult)(onLoaded.obj)).result is the byte[]
      *
      */
+    @UnsupportedAppUsage
     public void loadEFLinearFixed(int fileid, int recordNum, Message onLoaded) {
         loadEFLinearFixed(fileid, getEFPath(fileid), recordNum, onLoaded);
     }
@@ -222,6 +231,7 @@
      *        file int[3] is the number of records in the EF file So int[0] *
      *        int[3] = int[1]
      */
+    @UnsupportedAppUsage
     public void getEFLinearRecordSize(int fileid, String path, Message onLoaded) {
         String efPath = (path == null) ? getEFPath(fileid) : path;
         Message response
@@ -240,6 +250,7 @@
      *        file int[3] is the number of records in the EF file So int[0] *
      *        int[3] = int[1]
      */
+    @UnsupportedAppUsage
     public void getEFLinearRecordSize(int fileid, Message onLoaded) {
         getEFLinearRecordSize(fileid, getEFPath(fileid), onLoaded);
     }
@@ -254,6 +265,7 @@
      * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
      *
      */
+    @UnsupportedAppUsage
     public void loadEFLinearFixedAll(int fileid, String path, Message onLoaded) {
         String efPath = (path == null) ? getEFPath(fileid) : path;
         Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
@@ -272,6 +284,7 @@
      * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
      *
      */
+    @UnsupportedAppUsage
     public void loadEFLinearFixedAll(int fileid, Message onLoaded) {
         loadEFLinearFixedAll(fileid, getEFPath(fileid), onLoaded);
     }
@@ -286,6 +299,7 @@
      *
      */
 
+    @UnsupportedAppUsage
     public void loadEFTransparent(int fileid, Message onLoaded) {
         Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
                         fileid, 0, onLoaded);
@@ -351,6 +365,7 @@
      * @param onComplete onComplete.obj will be an AsyncResult
      *                   onComplete.obj.userObj will be a IccIoResult on success
      */
+    @UnsupportedAppUsage
     public void updateEFLinearFixed(int fileid, String path, int recordNum, byte[] data,
             String pin2, Message onComplete) {
         String efPath = (path == null) ? getEFPath(fileid) : path;
@@ -368,6 +383,7 @@
      * @param onComplete onComplete.obj will be an AsyncResult
      *                   onComplete.obj.userObj will be a IccIoResult on success
      */
+    @UnsupportedAppUsage
     public void updateEFLinearFixed(int fileid, int recordNum, byte[] data,
             String pin2, Message onComplete) {
         mCi.iccIOForApp(COMMAND_UPDATE_RECORD, fileid, getEFPath(fileid),
@@ -380,6 +396,7 @@
      * @param fileid EF id
      * @param data must be exactly as long as the EF
      */
+    @UnsupportedAppUsage
     public void updateEFTransparent(int fileid, byte[] data, Message onComplete) {
         mCi.iccIOForApp(COMMAND_UPDATE_BINARY, fileid, getEFPath(fileid),
                         0, 0, data.length,
@@ -634,6 +651,7 @@
         return null;
     }
 
+    @UnsupportedAppUsage
     protected abstract String getEFPath(int efid);
     protected abstract void logd(String s);
     protected abstract void loge(String s);
diff --git a/src/java/com/android/internal/telephony/uicc/IccIoResult.java b/src/java/com/android/internal/telephony/uicc/IccIoResult.java
index f777e81..7a922af 100644
--- a/src/java/com/android/internal/telephony/uicc/IccIoResult.java
+++ b/src/java/com/android/internal/telephony/uicc/IccIoResult.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Build;
 
 /**
@@ -170,17 +171,22 @@
     }
 
 
+    @UnsupportedAppUsage
     public int sw1;
+    @UnsupportedAppUsage
     public int sw2;
 
+    @UnsupportedAppUsage
     public byte[] payload;
 
+    @UnsupportedAppUsage
     public IccIoResult(int sw1, int sw2, byte[] payload) {
         this.sw1 = sw1;
         this.sw2 = sw2;
         this.payload = payload;
     }
 
+    @UnsupportedAppUsage
     public IccIoResult(int sw1, int sw2, String hexString) {
         this(sw1, sw2, IccUtils.hexStringToBytes(hexString));
     }
@@ -201,6 +207,7 @@
      * See GSM 11.11 Section 9.4
      * (the fun stuff is absent in 51.011)
      */
+    @UnsupportedAppUsage
     public boolean success() {
         return sw1 == 0x90 || sw1 == 0x91 || sw1 == 0x9e || sw1 == 0x9f;
     }
diff --git a/src/java/com/android/internal/telephony/uicc/IccRecords.java b/src/java/com/android/internal/telephony/uicc/IccRecords.java
index 7bc2acc..f6b5520 100644
--- a/src/java/com/android/internal/telephony/uicc/IccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IccRecords.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -72,26 +73,35 @@
     };
 
     // ***** Instance Variables
+    @UnsupportedAppUsage
     protected AtomicBoolean mDestroyed = new AtomicBoolean(false);
     protected AtomicBoolean mLoaded = new AtomicBoolean(false);
+    @UnsupportedAppUsage
     protected Context mContext;
+    @UnsupportedAppUsage
     protected CommandsInterface mCi;
+    @UnsupportedAppUsage
     protected IccFileHandler mFh;
+    @UnsupportedAppUsage
     protected UiccCardApplication mParentApp;
+    @UnsupportedAppUsage
     protected TelephonyManager mTelephonyManager;
 
     protected RegistrantList mRecordsLoadedRegistrants = new RegistrantList();
     protected RegistrantList mLockedRecordsLoadedRegistrants = new RegistrantList();
     protected RegistrantList mNetworkLockedRecordsLoadedRegistrants = new RegistrantList();
     protected RegistrantList mImsiReadyRegistrants = new RegistrantList();
+    @UnsupportedAppUsage
     protected RegistrantList mRecordsEventsRegistrants = new RegistrantList();
     protected RegistrantList mNewSmsRegistrants = new RegistrantList();
     protected RegistrantList mNetworkSelectionModeAutomaticRegistrants = new RegistrantList();
     protected RegistrantList mSpnUpdatedRegistrants = new RegistrantList();
     protected RegistrantList mRecordsOverrideRegistrants = new RegistrantList();
 
+    @UnsupportedAppUsage
     protected int mRecordsToLoad;  // number of pending load requests
 
+    @UnsupportedAppUsage
     protected AdnRecordCache mAdnCache;
 
     // ***** Cached SIM State; cleared on channel close
@@ -106,6 +116,7 @@
     protected boolean mRecordsRequested = false; // true if we've made requests for the sim records
     protected int mLockedRecordsReqReason = LOCKED_RECORDS_REQ_REASON_NONE;
 
+    @UnsupportedAppUsage
     protected String mIccId;  // Includes only decimals (no hex)
 
     protected String mFullIccId;  // Includes hex characters in ICCID
@@ -113,19 +124,26 @@
     protected String mMsisdnTag = null;
     protected String mNewMsisdn = null;
     protected String mNewMsisdnTag = null;
+    @UnsupportedAppUsage
     protected String mVoiceMailNum = null;
     protected String mVoiceMailTag = null;
     protected String mNewVoiceMailNum = null;
     protected String mNewVoiceMailTag = null;
+    @UnsupportedAppUsage
     protected boolean mIsVoiceMailFixed = false;
+    @UnsupportedAppUsage
     protected String mImsi; // IMSI must be only valid numeric characters 0-9 without padding 'f's
+    @UnsupportedAppUsage
     private IccIoResult auth_rsp;
 
+    @UnsupportedAppUsage
     protected int mMncLength = UNINITIALIZED;
     protected int mMailboxIndex = 0; // 0 is no mailbox dailing number associated
 
+    @UnsupportedAppUsage
     private String mSpn;
 
+    @UnsupportedAppUsage
     protected String mGid1;
     protected String mGid2;
 
@@ -140,6 +158,7 @@
     protected String[] mEhplmns;
     protected String[] mFplmns;
 
+    @UnsupportedAppUsage
     private final Object mLock = new Object();
 
     CarrierTestOverride mCarrierTestOverride;
@@ -307,6 +326,7 @@
      * hex digits.
      * @return ICC ID without hex digits
      */
+    @UnsupportedAppUsage
     public String getIccId() {
         if (mCarrierTestOverride.isInTestMode() && mCarrierTestOverride.getFakeIccid() != null) {
             return mCarrierTestOverride.getFakeIccid();
@@ -323,6 +343,7 @@
         return mFullIccId;
     }
 
+    @UnsupportedAppUsage
     public void registerForRecordsLoaded(Handler h, int what, Object obj) {
         if (mDestroyed.get()) {
             return;
@@ -336,6 +357,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public void unregisterForRecordsLoaded(Handler h) {
         mRecordsLoadedRegistrants.remove(h);
     }
@@ -435,6 +457,7 @@
         mSpnUpdatedRegistrants.remove(h);
     }
 
+    @UnsupportedAppUsage
     public void registerForRecordsEvents(Handler h, int what, Object obj) {
         Registrant r = new Registrant (h, what, obj);
         mRecordsEventsRegistrants.add(r);
@@ -444,23 +467,28 @@
         r.notifyResult(EVENT_MWI);
         r.notifyResult(EVENT_CFI);
     }
+    @UnsupportedAppUsage
     public void unregisterForRecordsEvents(Handler h) {
         mRecordsEventsRegistrants.remove(h);
     }
 
+    @UnsupportedAppUsage
     public void registerForNewSms(Handler h, int what, Object obj) {
         Registrant r = new Registrant (h, what, obj);
         mNewSmsRegistrants.add(r);
     }
+    @UnsupportedAppUsage
     public void unregisterForNewSms(Handler h) {
         mNewSmsRegistrants.remove(h);
     }
 
+    @UnsupportedAppUsage
     public void registerForNetworkSelectionModeAutomatic(
             Handler h, int what, Object obj) {
         Registrant r = new Registrant (h, what, obj);
         mNetworkSelectionModeAutomaticRegistrants.add(r);
     }
+    @UnsupportedAppUsage
     public void unregisterForNetworkSelectionModeAutomatic(Handler h) {
         mNetworkSelectionModeAutomaticRegistrants.remove(h);
     }
@@ -472,6 +500,7 @@
      *
      * @return null if SIM is not yet ready or unavailable
      */
+    @UnsupportedAppUsage
     public String getIMSI() {
         if (mCarrierTestOverride.isInTestMode() && mCarrierTestOverride.getFakeIMSI() != null) {
             return mCarrierTestOverride.getFakeIMSI();
@@ -566,6 +595,7 @@
         return null;
     }
 
+    @UnsupportedAppUsage
     public String getMsisdnNumber() {
         return mMsisdn;
     }
@@ -574,6 +604,7 @@
      * Get the Group Identifier Level 1 (GID1) on a SIM for GSM.
      * @return null if SIM is not yet ready
      */
+    @UnsupportedAppUsage
     public String getGid1() {
         if (mCarrierTestOverride.isInTestMode() && mCarrierTestOverride.getFakeGid1() != null) {
             return mCarrierTestOverride.getFakeGid1();
@@ -607,6 +638,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public void setMsisdnNumber(String alphaTag, String number,
             Message onComplete) {
         loge("setMsisdn() should not be invoked on base IccRecords");
@@ -629,6 +661,7 @@
      *
      * @return null if SIM is not yet ready or no RUIM entry
      */
+    @UnsupportedAppUsage
     public String getServiceProviderName() {
         if (mCarrierTestOverride.isInTestMode() && mCarrierTestOverride.getFakeSpn() != null) {
             return mCarrierTestOverride.getFakeSpn();
@@ -716,6 +749,7 @@
      */
     public abstract void onRefresh(boolean fileChanged, int[] fileList);
 
+    @UnsupportedAppUsage
     public boolean getRecordsLoaded() {
         return mRecordsToLoad == 0 && mRecordsRequested;
     }
@@ -836,6 +870,7 @@
 
     protected abstract void handleFileUpdate(int efid);
 
+    @UnsupportedAppUsage
     protected void handleRefresh(IccRefreshResponse refreshResponse){
         if (refreshResponse == null) {
             if (DBG) log("handleRefresh received without input");
@@ -895,6 +930,7 @@
      * or is not valid for the type of IccCard. Generally used for
      * GSM/UMTS and the like SIMS
      */
+    @UnsupportedAppUsage
     public String getOperatorNumeric() {
         return null;
     }
@@ -915,6 +951,7 @@
      * @param enable
      * @param number to which CFU is enabled
      */
+    @UnsupportedAppUsage
     public void setVoiceCallForwardingFlag(int line, boolean enable, String number) {
     }
 
@@ -942,6 +979,7 @@
      *
      * @param s is the string to write
      */
+    @UnsupportedAppUsage
     protected abstract void log(String s);
 
     /**
@@ -959,6 +997,7 @@
         return null;
     }
 
+    @UnsupportedAppUsage
     public UsimServiceTable getUsimServiceTable() {
         return null;
     }
@@ -979,6 +1018,7 @@
      * @param data authentication challenge data
      * @return challenge response
      */
+    @UnsupportedAppUsage
     public String getIccSimChallengeResponse(int authContext, String data) {
         if (DBG) log("getIccSimChallengeResponse:");
 
diff --git a/src/java/com/android/internal/telephony/uicc/IccRefreshResponse.java b/src/java/com/android/internal/telephony/uicc/IccRefreshResponse.java
index c1d29f8..7d0f845 100644
--- a/src/java/com/android/internal/telephony/uicc/IccRefreshResponse.java
+++ b/src/java/com/android/internal/telephony/uicc/IccRefreshResponse.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * See also RIL_SimRefresh in include/telephony/ril.h
  *
@@ -28,8 +30,11 @@
     public static final int REFRESH_RESULT_INIT = 1;        /* The Icc has been initialized */
     public static final int REFRESH_RESULT_RESET = 2;       /* The Icc was reset */
 
+    @UnsupportedAppUsage
     public int             refreshResult;      /* Sim Refresh result */
+    @UnsupportedAppUsage
     public int             efId;               /* EFID */
+    @UnsupportedAppUsage
     public String          aid;                /* null terminated string, e.g.,
                                                   from 0xA0, 0x00 -> 0x41,
                                                   0x30, 0x30, 0x30 */
diff --git a/src/java/com/android/internal/telephony/uicc/IccServiceTable.java b/src/java/com/android/internal/telephony/uicc/IccServiceTable.java
index a96d499..b2e2f27 100644
--- a/src/java/com/android/internal/telephony/uicc/IccServiceTable.java
+++ b/src/java/com/android/internal/telephony/uicc/IccServiceTable.java
@@ -16,12 +16,14 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 /**
  * Wrapper class for an ICC EF containing a bit field of enabled services.
  */
 public abstract class IccServiceTable {
+    @UnsupportedAppUsage
     protected final byte[] mServiceTable;
 
     protected IccServiceTable(byte[] table) {
@@ -29,6 +31,7 @@
     }
 
     // Get the class name to use for log strings
+    @UnsupportedAppUsage
     protected abstract String getTag();
 
     // Get the array of enums to use for toString
diff --git a/src/java/com/android/internal/telephony/uicc/IsimRecords.java b/src/java/com/android/internal/telephony/uicc/IsimRecords.java
index 019cc79..65cfd6f 100644
--- a/src/java/com/android/internal/telephony/uicc/IsimRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IsimRecords.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * {@hide}
  */
@@ -26,6 +28,7 @@
      * Returns null if the IMPI hasn't been loaded or isn't present on the ISIM.
      * @return the IMS private user identity string, or null if not available
      */
+    @UnsupportedAppUsage
     String getIsimImpi();
 
     /**
@@ -33,6 +36,7 @@
      * Returns null if the IMS domain hasn't been loaded or isn't present on the ISIM.
      * @return the IMS home network domain name, or null if not available
      */
+    @UnsupportedAppUsage
     String getIsimDomain();
 
     /**
@@ -40,6 +44,7 @@
      * Returns null if the IMPU hasn't been loaded or isn't present on the ISIM.
      * @return an array of IMS public user identity strings, or null if not available
      */
+    @UnsupportedAppUsage
     String[] getIsimImpu();
 
     /**
diff --git a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
index 3b33c03..7f6e984 100644
--- a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncResult;
@@ -49,13 +50,20 @@
     private static final int EVENT_ISIM_AUTHENTICATE_DONE          = 91;
 
     // ISIM EF records (see 3GPP TS 31.103)
+    @UnsupportedAppUsage
     private String mIsimImpi;               // IMS private user identity
+    @UnsupportedAppUsage
     private String mIsimDomain;             // IMS home network domain name
+    @UnsupportedAppUsage
     private String[] mIsimImpu;             // IMS public user identity(s)
+    @UnsupportedAppUsage
     private String mIsimIst;                // IMS Service Table
+    @UnsupportedAppUsage
     private String[] mIsimPcscf;            // IMS Proxy Call Session Control Function
+    @UnsupportedAppUsage
     private String auth_rsp;
 
+    @UnsupportedAppUsage
     private final Object mLock = new Object();
 
     private static final int TAG_ISIM_VALUE = 0x80;     // From 3GPP TS 31.103
@@ -148,6 +156,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     protected void fetchIsimRecords() {
         mRecordsRequested = true;
 
@@ -260,6 +269,7 @@
      * @param record the byte array containing the IMS data string
      * @return the decoded String value, or null if the record can't be decoded
      */
+    @UnsupportedAppUsage
     private static String isimTlvToString(byte[] record) {
         SimTlv tlv = new SimTlv(record, 0, record.length);
         do {
@@ -436,6 +446,7 @@
         // Not applicable to Isim
     }
 
+    @UnsupportedAppUsage
     @Override
     protected void log(String s) {
         if (DBG) Rlog.d(LOG_TAG, "[ISIM] " + s);
diff --git a/src/java/com/android/internal/telephony/uicc/RuimRecords.java b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
index fd4debf..5c007a3 100644
--- a/src/java/com/android/internal/telephony/uicc/RuimRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
@@ -18,6 +18,7 @@
 
 import static com.android.internal.telephony.TelephonyProperties.PROPERTY_TEST_CSIM;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.AsyncResult;
@@ -59,13 +60,17 @@
 
     private String mPrlVersion;
     // From CSIM application
+    @UnsupportedAppUsage
     private byte[] mEFpl = null;
+    @UnsupportedAppUsage
     private byte[] mEFli = null;
     boolean mCsimSpnDisplayCondition = false;
     private String mMdn;
+    @UnsupportedAppUsage
     private String mMin;
     private String mHomeSystemId;
     private String mHomeNetworkId;
+    @UnsupportedAppUsage
     private String mNai;
 
     @Override
@@ -160,6 +165,7 @@
         mLoaded.set(false);
     }
 
+    @UnsupportedAppUsage
     public String getMdnNumber() {
         return mMyMobileNumber;
     }
@@ -203,6 +209,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private int adjstMinDigits (int digits) {
         // Per C.S0005 section 2.3.1.
         digits += 111;
@@ -216,6 +223,7 @@
      * Returns the 5 or 6 digit MCC/MNC of the operator that
      *  provided the RUIM card. Returns null of RUIM is not yet ready
      */
+    @UnsupportedAppUsage
     public String getRUIMOperatorNumeric() {
         String imsi = getIMSI();
 
@@ -451,6 +459,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void onGetCSimEprlDone(AsyncResult ar) {
         // C.S0065 section 5.2.57 for EFeprl encoding
         // C.S0016 section 3.5.5 for PRL format.
@@ -726,6 +735,7 @@
      * NOTE: This array will have duplicates. If this method will be caused
      * frequently or in a tight loop, it can be rewritten for efficiency.
      */
+    @UnsupportedAppUsage
     private static String[] getAssetLanguages(Context ctx) {
         final String[] locales = ctx.getAssets().getLocales();
         final String[] localeLangs = new String[locales.length];
@@ -837,6 +847,7 @@
         mRecordsToLoad++;
     }
 
+    @UnsupportedAppUsage
     private void fetchRuimRecords() {
         mRecordsRequested = true;
 
@@ -942,6 +953,7 @@
         fetchRuimRecords();
     }
 
+    @UnsupportedAppUsage
     public String getMdn() {
         return mMdn;
     }
@@ -958,14 +970,17 @@
         return mHomeNetworkId;
     }
 
+    @UnsupportedAppUsage
     public boolean getCsimSpnDisplayCondition() {
         return mCsimSpnDisplayCondition;
     }
+    @UnsupportedAppUsage
     @Override
     protected void log(String s) {
         Rlog.d(LOG_TAG, "[RuimRecords] " + s);
     }
 
+    @UnsupportedAppUsage
     @Override
     protected void loge(String s) {
         Rlog.e(LOG_TAG, "[RuimRecords] " + s);
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index ba10eff..49aa92d 100755
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.AsyncResult;
@@ -53,6 +54,7 @@
 
     // ***** Instance Variables
 
+    @UnsupportedAppUsage
     VoiceMailConstants mVmConfig;
 
     // ***** Cached SIM State; cleared on channel close
@@ -72,18 +74,26 @@
     private byte[] mCphsInfo = null;
     boolean mCspPlmnEnabled = true;
 
+    @UnsupportedAppUsage
     byte[] mEfMWIS = null;
+    @UnsupportedAppUsage
     byte[] mEfCPHS_MWI =null;
+    @UnsupportedAppUsage
     byte[] mEfCff = null;
+    @UnsupportedAppUsage
     byte[] mEfCfis = null;
 
+    @UnsupportedAppUsage
     byte[] mEfLi = null;
+    @UnsupportedAppUsage
     byte[] mEfPl = null;
 
+    @UnsupportedAppUsage
     int mSpnDisplayCondition;
     // Numeric network codes listed in TS 51.011 EF[SPDI]
     ArrayList<String> mSpdiNetworks = null;
 
+    @UnsupportedAppUsage
     UsimServiceTable mUsimServiceTable;
 
     @Override
@@ -253,6 +263,7 @@
 
     //***** Public Methods
 
+    @UnsupportedAppUsage
     @Override
     public String getMsisdnNumber() {
         return mMsisdn;
@@ -263,6 +274,7 @@
         return mUsimServiceTable;
     }
 
+    @UnsupportedAppUsage
     private int getExtFromEf(int ef) {
         int ext;
         switch (ef) {
@@ -318,6 +330,7 @@
         return mMsisdnTag;
     }
 
+    @UnsupportedAppUsage
     @Override
     public String getVoiceMailNumber() {
         return mVoiceMailNum;
@@ -497,6 +510,7 @@
     /**
      * {@inheritDoc}
      */
+    @UnsupportedAppUsage
     @Override
     public void setVoiceCallForwardingFlag(int line, boolean enable, String dialNumber) {
 
@@ -579,6 +593,7 @@
     /**
      * {@inheritDoc}
      */
+    @UnsupportedAppUsage
     @Override
     public String getOperatorNumeric() {
         String imsi = getIMSI();
@@ -1510,6 +1525,7 @@
         mRecordsToLoad++;
     }
 
+    @UnsupportedAppUsage
     protected void fetchSimRecords() {
         mRecordsRequested = true;
 
@@ -1696,9 +1712,13 @@
      */
     private enum GetSpnFsmState {
         IDLE,               // No initialized
+        @UnsupportedAppUsage
         INIT,               // Start FSM
+        @UnsupportedAppUsage
         READ_SPN_3GPP,      // Load EF_SPN firstly
+        @UnsupportedAppUsage
         READ_SPN_CPHS,      // Load EF_SPN_CPHS secondly
+        @UnsupportedAppUsage
         READ_SPN_SHORT_CPHS // Load EF_SPN_SHORT_CPHS last
     }
 
@@ -1719,6 +1739,7 @@
      *        ar.exception holds exception in error
      *        ar.result is byte[] for data in success
      */
+    @UnsupportedAppUsage
     private void getSpnFsm(boolean start, AsyncResult ar) {
         byte[] data;
 
@@ -1914,16 +1935,19 @@
     /**
      * check to see if Mailbox Number is allocated and activated in CPHS SST
      */
+    @UnsupportedAppUsage
     private boolean isCphsMailboxEnabled() {
         if (mCphsInfo == null)  return false;
         return ((mCphsInfo[1] & CPHS_SST_MBN_MASK) == CPHS_SST_MBN_ENABLED );
     }
 
+    @UnsupportedAppUsage
     @Override
     protected void log(String s) {
         Rlog.d(LOG_TAG, "[SIMRecords] " + s);
     }
 
+    @UnsupportedAppUsage
     @Override
     protected void loge(String s) {
         Rlog.e(LOG_TAG, "[SIMRecords] " + s);
@@ -1933,6 +1957,7 @@
         Rlog.w(LOG_TAG, "[SIMRecords] " + s, tr);
     }
 
+    @UnsupportedAppUsage
     protected void logv(String s) {
         Rlog.v(LOG_TAG, "[SIMRecords] " + s);
     }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCard.java b/src/java/com/android/internal/telephony/uicc/UiccCard.java
index a8db6c8..985bfa8 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCard.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
@@ -49,13 +50,18 @@
 
     // The lock object is created by UiccSlot that owns this UiccCard - this is to share the lock
     // between UiccSlot, UiccCard, EuiccCard, and UiccProfile for now.
+    @UnsupportedAppUsage
     protected final Object mLock;
+    @UnsupportedAppUsage
     private CardState mCardState;
     private String mIccid;
     protected String mCardId;
     private UiccProfile mUiccProfile;
+    @UnsupportedAppUsage
     private Context mContext;
+    @UnsupportedAppUsage
     private CommandsInterface mCi;
+    @UnsupportedAppUsage
     private final int mPhoneId;
 
     public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock) {
@@ -149,6 +155,7 @@
     /**
      * @deprecated Please use {@link UiccProfile#isApplicationOnIcc(AppType)} instead.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) {
         synchronized (mLock) {
@@ -160,6 +167,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public CardState getCardState() {
         synchronized (mLock) {
             return mCardState;
@@ -183,6 +191,7 @@
     /**
      * @deprecated Please use {@link UiccProfile#getApplication(int)} instead.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public UiccCardApplication getApplication(int family) {
         synchronized (mLock) {
@@ -197,6 +206,7 @@
     /**
      * @deprecated Please use {@link UiccProfile#getApplicationIndex(int)} instead.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public UiccCardApplication getApplicationIndex(int index) {
         synchronized (mLock) {
@@ -216,6 +226,7 @@
      *
      * @deprecated Please use {@link UiccProfile#getApplicationByType(int)} instead.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public UiccCardApplication getApplicationByType(int type) {
         synchronized (mLock) {
@@ -338,6 +349,7 @@
      * Returns number of applications on this card
      * @deprecated Please use {@link UiccProfile#getNumApplications()} instead.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public int getNumApplications() {
         if (mUiccProfile != null) {
@@ -441,6 +453,7 @@
      * @deprecated Please use
      * {@link UiccProfile#getCarrierPackageNamesForIntent(PackageManager, Intent)} instead.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public List<String> getCarrierPackageNamesForIntent(
             PackageManager packageManager, Intent intent) {
@@ -466,6 +479,7 @@
     /**
      * @deprecated Please use {@link UiccProfile#getOperatorBrandOverride()} instead.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public String getOperatorBrandOverride() {
         if (mUiccProfile != null) {
@@ -475,6 +489,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public String getIccId() {
         if (mIccid != null) {
             return mIccid;
@@ -499,10 +514,12 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void log(String msg) {
         Rlog.d(LOG_TAG, msg);
     }
 
+    @UnsupportedAppUsage
     private void loge(String msg) {
         Rlog.e(LOG_TAG, msg);
     }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
index 7a361e3..f30557a 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -58,15 +59,21 @@
     public static final int AUTH_CONTEXT_EAP_AKA = PhoneConstants.AUTH_CONTEXT_EAP_AKA;
     public static final int AUTH_CONTEXT_UNDEFINED = PhoneConstants.AUTH_CONTEXT_UNDEFINED;
 
+    @UnsupportedAppUsage
     private final Object  mLock = new Object();
     private UiccProfile   mUiccProfile; //parent
+    @UnsupportedAppUsage
     private AppState      mAppState;
+    @UnsupportedAppUsage
     private AppType       mAppType;
     private int           mAuthContext;
+    @UnsupportedAppUsage
     private PersoSubState mPersoSubState;
+    @UnsupportedAppUsage
     private String        mAid;
     private String        mAppLabel;
     private boolean       mPin1Replaced;
+    @UnsupportedAppUsage
     private PinState      mPin1State;
     private PinState      mPin2State;
     private boolean       mIccFdnEnabled;
@@ -78,11 +85,13 @@
     private boolean       mIgnoreApp;
     private boolean       mIccFdnAvailable = true; // Default is enabled.
 
+    @UnsupportedAppUsage
     private CommandsInterface mCi;
     private Context mContext;
     private IccRecords mIccRecords;
     private IccFileHandler mIccFh;
 
+    @UnsupportedAppUsage
     private boolean mDestroyed;//set to true once this App is commanded to be disposed of.
 
     private RegistrantList mReadyRegistrants = new RegistrantList();
@@ -118,6 +127,7 @@
         mCi.registerForNotAvailable(mHandler, EVENT_RADIO_UNAVAILABLE, null);
     }
 
+    @UnsupportedAppUsage
     public void update (IccCardApplicationStatus as, Context c, CommandsInterface ci) {
         synchronized (mLock) {
             if (mDestroyed) {
@@ -167,6 +177,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     void dispose() {
         synchronized (mLock) {
             if (DBG) log(mAppType + " being Disposed");
@@ -418,6 +429,7 @@
         }
     };
 
+    @UnsupportedAppUsage
     public void registerForReady(Handler h, int what, Object obj) {
         synchronized (mLock) {
             Registrant r = new Registrant (h, what, obj);
@@ -426,6 +438,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public void unregisterForReady(Handler h) {
         synchronized (mLock) {
             mReadyRegistrants.remove(h);
@@ -543,18 +556,21 @@
         }
     }
 
+    @UnsupportedAppUsage
     public AppState getState() {
         synchronized (mLock) {
             return mAppState;
         }
     }
 
+    @UnsupportedAppUsage
     public AppType getType() {
         synchronized (mLock) {
             return mAppType;
         }
     }
 
+    @UnsupportedAppUsage
     public int getAuthContext() {
         synchronized (mLock) {
             return mAuthContext;
@@ -588,12 +604,14 @@
         return authContext;
     }
 
+    @UnsupportedAppUsage
     public PersoSubState getPersoSubState() {
         synchronized (mLock) {
             return mPersoSubState;
         }
     }
 
+    @UnsupportedAppUsage
     public String getAid() {
         synchronized (mLock) {
             return mAid;
@@ -604,6 +622,7 @@
         return mAppLabel;
     }
 
+    @UnsupportedAppUsage
     public PinState getPin1State() {
         synchronized (mLock) {
             if (mPin1Replaced) {
@@ -613,12 +632,14 @@
         }
     }
 
+    @UnsupportedAppUsage
     public IccFileHandler getIccFileHandler() {
         synchronized (mLock) {
             return mIccFh;
         }
     }
 
+    @UnsupportedAppUsage
     public IccRecords getIccRecords() {
         synchronized (mLock) {
             return mIccRecords;
@@ -874,6 +895,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public int getPhoneId() {
         return mUiccProfile.getPhoneId();
     }
@@ -890,10 +912,12 @@
         return mUiccProfile;
     }
 
+    @UnsupportedAppUsage
     private void log(String msg) {
         Rlog.d(LOG_TAG, msg);
     }
 
+    @UnsupportedAppUsage
     private void loge(String msg) {
         Rlog.e(LOG_TAG, msg);
     }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index 76a0227..d8be6fb 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony.uicc;
 
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -124,7 +125,9 @@
         // Bytes for the length field, in ASCII HEX string form.
         private String lengthBytes;
         // Decoded length as integer.
+        @UnsupportedAppUsage
         private Integer length;
+        @UnsupportedAppUsage
         private String value;
 
         public TLV(String tag) {
@@ -182,9 +185,11 @@
 
     private UiccProfile mUiccProfile;  // Parent
     private UiccPkcs15 mUiccPkcs15; // ARF fallback
+    @UnsupportedAppUsage
     private AtomicInteger mState;
     private List<UiccAccessRule> mAccessRules;
     private String mRules;
+    @UnsupportedAppUsage
     private Message mLoadedCallback;
     // LocalLog buffer to hold important status messages for debugging.
     private LocalLog mStatusMessage = new LocalLog(100);
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 53a7cdd..06822d0 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -16,6 +16,10 @@
 
 package com.android.internal.telephony.uicc;
 
+import static android.telephony.TelephonyManager.UNINITIALIZED_CARD_ID;
+import static android.telephony.TelephonyManager.UNSUPPORTED_CARD_ID;
+
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -118,6 +122,7 @@
     private static final int EVENT_EID_READY = 9;
 
     // this needs to be here, because on bootup we dont know which index maps to which UiccSlot
+    @UnsupportedAppUsage
     private CommandsInterface[] mCis;
     @VisibleForTesting
     public UiccSlot[] mUiccSlots;
@@ -128,6 +133,8 @@
     // The array index is the card ID (int).
     // This mapping exists to expose card-based functionality without exposing the EID, which is
     // considered sensetive information.
+    // mCardStrings is populated using values from the IccSlotStatus and IccCardStatus. For
+    // HAL < 1.2, these do not contain the EID or the ICCID, so mCardStrings will be empty
     private ArrayList<String> mCardStrings;
 
     // This is the card ID of the default eUICC. It starts as UNINITIALIZED_CARD_ID.
@@ -145,10 +152,13 @@
     // SharedPreferences key for saving the default euicc card ID
     private static final String DEFAULT_CARD = "default_card";
 
+    @UnsupportedAppUsage
     private static final Object mLock = new Object();
+    @UnsupportedAppUsage
     private static UiccController mInstance;
     private static ArrayList<IccSlotStatus> sLastSlotStatus;
 
+    @UnsupportedAppUsage
     @VisibleForTesting
     public Context mContext;
 
@@ -213,7 +223,7 @@
 
         mLauncher = new UiccStateChangedLauncher(c, this);
         mCardStrings = loadCardStrings();
-        mDefaultEuiccCardId = TelephonyManager.UNINITIALIZED_CARD_ID;
+        mDefaultEuiccCardId = UNINITIALIZED_CARD_ID;
     }
 
     /**
@@ -235,6 +245,7 @@
         return mPhoneIdToSlotId[phoneId];
     }
 
+    @UnsupportedAppUsage
     public static UiccController getInstance() {
         synchronized (mLock) {
             if (mInstance == null) {
@@ -245,6 +256,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public UiccCard getUiccCard(int phoneId) {
         synchronized (mLock) {
             return getUiccCardForPhone(phoneId);
@@ -371,6 +383,7 @@
     }
 
     // Easy to use API
+    @UnsupportedAppUsage
     public IccRecords getIccRecords(int phoneId, int family) {
         synchronized (mLock) {
             UiccCardApplication app = getUiccCardApplication(phoneId, family);
@@ -382,6 +395,7 @@
     }
 
     // Easy to use API
+    @UnsupportedAppUsage
     public IccFileHandler getIccFileHandler(int phoneId, int family) {
         synchronized (mLock) {
             UiccCardApplication app = getUiccCardApplication(phoneId, family);
@@ -394,6 +408,7 @@
 
 
     //Notifies when card status changes
+    @UnsupportedAppUsage
     public void registerForIccChanged(Handler h, int what, Object obj) {
         synchronized (mLock) {
             Registrant r = new Registrant (h, what, obj);
@@ -505,6 +520,7 @@
     }
 
     // Easy to use API
+    @UnsupportedAppUsage
     public UiccCardApplication getUiccCardApplication(int phoneId, int family) {
         synchronized (mLock) {
             UiccCard uiccCard = getUiccCardForPhone(phoneId);
@@ -570,7 +586,8 @@
 
         if (eidIsNotSupported(status)) {
             // we will never get EID from the HAL, so set mDefaultEuiccCardId to UNSUPPORTED_CARD_ID
-            mDefaultEuiccCardId = TelephonyManager.UNSUPPORTED_CARD_ID;
+            if (DBG) log("eid is not supported");
+            mDefaultEuiccCardId = UNSUPPORTED_CARD_ID;
         }
         mPhoneIdToSlotId[index] = slotId;
 
@@ -584,7 +601,7 @@
             mUiccSlots[slotId] = new UiccSlot(mContext, true);
         }
 
-        mUiccSlots[slotId].update(mCis[index], status, index);
+        mUiccSlots[slotId].update(mCis[index], status, index, slotId);
 
         UiccCard card = mUiccSlots[slotId].getUiccCard();
         if (card == null) {
@@ -604,7 +621,7 @@
         // EID may be unpopulated if RadioConfig<1.2
         // If so, just register for EID loaded and skip this stuff
         if (isEuicc && cardString == null
-                && mDefaultEuiccCardId != TelephonyManager.UNSUPPORTED_CARD_ID) {
+                && mDefaultEuiccCardId != UNSUPPORTED_CARD_ID) {
             ((EuiccCard) card).registerForEidReady(this, EVENT_EID_READY, index);
         }
 
@@ -648,18 +665,24 @@
      * to match to a card ID.
      *
      * @return the matching cardId, or UNINITIALIZED_CARD_ID if the card string does not map to a
-     * currently loaded cardId
+     * currently loaded cardId, or UNSUPPORTED_CARD_ID if the device does not support card IDs
      */
     public int convertToPublicCardId(String cardString) {
-        if (TextUtils.isEmpty(cardString)) {
-            return TelephonyManager.UNINITIALIZED_CARD_ID;
+        if (mDefaultEuiccCardId == UNSUPPORTED_CARD_ID) {
+            // even if cardString is not an EID, if EID is not supported (e.g. HAL < 1.2) we can't
+            // guarentee a working card ID implementation, so return UNSUPPORTED_CARD_ID
+            return UNSUPPORTED_CARD_ID;
         }
+        if (TextUtils.isEmpty(cardString)) {
+            return UNINITIALIZED_CARD_ID;
+        }
+
         if (cardString.length() < EID_LENGTH) {
             cardString = IccUtils.stripTrailingFs(cardString);
         }
         int id = mCardStrings.indexOf(cardString);
         if (id == -1) {
-            return TelephonyManager.UNINITIALIZED_CARD_ID;
+            return UNINITIALIZED_CARD_ID;
         } else {
             return id;
         }
@@ -680,6 +703,7 @@
             }
             String iccid = card.getIccId();
             int cardId;
+            boolean isRemovable = slot.isRemovable();
             if (isEuicc) {
                 eid = card.getCardId();
                 cardId = convertToPublicCardId(eid);
@@ -687,7 +711,8 @@
                 // leave eid null if the UICC is not embedded
                 cardId = convertToPublicCardId(iccid);
             }
-            UiccCardInfo info = new UiccCardInfo(isEuicc, cardId, eid, iccid, slotIndex);
+            UiccCardInfo info = new UiccCardInfo(isEuicc, cardId, eid, iccid, slotIndex,
+                    isRemovable);
             infos.add(info);
         }
         return infos;
@@ -778,9 +803,10 @@
             }
 
             if (!isValidPhoneIndex(iss.logicalSlotIndex)) {
-                mUiccSlots[i].update(null, iss);
+                mUiccSlots[i].update(null, iss, i /* slotIndex */);
             } else {
-                mUiccSlots[i].update(isActive ? mCis[iss.logicalSlotIndex] : null, iss);
+                mUiccSlots[i].update(isActive ? mCis[iss.logicalSlotIndex] : null, iss,
+                        i /* slotIndex */);
             }
 
             if (mUiccSlots[i].isEuicc()) {
@@ -928,7 +954,7 @@
         // set mCardStrings and the defaultEuiccCardId using the now available EID
         String eid = ((EuiccCard) card).getEid();
         addCardId(eid);
-        if (mDefaultEuiccCardId == TelephonyManager.UNINITIALIZED_CARD_ID) {
+        if (mDefaultEuiccCardId == UNINITIALIZED_CARD_ID) {
             // TODO(b/122738148) the default eUICC should not be removable
             mDefaultEuiccCardId = convertToPublicCardId(eid);
             log("onEidReady: eid=" + eid + " slot=" + slotId + " mDefaultEuiccCardId="
@@ -957,6 +983,7 @@
         return (index >= 0 && index < mUiccSlots.length);
     }
 
+    @UnsupportedAppUsage
     private void log(String string) {
         Rlog.d(LOG_TAG, string);
     }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index a5f5ee9..156dc62 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -63,6 +63,7 @@
     private String mIccId;
     private AnswerToReset mAtr;
     private int mPhoneId = INVALID_PHONE_ID;
+    private boolean mIsRemovable;
 
     private static final int EVENT_CARD_REMOVED = 13;
     private static final int EVENT_CARD_ADDED = 14;
@@ -77,7 +78,7 @@
     /**
      * Update slot. The main trigger for this is a change in the ICC Card status.
      */
-    public void update(CommandsInterface ci, IccCardStatus ics, int phoneId) {
+    public void update(CommandsInterface ci, IccCardStatus ics, int phoneId, int slotIndex) {
         if (DBG) log("cardStatus update: " + ics.toString());
         synchronized (mLock) {
             CardState oldState = mCardState;
@@ -86,6 +87,7 @@
             mPhoneId = phoneId;
             parseAtr(ics.atr);
             mCi = ci;
+            mIsRemovable = isSlotRemovable(slotIndex);
 
             int radioState = mCi.getRadioState();
             if (DBG) {
@@ -135,7 +137,7 @@
     /**
      * Update slot based on IccSlotStatus.
      */
-    public void update(CommandsInterface ci, IccSlotStatus iss) {
+    public void update(CommandsInterface ci, IccSlotStatus iss, int slotIndex) {
         if (DBG) log("slotStatus update: " + iss.toString());
         synchronized (mLock) {
             CardState oldState = mCardState;
@@ -143,6 +145,7 @@
             parseAtr(iss.atr);
             mCardState = iss.cardState;
             mIccId = iss.iccid;
+            mIsRemovable = isSlotRemovable(slotIndex);
             if (iss.slotState == IccSlotStatus.SlotState.SLOTSTATE_INACTIVE) {
                 // TODO: (b/79432584) evaluate whether should broadcast card state change
                 // even if it's inactive.
@@ -211,6 +214,22 @@
         return mUiccCard == null;
     }
 
+    // Return true if a slot index is for removable UICCs or eUICCs
+    private boolean isSlotRemovable(int slotIndex) {
+        int[] euiccSlots = mContext.getResources()
+                .getIntArray(com.android.internal.R.array.non_removable_euicc_slots);
+        if (euiccSlots == null) {
+            return true;
+        }
+        for (int euiccSlot : euiccSlots) {
+            if (euiccSlot == slotIndex) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
     private void checkIsEuiccSupported() {
         if (mAtr != null && mAtr.isEuiccSupported()) {
             mIsEuicc = true;
@@ -236,6 +255,10 @@
         return mPhoneId;
     }
 
+    public boolean isRemovable() {
+        return mIsRemovable;
+    }
+
     public String getIccId() {
         if (mIccId != null) {
             return mIccId;
diff --git a/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java b/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java
index d00475c..2c103ca 100644
--- a/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java
+++ b/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
+
 
 /**
  * Wrapper class for the USIM Service Table EF.
@@ -24,16 +26,20 @@
 public final class UsimServiceTable extends IccServiceTable {
     public enum UsimService {
         PHONEBOOK,
+        @UnsupportedAppUsage
         FDN,                                // Fixed Dialing Numbers
         FDN_EXTENSION,                      // FDN extension data in EF_EXT2
+        @UnsupportedAppUsage
         SDN,                                // Service Dialing Numbers
         SDN_EXTENSION,                      // SDN extension data in EF_EXT3
         BDN,                                // Barred Dialing Numbers
         BDN_EXTENSION,                      // BDN extension data in EF_EXT4
         OUTGOING_CALL_INFO,
         INCOMING_CALL_INFO,
+        @UnsupportedAppUsage
         SM_STORAGE,
         SM_STATUS_REPORTS,
+        @UnsupportedAppUsage
         SM_SERVICE_PARAMS,
         ADVICE_OF_CHARGE,
         CAP_CONFIG_PARAMS_2,
@@ -41,8 +47,10 @@
         CB_MESSAGE_ID_RANGES,
         GROUP_ID_LEVEL_1,
         GROUP_ID_LEVEL_2,
+        @UnsupportedAppUsage
         SPN,                                // Service Provider Name
         USER_PLMN_SELECT,
+        @UnsupportedAppUsage
         MSISDN,
         IMAGE,
         LOCALISED_SERVICE_AREAS,
@@ -67,10 +75,15 @@
         OPERATOR_PLMN_SELECT,
         HPLMN_SELECT,
         EXTENSION_5,                        // Extension data for ICI, OCI, MSISDN in EF_EXT5
+        @UnsupportedAppUsage
         PLMN_NETWORK_NAME,
+        @UnsupportedAppUsage
         OPERATOR_PLMN_LIST,
+        @UnsupportedAppUsage
         MBDN,                               // Mailbox Dialing Numbers
+        @UnsupportedAppUsage
         MWI_STATUS,                         // Message Waiting Indication status
+        @UnsupportedAppUsage
         CFI_STATUS,                         // Call Forwarding Indication status
         IGNORED_2,
         SERVICE_PROVIDER_DISPLAY_INFO,
@@ -108,12 +121,16 @@
         IWLAN_HPLMN_PRIORITY_INDICATION,
         IWLAN_LAST_REGISTERED_PLMN,
         EPS_MOBILITY_MANAGEMENT_INFO,
+        @UnsupportedAppUsage
         ALLOWED_CSG_LISTS_AND_INDICATIONS,
         CALL_CONTROL_ON_EPS_PDN_CONNECTION_BY_USIM,
         HPLMN_DIRECT_ACCESS,
         ECALL_DATA,
+        @UnsupportedAppUsage
         OPERATOR_CSG_LISTS_AND_INDICATIONS,
+        @UnsupportedAppUsage
         SM_OVER_IP,
+        @UnsupportedAppUsage
         CSG_DISPLAY_CONTROL,
         IMS_COMMUNICATION_CONTROL_BY_USIM,
         EXTENDED_TERMINAL_APPLICATIONS,
@@ -125,6 +142,7 @@
         super(table);
     }
 
+    @UnsupportedAppUsage
     public boolean isAvailable(UsimService service) {
         return super.isAvailable(service.ordinal());
     }
diff --git a/src/java/com/android/internal/telephony/uicc/VoiceMailConstants.java b/src/java/com/android/internal/telephony/uicc/VoiceMailConstants.java
index 2c70648..b3bdf14 100644
--- a/src/java/com/android/internal/telephony/uicc/VoiceMailConstants.java
+++ b/src/java/com/android/internal/telephony/uicc/VoiceMailConstants.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Environment;
 import android.util.Xml;
 import android.telephony.Rlog;
@@ -46,6 +47,7 @@
     static final int TAG = 2;
     static final int SIZE = 3;
 
+    @UnsupportedAppUsage
     VoiceMailConstants () {
         CarrierVmMap = new HashMap<String, String[]>();
         loadVoiceMail();
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java b/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java
index 4e4b4d7..7cfb8b0 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java
@@ -19,10 +19,12 @@
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 
-import android.os.IBinder;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -40,9 +42,9 @@
 public class ImsMmTelManagerTests extends TelephonyTest {
 
     @Mock
-    IBinder mMockBinder;
+    ITelephony.Stub mMockTelephonyInterface;
     @Mock
-    ITelephony mMockTelephonyInterface;
+    IPackageManager.Stub mMockPackageManager;
 
     public class LocalCallback extends ImsMmTelManager.RegistrationCallback {
         int mRegResult = -1;
@@ -56,8 +58,13 @@
     @Before
     public void setUp() throws Exception {
         super.setUp("ImsMmTelManagerTests");
-        doReturn(mMockTelephonyInterface).when(mMockBinder).queryLocalInterface(anyString());
-        mServiceManagerMockedServices.put("phone", mMockBinder);
+        doReturn(mMockTelephonyInterface).when(mMockTelephonyInterface).queryLocalInterface(
+                anyString());
+        doReturn(mMockPackageManager).when(mMockPackageManager).queryLocalInterface(anyString());
+        doReturn(true).when(mMockPackageManager).hasSystemFeature(
+                eq(PackageManager.FEATURE_TELEPHONY_IMS), anyInt());
+        mServiceManagerMockedServices.put("phone", mMockTelephonyInterface);
+        mServiceManagerMockedServices.put("package", mMockPackageManager);
     }
 
     @After
@@ -85,9 +92,9 @@
         IImsRegistrationCallback cbBinder = callbackCaptor.getValue();
         // Ensure the transport types are correct
         cbBinder.onRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
-        assertEquals(AccessNetworkConstants.TransportType.WWAN, cb.mRegResult);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, cb.mRegResult);
         cbBinder.onRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
-        assertEquals(AccessNetworkConstants.TransportType.WLAN, cb.mRegResult);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, cb.mRegResult);
         cbBinder.onRegistered(ImsRegistrationImplBase.REGISTRATION_TECH_NONE);
         assertEquals(-1, cb.mRegResult);
         // Wacky value
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
index 57f33ce..aa37ff7 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
@@ -226,7 +226,7 @@
     public void testRegistrationCallbackNoCallbackIfUnknown() throws RemoteException {
         mRegBinder.addRegistrationCallback(mCallback2);
         // Verify that if we have never set the registration state, we do not callback immediately
-        // with onDeregistered.
+        // with onUnregistered.
         verify(mCallback2, never()).onDeregistered(any(ImsReasonInfo.class));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
index a584f87..bef29e2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
@@ -15,8 +15,6 @@
  */
 package com.android.internal.telephony;
 
-import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
-
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Mockito.doReturn;
@@ -32,7 +30,6 @@
 import android.os.Message;
 import android.provider.Settings;
 import android.provider.Telephony;
-import android.telephony.CarrierConfigManager;
 import android.test.mock.MockContentResolver;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -47,6 +44,7 @@
     private FakeContentResolver mFakeContentResolver;
     private static int DATA_CARRIER_ACTION_EVENT = 0;
     private static int RADIO_CARRIER_ACTION_EVENT = 1;
+    private static int TEST_TIMEOUT = 5000;
     private CarrierActionAgentHandler mCarrierActionAgentHandler;
     @Mock
     private Handler mDataActionHandler;
@@ -105,7 +103,7 @@
         intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE,
                 IccCardConstants.INTENT_VALUE_ICC_LOADED);
         mContext.sendBroadcast(intent);
-        waitForMs(200);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
 
         // no carrier actions triggered from sim loading since there are same as the current one
         ArgumentCaptor<Message> message = ArgumentCaptor.forClass(Message.class);
@@ -115,7 +113,8 @@
         // disable metered apns and radio
         mCarrierActionAgentUT.carrierActionSetRadioEnabled(false);
         mCarrierActionAgentUT.carrierActionSetMeteredApnsEnabled(false);
-        waitForMs(200);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
         verify(mDataActionHandler, times(1)).sendMessageAtTime(message.capture(), anyLong());
         assertEquals(DATA_CARRIER_ACTION_EVENT, message.getValue().what);
         assertEquals(false, ((AsyncResult) message.getValue().obj).result);
@@ -127,7 +126,9 @@
         Settings.Global.putInt(mFakeContentResolver, Settings.Global.AIRPLANE_MODE_ON, 1);
         mFakeContentResolver.notifyChange(
                 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), null);
-        waitForMs(200);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
 
         // carrier actions triggered from APM
         verify(mDataActionHandler, times(2)).sendMessageAtTime(message.capture(), anyLong());
@@ -147,7 +148,7 @@
         intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE,
                 IccCardConstants.INTENT_VALUE_ICC_LOADED);
         mContext.sendBroadcast(intent);
-        waitForMs(200);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
 
         // no carrier actions triggered from sim loading since there are same as the current one
         ArgumentCaptor<Message> message = ArgumentCaptor.forClass(Message.class);
@@ -157,7 +158,8 @@
         // disable metered apns and radio
         mCarrierActionAgentUT.carrierActionSetRadioEnabled(false);
         mCarrierActionAgentUT.carrierActionSetMeteredApnsEnabled(false);
-        waitForMs(200);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
 
         verify(mDataActionHandler, times(1)).sendMessageAtTime(message.capture(), anyLong());
         assertEquals(DATA_CARRIER_ACTION_EVENT, message.getValue().what);
@@ -169,7 +171,9 @@
 
         // Simulate APN change
         mFakeContentResolver.notifyChange(Telephony.Carriers.CONTENT_URI, null);
-        waitForMs(200);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
+        waitForHandlerAction(mCarrierActionAgentUT, TEST_TIMEOUT);
 
         // Carrier actions triggered from APN change
         verify(mDataActionHandler, times(2)).sendMessageAtTime(message.capture(), anyLong());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java
index 6a57469..2604959 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java
@@ -177,27 +177,27 @@
         mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
         assertEquals(CID_ATT, mCarrierResolver.getCarrierId());
-        assertEquals(CID_ATT, mCarrierResolver.getPreciseCarrierId());
+        assertEquals(CID_ATT, mCarrierResolver.getSpecificCarrierId());
 
         doReturn(GID_TRACFONE).when(mPhone).getGroupIdLevel1();
         mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
         assertEquals(CID_TRACFONE, mCarrierResolver.getCarrierId());
-        assertEquals(CID_TRACFONE_ATT, mCarrierResolver.getPreciseCarrierId());
+        assertEquals(CID_TRACFONE_ATT, mCarrierResolver.getSpecificCarrierId());
 
         doReturn(MCCMNC_TRACFONE_TMO).when(mTelephonyManager)
                 .getSimOperatorNumericForPhone(eq(phoneId));
         mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
         assertEquals(CID_TRACFONE, mCarrierResolver.getCarrierId());
-        assertEquals(CID_TRACFONE_TMO, mCarrierResolver.getPreciseCarrierId());
+        assertEquals(CID_TRACFONE_TMO, mCarrierResolver.getSpecificCarrierId());
 
         doReturn(MCCMNC_O2).when(mTelephonyManager)
                 .getSimOperatorNumericForPhone(eq(phoneId));
         mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
         assertEquals(CID_O2, mCarrierResolver.getCarrierId());
-        assertEquals(CID_O2, mCarrierResolver.getPreciseCarrierId());
+        assertEquals(CID_O2, mCarrierResolver.getSpecificCarrierId());
 
         doReturn(MCCMNC_O2).when(mTelephonyManager)
                 .getSimOperatorNumericForPhone(eq(phoneId));
@@ -205,7 +205,7 @@
         mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
         waitForMs(200);
         assertEquals(CID_O2, mCarrierResolver.getCarrierId());
-        assertEquals(CID_O2_PREPAID, mCarrierResolver.getPreciseCarrierId());
+        assertEquals(CID_O2_PREPAID, mCarrierResolver.getSpecificCarrierId());
     }
 
     @Test
@@ -223,6 +223,7 @@
         waitForMs(200);
         assertEquals(CID_UNKNOWN, mCarrierResolver.getCarrierId());
         assertNull(mCarrierResolver.getCarrierName());
+        assertNull(mCarrierResolver.getCarrierName());
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierRestrictionRulesTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierRestrictionRulesTest.java
index 1eac933..fdefa1d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierRestrictionRulesTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierRestrictionRulesTest.java
@@ -207,7 +207,7 @@
         list.add(new CarrierIdentifier(MCC4, MNC4, null, null, null, null));
         list.add(new CarrierIdentifier(MCC5, MNC5, null, null, null, null));
 
-        List<Boolean> result = rules.isCarrierIdentifiersAllowed(list);
+        List<Boolean> result = rules.areCarrierIdentifiersAllowed(list);
 
         List<Boolean> expected =
                 Arrays.asList(true, true, true, true, true, true, true, true, true, true, true);
@@ -247,7 +247,7 @@
         list.add(new CarrierIdentifier(MCC4, MNC4, null, null, null, null));
         list.add(new CarrierIdentifier(MCC5, MNC5, null, null, null, null));
 
-        List<Boolean> result = rules.isCarrierIdentifiersAllowed(list);
+        List<Boolean> result = rules.areCarrierIdentifiersAllowed(list);
 
         List<Boolean> expected =
                 Arrays.asList(true, true, true, true, true, true, true,
@@ -282,7 +282,7 @@
         list.add(new CarrierIdentifier(MCC1, MNC3, null, null, null, null));
         list.add(new CarrierIdentifier(MCC1, MNC4, null, null, null, null));
 
-        List<Boolean> result = rules.isCarrierIdentifiersAllowed(list);
+        List<Boolean> result = rules.areCarrierIdentifiersAllowed(list);
 
         List<Boolean> expected = Arrays.asList(true, true, true, true, false, false);
         assertTrue(result.equals(expected));
@@ -309,7 +309,7 @@
         list.add(new CarrierIdentifier(MCC4, MNC4, null, null, null, null));
         list.add(new CarrierIdentifier(MCC5, MNC5, null, null, null, null));
 
-        List<Boolean> result = rules.isCarrierIdentifiersAllowed(list);
+        List<Boolean> result = rules.areCarrierIdentifiersAllowed(list);
 
         List<Boolean> expected = Arrays.asList(true, true, true, true);
         assertTrue(result.equals(expected));
@@ -335,7 +335,7 @@
         list.add(new CarrierIdentifier(MCC4, MNC4, null, null, null, null));
         list.add(new CarrierIdentifier(MCC5, MNC5, null, null, null, null));
 
-        List<Boolean> result = rules.isCarrierIdentifiersAllowed(list);
+        List<Boolean> result = rules.areCarrierIdentifiersAllowed(list);
 
         List<Boolean> expected = Arrays.asList(false, false, false);
         assertTrue(result.equals(expected));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityNrTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityNrTest.java
index e6e8590..ed7fc1c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityNrTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityNrTest.java
@@ -45,7 +45,7 @@
 
         // THEN the get method should return correct value
         assertThat(cellIdentityNr.getType()).isEqualTo(CellInfo.TYPE_NR);
-        assertThat(cellIdentityNr.getChannelNumber()).isEqualTo(NRARFCN);
+        assertThat(cellIdentityNr.getNrarfcn()).isEqualTo(NRARFCN);
         assertThat(cellIdentityNr.getPci()).isEqualTo(PCI);
         assertThat(cellIdentityNr.getTac()).isEqualTo(TAC);
         assertThat(cellIdentityNr.getOperatorAlphaLong()).isEqualTo(ALPHAL);
@@ -95,7 +95,7 @@
         // THEN the new object is equal to the old one
         assertThat(anotherCellIdentityNr).isEqualTo(anotherCellIdentityNr);
         assertThat(anotherCellIdentityNr.getType()).isEqualTo(CellInfo.TYPE_NR);
-        assertThat(anotherCellIdentityNr.getChannelNumber()).isEqualTo(NRARFCN);
+        assertThat(anotherCellIdentityNr.getNrarfcn()).isEqualTo(NRARFCN);
         assertThat(anotherCellIdentityNr.getPci()).isEqualTo(PCI);
         assertThat(anotherCellIdentityNr.getTac()).isEqualTo(TAC);
         assertThat(anotherCellIdentityNr.getOperatorAlphaLong()).isEqualTo(ALPHAL);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
index c9d82a4..918b705 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
@@ -133,7 +133,7 @@
         waitForMs(1000);
 
         NetworkRegistrationState expectedState = new NetworkRegistrationState(
-                domain, AccessNetworkConstants.TransportType.WWAN, voiceRegState,
+                domain, AccessNetworkConstants.TRANSPORT_TYPE_WWAN, voiceRegState,
                 ServiceState.rilRadioTechnologyToNetworkType(voiceRadioTech), reasonForDenial,
                 false, availableServices, null, cssSupported,
                 roamingIndicator, systemIsInPrl, defaultRoamingIndicator);
@@ -160,7 +160,7 @@
                         LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
 
         expectedState = new NetworkRegistrationState(
-                domain, AccessNetworkConstants.TransportType.WWAN, voiceRegState,
+                domain, AccessNetworkConstants.TRANSPORT_TYPE_WWAN, voiceRegState,
                 ServiceState.rilRadioTechnologyToNetworkType(voiceRadioTech), reasonForDenial,
                 false, availableServices, null, maxDataCalls, false, false, false,
                 lteVopsSupportInfo);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index 5637892..8df07b4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -41,7 +41,9 @@
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.AssetManager;
@@ -528,6 +530,7 @@
     private final Multimap<Intent, BroadcastReceiver> mOrderedBroadcastReceivers =
             ArrayListMultimap.create();
     private final HashSet<String> mPermissionTable = new HashSet<>();
+    private final HashSet<String> mSystemFeatures = new HashSet<>();
 
 
 
@@ -556,6 +559,7 @@
     private final BatteryManager mBatteryManager = mock(BatteryManager.class);
     private final EuiccManager mEuiccManager = mock(EuiccManager.class);
     private final TelecomManager mTelecomManager = mock(TelecomManager.class);
+    private final PackageInfo mPackageInfo = mock(PackageInfo.class);
 
     private final ContentProvider mContentProvider = spy(new FakeContentProvider());
 
@@ -586,6 +590,16 @@
             }
         }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), anyInt());
 
+        try {
+            doReturn(mPackageInfo).when(mPackageManager).getPackageInfoAsUser(any(), anyInt(),
+                    anyInt());
+        } catch (NameNotFoundException e) {
+        }
+
+        doAnswer((Answer<Boolean>)
+                invocation -> mSystemFeatures.contains((String) invocation.getArgument(0)))
+                .when(mPackageManager).hasSystemFeature(any());
+
         doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
         //doReturn(mBundle).when(mCarrierConfigManager).getConfig(anyInt());
         doReturn(mBundle).when(mCarrierConfigManager).getConfig();
@@ -697,6 +711,10 @@
         }
     }
 
+    public void addSystemFeature(String feature) {
+        mSystemFeatures.add(feature);
+    }
+
     private static void logd(String s) {
         Log.d(TAG, s);
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
index 6ef0f7e..72d9296 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
@@ -28,6 +28,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
@@ -104,7 +105,7 @@
         assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState());
         assertEquals(0, mCTUT.mForegroundCall.getConnections().size());
         try {
-            mCTUT.dial(mDialString);
+            mCTUT.dial(mDialString, new Bundle());
             waitForMs(100);
         } catch(Exception ex) {
             ex.printStackTrace();
@@ -117,7 +118,7 @@
         /* verify the command is sent out to RIL */
         verify(mSimulatedCommandsVerifier).dial(
                 eq(PhoneNumberUtils.extractNetworkPortionAlt(mDialString)), eq(false),
-                eq(null), anyInt(), eq((UUSInfo) null), isA(Message.class));
+                eq(null), eq(false), anyInt(), eq((UUSInfo) null), isA(Message.class));
     }
 
     @Test
@@ -218,7 +219,7 @@
 
         String mDialString = PhoneNumberUtils.stripSeparators("+17005554142");
         try {
-            mCTUT.dial(mDialString);
+            mCTUT.dial(mDialString, new Bundle());
         } catch(Exception ex) {
             ex.printStackTrace();
             Assert.fail("unexpected exception thrown" + ex.getMessage());
@@ -464,7 +465,7 @@
         waitForHandlerAction(mSimulatedCommands.getHandler(), 5000);
         // Try to place another call.
         try {
-            mCTUT.dial("650-555-1212");
+            mCTUT.dial("650-555-1212", new Bundle());
         } catch (CallStateException cse) {
             assertEquals(CallStateException.ERROR_OTASP_PROVISIONING_IN_PROCESS, cse.getError());
             return;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index d54ae1d..7e84f2d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -345,7 +345,7 @@
 
             Connection connection = mPhoneUT.dial("1234567890",
                     new PhoneInternalInterface.DialArgs.Builder().build());
-            verify(mCT).dial("1234567890", null, null);
+            verify(mCT).dialGsm("1234567890", null, null);
         } catch (CallStateException e) {
             fail();
         }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
index 06cd54f..ad5d0ab 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
@@ -48,6 +48,14 @@
     }
 
     @SmallTest
+    public void testRecipientAddress() throws Exception {
+        String pdu = "0891683108200505F011000D91683196032930F000000006C8329BFD0E01";
+        SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
+        assertEquals("+8613800250500", sms.getServiceCenterAddress());
+        assertEquals("+8613693092030", sms.getRecipientAddress());
+    }
+
+    @SmallTest
     public void testUdh() throws Exception {
         String pdu = "07914140279510F6440A8111110301003BF56080207130138A8C0B05040B8423F"
                 + "000032A02010106276170706C69636174696F6E2F766E642E7761702E6D6D732D"
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java
index 1f553fe..636bbc5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java
@@ -19,7 +19,7 @@
 import static junit.framework.Assert.assertEquals;
 
 import android.os.Parcel;
-import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.CellIdentityLte;
 import android.telephony.NetworkRegistrationState;
 import android.telephony.TelephonyManager;
@@ -36,7 +36,7 @@
     public void testParcel() {
         NetworkRegistrationState nrs = new NetworkRegistrationState(
                 NetworkRegistrationState.DOMAIN_CS,
-                TransportType.WWAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationState.REG_STATE_HOME,
                 TelephonyManager.NETWORK_TYPE_LTE,
                 0,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
index ceb3e8b..d5f400b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
@@ -40,6 +40,7 @@
 import android.os.HandlerThread;
 import android.os.Message;
 import android.os.Messenger;
+import android.telephony.PhoneCapability;
 import android.telephony.SubscriptionManager;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -88,6 +89,9 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
+
+        PhoneCapability phoneCapability = new PhoneCapability(1, 1, 0, null, false);
+        doReturn(phoneCapability).when(mPhoneConfigurationManager).getCurrentPhoneCapability();
     }
 
     @After
@@ -382,13 +386,14 @@
         assertTrue(mDataAllowed[0]);
 
         // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated.
-        mPhoneSwitcher.setPreferredDataSubscriptionId(2);
+        mPhoneSwitcher.trySetPreferredSubscription(2, false, null);
         waitABit();
         assertFalse(mDataAllowed[0]);
         assertTrue(mDataAllowed[1]);
 
         // Unset preferred sub should make default data sub (phone 0 / sub 1) activated again.
-        mPhoneSwitcher.setPreferredDataSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+        mPhoneSwitcher.trySetPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                false, null);
         waitABit();
         assertTrue(mDataAllowed[0]);
         assertFalse(mDataAllowed[1]);
@@ -437,7 +442,7 @@
         assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));
 
         // Set sub 2 as preferred sub should make phone 1 preferredDataModem
-        mPhoneSwitcher.setPreferredDataSubscriptionId(2);
+        mPhoneSwitcher.trySetPreferredSubscription(2, false, null);
         waitABit();
         verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
         verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
@@ -450,7 +455,8 @@
         clearInvocations(mActivePhoneSwitchHandler);
 
         // Unset preferred sub should make phone0 preferredDataModem again.
-        mPhoneSwitcher.setPreferredDataSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+        mPhoneSwitcher.trySetPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                false, null);
         waitABit();
         verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
         verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
@@ -636,7 +642,13 @@
         doReturn(mDefaultDataSub).when(mSubscriptionController).getDefaultDataSubId();
         doAnswer(invocation -> {
             int phoneId = (int) invocation.getArguments()[0];
-            return mSlotIndexToSubId[phoneId][0];
+            if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
+                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            } else if (phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
+                return mSlotIndexToSubId[0][0];
+            } else {
+                return mSlotIndexToSubId[phoneId][0];
+            }
         }).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt());
 
         doAnswer(invocation -> {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
index dfc2a0b..206ebea 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
@@ -151,6 +151,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 public class RILTest extends TelephonyTest {
 
@@ -212,7 +213,7 @@
     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;
+    private static final int TIMING_ADVANCE = 4;
     private static final long TIMESTAMP = 215924934;
     private static final int UARFCN = 690;
     private static final int TYPE_CDMA = 2;
@@ -1099,7 +1100,7 @@
         lte.signalStrengthLte.rsrq = -RSRQ;
         lte.signalStrengthLte.rssnr = RSSNR;
         lte.signalStrengthLte.cqi = CQI;
-        lte.signalStrengthLte.timingAdvance = TIME_ADVANCE;
+        lte.signalStrengthLte.timingAdvance = TIMING_ADVANCE;
         android.hardware.radio.V1_0.CellInfo record = new android.hardware.radio.V1_0.CellInfo();
         record.cellInfoType = TYPE_LTE;
         record.registered = false;
@@ -1120,7 +1121,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(
-                RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
+                RSSI, RSRP, RSRQ, RSSNR, CQI, TIMING_ADVANCE);
         expected.setCellIdentity(cil);
         expected.setCellSignalStrength(css);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_UNKNOWN);
@@ -1140,7 +1141,7 @@
         cellinfo.cellIdentityGsm.mnc = MNC_STR;
         cellinfo.signalStrengthGsm.signalStrength = RSSI_ASU;
         cellinfo.signalStrengthGsm.bitErrorRate = BIT_ERROR_RATE;
-        cellinfo.signalStrengthGsm.timingAdvance = TIME_ADVANCE;
+        cellinfo.signalStrengthGsm.timingAdvance = TIMING_ADVANCE;
         android.hardware.radio.V1_0.CellInfo record = new android.hardware.radio.V1_0.CellInfo();
         record.cellInfoType = TYPE_GSM;
         record.registered = false;
@@ -1161,7 +1162,7 @@
         CellIdentityGsm ci = new CellIdentityGsm(
                 LAC, CID, ARFCN, BSIC, MCC_STR, MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
         CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
-                RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
+                RSSI, BIT_ERROR_RATE, TIMING_ADVANCE);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_UNKNOWN);
@@ -1305,7 +1306,7 @@
         CellIdentityLte cil = new CellIdentityLte(
                 CI, PCI, TAC, EARFCN, BANDWIDTH, MCC_STR, MNC_STR, ALPHA_LONG, ALPHA_SHORT);
         CellSignalStrengthLte css = new CellSignalStrengthLte(
-                RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
+                RSSI, RSRP, RSRQ, RSSNR, CQI, TIMING_ADVANCE);
         expected.setCellIdentity(cil);
         expected.setCellSignalStrength(css);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1326,7 +1327,7 @@
         CellIdentityLte cil = new CellIdentityLte(CI, PCI, TAC, EARFCN, BANDWIDTH, MCC_STR, MNC_STR,
                 EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
         CellSignalStrengthLte css = new CellSignalStrengthLte(
-                RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
+                RSSI, RSRP, RSRQ, RSSNR, CQI, TIMING_ADVANCE);
         expected.setCellIdentity(cil);
         expected.setCellSignalStrength(css);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1349,7 +1350,7 @@
         CellIdentityLte cil = new CellIdentityLte(
                 CI, PCI, TAC, EARFCN, BANDWIDTH, null, null, ALPHA_LONG, ALPHA_SHORT);
         CellSignalStrengthLte css = new CellSignalStrengthLte(
-                RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
+                RSSI, RSRP, RSRQ, RSSNR, CQI, TIMING_ADVANCE);
         expected.setCellIdentity(cil);
         expected.setCellSignalStrength(css);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1369,7 +1370,7 @@
         CellIdentityGsm ci = new CellIdentityGsm(
                 LAC, CID, ARFCN, BSIC, MCC_STR, MNC_STR, ALPHA_LONG, ALPHA_SHORT);
         CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
-                RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
+                RSSI, BIT_ERROR_RATE, TIMING_ADVANCE);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1390,7 +1391,7 @@
         CellIdentityGsm ci = new CellIdentityGsm(
                 LAC, CID, ARFCN, BSIC, MCC_STR, MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
         CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
-                RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
+                RSSI, BIT_ERROR_RATE, TIMING_ADVANCE);
         expected.setCellIdentity(ci);
         expected.setCellSignalStrength(cs);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1413,7 +1414,7 @@
         CellIdentityGsm ci = new CellIdentityGsm(
                 LAC, CID, ARFCN, BSIC, null, null, ALPHA_LONG, ALPHA_SHORT);
         CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
-                RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
+                RSSI, BIT_ERROR_RATE, TIMING_ADVANCE);
         expected.setCellIdentity(ci);
         expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
         expected.setCellSignalStrength(cs);
@@ -1603,24 +1604,89 @@
         assertEquals("100:foo", request.getWorkSourceClientId());
     }
 
-    private ArrayList<CellInfo> getCellInfoListForLTE(
-            String mcc, String mnc, String alphaLong, String alphaShort) {
-        android.hardware.radio.V1_2.CellInfoLte lte = new android.hardware.radio.V1_2.CellInfoLte();
+    @Test
+    public void testCellInfoTimestamp_1_4() {
+        ArrayList<android.hardware.radio.V1_4.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_4.CellInfo>();
+
+        for (int i = 0; i < 5 /* arbitrary */; i++) {
+            android.hardware.radio.V1_4.CellInfo record =
+                    new android.hardware.radio.V1_4.CellInfo();
+            record.info = new android.hardware.radio.V1_4.CellInfo.Info();
+            record.info.lte(new android.hardware.radio.V1_4.CellInfoLte());
+            initializeCellInfoLte_1_2(record.info.lte().base);
+            record.info.lte().base.cellIdentityLte.base.ci += i; // make them marginally unique
+
+            records.add(record);
+        }
+        List<CellInfo> cil = RIL.convertHalCellInfoList_1_4(records);
+
+        // Check that all timestamps are set to a valid number and are equal
+        final long ts = cil.get(0).getTimeStamp();
+        for (CellInfo ci : cil) {
+            assertTrue(ci.getTimeStamp() > 0 && ci.getTimeStamp() != Long.MAX_VALUE);
+            assertEquals(ci.getTimeStamp(), ts);
+        }
+    }
+
+    @Test
+    public void testCellInfoTimestamp_1_2() {
+        ArrayList<android.hardware.radio.V1_2.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_2.CellInfo>();
+
+        for (int i = 0; i < 5 /* arbitrary */; i++) {
+            android.hardware.radio.V1_2.CellInfo record =
+                    new android.hardware.radio.V1_2.CellInfo();
+            record.cellInfoType = TYPE_LTE;
+            record.timeStamp = Long.MAX_VALUE;
+            record.registered = false;
+            record.timeStampType = RIL_TIMESTAMP_TYPE_OEM_RIL;
+            record.lte.add(new android.hardware.radio.V1_2.CellInfoLte());
+            initializeCellInfoLte_1_2(record.lte.get(0));
+            record.lte.get(0).cellIdentityLte.base.ci += i; // make them marginally unique
+
+            records.add(record);
+        }
+        List<CellInfo> cil = RIL.convertHalCellInfoList_1_2(records);
+
+        // Check that all timestamps are set to a valid number and are equal
+        final long ts = cil.get(0).getTimeStamp();
+        for (CellInfo ci : cil) {
+            assertTrue(ci.getTimeStamp() > 0 && ci.getTimeStamp() != Long.MAX_VALUE);
+            assertEquals(ci.getTimeStamp(), ts);
+        }
+    }
+
+    private static void initializeCellInfoLte_1_2(android.hardware.radio.V1_2.CellInfoLte lte) {
         lte.cellIdentityLte.base.ci = CI;
         lte.cellIdentityLte.base.pci = PCI;
         lte.cellIdentityLte.base.tac = TAC;
         lte.cellIdentityLte.base.earfcn = EARFCN;
         lte.cellIdentityLte.bandwidth = BANDWIDTH;
-        lte.cellIdentityLte.base.mcc = mcc;
-        lte.cellIdentityLte.base.mnc = mnc;
-        lte.cellIdentityLte.operatorNames.alphaLong = alphaLong;
-        lte.cellIdentityLte.operatorNames.alphaShort = alphaShort;
         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;
+        lte.signalStrengthLte.timingAdvance = TIMING_ADVANCE;
+
+        lte.cellIdentityLte.operatorNames.alphaLong = ALPHA_LONG;
+        lte.cellIdentityLte.operatorNames.alphaShort = ALPHA_SHORT;
+        lte.cellIdentityLte.base.mcc = MCC_STR;
+        lte.cellIdentityLte.base.mnc = MNC_STR;
+    }
+
+    private ArrayList<CellInfo> getCellInfoListForLTE(
+            String mcc, String mnc, String alphaLong, String alphaShort) {
+        android.hardware.radio.V1_2.CellInfoLte lte = new android.hardware.radio.V1_2.CellInfoLte();
+
+        initializeCellInfoLte_1_2(lte);
+        // Override the defaults for test-specific purposes
+        lte.cellIdentityLte.operatorNames.alphaLong = alphaLong;
+        lte.cellIdentityLte.operatorNames.alphaShort = alphaShort;
+        lte.cellIdentityLte.base.mcc = mcc;
+        lte.cellIdentityLte.base.mnc = mnc;
+
         android.hardware.radio.V1_2.CellInfo record = new android.hardware.radio.V1_2.CellInfo();
         record.cellInfoType = TYPE_LTE;
         record.registered = false;
@@ -1648,7 +1714,7 @@
         cellinfo.cellIdentityGsm.operatorNames.alphaShort = alphaShort;
         cellinfo.signalStrengthGsm.signalStrength = RSSI_ASU;
         cellinfo.signalStrengthGsm.bitErrorRate = BIT_ERROR_RATE;
-        cellinfo.signalStrengthGsm.timingAdvance = TIME_ADVANCE;
+        cellinfo.signalStrengthGsm.timingAdvance = TIMING_ADVANCE;
         android.hardware.radio.V1_2.CellInfo record = new android.hardware.radio.V1_2.CellInfo();
         record.cellInfoType = TYPE_GSM;
         record.registered = false;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java
index 45a4a7b..dd40f7f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java
@@ -38,7 +38,7 @@
         ServiceState ss = new ServiceState();
         // add data registration state
         ss.addNetworkRegistrationState(new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationState.REG_STATE_ROAMING,
                 TelephonyManager.NETWORK_TYPE_UNKNOWN, 0,
                 false, null, null));
@@ -285,7 +285,7 @@
     @SmallTest
     public void testNetworkRegistrationState() {
         NetworkRegistrationState wwanVoiceRegState = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 0, 0, 0, false,
                 null, null, true, 0, 0, 0);
 
@@ -293,12 +293,12 @@
                 new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
                         LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
         NetworkRegistrationState wwanDataRegState = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 0, 0, 0, false, null, null, 0, false, false, false,
                 lteVopsSupportInfo);
 
         NetworkRegistrationState wlanRegState = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WLAN,
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
                 0, 0, 0, false,
                 null, null);
 
@@ -309,18 +309,18 @@
         ss.addNetworkRegistrationState(wlanRegState);
 
         assertEquals(ss.getNetworkRegistrationStates(NetworkRegistrationState.DOMAIN_CS,
-                AccessNetworkConstants.TransportType.WWAN), wwanVoiceRegState);
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN), wwanVoiceRegState);
         assertEquals(ss.getNetworkRegistrationStates(NetworkRegistrationState.DOMAIN_PS,
-                AccessNetworkConstants.TransportType.WWAN), wwanDataRegState);
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN), wwanDataRegState);
         assertEquals(ss.getNetworkRegistrationStates(NetworkRegistrationState.DOMAIN_PS,
-                AccessNetworkConstants.TransportType.WLAN), wlanRegState);
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN), wlanRegState);
 
         wwanDataRegState = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 0, 0, 0, true, null, null, 0, false, false, false, lteVopsSupportInfo);
         ss.addNetworkRegistrationState(wwanDataRegState);
         assertEquals(ss.getNetworkRegistrationStates(NetworkRegistrationState.DOMAIN_PS,
-                AccessNetworkConstants.TransportType.WWAN), wwanDataRegState);
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN), wwanDataRegState);
     }
 
     @SmallTest
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index aa7160e..4742279 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -57,7 +57,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellIdentity;
 import android.telephony.CellIdentityCdma;
@@ -224,6 +224,12 @@
         mSSTTestHandler.start();
         waitUntilReady();
         waitForMs(600);
+
+        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
+        mContext.sendBroadcast(intent);
+        waitForMs(100);
+
         logd("ServiceStateTrackerTest -Setup!");
     }
 
@@ -642,7 +648,7 @@
         CellIdentityGsm cellIdentityGsm = new CellIdentityGsm(
                 2, 3, 900, 5, "001", "01", "test", "tst");
         NetworkRegistrationState result = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationState.REG_STATE_HOME, 0, 0, false, null,
                 cellIdentityGsm);
 
@@ -663,7 +669,7 @@
     public void testCdmaCellLocation() {
         CellIdentityCdma cellIdentityCdma = new CellIdentityCdma(1, 2, 3, 4, 5, "test", "tst");
         NetworkRegistrationState result = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationState.REG_STATE_HOME, 0, 0, false, null, cellIdentityCdma);
 
         sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_GET_LOC_DONE,
@@ -903,7 +909,8 @@
 
         waitForMs(100);
 
-        sst.registerForDataConnectionAttached(mTestHandler, EVENT_DATA_CONNECTION_ATTACHED, null);
+        sst.registerForDataConnectionAttached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTestHandler, EVENT_DATA_CONNECTION_ATTACHED, null);
 
         // set service state in service and trigger events to post message on handler
         mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
@@ -925,7 +932,8 @@
         waitForMs(100);
 
         // Unregister registrant
-        sst.unregisterForDataConnectionAttached(mTestHandler);
+        sst.unregisterForDataConnectionAttached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTestHandler);
 
         // set service state in service
         mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
@@ -949,7 +957,8 @@
 
         waitForMs(100);
 
-        sst.registerForDataConnectionAttached(mTestHandler, EVENT_DATA_CONNECTION_ATTACHED, null);
+        sst.registerForDataConnectionAttached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTestHandler, EVENT_DATA_CONNECTION_ATTACHED, null);
 
         // set service state in service and trigger events to post message on handler
         mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
@@ -971,7 +980,8 @@
         waitForMs(100);
 
         // Unregister registrant
-        sst.unregisterForDataConnectionAttached(mTestHandler);
+        sst.unregisterForDataConnectionAttached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTestHandler);
 
         // set service state in service
         mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
@@ -993,7 +1003,8 @@
         mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
         mSimulatedCommands.notifyNetworkStateChanged();
 
-        sst.registerForDataConnectionDetached(mTestHandler, EVENT_DATA_CONNECTION_DETACHED, null);
+        sst.registerForDataConnectionDetached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTestHandler, EVENT_DATA_CONNECTION_DETACHED, null);
 
         // set service state out of service and trigger events to post message on handler
         mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
@@ -1015,7 +1026,8 @@
         waitForMs(100);
 
         // Unregister registrant
-        sst.unregisterForDataConnectionDetached(mTestHandler);
+        sst.unregisterForDataConnectionDetached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTestHandler);
 
         // set service state out of service
         mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
@@ -1050,11 +1062,15 @@
     @Test
     @MediumTest
     public void testRegisterForDataRegStateOrRatChange() {
-        int drs = NetworkRegistrationState.REG_STATE_HOME;
-        int rat = sst.mSS.RIL_RADIO_TECHNOLOGY_LTE;
-        sst.mSS.setRilDataRadioTechnology(rat);
-        sst.mSS.setDataRegState(drs);
-        sst.registerForDataRegStateOrRatChanged(mTestHandler, EVENT_DATA_RAT_CHANGED, null);
+        NetworkRegistrationState nrs = new NetworkRegistrationState.Builder()
+                .setDomain(NetworkRegistrationState.DOMAIN_PS)
+                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+                .setRegState(NetworkRegistrationState.REG_STATE_HOME)
+                .build();
+        sst.mSS.addNetworkRegistrationState(nrs);
+        sst.registerForDataRegStateOrRatChanged(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTestHandler, EVENT_DATA_RAT_CHANGED, null);
 
         waitForMs(100);
 
@@ -1062,7 +1078,8 @@
         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
         verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
         assertEquals(EVENT_DATA_RAT_CHANGED, messageArgumentCaptor.getValue().what);
-        assertEquals(new Pair<Integer, Integer>(drs, rat),
+        assertEquals(new Pair<Integer, Integer>(ServiceState.STATE_IN_SERVICE,
+                        ServiceState.RIL_RADIO_TECHNOLOGY_LTE),
                 ((AsyncResult)messageArgumentCaptor.getValue().obj).result);
     }
 
@@ -1423,7 +1440,8 @@
 
         sst.registerForDataRoamingOff(mTestHandler, EVENT_DATA_ROAMING_OFF, null, true);
         sst.registerForVoiceRoamingOff(mTestHandler, EVENT_VOICE_ROAMING_OFF, null);
-        sst.registerForDataConnectionDetached(mTestHandler, EVENT_DATA_CONNECTION_DETACHED, null);
+        sst.registerForDataConnectionDetached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTestHandler, EVENT_DATA_CONNECTION_DETACHED, null);
 
         // Call functions which would trigger posting of message on test handler
         doReturn(false).when(mPhone).isPhoneTypeGsm();
@@ -1573,7 +1591,8 @@
                 new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
                     LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
         NetworkRegistrationState dataResult = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, TransportType.WWAN, state, dataRat, 0, false,
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                state, dataRat, 0, false,
                 null, cid, 1, false, false, false, lteVopsSupportInfo);
         sst.mPollingContext[0] = 2;
         // update data reg state to be in service
@@ -1582,7 +1601,8 @@
                 new AsyncResult(sst.mPollingContext, dataResult, null)));
         waitForMs(200);
         NetworkRegistrationState voiceResult = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, TransportType.WWAN, state, voiceRat, 0, false,
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                state, voiceRat, 0, false,
                 null, cid, false, 0, 0, 0);
         sst.sendMessage(sst.obtainMessage(
                 ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
@@ -1671,11 +1691,11 @@
                 new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
                     LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
         NetworkRegistrationState dataResult = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationState.REG_STATE_HOME, TelephonyManager.NETWORK_TYPE_LTE, 0,
                 false, null, cellId, 1, false, false, false, lteVopsSupportInfo);
         NetworkRegistrationState voiceResult = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationState.REG_STATE_HOME, TelephonyManager.NETWORK_TYPE_LTE, 0,
                 false, null, cellId, false, 0, 0, 0);
         sst.mPollingContext[0] = 2;
@@ -1742,12 +1762,12 @@
                 new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
                     LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
         NetworkRegistrationState dataResult = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationState.REG_STATE_NOT_REG_NOT_SEARCHING,
                 TelephonyManager.NETWORK_TYPE_UNKNOWN, 0, false, null, null, 1, false, false,
                 false, lteVopsSupportInfo);
         NetworkRegistrationState voiceResult = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationState.REG_STATE_NOT_REG_NOT_SEARCHING,
                 TelephonyManager.NETWORK_TYPE_UNKNOWN, 0, false, null, null, false, 0, 0, 0);
         sst.mPollingContext[0] = 2;
@@ -1796,14 +1816,11 @@
         doReturn(true).when(mRuimRecords).isProvisioned();
         assertEquals(null, sst.getMdnNumber());
 
-        // if ruim is not provisioned, and mdn is non null, sst should still return null
+        // if ruim is not provisioned, and mdn is non null, sst should still return the correct
+        // value
         doReturn(false).when(mRuimRecords).isProvisioned();
         String mockMdn = "mockMdn";
         doReturn(mockMdn).when(mRuimRecords).getMdn();
-        assertEquals(null, sst.getMdnNumber());
-
-        // if ruim is provisioned, and mdn is non null, sst should also return the correct value
-        doReturn(true).when(mRuimRecords).isProvisioned();
         assertEquals(mockMdn, sst.getMdnNumber());
     }
 
@@ -1822,7 +1839,7 @@
                     LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED);
 
         NetworkRegistrationState dataResult = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_PS, TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationState.REG_STATE_HOME, TelephonyManager.NETWORK_TYPE_LTE, 0,
                 false, null, cellId, 1, false, false, false, lteVopsSupportInfo);
         sst.mPollingContext[0] = 2;
@@ -1831,7 +1848,7 @@
                 ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
                 new AsyncResult(sst.mPollingContext, dataResult, null)));
         NetworkRegistrationState voiceResult = new NetworkRegistrationState(
-                NetworkRegistrationState.DOMAIN_CS, TransportType.WWAN,
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 NetworkRegistrationState.REG_STATE_HOME, TelephonyManager.NETWORK_TYPE_LTE, 0,
                 false, null, cellId, false, 0, 0, 0);
         sst.sendMessage(sst.obtainMessage(
@@ -1842,15 +1859,15 @@
         assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
         NetworkRegistrationState sSnetworkRegistrationState =
                 sst.mSS.getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
-                        TransportType.WWAN);
+                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         assertEquals(lteVopsSupportInfo,
-                sSnetworkRegistrationState.getDataSpecificStates().lteVopsSupportInfo);
+                sSnetworkRegistrationState.getDataSpecificStates().getLteVopsSupportInfo());
 
         lteVopsSupportInfo =
                 new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
                     LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED);
         dataResult = new NetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
-                TransportType.WWAN, NetworkRegistrationState.REG_STATE_HOME,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, NetworkRegistrationState.REG_STATE_HOME,
                 TelephonyManager.NETWORK_TYPE_LTE, 0, false, null, cellId, 1, false, false, false,
                 lteVopsSupportInfo);
         sst.mPollingContext[0] = 1;
@@ -1862,6 +1879,6 @@
         sSnetworkRegistrationState =
                 sst.mSS.getNetworkRegistrationState(2, 1);
         assertEquals(lteVopsSupportInfo,
-                sSnetworkRegistrationState.getDataSpecificStates().lteVopsSupportInfo);
+                sSnetworkRegistrationState.getDataSpecificStates().getLteVopsSupportInfo());
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index d4b7b4a..0a683b0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -148,7 +148,7 @@
 
         testInsertSim();
         /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList();
+        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
         assertTrue(subIds != null && subIds.length != 0);
         int subID = subIds[0];
 
@@ -189,7 +189,7 @@
         testInsertSim();
 
         /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList();
+        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
         assertTrue(subIds != null && subIds.length != 0);
         int subID = subIds[0];
 
@@ -300,7 +300,7 @@
     @SmallTest
     public void testMigrateImsSettings() throws Exception {
         testInsertSim();
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList();
+        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
         assertTrue(subIds != null && subIds.length != 0);
         int subID = subIds[0];
 
@@ -554,7 +554,7 @@
         /* insert some sims */
         testInsertMultipleRemoteSims();
         assertEquals(1, mSubscriptionControllerUT.getDefaultSubId());
-        int[] subIdsArray = mSubscriptionControllerUT.getActiveSubIdList();
+        int[] subIdsArray = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
         assertTrue(subIdsArray.length > 0);
         int len = subIdsArray.length;
 
@@ -564,7 +564,7 @@
 
         assertTrue(result > 0);
         // now check the number of subs left. should be one less than earlier
-        int[] newSubIdsArray = mSubscriptionControllerUT.getActiveSubIdList();
+        int[] newSubIdsArray = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
         assertTrue(newSubIdsArray.length > 0);
         assertEquals(len - 1, newSubIdsArray.length);
 
@@ -779,7 +779,7 @@
     public void testEnableDisableSubscriptionSingleSim() throws Exception {
         testInsertSim();
         // UiccSlotInfo that maps logicalSlotIndex 0 to physicalSlotIndex 0.
-        UiccSlotInfo slotInfo = new UiccSlotInfo(true, false, "", 0, 0, false);
+        UiccSlotInfo slotInfo = new UiccSlotInfo(true, false, "", 0, 0, false, false);
         UiccSlotInfo[] slotInfos = new UiccSlotInfo[] {slotInfo};
         doReturn(slotInfos).when(mTelephonyManager).getUiccSlotsInfo();
 
@@ -802,8 +802,8 @@
         mSubscriptionControllerUT.addSubInfoRecord("123", 1);   // sub 1
         mSubscriptionControllerUT.addSubInfoRecord("456", 0);   // sub 2
 
+        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
         // Make sure the return sub ids are sorted by slot index
-        assertTrue("active sub ids = " + mSubscriptionControllerUT.getActiveSubIdList(),
-                Arrays.equals(mSubscriptionControllerUT.getActiveSubIdList(), new int[]{2, 1}));
+        assertTrue("active sub ids = " + subIds, Arrays.equals(subIds, new int[]{2, 1}));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
index c804cd0..52a0cb1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
@@ -151,7 +151,8 @@
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 SubscriptionManager.CONTENT_URI.getAuthority(),
                 new FakeSubscriptionContentProvider());
-        doReturn(new int[]{}).when(mSubscriptionController).getActiveSubIdList();
+        doReturn(new int[]{}).when(mSubscriptionController)
+                .getActiveSubIdList(/*visibleOnly*/false);
         mIccRecord = mUiccProfile.getIccRecords();
 
         mSubscriptionInfoUpdaterHandlerThread = new SubscriptionInfoUpdaterHandlerThread(TAG);
@@ -170,7 +171,8 @@
     public void testSimAbsent() throws Exception {
         doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
                 .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean());
-        doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController).getActiveSubIdList();
+        doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController)
+                .getActiveSubIdList(/*visibleOnly*/false);
         mUpdater.updateInternalIccState(
                 IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1);
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 35bab98..b708b1e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -15,8 +15,8 @@
  */
 package com.android.internal.telephony;
 
+import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
 import static android.telephony.PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE;
-import static android.telephony.PhoneStateListener.LISTEN_PREFERRED_DATA_SUBID_CHANGE;
 import static android.telephony.PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED;
 
 import static org.junit.Assert.assertEquals;
@@ -44,7 +44,7 @@
     private PhoneStateListener mPhoneStateListener;
     private TelephonyRegistry mTelephonyRegistry;
     private PhoneCapability mPhoneCapability;
-    private int mPreferredSubId;
+    private int mActiveSubId;
     private int mSrvccState = -1;
 
     public class PhoneStateListenerWrapper extends PhoneStateListener {
@@ -60,8 +60,8 @@
             setReady(true);
         }
         @Override
-        public void onPreferredDataSubIdChanged(int preferredSubId) {
-            mPreferredSubId = preferredSubId;
+        public void onActiveDataSubscriptionIdChanged(int activeSubId) {
+            mActiveSubId = activeSubId;
             setReady(true);
         }
     }
@@ -121,23 +121,23 @@
 
 
     @Test @SmallTest
-    public void testPreferredDataSubChanged() {
+    public void testActiveDataSubChanged() {
         // mTelephonyRegistry.listen with notifyNow = true should trigger callback immediately.
         setReady(false);
-        int preferredSubId = 0;
-        mTelephonyRegistry.notifyPreferredDataSubIdChanged(preferredSubId);
+        int activeSubId = 0;
+        mTelephonyRegistry.notifyActiveDataSubIdChanged(activeSubId);
         mTelephonyRegistry.listen(mContext.getOpPackageName(),
                 mPhoneStateListener.callback,
-                LISTEN_PREFERRED_DATA_SUBID_CHANGE, true);
+                LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE, true);
         waitUntilReady();
-        assertEquals(preferredSubId, mPreferredSubId);
+        assertEquals(activeSubId, mActiveSubId);
 
         // notifyPhoneCapabilityChanged with a new capability. Callback should be triggered.
         setReady(false);
-        mPreferredSubId = 1;
-        mTelephonyRegistry.notifyPreferredDataSubIdChanged(preferredSubId);
+        mActiveSubId = 1;
+        mTelephonyRegistry.notifyActiveDataSubIdChanged(activeSubId);
         waitUntilReady();
-        assertEquals(preferredSubId, mPreferredSubId);
+        assertEquals(activeSubId, mActiveSubId);
     }
 
     /**
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 74f288d..62b26ce 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -44,7 +44,8 @@
 import android.os.ServiceManager;
 import android.provider.BlockedNumberContract;
 import android.provider.Settings;
-import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.NetworkRegistrationState;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -143,6 +144,8 @@
     @Mock
     protected ServiceState mServiceState;
     @Mock
+    protected NetworkRegistrationState mNetworkRegistrationState;
+    @Mock
     protected SimulatedCommandsVerifier mSimulatedCommandsVerifier;
     @Mock
     protected IDeviceIdleController mIDeviceIdleController;
@@ -212,6 +215,10 @@
     protected RestrictedState mRestrictedState;
     @Mock
     protected DataEnabledSettings mDataEnabledSettings;
+    @Mock
+    protected PhoneConfigurationManager mPhoneConfigurationManager;
+    @Mock
+    protected CellularNetworkValidator mCellularNetworkValidator;
 
     protected ImsCallProfile mImsCallProfile;
     protected TelephonyManager mTelephonyManager;
@@ -482,11 +489,16 @@
         mSST.mSS = mServiceState;
         mSST.mRestrictedState = mRestrictedState;
         mServiceManagerMockedServices.put("connectivity_metrics_logger", mConnMetLoggerBinder);
-        doReturn(new int[]{TransportType.WWAN, TransportType.WLAN})
+        doReturn(new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN})
                 .when(mTransportManager).getAvailableTransports();
-        doReturn(TransportType.WWAN).when(mTransportManager).getCurrentTransport(anyInt());
+        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mTransportManager)
+                .getCurrentTransport(anyInt());
         doReturn(true).when(mDataEnabledSettings).isDataEnabled();
         doReturn(true).when(mDataEnabledSettings).isInternalDataEnabled();
+        doReturn(mNetworkRegistrationState).when(mServiceState).getNetworkRegistrationState(
+                anyInt(), anyInt());
+        doReturn(new HalVersion(1, 4)).when(mPhone).getHalVersion();
 
         //SIM
         doReturn(1).when(mTelephonyManager).getSimCount();
@@ -500,6 +512,10 @@
         Settings.Global.putInt(resolver,
                 Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, 1);
 
+        // CellularNetworkValidator
+        doReturn(SubscriptionManager.INVALID_PHONE_INDEX)
+                .when(mCellularNetworkValidator).getSubIdInValidation();
+
         //Use reflection to mock singletons
         replaceInstance(CallManager.class, "INSTANCE", null, mCallManager);
         replaceInstance(TelephonyComponentFactory.class, "sInstance", null,
@@ -526,6 +542,10 @@
         replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
         replaceInstance(PhoneFactory.class, "sSubInfoRecordUpdater", null, mSubInfoRecordUpdater);
         replaceInstance(RadioConfig.class, "sRadioConfig", null, mMockRadioConfig);
+        replaceInstance(PhoneConfigurationManager.class, "sInstance", null,
+                mPhoneConfigurationManager);
+        replaceInstance(CellularNetworkValidator.class, "sInstance", null,
+                mCellularNetworkValidator);
 
         assertNotNull("Failed to set up SubscriptionController singleton",
                 SubscriptionController.getInstance());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java
index 379815d..a315bde 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java
@@ -115,6 +115,14 @@
     }
 
     @SmallTest
+    public void testRecipientAddress() throws Exception {
+        String pdu = "011a0000001002080d0003100160010610262d5ab500040401448888";
+        SmsMessage sms = SmsMessage.createFromEfRecord(0,
+                HexDump.hexStringToByteArray(pdu));
+        assertEquals("12222", sms.getRecipientAddress());
+    }
+
+    @SmallTest
     public void testUserData7bitGsm() throws Exception {
         String pdu = "00031040900112488ea794e074d69e1b7392c270326cde9e98";
         BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
index b4ce3e3..3be4104 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
@@ -129,6 +129,7 @@
         assertEquals(a1.getMvnoMatchData(), a2.getMvnoMatchData());
         assertEquals(a1.getNetworkTypeBitmask(), a2.getNetworkTypeBitmask());
         assertEquals(a1.getApnSetId(), a2.getApnSetId());
+        assertEquals(a1.getSkip464Xlat(), a2.getSkip464Xlat());
     }
 
     @Test
@@ -229,7 +230,7 @@
         expectedApn = ApnSetting.makeApnSetting(
                 -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
                 mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
-                0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, -1);
+                0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, -1, -1);
         assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
 
         // A v6 string with carrierId=100
@@ -239,7 +240,17 @@
         expectedApn = ApnSetting.makeApnSetting(
             -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
             mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
-            0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, 100);
+            0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, 100, -1);
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v7 string with skip_464xlat=1
+        testString =
+            "[ApnSettingV7] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,0,3,"
+                + "-1, 1";
+        expectedApn = ApnSetting.makeApnSetting(
+            -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+            mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+            0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, -1, 1);
         assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
 
         // Return no apn if insufficient fields given.
@@ -279,7 +290,7 @@
         expectedApns.add(ApnSetting.makeApnSetting(
                 -1, "12346", "Name1", "apn2", "", -1, null, "", -1, "", "", 0,
                 mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
-                0, 0, false, 0, 0, 0, 0, -1, "", 3, -1));
+                0, 0, false, 0, 0, 0, 0, -1, "", 3, -1, -1));
         assertApnSettingsEqual(expectedApns, ApnSetting.arrayFromString(testString));
     }
 
@@ -292,9 +303,9 @@
                 null, null, -1, "user", "password", 0,
                 ApnSetting.TYPE_DEFAULT, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
                 4096, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "");
-        String expected = "[ApnSettingV6] Name, 99, 12345, apn, null, "
+        String expected = "[ApnSettingV7] Name, 99, 12345, apn, null, "
                 + "null, null, null, 10, 0, hipri | default, "
-                + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 4096, 0, -1";
+                + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 4096, 0, -1, -1";
         assertEquals(expected, apn.toString());
 
         final int networkTypeBitmask = 1 << (14 - 1);
@@ -302,10 +313,10 @@
                 99, "12345", "Name", "apn", null, 10,
                 null, null, -1, "user", "password", 0,
                 ApnSetting.TYPE_DEFAULT, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
-                networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "", 3, -1);
-        expected = "[ApnSettingV6] Name, 99, 12345, apn, null, "
+                networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "", 3, -1, 1);
+        expected = "[ApnSettingV7] Name, 99, 12345, apn, null, "
                 + "null, null, null, 10, 0, hipri | default, "
-                + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 8192, 3, -1";
+                + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 8192, 3, -1, 1";
         assertEquals(expected, apn.toString());
     }
 
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 7fd6f35..e95add2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
@@ -52,8 +52,8 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
 import android.telephony.data.ApnSetting;
@@ -157,6 +157,93 @@
             -1,                     // mvno_type
             "");                    // mnvo_match_data
 
+    private ApnSetting mApn3 = ApnSetting.makeApnSetting(
+            2164,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "spmode.ne.jp",         // apn
+            null,                   // proxy
+            -1,                     // port
+            null,                   // mmsc
+            null,                   // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_DEFAULT, // types
+            ApnSetting.PROTOCOL_IPV6, // protocol
+            ApnSetting.PROTOCOL_IP, // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "",                     // mnvo_match_data
+            0,                      // apn_set_id
+            -1,                     // carrier_id
+            1);                     // skip_464xlat
+
+    private ApnSetting mApn4 = ApnSetting.makeApnSetting(
+            2164,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "spmode.ne.jp",         // apn
+            null,                   // proxy
+            -1,                     // port
+            null,                   // mmsc
+            null,                   // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_IMS,    // types
+            ApnSetting.PROTOCOL_IPV6, // protocol
+            ApnSetting.PROTOCOL_IP, // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
+
+    private ApnSetting mApn5 = ApnSetting.makeApnSetting(
+            2164,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "spmode.ne.jp",         // apn
+            null,                   // proxy
+            -1,                     // port
+            null,                   // mmsc
+            null,                   // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_IMS,    // types
+            ApnSetting.PROTOCOL_IPV6, // protocol
+            ApnSetting.PROTOCOL_IP, // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "",                     // mnvo_match_data
+            0,                      // apn_set_id
+            -1,                     // carrier_id
+            0);                     // skip_464xlat
+
     private class DataConnectionTestHandler extends HandlerThread {
 
         private DataConnectionTestHandler(String name) {
@@ -167,8 +254,9 @@
         public void onLooperPrepared() {
             Handler h = new Handler();
 
-            DataServiceManager manager = new DataServiceManager(mPhone, TransportType.WWAN);
-            mDcc = DcController.makeDcc(mPhone, mDcTracker, manager, h);
+            DataServiceManager manager = new DataServiceManager(mPhone,
+                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN, "");
+            mDcc = DcController.makeDcc(mPhone, mDcTracker, manager, h, "");
             mDcc.start();
             mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, manager,
                     mDcTesterFailBringUpAll, mDcc);
@@ -510,6 +598,44 @@
     }
 
     @Test
+    public void testShouldSkip464Xlat() throws Exception {
+        assertFalse(testShouldSkip464XlatEvent(mApn1));
+        disconnectEvent();
+
+        assertTrue(testShouldSkip464XlatEvent(mApn3));
+        disconnectEvent();
+
+        assertTrue(testShouldSkip464XlatEvent(mApn4));
+        disconnectEvent();
+
+        assertFalse(testShouldSkip464XlatEvent(mApn5));
+        disconnectEvent();
+    }
+
+    private boolean testShouldSkip464XlatEvent(ApnSetting apn) throws Exception {
+        Method method = DataConnection.class.getDeclaredMethod("shouldSkip464Xlat");
+        method.setAccessible(true);
+
+        doReturn(apn).when(mApnContext).getApnSetting();
+        connectEvent();
+        logd(getNetworkCapabilities().toString());
+
+        return (Boolean) method.invoke(mDc);
+    }
+
+    private void connectEvent() throws Exception {
+        mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp);
+        waitForMs(200);
+        assertEquals("DcActiveState", getCurrentState().getName());
+    }
+
+    private void disconnectEvent() throws Exception {
+        mDc.sendMessage(DataConnection.EVENT_DISCONNECT, mDcp);
+        waitForMs(100);
+        assertEquals("DcInactiveState", getCurrentState().getName());
+    }
+
+    @Test
     @SmallTest
     public void testIsIpAddress() throws Exception {
         // IPv4
@@ -603,7 +729,7 @@
         waitForMs(200);
 
         DataServiceManager mockDsm = mock(DataServiceManager.class);
-        doReturn(TransportType.WLAN).when(mockDsm).getTransportType();
+        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mockDsm).getTransportType();
         replaceInstance(DataConnection.class, "mDataServiceManager", mDc, mockDsm);
 
         final int sessionHandle = 0xF00;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
index 27d1839..b7b49fd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
@@ -85,7 +85,7 @@
         @Override
         public void onLooperPrepared() {
             mHandler = new Handler();
-            mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, mHandler);
+            mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, mHandler, "");
             mDcc.start();
             setReady(true);
         }
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 a6f359f..27eae4a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -61,7 +61,8 @@
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.provider.Telephony;
-import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
@@ -181,7 +182,7 @@
 
         @Override
         public void onLooperPrepared() {
-            mDct = new DcTracker(mPhone, TransportType.WWAN);
+            mDct = new DcTracker(mPhone, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
             setReady(true);
         }
     }
@@ -229,7 +230,8 @@
                                     Telephony.Carriers.MVNO_MATCH_DATA,
                                     Telephony.Carriers.NETWORK_TYPE_BITMASK,
                                     Telephony.Carriers.APN_SET_ID,
-                                    Telephony.Carriers.CARRIER_ID});
+                                    Telephony.Carriers.CARRIER_ID,
+                                    Telephony.Carriers.SKIP_464XLAT});
 
                     mc.addRow(new Object[]{
                             2163,                   // id
@@ -260,7 +262,8 @@
                             "",                     // mnvo_match_data
                             NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
                             0,                      // apn_set_id
-                            -1                      // carrier_id
+                            -1,                     // carrier_id
+                            -1                      // skip_464xlat
                     });
 
                     mc.addRow(new Object[]{
@@ -292,7 +295,8 @@
                             "",                     // mnvo_match_data
                             NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
                             0,                      // apn_set_id
-                            -1                      // carrier_id
+                            -1,                     // carrier_id
+                            -1                      // skip_464xlat
                     });
 
                     mc.addRow(new Object[]{
@@ -324,7 +328,8 @@
                             "",                     // mnvo_match_data
                             0,                      // network_type_bitmask
                             0,                      // apn_set_id
-                            -1                      // carrier_id
+                            -1,                     // carrier_id
+                            -1                      // skip_464xlat
                     });
 
                     mc.addRow(new Object[]{
@@ -356,7 +361,8 @@
                             "",                     // mnvo_match_data
                             NETWORK_TYPE_EHRPD_BITMASK, // network_type_bitmask
                             0,                      // apn_set_id
-                            -1                      // carrier_id
+                            -1,                     // carrier_id
+                            -1                      // skip_464xlat
                     });
 
                     mc.addRow(new Object[]{
@@ -388,7 +394,8 @@
                             "",                     // mnvo_match_data
                             0,                      // network_type_bitmask
                             0,                      // apn_set_id
-                            -1                      // carrier_id
+                            -1,                     // carrier_id
+                            -1                      // skip_464xlat
                     });
 
                     return mc;
@@ -422,6 +429,8 @@
         doReturn("fake.action_attached").when(mPhone).getActionAttached();
         doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_LTE).when(mServiceState)
                 .getRilDataRadioTechnology();
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mNetworkRegistrationState)
+                .getAccessNetworkTechnology();
 
         mContextFixture.putStringArrayResource(com.android.internal.R.array.networkAttributes,
                 sNetworkAttributes);
@@ -443,6 +452,8 @@
 
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 Telephony.Carriers.CONTENT_URI.getAuthority(), mApnSettingContentProvider);
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
 
         doReturn(true).when(mSimRecords).getRecordsLoaded();
         doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
@@ -479,6 +490,11 @@
         mDcTrackerTestHandler = new DcTrackerTestHandler(getClass().getSimpleName());
         mDcTrackerTestHandler.start();
         waitUntilReady();
+
+        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
+        mContext.sendBroadcast(intent);
+
         waitForMs(600);
         logd("DcTrackerTest -Setup!");
     }
@@ -592,8 +608,7 @@
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         // Verify if RIL command was sent properly.
         verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -641,8 +656,7 @@
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         // Verify if RIL command was sent properly.
         verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -657,7 +671,8 @@
         // Simulate the timer expires.
         Intent intent = new Intent("com.android.internal.telephony.data-reconnect.default");
         intent.putExtra("reconnect_alarm_extra_type", PhoneConstants.APN_TYPE_DEFAULT);
-        intent.putExtra("reconnect_alarm_extra_transport_type", TransportType.WWAN);
+        intent.putExtra("reconnect_alarm_extra_transport_type",
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, 0);
         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         mContext.sendBroadcast(intent);
@@ -666,8 +681,7 @@
         dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         // Verify if RIL command was sent properly.
         verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN2, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -698,8 +712,7 @@
 
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 5, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -735,20 +748,24 @@
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
 
         mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
+        waitForHandlerAction(mDct, 1000);
         mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
+        waitForHandlerAction(mDct, 1000);
 
         logd("Sending EVENT_RECORDS_LOADED");
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
-        waitForMs(200);
+        waitForHandlerAction(mDct, 1000);
 
         logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
+        waitForHandlerAction(mDct, 1000);
+        logd("Handling EVENT_DATA_CONNECTION_ATTACHED complete");
+        // dataconnection is on a different handler
         waitForMs(200);
 
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -803,8 +820,7 @@
         waitForMs(200);
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN3, 2, 64, 0, 0);
@@ -854,7 +870,8 @@
         mDct.sendMessage(mDct.obtainMessage(intArgumentCaptor.getValue(), null));
         waitForMs(100);
 
-        verify(mSST, times(1)).registerForDataConnectionAttached(eq(mDct),
+        verify(mSST, times(1)).registerForDataConnectionAttached(
+                eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), eq(mDct),
                 intArgumentCaptor.capture(), eq(null));
         // Ideally this should send EVENT_DATA_CONNECTION_ATTACHED");
         mDct.sendMessage(mDct.obtainMessage(intArgumentCaptor.getValue(), null));
@@ -868,12 +885,13 @@
 
         verifyDataConnected(FAKE_APN1);
 
-        assertTrue(mDct.getAutoAttachOnCreation());
+        assertTrue(mDct.getAutoAttachEnabled());
         mDct.update();
         // The auto attach flag should be reset after update
-        assertFalse(mDct.getAutoAttachOnCreation());
+        assertFalse(mDct.getAutoAttachEnabled());
 
-        verify(mSST, times(1)).registerForDataConnectionDetached(eq(mDct),
+        verify(mSST, times(1)).registerForDataConnectionDetached(
+                eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), eq(mDct),
                 intArgumentCaptor.capture(), eq(null));
         // Ideally this should send EVENT_DATA_CONNECTION_DETACHED
         mDct.sendMessage(mDct.obtainMessage(intArgumentCaptor.getValue(), null));
@@ -911,8 +929,7 @@
 
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 5, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -954,8 +971,7 @@
         waitForMs(200);
 
         verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), any(DataProfile.class),
+                eq(AccessNetworkType.EUTRAN), any(DataProfile.class),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
     }
@@ -1008,8 +1024,7 @@
         waitForMs(200);
 
         verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), any(DataProfile.class),
+                eq(AccessNetworkType.EUTRAN), any(DataProfile.class),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
     }
@@ -1130,8 +1145,8 @@
     @SmallTest
     public void testTrySetupDefaultOnIWLAN() throws Exception {
         initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
-        doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN).when(mServiceState)
-                .getRilDataRadioTechnology();
+        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mNetworkRegistrationState)
+                .getAccessNetworkTechnology();
 
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
@@ -1183,8 +1198,8 @@
     @Test
     @SmallTest
     public void testUpdateWaitingApnListOnDataRatChange() throws Exception {
-        doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD).when(mServiceState)
-                .getRilDataRadioTechnology();
+        doReturn(TelephonyManager.NETWORK_TYPE_EHRPD).when(mNetworkRegistrationState)
+                .getAccessNetworkTechnology();
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
         mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
@@ -1201,8 +1216,7 @@
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         // Verify if RIL command was sent properly.
         verify(mSimulatedCommandsVerifier).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.CDMA2000), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN4, 0, 21, 2, NETWORK_TYPE_EHRPD_BITMASK);
@@ -1210,8 +1224,8 @@
 
         //data rat change from ehrpd to lte
         logd("Sending EVENT_DATA_RAT_CHANGED");
-        doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_LTE).when(mServiceState)
-                .getRilDataRadioTechnology();
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mNetworkRegistrationState)
+                .getAccessNetworkTechnology();
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
         waitForMs(200);
 
@@ -1227,15 +1241,15 @@
         Intent intent = new Intent("com.android.internal.telephony.data-reconnect.default");
         intent.putExtra("reconnect_alarm_extra_type", PhoneConstants.APN_TYPE_DEFAULT);
         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, 0);
-        intent.putExtra("reconnect_alarm_extra_transport_type", TransportType.WWAN);
+        intent.putExtra("reconnect_alarm_extra_transport_type",
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         mContext.sendBroadcast(intent);
         waitForMs(200);
 
         // Verify if RIL command was sent properly.
         verify(mSimulatedCommandsVerifier).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1303,8 +1317,8 @@
     @Test
     @SmallTest
     public void testDataRatChangeOOS() throws Exception {
-        doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD).when(mServiceState)
-                .getRilDataRadioTechnology();
+        doReturn(TelephonyManager.NETWORK_TYPE_EHRPD).when(mNetworkRegistrationState)
+                .getAccessNetworkTechnology();
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT});
         mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
@@ -1321,8 +1335,7 @@
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         // Verify if RIL command was sent properly.
         verify(mSimulatedCommandsVerifier).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                        mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.CDMA2000), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN4, 0, 21, 2, NETWORK_TYPE_EHRPD_BITMASK);
@@ -1330,8 +1343,8 @@
 
         // Data rat change from ehrpd to unknown due to OOS
         logd("Sending EVENT_DATA_RAT_CHANGED");
-        doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN).when(mServiceState)
-                .getRilDataRadioTechnology();
+        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mNetworkRegistrationState)
+                .getAccessNetworkTechnology();
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
         waitForMs(200);
 
@@ -1341,8 +1354,8 @@
                 any(Message.class));
 
         // Data rat resume from unknown to ehrpd
-        doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD).when(mServiceState)
-                .getRilDataRadioTechnology();
+        doReturn(TelephonyManager.NETWORK_TYPE_EHRPD).when(mNetworkRegistrationState)
+                .getAccessNetworkTechnology();
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
         waitForMs(200);
 
@@ -1429,9 +1442,6 @@
     @Test
     @SmallTest
     public void testNetworkStatusChangedRecoveryOFF() throws Exception {
-        ContentResolver resolver = mContext.getContentResolver();
-        Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
-
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
         mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
@@ -1447,8 +1457,7 @@
 
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1467,6 +1476,7 @@
         verify(mSimulatedCommandsVerifier, times(0)).getDataCallList(any(Message.class));
     }
 
+    @FlakyTest
     @Test
     @SmallTest
     public void testNetworkStatusChangedRecoveryON() throws Exception {
@@ -1488,8 +1498,7 @@
 
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, timeout(TEST_TIMEOUT).times(2)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1505,12 +1514,9 @@
         waitForMs(200);
 
         verify(mSimulatedCommandsVerifier, times(1)).getDataCallList(any(Message.class));
-
-        // reset the setting at the end of this test
-        Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
-        waitForMs(200);
     }
 
+    @FlakyTest
     @Test
     @SmallTest
     public void testRecoveryStepPDPReset() throws Exception {
@@ -1534,8 +1540,7 @@
 
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, timeout(TEST_TIMEOUT).times(2)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1549,10 +1554,6 @@
         verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(
                 eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
                 any(Message.class));
-
-        // reset the setting at the end of this test
-        Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
-        waitForMs(200);
     }
 
 
@@ -1579,8 +1580,7 @@
 
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1592,9 +1592,6 @@
 
         // expected to get preferred network type
         verify(mSST, times(1)).reRegisterNetwork(eq(null));
-
-        // reset the setting at the end of this test
-        Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
     }
 
     @Test
@@ -1620,8 +1617,7 @@
 
         ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
         verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
-                eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
-                mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                 eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 any(Message.class));
         verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1633,9 +1629,6 @@
 
         // expected to get preferred network type
         verify(mSST, times(1)).powerOffRadioSafely();
-
-        // reset the setting at the end of this test
-        Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
     }
 
     private void verifyDataEnabledChangedMessage(boolean enabled, int reason) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TransportManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TransportManagerTest.java
new file mode 100644
index 0000000..4d3c96d
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TransportManagerTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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.dataconnection;
+
+import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.data.ApnSetting;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.dataconnection.AccessNetworksManager.QualifiedNetworks;
+import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class TransportManagerTest extends TelephonyTest {
+    private static final int EVENT_HANDOVER_NEEDED = 1;
+
+    @Mock
+    private Handler mTestHandler;
+
+    private TransportManager mTransportManager;
+
+    private TransportManagerTestHandler mTransportManagerTestHandler;
+
+    private class TransportManagerTestHandler extends HandlerThread {
+
+        private TransportManagerTestHandler(String name) {
+            super(name);
+        }
+
+        @Override
+        public void onLooperPrepared() {
+            mTransportManager = new TransportManager(mPhone);
+            setReady(true);
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        mTransportManagerTestHandler = new TransportManagerTestHandler(TAG);
+        mTransportManagerTestHandler.start();
+        waitUntilReady();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mTransportManagerTestHandler.quit();
+        mTransportManagerTestHandler.join();
+        super.tearDown();
+    }
+
+    @Test
+    @SmallTest
+    public void testHandoverNeeded() throws Exception {
+        mTransportManager.registerForHandoverNeededEvent(mTestHandler, EVENT_HANDOVER_NEEDED);
+
+        // Initial qualified networks
+        List<QualifiedNetworks> networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.EUTRAN, AccessNetworkType.UTRAN,
+                                AccessNetworkType.IWLAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        waitForMs(100);
+        // Verify handover needed event was not sent
+        verify(mTestHandler, never()).sendMessageAtTime(any(Message.class), anyLong());
+
+        // Now change the order of qualified networks by putting IWLAN first
+        networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.IWLAN, AccessNetworkType.UTRAN,
+                                AccessNetworkType.EUTRAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        waitForMs(100);
+
+        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
+
+        // Verify handover needed event was sent and the the target transport is WLAN.
+        verify(mTestHandler, times(1)).sendMessageAtTime(messageArgumentCaptor.capture(),
+                anyLong());
+        Message message = messageArgumentCaptor.getValue();
+        assertEquals(EVENT_HANDOVER_NEEDED, message.what);
+        AsyncResult ar = (AsyncResult) message.obj;
+        HandoverParams params = (HandoverParams) ar.result;
+        assertEquals(ApnSetting.TYPE_IMS, params.apnType);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, params.targetTransport);
+
+        // Now change the order of qualified networks by putting UTRAN first
+        networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.UTRAN, AccessNetworkType.EUTRAN,
+                                AccessNetworkType.IWLAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        waitForMs(100);
+
+        messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
+
+        // Verify handover needed event was sent and the the target transport is WWAN.
+        verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
+                anyLong());
+        message = messageArgumentCaptor.getValue();
+        assertEquals(EVENT_HANDOVER_NEEDED, message.what);
+        ar = (AsyncResult) message.obj;
+        params = (HandoverParams) ar.result;
+        assertEquals(ApnSetting.TYPE_IMS, params.apnType);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, params.targetTransport);
+    }
+
+    @Test
+    @SmallTest
+    public void testHandoverNotNeeded() throws Exception {
+        mTransportManager.registerForHandoverNeededEvent(mTestHandler, EVENT_HANDOVER_NEEDED);
+
+        // Initial qualified networks
+        List<QualifiedNetworks> networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.EUTRAN, AccessNetworkType.UTRAN,
+                                AccessNetworkType.IWLAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        waitForMs(100);
+        // Verify handover needed event was not sent
+        verify(mTestHandler, never()).sendMessageAtTime(any(Message.class), anyLong());
+
+        // Now change the order of qualified networks by swapping EUTRAN and UTRAN.
+        networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.UTRAN, AccessNetworkType.EUTRAN,
+                                AccessNetworkType.IWLAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        waitForMs(100);
+        // Verify handover needed event was not sent
+        verify(mTestHandler, never()).sendMessageAtTime(any(Message.class), anyLong());
+    }
+}
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 7f60179..a4b3b58 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
@@ -52,6 +52,7 @@
 import android.service.euicc.GetDownloadableSubscriptionMetadataResult;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.telephony.UiccAccessRule;
 import android.telephony.UiccCardInfo;
 import android.telephony.euicc.DownloadableSubscription;
@@ -196,31 +197,38 @@
     @Test(expected = SecurityException.class)
     public void testGetEid_noPrivileges() throws Exception {
         setGetEidPermissions(false /* hasPhoneStatePrivileged */, false /* hasCarrierPrivileges */);
-        callGetEid(true /* success */, "ABCDE" /* eid */);
+        callGetEid(true /* success */, "ABCDE" /* eid */, CARD_ID);
     }
 
     @Test
     public void testGetEid_withPhoneStatePrivileged() throws Exception {
         setGetEidPermissions(true /* hasPhoneStatePrivileged */, false /* hasCarrierPrivileges */);
-        assertEquals("ABCDE", callGetEid(true /* success */, "ABCDE" /* eid */));
+        assertEquals("ABCDE", callGetEid(true /* success */, "ABCDE" /* eid */, CARD_ID));
     }
 
     @Test
     public void testGetEid_withCarrierPrivileges() throws Exception {
         setGetEidPermissions(false /* hasPhoneStatePrivileged */, true /* hasCarrierPrivileges */);
-        assertEquals("ABCDE", callGetEid(true /* success */, "ABCDE" /* eid */));
+        assertEquals("ABCDE", callGetEid(true /* success */, "ABCDE" /* eid */, CARD_ID));
     }
 
     @Test
     public void testGetEid_failure() throws Exception {
         setGetEidPermissions(true /* hasPhoneStatePrivileged */, false /* hasCarrierPrivileges */);
-        assertNull(callGetEid(false /* success */, null /* eid */));
+        assertNull(callGetEid(false /* success */, null /* eid */, CARD_ID));
     }
 
     @Test
     public void testGetEid_nullReturnValue() throws Exception {
         setGetEidPermissions(true /* hasPhoneStatePrivileged */, false /* hasCarrierPrivileges */);
-        assertNull(callGetEid(true /* success */, null /* eid */));
+        assertNull(callGetEid(true /* success */, null /* eid */, CARD_ID));
+    }
+
+    @Test
+    public void testGetEid_unsupportedCardId() throws Exception {
+        setGetEidPermissions(false /* hasPhoneStatePrivileged */, true /* hasCarrierPrivileges */);
+        assertEquals("ABCDE", callGetEid(true /* success */, "ABCDE" /* eid */,
+                TelephonyManager.UNSUPPORTED_CARD_ID));
     }
 
     @Test(expected = SecurityException.class)
@@ -975,15 +983,16 @@
                 false, "", false, false, 0, 0, 0);
         when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn(
                 hasPrivileges);
-        when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
+        when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
                 Collections.singletonList(subInfo));
     }
 
     private void setCanManageSubscriptionOnTargetSim(boolean isTargetEuicc, boolean hasPrivileges)
             throws Exception {
-        UiccCardInfo cardInfo1 = new UiccCardInfo(isTargetEuicc, CARD_ID, "", "", 0);
+        UiccCardInfo cardInfo1 = new UiccCardInfo(isTargetEuicc, CARD_ID, "", "", 0,
+                false /* isRemovable */);
         UiccCardInfo cardInfo2 = new UiccCardInfo(true /* isEuicc */, 1 /* cardId */,
-                "", "", 0);
+                "", "", 0, false /* isRemovable */);
         ArrayList<UiccCardInfo> cardInfos = new ArrayList<>();
         cardInfos.add(cardInfo1);
         cardInfos.add(cardInfo2);
@@ -1002,7 +1011,7 @@
         when(mSubscriptionManager.canManageSubscription(subInfo2, PACKAGE_NAME)).thenReturn(
                 hasPrivileges);
         ArrayList<SubscriptionInfo> subInfos = new ArrayList<>(Arrays.asList(subInfo1, subInfo2));
-        when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subInfos);
+        when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(subInfos);
     }
 
     private void prepareOperationSubscription(boolean hasPrivileges) throws Exception {
@@ -1016,7 +1025,7 @@
                 Collections.singletonList(subInfo));
     }
 
-    private String callGetEid(final boolean success, final @Nullable String eid) {
+    private String callGetEid(final boolean success, final @Nullable String eid, int cardId) {
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Exception {
@@ -1031,7 +1040,7 @@
             }
         }).when(mMockConnector).getEid(anyInt(),
                 Mockito.<EuiccConnector.GetEidCommandCallback>any());
-        return mController.getEid(CARD_ID, PACKAGE_NAME);
+        return mController.getEid(cardId, PACKAGE_NAME);
     }
 
     private int callGetOtaStatus(final boolean success, final int status) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
index ab0d061..9482afc 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.pm.PackageManager;
 import android.os.IBinder;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
@@ -34,7 +35,9 @@
 import android.telephony.ims.ImsMmTelManager;
 import android.telephony.ims.ProvisioningManager;
 import android.telephony.ims.stub.ImsConfigImplBase;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.ims.ImsConfig;
 import com.android.ims.ImsManager;
@@ -44,10 +47,12 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.Mock;
 
 import java.util.Hashtable;
 
+@RunWith(AndroidJUnit4.class)
 public class ImsManagerTest extends TelephonyTest {
     private static final String UNSET_PROVISIONED_STRING = "unset";
     private static final boolean ENHANCED_4G_MODE_DEFAULT_VAL = true;
@@ -57,10 +62,14 @@
     private static final boolean VT_IMS_ENABLE_DEFAULT_VAL = true;
     private static final boolean WFC_IMS_EDITABLE_VAL = true;
     private static final boolean WFC_IMS_NOT_EDITABLE_VAL = false;
+    private static final boolean WFC_IMS_ROAMING_EDITABLE_VAL = true;
+    private static final boolean WFC_IMS_ROAMING_NOT_EDITABLE_VAL = false;
     private static final int WFC_IMS_MODE_DEFAULT_VAL =
             ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
     private static final int WFC_IMS_ROAMING_MODE_DEFAULT_VAL =
             ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED;
+    private static final boolean WFC_USE_HOME_MODE_FOR_ROAMING_VAL = true;
+    private static final boolean WFC_NOT_USE_HOME_MODE_FOR_ROAMING_VAL = false;
 
     PersistableBundle mBundle;
     @Mock IBinder mBinder;
@@ -78,6 +87,8 @@
         super.setUp("ImsManagerTest");
         mPhoneId = mPhone.getPhoneId();
         mBundle = mContextFixture.getCarrierConfigBundle();
+        // Force MmTelFeatureConnection to create an executor using Looper.myLooper().
+        doReturn(null).when(mContext).getMainLooper();
 
         doReturn(mSubId).when(mSubscriptionController).getSubId(mPhoneId);
 
@@ -85,6 +96,7 @@
         mServiceManagerMockedServices.put("isub", mBinder);
 
         doReturn(true).when(mMmTelFeatureConnection).isBinderAlive();
+        mContextFixture.addSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS);
 
         mImsManagerInstances.remove(mPhoneId);
 
@@ -101,6 +113,8 @@
                 ENHANCED_4G_MODE_EDITABLE);
         mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL,
                 WFC_IMS_EDITABLE_VAL);
+        mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL,
+                WFC_IMS_ROAMING_EDITABLE_VAL);
         mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL,
                 WFC_IMS_ENABLE_DEFAULT_VAL);
         mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL,
@@ -112,6 +126,9 @@
         mBundle.putBoolean(CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL,
                 ENHANCED_4G_MODE_DEFAULT_VAL);
         mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, true);
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL,
+                WFC_NOT_USE_HOME_MODE_FOR_ROAMING_VAL);
     }
 
     @Test @SmallTest
@@ -647,6 +664,98 @@
                 eq(WFC_IMS_MODE_DEFAULT_VAL));
     }
 
+    /**
+     * Tests the operation of getWfcMode when the configuration to use the home network mode when
+     * roaming for WFC is false. First, it checks that the user setting for WFC_IMS_ROAMING_MODE is
+     * returned when WFC roaming is set to editable. Then, it switches the WFC roaming mode to not
+     * editable and ensures that the default WFC roaming mode is returned.
+     *
+     * Preconditions:
+     *  - CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL = false
+     */
+    @Test @SmallTest
+    public void getWfcMode_useWfcHomeModeConfigFalse_shouldUseWfcRoamingMode() {
+        // Set some values that are different than the defaults for WFC mode.
+        doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY))
+                .when(mSubscriptionController).getSubscriptionProperty(
+                anyInt(),
+                eq(SubscriptionManager.WFC_IMS_MODE),
+                anyString());
+        doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
+                .when(mSubscriptionController).getSubscriptionProperty(
+                anyInt(),
+                eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
+                anyString());
+
+        ImsManager imsManager = getImsManagerAndInitProvisionedValues();
+
+        // Check that use the WFC roaming network mode.
+        assertEquals(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED,
+                imsManager.getWfcMode(true));
+        verify(mSubscriptionController, times(1)).getSubscriptionProperty(
+                anyInt(),
+                eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
+                anyString());
+
+        // Set WFC roaming network mode to not editable.
+        mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL,
+                WFC_IMS_ROAMING_NOT_EDITABLE_VAL);
+
+        // Check that use the default WFC roaming network mode.
+        assertEquals(WFC_IMS_ROAMING_MODE_DEFAULT_VAL, imsManager.getWfcMode(true));
+        verify(mSubscriptionController, times(1)).getSubscriptionProperty(
+                anyInt(),
+                eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
+                anyString());
+    }
+
+    /**
+     * Tests the operation of getWfcMode when the configuration to use the home network mode when
+     * roaming for WFC is true independent of whether or not the WFC roaming mode is editable.
+     *
+     * Preconditions:
+     *  - CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL = true
+     */
+    @Test @SmallTest
+    public void getWfcMode_useWfcHomeModeConfigTrue_shouldUseWfcHomeMode() {
+        // Set some values that are different than the defaults for WFC mode.
+        doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY))
+                .when(mSubscriptionController).getSubscriptionProperty(
+                anyInt(),
+                eq(SubscriptionManager.WFC_IMS_MODE),
+                anyString());
+        doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
+                .when(mSubscriptionController).getSubscriptionProperty(
+                anyInt(),
+                eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
+                anyString());
+
+        // Set to use WFC home network mode in roaming network.
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL,
+                WFC_USE_HOME_MODE_FOR_ROAMING_VAL);
+
+        ImsManager imsManager = getImsManagerAndInitProvisionedValues();
+
+        // Check that use the WFC home network mode.
+        assertEquals(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY, imsManager.getWfcMode(true));
+        verify(mSubscriptionController, times(1)).getSubscriptionProperty(
+                anyInt(),
+                eq(SubscriptionManager.WFC_IMS_MODE),
+                anyString());
+
+        // Set WFC home network mode to not editable.
+        mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL,
+                WFC_IMS_NOT_EDITABLE_VAL);
+
+        // Check that use the default WFC home network mode.
+        assertEquals(WFC_IMS_MODE_DEFAULT_VAL, imsManager.getWfcMode(true));
+        verify(mSubscriptionController, times(1)).getSubscriptionProperty(
+                anyInt(),
+                eq(SubscriptionManager.WFC_IMS_MODE),
+                anyString());
+    }
+
     private ImsManager getImsManagerAndInitProvisionedValues() {
         when(mImsConfigImplBaseMock.getConfigInt(anyInt()))
                 .thenAnswer(invocation ->  {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java
index 0acb694..26afbe3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
@@ -193,7 +194,7 @@
 
         // Simulate subscriptions changed, where testSub1 is no longer active
         doReturn(createSubscriptionInfoList(new int[] {testSub2, testSub3}))
-                .when(mSubscriptionManager).getActiveSubscriptionInfoList();
+                .when(mSubscriptionManager).getActiveSubscriptionInfoList(anyBoolean());
         mCallbackManagerUT.mSubChangedListener.onSubscriptionsChanged();
         assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback1));
         // verify that the subscription changed listener is not removed, since we still have a
@@ -220,7 +221,7 @@
 
         // Simulate subscriptions changed, where testSub1 is no longer active
         doReturn(createSubscriptionInfoList(new int[] {testSub2}))
-                .when(mSubscriptionManager).getActiveSubscriptionInfoList();
+                .when(mSubscriptionManager).getActiveSubscriptionInfoList(anyBoolean());
         mCallbackManagerUT.mSubChangedListener.onSubscriptionsChanged();
         assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback1));
         // verify that the subscription listener is removed, since the only active callback has been
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/RcsMessageStoreControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/RcsMessageStoreControllerTest.java
index 25cfb20..39ec048 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/RcsMessageStoreControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/RcsMessageStoreControllerTest.java
@@ -65,7 +65,7 @@
         mContentResolver = (MockContentResolver) mContext.getContentResolver();
         mContentResolver.addProvider("rcs", mFakeRcsProvider);
 
-        mRcsMessageStoreController = new RcsMessageStoreController(mContentResolver, null);
+        mRcsMessageStoreController = new RcsMessageStoreController(mContentResolver);
     }
 
     @After
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 f0b93a9..82c62dd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -54,6 +55,7 @@
         replaceInstance(ImsPhoneCallTracker.class, "mPhone", mImsCT, mImsPhone);
 
         mImsCallUT = new ImsPhoneCall(mImsCT, ImsPhoneCall.CONTEXT_FOREGROUND);
+        when(mImsCT.getPhone()).thenReturn(mImsPhone);
         mMediaProfile = new ImsStreamMediaProfile();
     }
 
@@ -119,8 +121,6 @@
         }
     }
 
-    @FlakyTest
-    @Ignore
     @Test
     @SmallTest
     public void testUpdateRingBackTone() {
@@ -138,6 +138,22 @@
 
     @Test
     @SmallTest
+    public void testStopRingingOnHandover() {
+        //Mock local tone
+        mMediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_INACTIVE;
+        mImsCallProfile.mMediaProfile = mMediaProfile;
+
+        mImsCallUT.update(null, mImsCall, Call.State.ALERTING);
+        verify(mImsPhone, times(1)).startRingbackTone();
+        assertEquals(Call.State.ALERTING, mImsCallUT.getState());
+
+        // Emulate ringback terminate on handover.
+        mImsCallUT.maybeStopRingback();
+        verify(mImsPhone, times(1)).stopRingbackTone();
+    }
+
+    @Test
+    @SmallTest
     public void testSwitchWith() {
         // this call in active state with connection 1 attached
         mImsCallUT.attach(mConnection1, Call.State.ACTIVE);
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 e8a002c..8227cde 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -38,6 +38,7 @@
 
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -110,7 +111,7 @@
         }
         @Override
         public void onLooperPrepared() {
-            mCTUT = new ImsPhoneCallTracker(mImsPhone);
+            mCTUT = new ImsPhoneCallTracker(mImsPhone, Runnable::run);
             mCTUT.addReasonCodeRemapping(null, "Wifi signal lost.", ImsReasonInfo.CODE_WIFI_LOST);
             mCTUT.addReasonCodeRemapping(501, "Call answered elsewhere.",
                     ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
@@ -188,6 +189,7 @@
         imsCallMocking(mSecondImsCall);
         doReturn(ImsFeature.STATE_READY).when(mImsManager).getImsServiceState();
         doReturn(mImsCallProfile).when(mImsManager).createCallProfile(anyInt(), anyInt());
+        mContextFixture.addSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS);
 
         doAnswer(invocation -> {
             mMmTelListener = (MmTelFeature.Listener) invocation.getArguments()[0];
@@ -272,7 +274,7 @@
     @SmallTest
     public void testImsDeregistered() {
         // when IMS is deregistered
-        mRegistrationCallback.onDeregistered(new ImsReasonInfo());
+        mRegistrationCallback.onUnregistered(new ImsReasonInfo());
         // then service state should be OUT_OF_SERVICE and ImsPhone state set to not registered
         verify(mImsPhone).setServiceState(eq(ServiceState.STATE_OUT_OF_SERVICE));
         verify(mImsPhone).setImsRegistered(eq(false));
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 2555488..6432d05 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -285,7 +285,7 @@
         mImsPhoneUT.dispose();
         assertEquals(0, list.size());
         verify(mImsCT).dispose();
-        verify(mSST).unregisterForDataRegStateOrRatChanged(mImsPhoneUT);
+        verify(mSST, times(2)).unregisterForDataRegStateOrRatChanged(anyInt(), eq(mImsPhoneUT));
     }
 
     @Test
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 cf9e72a..2c0a793 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneMock.java
@@ -36,7 +36,6 @@
 import android.telephony.VoLteServiceState;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.PhoneConstants.DataState;
 import com.android.internal.telephony.test.SimulatedRadioControl;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
 import com.android.internal.telephony.uicc.IccFileHandler;
@@ -1077,10 +1076,6 @@
         throw new RuntimeException("not implemented");
     }
 
-    public DataState getDataConnectionState(String apnType) {
-        throw new RuntimeException("not implemented");
-    }
-
     public DataActivityState getDataActivityState() {
         throw new RuntimeException("not implemented");
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionControllerMock.java b/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionControllerMock.java
index 411ed1d..2007dca 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionControllerMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionControllerMock.java
@@ -259,7 +259,7 @@
         throw new RuntimeException("not implemented");
     }
     @Override
-    public int[] getActiveSubIdList() {
+    public int[] getActiveSubIdList(boolean visibleOnly) {
         throw new RuntimeException("not implemented");
     }
     @Override
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 44ae673..412cc1b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
@@ -369,7 +369,8 @@
     }
 
     @Override
-    public void notifyCallQualityChanged(CallQuality callQuality, int phoneId) {
+    public void notifyCallQualityChanged(CallQuality callQuality, int phoneId,
+            int callNetworkType) {
         throw new RuntimeException("Not implemented");
     }
 
@@ -426,12 +427,12 @@
     }
 
     @Override
-    public void notifyRadioPowerStateChanged(int state) {
+    public void notifyActiveDataSubIdChanged(int subId) {
         throw new RuntimeException("Not implemented");
     }
 
     @Override
-    public void notifyPreferredDataSubIdChanged(int subId) {
+    public void notifyRadioPowerStateChanged(int state) {
         throw new RuntimeException("Not implemented");
     }
 
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 8a3625a..7cb6d78 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
@@ -109,8 +109,9 @@
                 mIccCardStatus.mImsSubscriptionAppIndex =
                         mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
         mSimulatedCommands.setIccCardStatus(mIccCardStatus);
-        // slotIndex should be invalid when testing with older versions (before 1.2) of hal
-        mIccCardStatus.physicalSlotIndex = UiccController.INVALID_SLOT_ID;
+        // for testing we pretend slotIndex is set. In reality it would be invalid on older versions
+        // (before 1.2) of hal
+        mIccCardStatus.physicalSlotIndex = 0;
         mUiccControllerHandlerThread = new UiccControllerHandlerThread(TAG);
         mUiccControllerHandlerThread.start();
         waitUntilReady();
@@ -235,6 +236,7 @@
         ics.atr = "abcdef0123456789abcdef";
         ics.iccid = "123451234567890";
         ics.eid = "A1B2C3D4";
+        ics.physicalSlotIndex = 0;
         AsyncResult ar = new AsyncResult(null, ics, null);
         Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
         mUiccControllerUT.handleMessage(msg);
@@ -314,6 +316,8 @@
         doReturn(false).when(mMockSlot).isEuicc();
         doReturn(mMockCard).when(mMockSlot).getUiccCard();
         doReturn("ASDF1234").when(mMockCard).getCardId();
+        doReturn(true).when(mMockSlot).isRemovable();
+        doReturn("A1B2C3D4").when(mMockCard).getCardId();
         doReturn("123451234567890").when(mMockCard).getIccId();
         doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mMockCard).getCardState();
 
@@ -323,6 +327,7 @@
         ics.setUniversalPinState(3 /* disabled */);
         ics.atr = "abcdef0123456789abcdef";
         ics.iccid = "123451234567890";
+        ics.physicalSlotIndex = 0;
         AsyncResult ar = new AsyncResult(null, ics, null);
         Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
         mUiccControllerUT.handleMessage(msg);
@@ -333,7 +338,8 @@
                 0,         // cardId
                 null,      // eid
                 ics.iccid, // iccid is unknown
-                0);        // slotIndex
+                0,         // slotIndex
+                true);     // isRemovable
         assertEquals(uiccCardInfo, mUiccControllerUT.getAllUiccCardInfos().get(0));
     }
 
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 2c55915..42f017f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
@@ -65,7 +65,8 @@
                 public void handleMessage(Message msg) {
                     switch (msg.what) {
                         case UICCCARD_UPDATE_CARD_STATE_EVENT:
-                            mUiccSlot.update(mSimulatedCommands, mIccCardStatus, 0 /* phoneId */);
+                            mUiccSlot.update(mSimulatedCommands, mIccCardStatus, 0 /* phoneId */,
+                                    0 /* slotIndex */);
                             setReady(true);
                             break;
                         default:
@@ -117,7 +118,7 @@
         assertNull(mUiccSlot.getIccId());
 
         // update slot to inactive
-        mUiccSlot.update(null, iss);
+        mUiccSlot.update(null, iss, 0 /* slotIndex */);
 
         // assert on updated values
         assertFalse(mUiccSlot.isActive());
@@ -144,7 +145,7 @@
         iss.iccid = "fake-iccid";
 
         // update slot to inactive
-        mUiccSlot.update(mSimulatedCommands, iss);
+        mUiccSlot.update(mSimulatedCommands, iss, 0 /* slotIndex */);
 
         // assert on updated values
         assertTrue(mUiccSlot.isActive());
@@ -155,7 +156,7 @@
                 IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId);
 
         // update slot to active
-        mUiccSlot.update(mSimulatedCommands, iss);
+        mUiccSlot.update(mSimulatedCommands, iss, 0 /* slotIndex */);
 
         // assert on updated values
         assertTrue(mUiccSlot.isActive());
@@ -178,7 +179,7 @@
         assertNull(mUiccSlot.getIccId());
 
         // update slot to inactive
-        mUiccSlot.update(null, iss);
+        mUiccSlot.update(null, iss, 0 /* slotIndex */);
 
         // assert on updated values
         assertFalse(mUiccSlot.isActive());
@@ -189,7 +190,7 @@
         iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_ACTIVE;
 
         // update slot to active
-        mUiccSlot.update(mSimulatedCommands, iss);
+        mUiccSlot.update(mSimulatedCommands, iss, 0 /* slotIndex */);
 
         // assert on updated values
         assertTrue(mUiccSlot.isActive());
@@ -213,7 +214,7 @@
         assertNull(mUiccSlot.getIccId());
 
         // update slot to inactive
-        mUiccSlot.update(null, iss);
+        mUiccSlot.update(null, iss, 0 /* slotIndex */);
 
         // assert on updated values
         assertFalse(mUiccSlot.isActive());
@@ -224,7 +225,7 @@
         iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_ACTIVE;
 
         // update slot to active
-        mUiccSlot.update(mSimulatedCommands, iss);
+        mUiccSlot.update(mSimulatedCommands, iss, 0 /* slotIndex */);
 
         // assert on updated values
         assertTrue(mUiccSlot.isActive());
@@ -235,9 +236,10 @@
     @SmallTest
     public void testUpdateAbsentState() {
         int phoneId = 0;
+        int slotIndex = 0;
         // Make sure when received CARDSTATE_ABSENT state in the first time,
         mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_ABSENT;
-        mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId);
+        mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
         verify(mSubInfoRecordUpdater).updateInternalIccState(
                 IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId);
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
@@ -248,9 +250,10 @@
     @SmallTest
     public void testUiccSlotCreateAndDispose() {
         int phoneId = 0;
+        int slotIndex = 0;
         // Simulate when SIM is added, UiccCard and UiccProfile should be created.
         mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
-        mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId);
+        mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
         verify(mTelephonyComponentFactory).makeUiccProfile(
                 anyObject(), eq(mSimulatedCommands), eq(mIccCardStatus), anyInt(), anyObject(),
                 anyObject());
@@ -260,11 +263,44 @@
         // Simulate when SIM is removed, UiccCard and UiccProfile should be disposed and ABSENT
         // state is sent to SubscriptionInfoUpdater.
         mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_ABSENT;
-        mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId);
+        mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
         verify(mSubInfoRecordUpdater).updateInternalIccState(
                 IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId);
         verify(mUiccProfile).dispose();
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
         assertNull(mUiccSlot.getUiccCard());
     }
+
+    @Test
+    public void testNotRemovable() throws InterruptedException {
+        int phoneId = 0;
+        int slotIndex = 0;
+
+        // mock the resource overlay which declares the euicc slots
+        mContextFixture.putIntArrayResource(com.android.internal.R.array.non_removable_euicc_slots,
+                new int[]{0, 1});
+
+        // Simulate when SIM is added, UiccCard and UiccProfile should be created.
+        mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
+        mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
+
+        assertFalse("EuiccCard should not be removable", mUiccSlot.isRemovable());
+    }
+
+    @Test
+    public void testIsRemovable() throws InterruptedException {
+        int phoneId = 0;
+        int slotIndex = 0;
+
+        // mock the resource overlay which declares the euicc slots
+        mContextFixture.putIntArrayResource(com.android.internal.R.array.non_removable_euicc_slots,
+                new int[]{1});
+
+        // Simulate when SIM is added, UiccCard and UiccProfile should be created.
+        mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
+        mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
+
+        assertTrue("EuiccCard should be removable", mUiccSlot.isRemovable());
+    }
+
 }