LegacyState does not send notifyDisplayInfoChanged am: 545dd7778c am: 6acc0754d3

Change-Id: I221c2c893f4683b8da16d44d51589b89cfa3abf0
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index 40ffd58..2dde70d 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -52,6 +52,8 @@
     static final int CLIR_INVOCATION = 1;   // (restrict CLI presentation)
     static final int CLIR_SUPPRESSION = 2;  // (allow CLI presentation)
 
+    // Used as return value for CDMA SS query
+    static final int SS_STATUS_UNKNOWN          = 0xff;
 
     // Used as parameters for call forward methods below
     static final int CF_ACTION_DISABLE          = 0;
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 19f7778..6790fa7 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -55,6 +55,8 @@
 import android.provider.Settings;
 import android.provider.Telephony;
 import android.sysprop.TelephonyProperties;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
 import android.telephony.AccessNetworkConstants;
@@ -80,6 +82,7 @@
 
 import com.android.ims.ImsManager;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.cdma.CdmaMmiCode;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
@@ -112,6 +115,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -2099,6 +2103,26 @@
             && mImsPhone.isUtEnabled();
     }
 
+    private boolean isCsRetry(Message onComplete) {
+        if (onComplete != null) {
+            return onComplete.getData().getBoolean(CS_FALLBACK_SS, false);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean useSsOverIms(Message onComplete) {
+        boolean isUtEnabled = isUtEnabled();
+
+        Rlog.d(LOG_TAG, "useSsOverIms: isUtEnabled()= " + isUtEnabled +
+                " isCsRetry(onComplete))= " + isCsRetry(onComplete));
+
+        if (isUtEnabled && !isCsRetry(onComplete)) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
         getCallForwardingOption(commandInterfaceCFReason,
@@ -2108,16 +2132,13 @@
     @Override
     public void getCallForwardingOption(int commandInterfaceCFReason, int serviceClass,
             Message onComplete) {
-        if (isPhoneTypeGsm() || isImsUtEnabledOverCdma()) {
-            Phone imsPhone = mImsPhone;
-            if ((imsPhone != null)
-                    && ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
-                    || imsPhone.isUtEnabled())) {
-                imsPhone.getCallForwardingOption(commandInterfaceCFReason, serviceClass,
-                        onComplete);
-                return;
-            }
+        Phone imsPhone = mImsPhone;
+        if (useSsOverIms(onComplete)) {
+            imsPhone.getCallForwardingOption(commandInterfaceCFReason, serviceClass, onComplete);
+            return;
+        }
 
+        if (isPhoneTypeGsm()) {
             if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) {
                 if (DBG) logd("requesting call forwarding query.");
                 Message resp;
@@ -2129,9 +2150,8 @@
                 mCi.queryCallForwardStatus(commandInterfaceCFReason, serviceClass, null, resp);
             }
         } else {
-            loge("getCallForwardingOption: not possible in CDMA without IMS");
-            AsyncResult.forMessage(onComplete, null,
-                    CommandException.fromRilErrno(RILConstants.REQUEST_NOT_SUPPORTED));
+            loge("getCallForwardingOption: not possible in CDMA, just return empty result");
+            AsyncResult.forMessage(onComplete, makeEmptyCallForward(), null);
             onComplete.sendToTarget();
         }
     }
@@ -2153,17 +2173,14 @@
             int serviceClass,
             int timerSeconds,
             Message onComplete) {
-        if (isPhoneTypeGsm() || isImsUtEnabledOverCdma()) {
-            Phone imsPhone = mImsPhone;
-            if ((imsPhone != null)
-                    && ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
-                    || imsPhone.isUtEnabled())) {
-                imsPhone.setCallForwardingOption(commandInterfaceCFAction,
-                        commandInterfaceCFReason, dialingNumber, serviceClass,
-                        timerSeconds, onComplete);
-                return;
-            }
+        Phone imsPhone = mImsPhone;
+        if (useSsOverIms(onComplete)) {
+            imsPhone.setCallForwardingOption(commandInterfaceCFAction, commandInterfaceCFReason,
+                    dialingNumber, serviceClass, timerSeconds, onComplete);
+            return;
+        }
 
+        if (isPhoneTypeGsm()) {
             if ((isValidCommandInterfaceCFAction(commandInterfaceCFAction)) &&
                     (isValidCommandInterfaceCFReason(commandInterfaceCFReason))) {
 
@@ -2183,9 +2200,20 @@
                         resp);
             }
         } else {
-            loge("setCallForwardingOption: not possible in CDMA without IMS");
-            AsyncResult.forMessage(onComplete, null,
-                    CommandException.fromRilErrno(RILConstants.REQUEST_NOT_SUPPORTED));
+            String formatNumber = GsmCdmaConnection.formatDialString(dialingNumber);
+            String cfNumber = CdmaMmiCode.getCallForwardingPrefixAndNumber(
+                    commandInterfaceCFAction, commandInterfaceCFReason, formatNumber);
+            loge("setCallForwardingOption: dial for set call forwarding"
+                    + " prefixWithNumber= " + cfNumber + " number= " + dialingNumber);
+
+            PhoneAccountHandle phoneAccountHandle = subscriptionIdToPhoneAccountHandle(getSubId());
+            Bundle extras = new Bundle();
+            extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+
+            final TelecomManager telecomManager = TelecomManager.from(mContext);
+            telecomManager.placeCall(Uri.parse(PhoneAccount.SCHEME_TEL + cfNumber), extras);
+
+            AsyncResult.forMessage(onComplete, CommandsInterface.SS_STATUS_UNKNOWN, null);
             onComplete.sendToTarget();
         }
     }
@@ -2193,12 +2221,13 @@
     @Override
     public void getCallBarring(String facility, String password, Message onComplete,
             int serviceClass) {
+        Phone imsPhone = mImsPhone;
+        if (useSsOverIms(onComplete)) {
+            imsPhone.getCallBarring(facility, password, onComplete, serviceClass);
+            return;
+        }
+
         if (isPhoneTypeGsm()) {
-            Phone imsPhone = mImsPhone;
-            if ((imsPhone != null) && imsPhone.isUtEnabled()) {
-                imsPhone.getCallBarring(facility, password, onComplete, serviceClass);
-                return;
-            }
             mCi.queryFacilityLock(facility, password, serviceClass, onComplete);
         } else {
             loge("getCallBarringOption: not possible in CDMA");
@@ -2208,12 +2237,13 @@
     @Override
     public void setCallBarring(String facility, boolean lockState, String password,
             Message onComplete, int serviceClass) {
+        Phone imsPhone = mImsPhone;
+        if (useSsOverIms(onComplete)) {
+            imsPhone.setCallBarring(facility, lockState, password, onComplete, serviceClass);
+            return;
+        }
+
         if (isPhoneTypeGsm()) {
-            Phone imsPhone = mImsPhone;
-            if ((imsPhone != null) && imsPhone.isUtEnabled()) {
-                imsPhone.setCallBarring(facility, lockState, password, onComplete, serviceClass);
-                return;
-            }
             mCi.setFacilityLock(facility, lockState, password, serviceClass, onComplete);
         } else {
             loge("setCallBarringOption: not possible in CDMA");
@@ -2239,30 +2269,31 @@
 
     @Override
     public void getOutgoingCallerIdDisplay(Message onComplete) {
+        Phone imsPhone = mImsPhone;
+        if (useSsOverIms(onComplete)) {
+            imsPhone.getOutgoingCallerIdDisplay(onComplete);
+            return;
+        }
+
         if (isPhoneTypeGsm()) {
-            Phone imsPhone = mImsPhone;
-            if ((imsPhone != null)
-                    && ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
-                    || imsPhone.isUtEnabled())) {
-                imsPhone.getOutgoingCallerIdDisplay(onComplete);
-                return;
-            }
             mCi.getCLIR(onComplete);
         } else {
             loge("getOutgoingCallerIdDisplay: not possible in CDMA");
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED));
+            onComplete.sendToTarget();
         }
     }
 
     @Override
     public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) {
+        Phone imsPhone = mImsPhone;
+        if (useSsOverIms(onComplete)) {
+            imsPhone.setOutgoingCallerIdDisplay(commandInterfaceCLIRMode, onComplete);
+            return;
+        }
+
         if (isPhoneTypeGsm()) {
-            Phone imsPhone = mImsPhone;
-            if ((imsPhone != null)
-                    && ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
-                    || imsPhone.isUtEnabled())) {
-                imsPhone.setOutgoingCallerIdDisplay(commandInterfaceCLIRMode, onComplete);
-                return;
-            }
             // Packing CLIR value in the message. This will be required for
             // SharedPreference caching, if the message comes back as part of
             // a success response.
@@ -2270,51 +2301,84 @@
                     obtainMessage(EVENT_SET_CLIR_COMPLETE, commandInterfaceCLIRMode, 0, onComplete));
         } else {
             loge("setOutgoingCallerIdDisplay: not possible in CDMA");
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED));
+            onComplete.sendToTarget();
+        }
+    }
+
+    @Override
+    public void queryCLIP(Message onComplete) {
+        Phone imsPhone = mImsPhone;
+        if (useSsOverIms(onComplete)) {
+            imsPhone.queryCLIP(onComplete);
+            return;
+        }
+
+        if (isPhoneTypeGsm()) {
+            mCi.queryCLIP(onComplete);
+        } else {
+            loge("queryCLIP: not possible in CDMA");
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED));
+            onComplete.sendToTarget();
         }
     }
 
     @Override
     public void getCallWaiting(Message onComplete) {
-        if (isPhoneTypeGsm() || isImsUtEnabledOverCdma()) {
-            Phone imsPhone = mImsPhone;
-            if ((imsPhone != null)
-                    && ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
-                    || imsPhone.isUtEnabled())) {
-                imsPhone.getCallWaiting(onComplete);
-                return;
-            }
+        Phone imsPhone = mImsPhone;
+        if (useSsOverIms(onComplete)) {
+            imsPhone.getCallWaiting(onComplete);
+            return;
+        }
 
+        if (isPhoneTypeGsm()) {
             //As per 3GPP TS 24.083, section 1.6 UE doesn't need to send service
             //class parameter in call waiting interrogation  to network
             mCi.queryCallWaiting(CommandsInterface.SERVICE_CLASS_NONE, onComplete);
         } else {
-            mCi.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
+            int arr[] = {CommandsInterface.SS_STATUS_UNKNOWN, CommandsInterface.SERVICE_CLASS_NONE};
+            AsyncResult.forMessage(onComplete, arr, null);
+            onComplete.sendToTarget();
         }
     }
 
     @Override
     public void setCallWaiting(boolean enable, Message onComplete) {
-        if (isPhoneTypeGsm() || isImsUtEnabledOverCdma()) {
-            Phone imsPhone = mImsPhone;
-            if ((imsPhone != null)
-                    && ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
-                    || imsPhone.isUtEnabled())) {
-                imsPhone.setCallWaiting(enable, onComplete);
-                return;
-            }
-            int serviceClass = CommandsInterface.SERVICE_CLASS_VOICE;
-            CarrierConfigManager configManager = (CarrierConfigManager)
-                    getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
-            PersistableBundle b = configManager.getConfigForSubId(getSubId());
-            if (b != null) {
-                serviceClass = b.getInt(CarrierConfigManager.KEY_CALL_WAITING_SERVICE_CLASS_INT,
-                        CommandsInterface.SERVICE_CLASS_VOICE);
-            }
+        int serviceClass = CommandsInterface.SERVICE_CLASS_VOICE;
+        CarrierConfigManager configManager = (CarrierConfigManager)
+            getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        PersistableBundle b = configManager.getConfigForSubId(getSubId());
+        if (b != null) {
+            serviceClass = b.getInt(CarrierConfigManager.KEY_CALL_WAITING_SERVICE_CLASS_INT,
+                    CommandsInterface.SERVICE_CLASS_VOICE);
+        }
+        setCallWaiting(enable, serviceClass, onComplete);
+    }
+
+    @Override
+    public void setCallWaiting(boolean enable, int serviceClass, Message onComplete) {
+        Phone imsPhone = mImsPhone;
+        if (useSsOverIms(onComplete)) {
+            imsPhone.setCallWaiting(enable, onComplete);
+            return;
+        }
+
+        if (isPhoneTypeGsm()) {
             mCi.setCallWaiting(enable, serviceClass, onComplete);
         } else {
-            loge("method setCallWaiting is NOT supported in CDMA without IMS!");
-            AsyncResult.forMessage(onComplete, null,
-                    CommandException.fromRilErrno(RILConstants.REQUEST_NOT_SUPPORTED));
+            String cwPrefix = CdmaMmiCode.getCallWaitingPrefix(enable);
+            Rlog.i(LOG_TAG, "setCallWaiting in CDMA : dial for set call waiting" + " prefix= " + cwPrefix);
+
+            PhoneAccountHandle phoneAccountHandle = subscriptionIdToPhoneAccountHandle(getSubId());
+            Bundle extras = new Bundle();
+            extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+
+            final TelecomManager telecomManager = TelecomManager.from(mContext);
+            telecomManager.placeCall(Uri.parse(PhoneAccount.SCHEME_TEL + cwPrefix), extras);
+
+            AsyncResult.forMessage(onComplete, CommandsInterface.SS_STATUS_UNKNOWN, null);
             onComplete.sendToTarget();
         }
     }
@@ -4230,6 +4294,37 @@
         }
     }
 
+    private CallForwardInfo[] makeEmptyCallForward() {
+        CallForwardInfo infos[] = new CallForwardInfo[1];
+
+        infos[0] = new CallForwardInfo();
+        infos[0].status = CommandsInterface.SS_STATUS_UNKNOWN;
+        infos[0].reason = 0;
+        infos[0].serviceClass = CommandsInterface.SERVICE_CLASS_VOICE;
+        infos[0].toa = PhoneNumberUtils.TOA_Unknown;
+        infos[0].number = "";
+        infos[0].timeSeconds = 0;
+
+        return infos;
+    }
+
+    private PhoneAccountHandle subscriptionIdToPhoneAccountHandle(final int subId) {
+        final TelecomManager telecomManager = TelecomManager.from(mContext);
+        final TelephonyManager telephonyManager = TelephonyManager.from(mContext);
+        final Iterator<PhoneAccountHandle> phoneAccounts =
+            telecomManager.getCallCapablePhoneAccounts(true).listIterator();
+
+        while (phoneAccounts.hasNext()) {
+            final PhoneAccountHandle phoneAccountHandle = phoneAccounts.next();
+            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(phoneAccountHandle);
+            if (subId == telephonyManager.getSubIdForPhoneAccount(phoneAccount)) {
+                return phoneAccountHandle;
+            }
+        }
+
+        return null;
+    }
+
     @UnsupportedAppUsage
     private void logd(String s) {
         Rlog.d(LOG_TAG, "[" + mPhoneId + "] " + s);
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index 7fe45ec..f8ff7b0 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -38,7 +38,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.UserManager;
 import android.provider.Telephony;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SmsCbMessage;
@@ -174,22 +173,13 @@
     };
 
     protected IccSmsInterfaceManager(Phone phone) {
-        this(phone, phone.getContext(),
-                (AppOpsManager) phone.getContext().getSystemService(Context.APP_OPS_SERVICE),
-                (UserManager) phone.getContext().getSystemService(Context.USER_SERVICE),
-                new SmsDispatchersController(
-                        phone, phone.mSmsStorageMonitor, phone.mSmsUsageMonitor));
-    }
-
-    @VisibleForTesting
-    public IccSmsInterfaceManager(
-            Phone phone, Context context, AppOpsManager appOps, UserManager userManager,
-            SmsDispatchersController dispatchersController) {
         mPhone = phone;
-        mContext = context;
-        mAppOps = appOps;
-        mDispatchersController = dispatchersController;
-        mSmsPermissions = new SmsPermissions(phone, context, appOps);
+        mContext = phone.getContext();
+        mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+        mDispatchersController =
+                new SmsDispatchersController(
+                        phone, phone.mSmsStorageMonitor, phone.mSmsUsageMonitor);
+        mSmsPermissions = new SmsPermissions(phone, mContext, mAppOps);
 
         mContext.registerReceiver(
                 new BroadcastReceiver() {
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index af72beb..5188ba0 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -343,6 +343,10 @@
      * TODO: Replace this with a proper exception; {@link CallStateException} doesn't make sense.
      */
     public static final String CS_FALLBACK = "cs_fallback";
+
+    // Used for retry over cs for supplementary services
+    public static final String CS_FALLBACK_SS = "cs_fallback_ss";
+
     /**
      * @deprecated Use {@link android.telephony.ims.ImsManager#EXTRA_WFC_REGISTRATION_FAILURE_TITLE}
      * instead.
@@ -3627,6 +3631,15 @@
     }
 
     /*
+     * This function is for CSFB SS. GsmCdmaPhone overrides this function.
+     */
+    public void setCallWaiting(boolean enable, int serviceClass, Message onComplete) {
+    }
+
+    public void queryCLIP(Message onComplete) {
+    }
+
+    /*
      * Returns the subscription id.
      */
     @UnsupportedAppUsage
@@ -4292,6 +4305,10 @@
         return mCarrierPrivilegesTracker;
     }
 
+    public boolean useSsOverIms(Message onComplete) {
+        return false;
+    }
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("Phone: subId=" + getSubId());
         pw.println(" mPhoneId=" + mPhoneId);
diff --git a/src/java/com/android/internal/telephony/RatRatcheter.java b/src/java/com/android/internal/telephony/RatRatcheter.java
index 4d9cc3e..7406cef 100644
--- a/src/java/com/android/internal/telephony/RatRatcheter.java
+++ b/src/java/com/android/internal/telephony/RatRatcheter.java
@@ -131,7 +131,7 @@
 
         // Different rat family, don't need rat ratchet and update cell bandwidths.
         if (!isSameRatFamily(oldSS, newSS)) {
-            return;
+           return;
         }
 
         updateBandwidths(oldSS.getCellBandwidths(), newSS);
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index dcc0883..87baadd 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -3230,8 +3230,8 @@
 
             boolean isOldCA = oldNrs != null ? (oldNrs.getDataSpecificInfo() != null
                     ? oldNrs.getDataSpecificInfo().isUsingCarrierAggregation() : false) : false;
-            boolean isNewCA = newNrs != null ? (newNrs.getDataSpecificInfo() != null
-                    ? newNrs.getDataSpecificInfo().isUsingCarrierAggregation() : false) : false;
+            boolean isNewCA = newNrs!= null ? (newNrs. getDataSpecificInfo() != null
+                    ? newNrs. getDataSpecificInfo().isUsingCarrierAggregation() : false) : false;
 
             hasRilDataRadioTechnologyChanged.put(transport, oldRAT != newRAT || isOldCA != isNewCA);
             if (oldRAT != newRAT) {
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java b/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
index 88872c9..f41f699 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
@@ -16,6 +16,13 @@
 
 package com.android.internal.telephony.cdma;
 
+import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE;
+import static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION;
+import static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY;
+import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE;
+import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY;
+import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
+
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
@@ -381,6 +388,56 @@
         return null;
     }
 
+    public static String getCallForwardingPrefixAndNumber(int action, int reason, String number) {
+        String prefixWithNum = "";
+        switch(reason) {
+            case CF_REASON_UNCONDITIONAL: {
+                if (action == CF_ACTION_REGISTRATION) {
+                    prefixWithNum = "*72" + number;
+                } else if (action == CF_ACTION_DISABLE) {
+                    prefixWithNum = "*720";
+                }
+                break;
+            }
+            case CF_REASON_BUSY: {
+                if (action == CF_ACTION_REGISTRATION) {
+                    prefixWithNum = "*90" + number;
+                } else if (action == CF_ACTION_DISABLE) {
+                    prefixWithNum = "*900";
+                }
+                break;
+            }
+            case CF_REASON_NO_REPLY: {
+                if (action == CF_ACTION_REGISTRATION) {
+                    prefixWithNum = "*92" + number;
+                } else if (action == CF_ACTION_DISABLE) {
+                    prefixWithNum = "*920";
+                }
+                break;
+            }
+            case CF_REASON_NOT_REACHABLE: {
+                if (action == CF_ACTION_REGISTRATION) {
+                    prefixWithNum = "*68" + number;
+                } else if (action == CF_ACTION_DISABLE) {
+                    prefixWithNum = "*680";
+                }
+                break;
+            }
+            default:
+                Rlog.d(LOG_TAG, "getCallForwardingPrefix not match any prefix");
+                break;
+        }
+        return prefixWithNum;
+    }
+
+    public static String getCallWaitingPrefix(boolean enable) {
+        if (enable) {
+            return "*74";
+        } else {
+            return "*740";
+        }
+    }
+
     @Override
     public boolean isNetworkInitiatedUssd() {
         Rlog.w(LOG_TAG, "isNetworkInitiated is not implemented in CdmaMmiCode");
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 9a2b662..d67ce9e 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -1031,7 +1031,8 @@
     private void updateTcpBufferSizes(int rilRat) {
         String sizes = null;
         ServiceState ss = mPhone.getServiceState();
-        if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && ss.isUsingCarrierAggregation()) {
+        if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE &&
+                ss.isUsingCarrierAggregation()) {
             rilRat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA;
         }
         String ratName = ServiceState.rilRadioTechnologyToString(rilRat).toLowerCase(Locale.ROOT);
@@ -1046,8 +1047,8 @@
         // 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 (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
-                && ((rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE
-                || rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA) && isNRConnected())
+                && ((rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE ||
+                rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA) && isNRConnected())
                 && mPhone.getServiceStateTracker().getNrContextIds().contains(mCid)) {
             ratName = RAT_NAME_5G;
         }
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 0771d26..8c003da 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -2636,8 +2636,7 @@
         // since we don't want to unset user preference from system update, pass true as the default
         // value if shared pref does not exist and set shared pref to false explicitly from factory
         // reset.
-        if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)
-                && Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
+        if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)) {
             sp.edit().putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, false).commit();
         }
         return sp.getBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, true);
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccConnector.java b/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
index b922568..f135e62 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
@@ -96,7 +96,7 @@
      * true or onServiceDisconnected is called (and no package change has occurred which should
      * force us to reestablish the binding).
      */
-    static final int BIND_TIMEOUT_MILLIS = 30000;
+    private static final int BIND_TIMEOUT_MILLIS = 30000;
 
     /**
      * Maximum amount of idle time to hold the binding while in {@link ConnectedState}. After this,
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccController.java b/src/java/com/android/internal/telephony/euicc/EuiccController.java
index c956a88..de9b113 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccController.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccController.java
@@ -15,8 +15,6 @@
  */
 package com.android.internal.telephony.euicc;
 
-import static com.android.internal.telephony.euicc.EuiccConnector.BIND_TIMEOUT_MILLIS;
-
 import android.Manifest;
 import android.Manifest.permission;
 import android.annotation.NonNull;
@@ -73,6 +71,11 @@
     @VisibleForTesting
     static final String EXTRA_OPERATION = "operation";
 
+    /**
+     * Time out for {@link #dump(FileDescriptor, PrintWriter, String[])}
+     */
+    private static final int EUICC_DUMP_TIME_OUT_SECONDS = 5;
+
     // Aliases so line lengths stay short.
     private static final int OK = EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK;
     private static final int RESOLVABLE_ERROR =
@@ -1300,8 +1303,8 @@
                 }
             });
 
-            // Wait up to 30 seconds
-            if (!countDownLatch.await(BIND_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) {
+            // Wait up to 5 seconds
+            if (!countDownLatch.await(EUICC_DUMP_TIME_OUT_SECONDS, TimeUnit.SECONDS)) {
                 pw.println("===== EUICC SERVICE TIMEOUT =====");
             }
         } catch (InterruptedException e) {
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 7e792a7..e26ea55 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -139,6 +139,7 @@
     public static final int EVENT_SERVICE_STATE_CHANGED             = EVENT_LAST + 8;
     private static final int EVENT_VOICE_CALL_ENDED                  = EVENT_LAST + 9;
     private static final int EVENT_INITIATE_VOLTE_SILENT_REDIAL      = EVENT_LAST + 10;
+    private static final int EVENT_GET_CLIP_DONE                     = EVENT_LAST + 11;
 
     static final int RESTART_ECM_TIMER = 0; // restart Ecm timer
     static final int CANCEL_ECM_TIMER  = 1; // cancel Ecm timer
@@ -302,6 +303,85 @@
         }
     }
 
+    // Create SS (Supplementary Service) so that save SS params &
+    // mOnComplete (Message object passed by client) can be packed
+    // given as a single SS object as user data to UtInterface.
+    @VisibleForTesting
+    public static class SS {
+        int mCfAction;
+        int mCfReason;
+        String mDialingNumber;
+        int mTimerSeconds;
+        boolean mEnable;
+        int mClirMode;
+        String mFacility;
+        boolean mLockState;
+        String mPassword;
+        int mServiceClass;
+        @VisibleForTesting
+        public Message mOnComplete;
+
+        // Default // Query CW, CLIR, CLIP
+        SS(Message onComplete) {
+            mOnComplete = onComplete;
+        }
+
+        // Update CLIP
+        SS(boolean enable, Message onComplete) {
+            mEnable = enable;
+            mOnComplete = onComplete;
+        }
+
+        // Update CLIR
+        SS(int clirMode, Message onComplete) {
+            mClirMode = clirMode;
+            mOnComplete = onComplete;
+        }
+
+        // Update CW
+        SS(boolean enable, int serviceClass, Message onComplete) {
+            mEnable = enable;
+            mServiceClass = serviceClass;
+            mOnComplete = onComplete;
+        }
+
+        // Query CF
+        SS(int cfReason, int serviceClass, Message onComplete) {
+            mCfReason = cfReason;
+            mServiceClass = serviceClass;
+            mOnComplete = onComplete;
+        }
+
+        // Update CF
+        SS(int cfAction, int cfReason, String dialingNumber,
+           int serviceClass, int timerSeconds, Message onComplete) {
+            mCfAction = cfAction;
+            mCfReason = cfReason;
+            mDialingNumber = dialingNumber;
+            mServiceClass = serviceClass;
+            mTimerSeconds = timerSeconds;
+            mOnComplete = onComplete;
+        }
+
+        // Query CB
+        SS(String facility, String password, int serviceClass, Message onComplete) {
+            mFacility = facility;
+            mPassword = password;
+            mServiceClass = serviceClass;
+            mOnComplete = onComplete;
+        }
+
+        // Update CB
+        SS(String facility, boolean lockState, String password,
+                int serviceClass, Message onComplete) {
+            mFacility = facility;
+            mLockState = lockState;
+            mPassword = password;
+            mServiceClass = serviceClass;
+            mOnComplete = onComplete;
+        }
+    }
+
     // Constructors
     public ImsPhone(Context context, PhoneNotifier notifier, Phone defaultPhone) {
         this(context, notifier, defaultPhone, false);
@@ -1010,7 +1090,8 @@
     public void getOutgoingCallerIdDisplay(Message onComplete) {
         if (DBG) logd("getCLIR");
         Message resp;
-        resp = obtainMessage(EVENT_GET_CLIR_DONE, onComplete);
+        SS ss = new SS(onComplete);
+        resp = obtainMessage(EVENT_GET_CLIR_DONE, ss);
 
         try {
             ImsUtInterface ut = mCT.getUtInterface();
@@ -1027,7 +1108,8 @@
         // Packing CLIR value in the message. This will be required for
         // SharedPreference caching, if the message comes back as part of
         // a success response.
-        resp = obtainMessage(EVENT_SET_CLIR_DONE, clirMode, 0, onComplete);
+        SS ss = new SS(clirMode, onComplete);
+        resp = obtainMessage(EVENT_SET_CLIR_DONE, ss);
         try {
             ImsUtInterface ut = mCT.getUtInterface();
             ut.updateCLIR(clirMode, resp);
@@ -1036,6 +1118,21 @@
         }
     }
 
+    @Override
+    public void queryCLIP(Message onComplete) {
+        Message resp;
+        SS ss = new SS(onComplete);
+        resp = obtainMessage(EVENT_GET_CLIP_DONE, ss);
+
+        try {
+            Rlog.d(LOG_TAG, "ut.queryCLIP");
+            ImsUtInterface ut = mCT.getUtInterface();
+            ut.queryCLIP(resp);
+        } catch (ImsException e) {
+            sendErrorResponse(onComplete, e);
+        }
+    }
+
     @UnsupportedAppUsage
     @Override
     public void getCallForwardingOption(int commandInterfaceCFReason,
@@ -1051,7 +1148,8 @@
         if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) {
             if (DBG) logd("requesting call forwarding query.");
             Message resp;
-            resp = obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete);
+            SS ss = new SS(commandInterfaceCFReason, serviceClass, onComplete);
+            resp = obtainMessage(EVENT_GET_CALL_FORWARD_DONE, ss);
 
             try {
                 ImsUtInterface ut = mCT.getUtInterface();
@@ -1089,10 +1187,9 @@
         if ((isValidCommandInterfaceCFAction(commandInterfaceCFAction)) &&
                 (isValidCommandInterfaceCFReason(commandInterfaceCFReason))) {
             Message resp;
-            Cf cf = new Cf(dialingNumber, GsmMmiCode.isVoiceUnconditionalForwarding(
-                    commandInterfaceCFReason, serviceClass), onComplete);
-            resp = obtainMessage(EVENT_SET_CALL_FORWARD_DONE,
-                    isCfEnable(commandInterfaceCFAction) ? 1 : 0, 0, cf);
+            SS ss = new SS(commandInterfaceCFAction, commandInterfaceCFReason,
+                    dialingNumber, serviceClass, timerSeconds, onComplete);
+            resp = obtainMessage(EVENT_SET_CALL_FORWARD_DONE, ss);
 
             try {
                 ImsUtInterface ut = mCT.getUtInterface();
@@ -1115,7 +1212,8 @@
     public void getCallWaiting(Message onComplete) {
         if (DBG) logd("getCallWaiting");
         Message resp;
-        resp = obtainMessage(EVENT_GET_CALL_WAITING_DONE, onComplete);
+        SS ss = new SS(onComplete);
+        resp = obtainMessage(EVENT_GET_CALL_WAITING_DONE, ss);
 
         try {
             ImsUtInterface ut = mCT.getUtInterface();
@@ -1142,7 +1240,8 @@
     public void setCallWaiting(boolean enable, int serviceClass, Message onComplete) {
         if (DBG) logd("setCallWaiting enable=" + enable);
         Message resp;
-        resp = obtainMessage(EVENT_SET_CALL_WAITING_DONE, onComplete);
+        SS ss = new SS(enable, serviceClass, onComplete);
+        resp = obtainMessage(EVENT_SET_CALL_WAITING_DONE, ss);
 
         try {
             ImsUtInterface ut = mCT.getUtInterface();
@@ -1189,7 +1288,8 @@
             int serviceClass) {
         if (DBG) logd("getCallBarring facility=" + facility + ", serviceClass = " + serviceClass);
         Message resp;
-        resp = obtainMessage(EVENT_GET_CALL_BARRING_DONE, onComplete);
+        SS ss = new SS(facility, password, serviceClass, onComplete);
+        resp = obtainMessage(EVENT_GET_CALL_BARRING_DONE, ss);
 
         try {
             ImsUtInterface ut = mCT.getUtInterface();
@@ -1214,7 +1314,8 @@
                     + ", lockState=" + lockState + ", serviceClass = " + serviceClass);
         }
         Message resp;
-        resp = obtainMessage(EVENT_SET_CALL_BARRING_DONE, onComplete);
+        SS ss = new SS(facility, lockState, password, serviceClass, onComplete);
+        resp = obtainMessage(EVENT_SET_CALL_BARRING_DONE, ss);
 
         int action;
         if (lockState) {
@@ -1549,18 +1650,99 @@
         }
     }
 
+    boolean isCsRetryException(Throwable e) {
+        if ((e != null) && (e instanceof ImsException)
+                && (((ImsException)e).getCode()
+                    == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED)) {
+            return true;
+        }
+        return false;
+    }
+
+    private Bundle setCsfbBundle(boolean isCsRetry) {
+        Bundle b = new Bundle();
+        b.putBoolean(CS_FALLBACK_SS, isCsRetry);
+        return b;
+    }
+
+    private void sendResponseOrRetryOnCsfbSs(SS ss, int what, Throwable e, Object obj) {
+        if (!isCsRetryException(e)) {
+            sendResponse(ss.mOnComplete, obj, e);
+            return;
+        }
+
+        Rlog.d(LOG_TAG, "Try CSFB: " + what);
+        ss.mOnComplete.setData(setCsfbBundle(true));
+
+        switch (what) {
+            case EVENT_GET_CALL_FORWARD_DONE:
+                mDefaultPhone.getCallForwardingOption(ss.mCfReason,
+                                                      ss.mServiceClass,
+                                                      ss.mOnComplete);
+                break;
+            case EVENT_SET_CALL_FORWARD_DONE:
+                mDefaultPhone.setCallForwardingOption(ss.mCfAction,
+                                                      ss.mCfReason,
+                                                      ss.mDialingNumber,
+                                                      ss.mServiceClass,
+                                                      ss.mTimerSeconds,
+                                                      ss.mOnComplete);
+                break;
+            case EVENT_GET_CALL_BARRING_DONE:
+                mDefaultPhone.getCallBarring(ss.mFacility,
+                                             ss.mPassword,
+                                             ss.mOnComplete,
+                                             ss.mServiceClass);
+                break;
+            case EVENT_SET_CALL_BARRING_DONE:
+                mDefaultPhone.setCallBarring(ss.mFacility,
+                                             ss.mLockState,
+                                             ss.mPassword,
+                                             ss.mOnComplete,
+                                             ss.mServiceClass);
+                break;
+            case EVENT_GET_CALL_WAITING_DONE:
+                mDefaultPhone.getCallWaiting(ss.mOnComplete);
+                break;
+            case EVENT_SET_CALL_WAITING_DONE:
+                mDefaultPhone.setCallWaiting(ss.mEnable,
+                                             ss.mServiceClass,
+                                             ss.mOnComplete);
+                break;
+            case EVENT_GET_CLIR_DONE:
+                mDefaultPhone.getOutgoingCallerIdDisplay(ss.mOnComplete);
+                break;
+            case EVENT_SET_CLIR_DONE:
+                mDefaultPhone.setOutgoingCallerIdDisplay(ss.mClirMode, ss.mOnComplete);
+                break;
+            case EVENT_GET_CLIP_DONE:
+                mDefaultPhone.queryCLIP(ss.mOnComplete);
+                break;
+            default:
+                break;
+        }
+    }
+
     @Override
     public void handleMessage(Message msg) {
         AsyncResult ar = (AsyncResult) msg.obj;
+        Message onComplete;
+        SS ss = null;
+        if (ar.userObj instanceof SS) {
+            ss = (SS) ar.userObj;
+        }
 
         if (DBG) logd("handleMessage what=" + msg.what);
         switch (msg.what) {
             case EVENT_SET_CALL_FORWARD_DONE:
-                Cf cf = (Cf) ar.userObj;
-                if (cf.mIsCfu && ar.exception == null) {
-                    setVoiceCallForwardingFlag(getIccRecords(), 1, msg.arg1 == 1, cf.mSetCfNumber);
+                if (ar.exception == null && ss != null &&
+                    (ss.mCfReason == CF_REASON_UNCONDITIONAL)) {
+                    setVoiceCallForwardingFlag(getIccRecords(), 1, isCfEnable(ss.mCfAction),
+                                               ss.mDialingNumber);
                 }
-                sendResponse(cf.mOnComplete, null, ar.exception);
+                if (ss != null) {
+                    sendResponseOrRetryOnCsfbSs(ss, msg.what, ar.exception, null);
+                }
                 break;
 
             case EVENT_GET_CALL_FORWARD_DONE:
@@ -1568,7 +1750,9 @@
                 if (ar.exception == null) {
                     cfInfos = handleCfQueryResult((ImsCallForwardInfo[])ar.result);
                 }
-                sendResponse((Message) ar.userObj, cfInfos, ar.exception);
+                if (ss != null) {
+                    sendResponseOrRetryOnCsfbSs(ss, msg.what, ar.exception, cfInfos);
+                }
                 break;
 
             case EVENT_GET_CALL_BARRING_DONE:
@@ -1581,7 +1765,9 @@
                         ssInfos = handleCwQueryResult((ImsSsInfo[])ar.result);
                     }
                 }
-                sendResponse((Message) ar.userObj, ssInfos, ar.exception);
+                if (ss != null) {
+                    sendResponseOrRetryOnCsfbSs(ss, msg.what, ar.exception, ssInfos);
+                }
                 break;
 
             case EVENT_GET_CLIR_DONE:
@@ -1592,17 +1778,33 @@
                     // that for compatibility
                     clirInfo = ssInfo.getCompatArray(ImsSsData.SS_CLIR);
                 }
-                sendResponse((Message) ar.userObj, clirInfo, ar.exception);
+                if (ss != null) {
+                    sendResponseOrRetryOnCsfbSs(ss, msg.what, ar.exception, clirInfo);
+                }
+                break;
+
+            case EVENT_GET_CLIP_DONE:
+                Bundle ssInfoResp = null;
+                if (ar.exception == null) {
+                    ssInfoResp = (Bundle) ar.result;
+                }
+                if (ss != null) {
+                    sendResponseOrRetryOnCsfbSs(ss, msg.what, ar.exception, ssInfoResp);
+                }
                 break;
 
             case EVENT_SET_CLIR_DONE:
                 if (ar.exception == null) {
-                    saveClirSetting(msg.arg1);
+                    if (ss != null) {
+                        saveClirSetting(ss.mClirMode);
+                    }
                 }
                  // (Intentional fallthrough)
             case EVENT_SET_CALL_BARRING_DONE:
             case EVENT_SET_CALL_WAITING_DONE:
-                sendResponse((Message) ar.userObj, null, ar.exception);
+                if (ss != null) {
+                    sendResponseOrRetryOnCsfbSs(ss, msg.what, ar.exception, null);
+                }
                 break;
 
             case EVENT_DEFAULT_PHONE_DATA_STATE_CHANGED:
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index c162b7a..bc5d9d8 100755
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -1429,6 +1429,9 @@
             }
         } else {
             log("No carrier ImsReasonInfo mappings defined.");
+            if (!mImsReasonCodeMap.isEmpty()) {
+                mImsReasonCodeMap.clear();
+            }
         }
     }
 
@@ -1705,6 +1708,8 @@
             ImsCall callToHold = mForegroundCall.getImsCall();
             HoldSwapState oldHoldState = mHoldSwitchingState;
             mHoldSwitchingState = HoldSwapState.HOLDING_TO_ANSWER_INCOMING;
+            ImsCall callExpectedToResume = mCallExpectedToResume;
+            mCallExpectedToResume = mRingingCall.getImsCall();
             mForegroundCall.switchWith(mBackgroundCall);
             logHoldSwapState("holdActiveCallForWaitingCall");
             try {
@@ -1714,6 +1719,7 @@
             } catch (ImsException e) {
                 mForegroundCall.switchWith(mBackgroundCall);
                 mHoldSwitchingState = oldHoldState;
+                mCallExpectedToResume = callExpectedToResume;
                 logHoldSwapState("holdActiveCallForWaitingCall - fail");
                 throw new CallStateException(e.getMessage());
             }
@@ -1911,6 +1917,7 @@
             fgImsCall.merge(bgImsCall);
         } catch (ImsException e) {
             log("conference " + e.getMessage());
+            handleConferenceFailed(foregroundConnection, backgroundConnection);
         }
     }
 
@@ -4896,4 +4903,15 @@
     public ArrayList<ImsPhoneConnection> getConnections() {
         return mConnections;
     }
+
+    private void handleConferenceFailed(ImsPhoneConnection fgConnection,
+            ImsPhoneConnection bgConnection) {
+        if (fgConnection != null) {
+            fgConnection.handleMergeComplete();
+        }
+        if (bgConnection != null) {
+            bgConnection.handleMergeComplete();
+        }
+        mPhone.notifySuppServiceFailed(Phone.SuppService.CONFERENCE);
+    }
 }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
index e2b1534..25ff97f 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
@@ -924,24 +924,23 @@
                 if (isActivate()
                         && !mPhone.getDefaultPhone().isClirActivationAndDeactivationPrevented()) {
                     try {
-                        mPhone.mCT.getUtInterface().updateCLIR(CommandsInterface.CLIR_INVOCATION,
+                        mPhone.setOutgoingCallerIdDisplay(CommandsInterface.CLIR_INVOCATION,
                             obtainMessage(EVENT_SET_COMPLETE, this));
-                    } catch (ImsException e) {
+                    } catch (Exception e) {
                         Rlog.d(LOG_TAG, "processCode: Could not get UT handle for updateCLIR.");
                     }
                 } else if (isDeactivate()
                         && !mPhone.getDefaultPhone().isClirActivationAndDeactivationPrevented()) {
                     try {
-                        mPhone.mCT.getUtInterface().updateCLIR(CommandsInterface.CLIR_SUPPRESSION,
+                        mPhone.setOutgoingCallerIdDisplay(CommandsInterface.CLIR_SUPPRESSION,
                             obtainMessage(EVENT_SET_COMPLETE, this));
-                    } catch (ImsException e) {
+                    } catch (Exception e) {
                         Rlog.d(LOG_TAG, "processCode: Could not get UT handle for updateCLIR.");
                     }
                 } else if (isInterrogate()) {
                     try {
-                        mPhone.mCT.getUtInterface()
-                            .queryCLIR(obtainMessage(EVENT_GET_CLIR_COMPLETE, this));
-                    } catch (ImsException e) {
+                        mPhone.getOutgoingCallerIdDisplay(obtainMessage(EVENT_GET_CLIR_COMPLETE, this));
+                    } catch (Exception e) {
                         Rlog.d(LOG_TAG, "processCode: Could not get UT handle for queryCLIR.");
                     }
                 } else {
@@ -951,9 +950,8 @@
                 // NOTE: Refer to the note above.
                 if (isInterrogate()) {
                     try {
-                        mPhone.mCT.getUtInterface()
-                            .queryCLIP(obtainMessage(EVENT_SUPP_SVC_QUERY_COMPLETE, this));
-                    } catch (ImsException e) {
+                        mPhone.queryCLIP(obtainMessage(EVENT_SUPP_SVC_QUERY_COMPLETE, this));
+                    } catch (Exception e) {
                         Rlog.d(LOG_TAG, "processCode: Could not get UT handle for queryCLIP.");
                     }
                 } else if (isActivate() || isDeactivate()) {
@@ -1291,6 +1289,8 @@
                 return mContext.getText(com.android.internal.R.string.stk_cc_ss_to_ss);
             } else if (err.getCommandError() == CommandException.Error.SS_MODIFIED_TO_DIAL_VIDEO) {
                 return mContext.getText(com.android.internal.R.string.stk_cc_ss_to_dial_video);
+            } else if (err.getCommandError() == CommandException.Error.INTERNAL_ERR) {
+                return mContext.getText(com.android.internal.R.string.mmiError);
             }
         }
         return null;
@@ -1349,6 +1349,9 @@
             } else if (ar.exception instanceof ImsException) {
                 sb.append(getImsErrorMessage(ar));
             }
+        } else if ((int)ar.result == CommandsInterface.SS_STATUS_UNKNOWN) {
+            mState = State.FAILED;
+            sb = null;
         } else if (isActivate()) {
             mState = State.COMPLETE;
             if (mIsCallFwdReg) {
@@ -1492,6 +1495,11 @@
             else {
                 sb.append(getErrorMessage(ar));
             }
+        } else if (ar.result instanceof CallForwardInfo[] &&
+                   ((CallForwardInfo[]) ar.result)[0].status
+                    == CommandsInterface.SS_STATUS_UNKNOWN) {
+            sb = null;
+            mState = State.FAILED;
         } else {
             CallForwardInfo infos[];
 
@@ -1574,15 +1582,20 @@
                 }
 
             } else {
-                Rlog.d(LOG_TAG, "onSuppSvcQueryComplete: Received Call Barring Response.");
-                // Response for Call Barring queries.
-                int[] cbInfos = (int[]) ar.result;
-                if (cbInfos[0] == 1) {
-                    sb.append(mContext.getText(com.android.internal.R.string.serviceEnabled));
-                    mState = State.COMPLETE;
+                Rlog.d(LOG_TAG,
+                        "onSuppSvcQueryComplete: Received Call Barring/CSFB CLIP Response.");
+                // Response for Call Barring and CSFB CLIP queries.
+                int[] infos = (int[]) ar.result;
+                if (infos == null || infos.length == 0) {
+                    sb.append(mContext.getText(com.android.internal.R.string.mmiError));
                 } else {
-                    sb.append(mContext.getText(com.android.internal.R.string.serviceDisabled));
-                    mState = State.COMPLETE;
+                    if (infos[0] == 1) {
+                        sb.append(mContext.getText(com.android.internal.R.string.serviceEnabled));
+                        mState = State.COMPLETE;
+                    } else {
+                        sb.append(mContext.getText(com.android.internal.R.string.serviceDisabled));
+                        mState = State.COMPLETE;
+                    }
                 }
             }
         }
@@ -1645,16 +1658,18 @@
         if (ar.exception != null) {
             if (ar.exception instanceof ImsException) {
                 sb.append(getImsErrorMessage(ar));
+            } else {
+                sb.append(getErrorMessage(ar));
             }
         } else {
-            ImsSsInfo ssInfo = (ImsSsInfo) ar.result;
+            int[] clirInfo = (int[]) ar.result;
             // ssInfo.getClirOutgoingState() = The 'n' parameter from TS 27.007 7.7
             // ssInfo.getClirInterrogationStatus() = The 'm' parameter from TS 27.007 7.7
-            Rlog.d(LOG_TAG, "onQueryClirComplete: CLIR param n=" + ssInfo.getClirOutgoingState()
-                    + " m=" + ssInfo.getClirInterrogationStatus());
+            Rlog.d(LOG_TAG, "onQueryClirComplete: CLIR param n=" + clirInfo[0]
+                    + " m=" + clirInfo[1]);
 
             // 'm' parameter.
-            switch (ssInfo.getClirInterrogationStatus()) {
+            switch (clirInfo[1]) {
                 case ImsSsInfo.CLIR_STATUS_NOT_PROVISIONED:
                     sb.append(mContext.getText(
                             com.android.internal.R.string.serviceNotProvisioned));
@@ -1667,7 +1682,7 @@
                     break;
                 case ImsSsInfo.CLIR_STATUS_TEMPORARILY_RESTRICTED:
                     // 'n' parameter.
-                    switch (ssInfo.getClirOutgoingState()) {
+                    switch (clirInfo[0]) {
                         case ImsSsInfo.CLIR_OUTGOING_DEFAULT:
                             sb.append(mContext.getText(
                                     com.android.internal.R.string.CLIRDefaultOnNextCallOn));
@@ -1691,7 +1706,7 @@
                     break;
                 case ImsSsInfo.CLIR_STATUS_TEMPORARILY_ALLOWED:
                     // 'n' parameter.
-                    switch (ssInfo.getClirOutgoingState()) {
+                    switch (clirInfo[0]) {
                         case ImsSsInfo.CLIR_OUTGOING_DEFAULT:
                             sb.append(mContext.getText(
                                     com.android.internal.R.string.CLIRDefaultOffNextCallOff));
@@ -1737,11 +1752,13 @@
             } else {
                 sb.append(getErrorMessage(ar));
             }
-
+        } else if ((ar.result instanceof int[]) &&
+                   ((int[])ar.result)[0] == CommandsInterface.SS_STATUS_UNKNOWN) {
+            sb = null;
         } else {
             int[] ints = (int[])ar.result;
 
-            if (ints.length != 0) {
+            if (ints != null && ints.length != 0) {
                 if (ints[0] == 0) {
                     sb.append(mContext.getText(com.android.internal.R.string.serviceDisabled));
                     mState = State.COMPLETE;
@@ -1850,8 +1867,7 @@
             case ImsSsData.SS_INTERROGATION:
                 if (ssData.isTypeClir()) {
                     Rlog.d(LOG_TAG, "CLIR INTERROGATION");
-                    ImsSsInfo clirInfo = ssData.getSuppServiceInfo().get(0);
-                    onQueryClirComplete(new AsyncResult(null, clirInfo, ex));
+                    onQueryClirComplete(new AsyncResult(null, ssData.getSuppServiceInfoCompat(), ex));
                 } else if (ssData.isTypeCF()) {
                     Rlog.d(LOG_TAG, "CALL FORWARD INTERROGATION");
                     // Have to translate to an array, since the modem still returns it in the
diff --git a/src/java/com/android/internal/telephony/uicc/CsimFileHandler.java b/src/java/com/android/internal/telephony/uicc/CsimFileHandler.java
index c5dd05c..2190df6 100644
--- a/src/java/com/android/internal/telephony/uicc/CsimFileHandler.java
+++ b/src/java/com/android/internal/telephony/uicc/CsimFileHandler.java
@@ -43,8 +43,12 @@
         case EF_CSIM_IMSIM:
         case EF_CSIM_CDMAHOME:
         case EF_CSIM_EPRL:
+        case EF_CSIM_PRL:
         case EF_CSIM_MIPUPP:
             return MF_SIM + DF_ADF;
+        case EF_CSIM_MSPL:
+        case EF_CSIM_MLPL:
+            return MF_SIM + DF_TELECOM + DF_MMSS;
         }
         String path = getCommonIccEFPath(efid);
         if (path == null) {
diff --git a/src/java/com/android/internal/telephony/uicc/IccConstants.java b/src/java/com/android/internal/telephony/uicc/IccConstants.java
index 0f41f1e..5eae070 100644
--- a/src/java/com/android/internal/telephony/uicc/IccConstants.java
+++ b/src/java/com/android/internal/telephony/uicc/IccConstants.java
@@ -72,6 +72,10 @@
     static final int EF_CSIM_IMSIM = 0x6F22;
     static final int EF_CSIM_CDMAHOME = 0x6F28;
     static final int EF_CSIM_EPRL = 0x6F5A;
+    static final int EF_CSIM_PRL = 0x6F30;
+    // C.S0074-Av1.0 Section 4
+    static final int EF_CSIM_MLPL = 0x4F20;
+    static final int EF_CSIM_MSPL = 0x4F21;
     static final int EF_CSIM_MIPUPP = 0x6F4D;
 
     //ISIM access
@@ -103,6 +107,7 @@
     static final String DF_GRAPHICS = "5F50";
     static final String DF_GSM = "7F20";
     static final String DF_CDMA = "7F25";
+    static final String DF_MMSS = "5F3C";
 
     //UICC access
     static final String DF_ADF = "7FFF";
diff --git a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
index b44eda0..64ac883 100644
--- a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
@@ -45,9 +45,6 @@
                                                         // STOPSHIP if true
     public static final String INTENT_ISIM_REFRESH = "com.android.intent.isim_refresh";
 
-    private static final int EVENT_APP_READY = 1;
-    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
@@ -62,9 +59,6 @@
     @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
 
     @Override
@@ -117,25 +111,6 @@
                     super.handleMessage(msg);
                     break;
 
-                case EVENT_ISIM_AUTHENTICATE_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    log("EVENT_ISIM_AUTHENTICATE_DONE");
-                    if (ar.exception != null) {
-                        log("Exception ISIM AKA: " + ar.exception);
-                    } else {
-                        try {
-                            auth_rsp = (String)ar.result;
-                            log("ISIM AKA: auth_rsp = " + auth_rsp);
-                        } catch (Exception e) {
-                            log("Failed to parse ISIM AKA contents: " + e);
-                        }
-                    }
-                    synchronized (mLock) {
-                        mLock.notifyAll();
-                    }
-
-                    break;
-
                 default:
                     super.handleMessage(msg);   // IccRecords handles generic record load responses
 
diff --git a/src/java/com/android/internal/telephony/uicc/RuimFileHandler.java b/src/java/com/android/internal/telephony/uicc/RuimFileHandler.java
index 2323b5a..f24fed3 100644
--- a/src/java/com/android/internal/telephony/uicc/RuimFileHandler.java
+++ b/src/java/com/android/internal/telephony/uicc/RuimFileHandler.java
@@ -64,8 +64,12 @@
         case EF_CSIM_IMSIM:
         case EF_CSIM_CDMAHOME:
         case EF_CSIM_EPRL:
+        case EF_CSIM_PRL:
         case EF_CSIM_MIPUPP:
             return MF_SIM + DF_CDMA;
+        case EF_CSIM_MSPL:
+        case EF_CSIM_MLPL:
+            return MF_SIM + DF_TELECOM + DF_MMSS;
         }
         return getCommonIccEFPath(efid);
     }
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 0a972ab..b14ce87 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -25,7 +25,6 @@
 import static com.android.testutils.NetworkStatsUtilsKt.assertNetworkStatsEquals;
 
 import static junit.framework.Assert.assertNotNull;
-import static junit.framework.TestCase.fail;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -1066,19 +1065,13 @@
     @SmallTest
     public void testNoHoldErrorMessageWhenCallDisconnected() {
         when(mImsPhoneConnection.getImsCall()).thenReturn(mImsCall);
-        doAnswer(new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocationOnMock) {
-                fail("Error message showed when the call has already been disconnected!");
-                return null;
-            }
-        }).when(mImsPhoneConnection)
-                .onConnectionEvent(eq(android.telecom.Connection.EVENT_CALL_HOLD_FAILED), any());
         mCTUT.getConnections().add(mImsPhoneConnection);
         when(mImsPhoneConnection.getState()).thenReturn(ImsPhoneCall.State.DISCONNECTED);
-        ImsReasonInfo info = new ImsReasonInfo(ImsReasonInfo.CODE_UNSPECIFIED,
+        final ImsReasonInfo info = new ImsReasonInfo(ImsReasonInfo.CODE_UNSPECIFIED,
                 ImsReasonInfo.CODE_UNSPECIFIED, null);
         mCTUT.getImsCallListener().onCallHoldFailed(mImsPhoneConnection.getImsCall(), info);
+        verify(mImsPhoneConnection, never()).onConnectionEvent(
+                eq(android.telecom.Connection.EVENT_CALL_HOLD_FAILED), any());
     }
 
     @Test
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 0531d72..8797c32 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -70,6 +70,7 @@
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.imsphone.ImsPhone.SS;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
@@ -475,11 +476,15 @@
 
         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
         verify(mImsUtInterface).queryCLIR(messageArgumentCaptor.capture());
-        assertEquals(msg, messageArgumentCaptor.getValue().obj);
+        assertNotNull(messageArgumentCaptor.getValue().obj);
+        SS ss = (SS) messageArgumentCaptor.getValue().obj;
+        assertEquals(msg, ss.mOnComplete);
 
         mImsPhoneUT.setOutgoingCallerIdDisplay(1234, msg);
         verify(mImsUtInterface).updateCLIR(eq(1234), messageArgumentCaptor.capture());
-        assertEquals(msg, messageArgumentCaptor.getValue().obj);
+        assertNotNull(messageArgumentCaptor.getValue().obj);
+        ss = (SS) messageArgumentCaptor.getValue().obj;
+        assertEquals(msg, ss.mOnComplete);
     }
 
     @FlakyTest
@@ -509,12 +514,16 @@
 
         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
         verify(mImsUtInterface).queryCallWaiting(messageArgumentCaptor.capture());
-        assertEquals(msg, messageArgumentCaptor.getValue().obj);
+        assertNotNull(messageArgumentCaptor.getValue().obj);
+        SS ss = (SS) messageArgumentCaptor.getValue().obj;
+        assertEquals(msg, ss.mOnComplete);
 
         mImsPhoneUT.setCallWaiting(true, msg);
         verify(mImsUtInterface).updateCallWaiting(eq(true),
                 eq(CommandsInterface.SERVICE_CLASS_VOICE), messageArgumentCaptor.capture());
-        assertEquals(msg, messageArgumentCaptor.getValue().obj);
+        assertNotNull(messageArgumentCaptor.getValue().obj);
+        ss = (SS) messageArgumentCaptor.getValue().obj;
+        assertEquals(msg, ss.mOnComplete);
     }
 
     @Test
@@ -545,14 +554,18 @@
         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
         verify(mImsUtInterface).queryCallBarring(eq(ImsUtImplBase.CALL_BARRING_ALL_OUTGOING),
                 messageArgumentCaptor.capture(), eq(CommandsInterface.SERVICE_CLASS_NONE));
-        assertEquals(msg, messageArgumentCaptor.getValue().obj);
+        assertNotNull(messageArgumentCaptor.getValue().obj);
+        SS ss = (SS) messageArgumentCaptor.getValue().obj;
+        assertEquals(msg, ss.mOnComplete);
 
         mImsPhoneUT.setCallBarring(CommandsInterface.CB_FACILITY_BAOIC, true, "abc", msg,
                 CommandsInterface.SERVICE_CLASS_NONE);
         verify(mImsUtInterface).updateCallBarring(eq(ImsUtImplBase.CALL_BARRING_OUTGOING_INTL),
                 eq(CommandsInterface.CF_ACTION_ENABLE), messageArgumentCaptor.capture(),
                 (String[]) eq(null), eq(CommandsInterface.SERVICE_CLASS_NONE), eq("abc"));
-        assertEquals(msg, messageArgumentCaptor.getValue().obj);
+        assertNotNull(messageArgumentCaptor.getValue().obj);
+        ss = (SS) messageArgumentCaptor.getValue().obj;
+        assertEquals(msg, ss.mOnComplete);
 
         mImsPhoneUT.setCallBarring(CommandsInterface.CB_FACILITY_BAOICxH, false, "abc", msg,
                 CommandsInterface.SERVICE_CLASS_NONE);
@@ -560,7 +573,9 @@
                 eq(ImsUtImplBase.CALL_BARRING_OUTGOING_INTL_EXCL_HOME),
                 eq(CommandsInterface.CF_ACTION_DISABLE), messageArgumentCaptor.capture(),
                 (String[]) eq(null), eq(CommandsInterface.SERVICE_CLASS_NONE), eq("abc"));
-        assertEquals(msg, messageArgumentCaptor.getValue().obj);
+        assertNotNull(messageArgumentCaptor.getValue().obj);
+        ss = (SS) messageArgumentCaptor.getValue().obj;
+        assertEquals(msg, ss.mOnComplete);
     }
 
     @Test