Merge "Revert "Revert "use new TelephonyManager API preferred_network_type"""
diff --git a/res/drawable/signal_strength_4g.xml b/res/drawable/signal_strength_4g.xml
new file mode 100644
index 0000000..9062096
--- /dev/null
+++ b/res/drawable/signal_strength_4g.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="9.208dp"
+    android:height="17dp"
+    android:viewportWidth="13.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M4.600000,7.800000l0.700000,0.000000l0.000000,1.300000L4.600000,9.100000L4.600000,11.000000L3.000000,11.000000L3.000000,9.200000L0.100000,9.200000L0.000000,8.100000L3.000000,2.500000l1.700000,0.000000L4.700000,7.800000zM1.600000,7.800000L3.000000,7.800000l0.000000,-3.000000L2.900000,5.000000L1.600000,7.800000z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M11.900000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S6.100000,9.000000 6.100000,7.900000L6.100000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000S8.100000,2.400000 9.000000,2.400000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S9.500000,3.700000 9.000000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S7.700000,5.000000 7.700000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L10.099999,7.800000L9.000000,7.800000L9.000000,6.600000l2.900000,0.000000L11.900000,9.900000z"/>
+</vector>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7773af6..de14389 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1074,8 +1074,8 @@
     <!-- Label for the "No service" notification item, when expanded. -->
     <string name="notification_network_selection_title">No service</string>
     <!-- Label for the expanded "No service" notification item, including the
-         operator name set by user -->
-    <string name="notification_network_selection_text">Selected network (<xliff:g id="operator_name">%s</xliff:g>) unavailable</string>
+         operator name set by user. No space after "network", appended in nonempty value. -->
+    <string name="notification_network_selection_text">Selected network<xliff:g id="operator_name">%s</xliff:g> unavailable</string>
 
     <!-- In-call screen: call failure message displayed in an error dialog. [CHAR_LIMIT=NONE] -->
     <string name="incall_error_power_off" product="watch">Turn on mobile network, turn off airplane mode or turn off battery saver mode to make a call.</string>
diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java
index bfeee7a..bdffb26 100644
--- a/src/com/android/phone/CallForwardEditPreference.java
+++ b/src/com/android/phone/CallForwardEditPreference.java
@@ -76,6 +76,11 @@
         mReplaceInvalidCFNumber = replaceInvalidCFNumber;
     }
 
+    void restoreCallForwardInfo(CallForwardInfo cf) {
+        handleCallForwardResult(cf);
+        updateSummaryText();
+    }
+
     @Override
     protected void onBindDialogView(View view) {
         // default the button clicked to be the cancel button.
@@ -100,7 +105,15 @@
             int action = (isToggled() || (mButtonClicked == DialogInterface.BUTTON_POSITIVE)) ?
                     CommandsInterface.CF_ACTION_REGISTRATION :
                     CommandsInterface.CF_ACTION_DISABLE;
-            int time = (reason != CommandsInterface.CF_REASON_NO_REPLY) ? 0 : 20;
+            int time = 0;
+            if (reason == CommandsInterface.CF_REASON_NO_REPLY) {
+                PersistableBundle carrierConfig = PhoneGlobals.getInstance()
+                        .getCarrierConfigForSubId(mPhone.getSubId());
+                if (carrierConfig.getBoolean(
+                        CarrierConfigManager.KEY_SUPPORT_NO_REPLY_TIMER_FOR_CFNRY_BOOL, true)) {
+                    time = 20;
+                }
+            }
             final String number = getPhoneNumber();
 
             Log.d(LOG_TAG, "callForwardInfo=" + callForwardInfo);
@@ -137,7 +150,7 @@
         }
     }
 
-    void handleCallForwardResult(CallForwardInfo cf) {
+    private void handleCallForwardResult(CallForwardInfo cf) {
         callForwardInfo = cf;
         Log.d(LOG_TAG, "handleGetCFResponse done, callForwardInfo=" + callForwardInfo);
         // In some cases, the network can send call forwarding URIs for voicemail that violate the
diff --git a/src/com/android/phone/CallGatewayManager.java b/src/com/android/phone/CallGatewayManager.java
index bdac983..1dd75c4 100644
--- a/src/com/android/phone/CallGatewayManager.java
+++ b/src/com/android/phone/CallGatewayManager.java
@@ -16,184 +16,19 @@
 
 package com.android.phone;
 
-import android.content.Intent;
 import android.net.Uri;
-import android.telecom.PhoneAccount;
-import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.Connection;
-
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * This class manages gateway information for outgoing calls. When calls are made, they may contain
- * gateway information for services which route phone calls through their own service/numbers.
- * The data consists of a number to call and the package name of the service. This data is used in
- * two ways:<br/>
- * 1. Call the appropriate routing number<br/>
- * 2. Display information about the routing to the user<br/>
- *
- * <p>When an outgoing call is finally placed in PhoneUtils.placeCall, it uses this class to get the
- * proper number to dial. It also saves an association between the connection object and the gateway
- * data into this class.
+ * TODO: Not much of this class is even used any more.  Need to unwind the RawGatewayInfo class as
+ * it is used in part of the placeCall method used in OTASP.
  */
 public class CallGatewayManager {
-    private static final String LOG_TAG = CallGatewayManager.class.getSimpleName();
-
-    /**
-     * Intent extra to specify the package name of the gateway
-     * provider.  Used to get the name displayed in the in-call screen
-     * during the call setup. The value is a string.
-     */
-    // TODO: This extra is currently set by the gateway application as
-    // a temporary measure. Ultimately, the framework will securely
-    // set it.
-    /* package */ static final String EXTRA_GATEWAY_PROVIDER_PACKAGE =
-            "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE";
-
-    /**
-     * Intent extra to specify the URI of the provider to place the
-     * call. The value is a string. It holds the gateway address
-     * (phone gateway URL should start with the 'tel:' scheme) that
-     * will actually be contacted to call the number passed in the
-     * intent URL or in the EXTRA_PHONE_NUMBER extra.
-     */
-    // TODO: Should the value be a Uri (Parcelable)? Need to make sure
-    // MMI code '#' don't get confused as URI fragments.
-    /* package */ static final String EXTRA_GATEWAY_URI =
-            "com.android.phone.extra.GATEWAY_URI";
-
     public static final RawGatewayInfo EMPTY_INFO = new RawGatewayInfo(null, null, null);
 
-    private final ConcurrentHashMap<Connection, RawGatewayInfo> mMap =
-        new ConcurrentHashMap<Connection, RawGatewayInfo>(4, 0.9f, 1);
-
-    private static CallGatewayManager sSingleton;
-
-    public static synchronized CallGatewayManager getInstance() {
-        if (sSingleton == null) {
-            sSingleton = new CallGatewayManager();
-        }
-        return sSingleton;
-    }
-
     private CallGatewayManager() {
     }
 
-    /**
-     * Static method returns an object containing the gateway data stored in the extras of the
-     * Intent parameter.  If no such data exists, returns a Null-Object RawGatewayInfo.
-     * @param intent The intent from which to read gateway data.
-     * @return A populated or empty RawGatewayInfo object.
-     */
-    public static RawGatewayInfo getRawGatewayInfo(Intent intent, String number) {
-        if (hasPhoneProviderExtras(intent)) {
-            return new RawGatewayInfo(intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE),
-                    getProviderGatewayUri(intent), number);
-        }
-        return EMPTY_INFO;
-    }
-
-    /**
-     * This function sets the current mapping from connection to gatewayInfo.
-     * @param connection The connection object for the placed outgoing call.
-     * @param gatewayInfo Gateway info gathered using getRawGatewayInfo.
-     */
-    public void setGatewayInfoForConnection(Connection connection, RawGatewayInfo gatewayInfo) {
-        if (!gatewayInfo.isEmpty()) {
-            mMap.put(connection, gatewayInfo);
-        } else {
-            mMap.remove(connection);
-        }
-    }
-
-    /**
-     * Clears the gateway information previously stored via setGatewayInfoForConnection.
-     */
-    public void clearGatewayData(Connection connection) {
-        setGatewayInfoForConnection(connection, EMPTY_INFO);
-    }
-
-    /**
-     * If the parameter matches the connection object we previously saved through
-     * setGatewayInfoForConnection, return the associated raw gateway info data. If not, then
-     * return an empty raw gateway info.
-     */
-    public RawGatewayInfo getGatewayInfo(Connection connection) {
-        final RawGatewayInfo info = mMap.get(connection);
-        if (info != null) {
-            return info;
-        }
-
-        return EMPTY_INFO;
-    }
-
-    /**
-     * Check if all the provider's info is present in the intent.
-     * @param intent Expected to have the provider's extra.
-     * @return true if the intent has all the extras to build the
-     * in-call screen's provider info overlay.
-     */
-    public static boolean hasPhoneProviderExtras(Intent intent) {
-        if (null == intent) {
-            return false;
-        }
-        final String name = intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE);
-        final String gatewayUri = intent.getStringExtra(EXTRA_GATEWAY_URI);
-
-        return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(gatewayUri);
-    }
-
-    /**
-     * Copy all the expected extras set when a 3rd party provider is
-     * used from the source intent to the destination one.  Checks all
-     * the required extras are present, if any is missing, none will
-     * be copied.
-     * @param src Intent which may contain the provider's extras.
-     * @param dst Intent where a copy of the extras will be added if applicable.
-     */
-    public static void checkAndCopyPhoneProviderExtras(Intent src, Intent dst) {
-        if (!hasPhoneProviderExtras(src)) {
-            Log.d(LOG_TAG, "checkAndCopyPhoneProviderExtras: some or all extras are missing.");
-            return;
-        }
-
-        dst.putExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE,
-                     src.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE));
-        dst.putExtra(EXTRA_GATEWAY_URI,
-                     src.getStringExtra(EXTRA_GATEWAY_URI));
-    }
-
-    /**
-     * Return the gateway uri from the intent.
-     * @param intent With the gateway uri extra.
-     * @return The gateway URI or null if not found.
-     */
-    public static Uri getProviderGatewayUri(Intent intent) {
-        final String uri = intent.getStringExtra(EXTRA_GATEWAY_URI);
-        return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
-    }
-
-    /**
-     * Return a formatted version of the uri's scheme specific
-     * part. E.g for 'tel:12345678', return '1-234-5678'.
-     * @param uri A 'tel:' URI with the gateway phone number.
-     * @return the provider's address (from the gateway uri) formatted
-     * for user display. null if uri was null or its scheme was not 'tel:'.
-     */
-    public static String formatProviderUri(Uri uri) {
-        if (uri != null) {
-            if (PhoneAccount.SCHEME_TEL.equals(uri.getScheme())) {
-                return PhoneNumberUtils.formatNumber(uri.getSchemeSpecificPart());
-            } else {
-                return uri.toString();
-            }
-        }
-        return null;
-    }
-
     public static class RawGatewayInfo {
         public String packageName;
         public Uri gatewayUri;
@@ -206,10 +41,6 @@
             this.trueNumber = trueNumber;
         }
 
-        public String getFormattedGatewayNumber() {
-            return formatProviderUri(gatewayUri);
-        }
-
         public boolean isEmpty() {
             return TextUtils.isEmpty(packageName) || gatewayUri == null;
         }
diff --git a/src/com/android/phone/CallLogger.java b/src/com/android/phone/CallLogger.java
deleted file mode 100644
index 60a2590..0000000
--- a/src/com/android/phone/CallLogger.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2013 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.phone;
-
-import android.net.Uri;
-import android.os.SystemProperties;
-import android.provider.CallLog.Calls;
-import android.telephony.DisconnectCause;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.phone.common.CallLogAsync;
-
-/**
- * Helper class for interacting with the call log.
- */
-class CallLogger {
-    private static final String LOG_TAG = CallLogger.class.getSimpleName();
-    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 1) &&
-        (SystemProperties.getInt("ro.debuggable", 0) == 1);
-    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
-    private PhoneGlobals mApplication;
-    private CallLogAsync mCallLog;
-
-    public CallLogger(PhoneGlobals application, CallLogAsync callLogAsync) {
-        mApplication = application;
-        mCallLog = callLogAsync;
-    }
-
-    /**
-     * Logs a call to the call log based on the connection object passed in.
-     *
-     * @param c The connection object for the call being logged.
-     * @param callLogType The type of call log entry.
-     */
-    public void logCall(Connection c, int callLogType) {
-        final String number = c.getAddress();
-        final long date = c.getCreateTime();
-        final long duration = c.getDurationMillis();
-        final Phone phone = c.getCall().getPhone();
-
-        final CallerInfo ci = getCallerInfoFromConnection(c);  // May be null.
-        final String logNumber = getLogNumber(c, ci);
-
-        if (DBG) {
-            log("- onDisconnect(): logNumber set to:" + PhoneUtils.toLogSafePhoneNumber(logNumber) +
-                ", number set to: " + PhoneUtils.toLogSafePhoneNumber(number));
-        }
-
-        // TODO: In getLogNumber we use the presentation from
-        // the connection for the CNAP. Should we use the one
-        // below instead? (comes from caller info)
-
-        // For international calls, 011 needs to be logged as +
-        final int presentation = getPresentation(c, ci);
-
-        final boolean isOtaspNumber = TelephonyCapabilities.supportsOtasp(phone)
-                && phone.isOtaSpNumber(number);
-
-        // Don't log OTASP calls.
-        if (!isOtaspNumber) {
-            logCall(ci, logNumber, presentation, callLogType, date, duration);
-        }
-    }
-
-    /**
-     * Came as logCall(Connection,int) but calculates the call type from the connection object.
-     */
-    public void logCall(Connection c) {
-        final int cause = c.getDisconnectCause();
-
-        // Set the "type" to be displayed in the call log (see constants in CallLog.Calls)
-        final int callLogType;
-
-        if (c.isIncoming()) {
-            callLogType = (cause == DisconnectCause.INCOMING_MISSED ?
-                           Calls.MISSED_TYPE : Calls.INCOMING_TYPE);
-        } else {
-            callLogType = Calls.OUTGOING_TYPE;
-        }
-        if (VDBG) log("- callLogType: " + callLogType + ", UserData: " + c.getUserData());
-
-        logCall(c, callLogType);
-    }
-
-    /**
-     * Logs a call to the call from the parameters passed in.
-     */
-    public void logCall(CallerInfo ci, String number, int presentation, int callType, long start,
-                        long duration) {
-        // no-op
-    }
-
-    /**
-     * Get the caller info.
-     *
-     * @param conn The phone connection.
-     * @return The CallerInfo associated with the connection. Maybe null.
-     */
-    private CallerInfo getCallerInfoFromConnection(Connection conn) {
-        CallerInfo ci = null;
-        Object o = conn.getUserData();
-
-        if ((o == null) || (o instanceof CallerInfo)) {
-            ci = (CallerInfo) o;
-        } else if (o instanceof Uri) {
-            ci = CallerInfo.getCallerInfo(mApplication.getApplicationContext(), (Uri) o);
-        } else {
-            ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
-        }
-        return ci;
-    }
-
-    /**
-     * Retrieve the phone number from the caller info or the connection.
-     *
-     * For incoming call the number is in the Connection object. For
-     * outgoing call we use the CallerInfo phoneNumber field if
-     * present. All the processing should have been done already (CDMA vs GSM numbers).
-     *
-     * If CallerInfo is missing the phone number, get it from the connection.
-     * Apply the Call Name Presentation (CNAP) transform in the connection on the number.
-     *
-     * @param conn The phone connection.
-     * @param callerInfo The CallerInfo. Maybe null.
-     * @return the phone number.
-     */
-    private String getLogNumber(Connection conn, CallerInfo callerInfo) {
-        String number = null;
-
-        if (conn.isIncoming()) {
-            number = conn.getAddress();
-        } else {
-            // For emergency and voicemail calls,
-            // CallerInfo.phoneNumber does *not* contain a valid phone
-            // number.  Instead it contains an I18N'd string such as
-            // "Emergency Number" or "Voice Mail" so we get the number
-            // from the connection.
-            if (null == callerInfo || TextUtils.isEmpty(callerInfo.phoneNumber) ||
-                callerInfo.isEmergencyNumber() || callerInfo.isVoiceMailNumber()) {
-                if (conn.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-                    // In cdma getAddress() is not always equals to getOrigDialString().
-                    number = conn.getOrigDialString();
-                } else {
-                    number = conn.getAddress();
-                }
-            } else {
-                number = callerInfo.phoneNumber;
-            }
-        }
-
-        if (null == number) {
-            return null;
-        } else {
-            int presentation = conn.getNumberPresentation();
-
-            // Do final CNAP modifications.
-            String newNumber = PhoneUtils.modifyForSpecialCnapCases(mApplication, callerInfo,
-                                                          number, presentation);
-
-            if (!PhoneNumberUtils.isUriNumber(number)) {
-                number = PhoneNumberUtils.stripSeparators(number);
-            }
-            if (VDBG) log("getLogNumber: " + number);
-            return number;
-        }
-    }
-
-    /**
-     * Get the presentation from the callerinfo if not null otherwise,
-     * get it from the connection.
-     *
-     * @param conn The phone connection.
-     * @param callerInfo The CallerInfo. Maybe null.
-     * @return The presentation to use in the logs.
-     */
-    private int getPresentation(Connection conn, CallerInfo callerInfo) {
-        int presentation;
-
-        if (null == callerInfo) {
-            presentation = conn.getNumberPresentation();
-        } else {
-            presentation = callerInfo.numberPresentation;
-            if (DBG) log("- getPresentation(): ignoring connection's presentation: " +
-                         conn.getNumberPresentation());
-        }
-        if (DBG) log("- getPresentation: presentation: " + presentation);
-        return presentation;
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 6e55c13..bd97b69 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -253,23 +253,6 @@
     }
 
     /**
-     * Resets the audio mode and speaker state when a call ends.
-     */
-    private void resetAudioStateAfterDisconnect() {
-        if (VDBG) log("resetAudioStateAfterDisconnect()...");
-
-        if (mBluetoothHeadset != null) {
-            mBluetoothHeadset.disconnectAudio();
-        }
-
-        // call turnOnSpeaker() with state=false and store=true even if speaker
-        // is already off to reset user requested speaker state.
-        PhoneUtils.turnOnSpeaker(mApplication, false, true);
-
-        PhoneUtils.setAudioMode(mCM);
-    }
-
-    /**
      * Helper class to play tones through the earpiece (or speaker / BT)
      * during a call, using the ToneGenerator.
      *
@@ -493,23 +476,6 @@
                     mState = TONE_OFF;
                 }
             }
-
-            // Finally, do the same cleanup we otherwise would have done
-            // in onDisconnect().
-            //
-            // (But watch out: do NOT do this if the phone is in use,
-            // since some of our tones get played *during* a call (like
-            // CALL_WAITING) and we definitely *don't*
-            // want to reset the audio mode / speaker / bluetooth after
-            // playing those!
-            // This call is really here for use with tones that get played
-            // *after* a call disconnects, like "busy" or "congestion" or
-            // "call ended", where the phone has already become idle but
-            // we need to defer the resetAudioStateAfterDisconnect() call
-            // till the tone finishes playing.)
-            if (mCM.getState() == PhoneConstants.State.IDLE) {
-                resetAudioStateAfterDisconnect();
-            }
         }
     }
 
diff --git a/src/com/android/phone/CdmaOptions.java b/src/com/android/phone/CdmaOptions.java
index 70744e5..9c713ef 100644
--- a/src/com/android/phone/CdmaOptions.java
+++ b/src/com/android/phone/CdmaOptions.java
@@ -39,6 +39,7 @@
 public class CdmaOptions {
     private static final String LOG_TAG = "CdmaOptions";
 
+    private CarrierConfigManager mCarrierConfigManager;
     private CdmaSystemSelectListPreference mButtonCdmaSystemSelect;
     private CdmaSubscriptionListPreference mButtonCdmaSubscription;
     private RestrictedPreference mButtonAPNExpand;
@@ -59,6 +60,7 @@
         mPrefFragment = prefFragment;
         mPrefScreen = prefScreen;
         mPrefFragment.addPreferencesFromResource(R.xml.cdma_options);
+        mCarrierConfigManager = new CarrierConfigManager(prefFragment.getContext());
 
         // Initialize preferences.
         mButtonCdmaSystemSelect = (CdmaSystemSelectListPreference) mPrefScreen
@@ -77,8 +79,7 @@
         int phoneType = TelephonyManager.from(mPrefFragment.getContext())
                 .createForSubscriptionId(mSubId).getPhoneType();
 
-        PersistableBundle carrierConfig =
-                PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
+        PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
         // Some CDMA carriers want the APN settings.
         boolean addAPNExpand = shouldAddApnExpandPreference(phoneType, carrierConfig);
         boolean addCdmaSubscription =
diff --git a/src/com/android/phone/GsmUmtsCallForwardOptions.java b/src/com/android/phone/GsmUmtsCallForwardOptions.java
index e562e46..6d80621 100644
--- a/src/com/android/phone/GsmUmtsCallForwardOptions.java
+++ b/src/com/android/phone/GsmUmtsCallForwardOptions.java
@@ -31,6 +31,7 @@
     private static final String KEY_TOGGLE = "toggle";
     private static final String KEY_STATUS = "status";
     private static final String KEY_NUMBER = "number";
+    private static final String KEY_ENABLE = "enable";
 
     private CallForwardEditPreference mButtonCFU;
     private CallForwardEditPreference mButtonCFB;
@@ -112,11 +113,12 @@
                 for (CallForwardEditPreference pref : mPreferences) {
                     Bundle bundle = mIcicle.getParcelable(pref.getKey());
                     pref.setToggled(bundle.getBoolean(KEY_TOGGLE));
+                    pref.setEnabled(bundle.getBoolean(KEY_ENABLE));
                     CallForwardInfo cf = new CallForwardInfo();
                     cf.number = bundle.getString(KEY_NUMBER);
                     cf.status = bundle.getInt(KEY_STATUS);
                     pref.init(this, mPhone, mReplaceInvalidCFNumbers);
-                    pref.handleCallForwardResult(cf);
+                    pref.restoreCallForwardInfo(cf);
                 }
             }
             mFirstResume = false;
@@ -131,6 +133,7 @@
         for (CallForwardEditPreference pref : mPreferences) {
             Bundle bundle = new Bundle();
             bundle.putBoolean(KEY_TOGGLE, pref.isToggled());
+            bundle.putBoolean(KEY_ENABLE, pref.isEnabled());
             if (pref.callForwardInfo != null) {
                 bundle.putString(KEY_NUMBER, pref.callForwardInfo.number);
                 bundle.putInt(KEY_STATUS, pref.callForwardInfo.status);
diff --git a/src/com/android/phone/GsmUmtsOptions.java b/src/com/android/phone/GsmUmtsOptions.java
index 19cd3ef..a3f5cfb 100644
--- a/src/com/android/phone/GsmUmtsOptions.java
+++ b/src/com/android/phone/GsmUmtsOptions.java
@@ -16,6 +16,7 @@
 
 package com.android.phone;
 
+import android.content.Context;
 import android.content.Intent;
 import android.os.PersistableBundle;
 import android.preference.Preference;
@@ -23,6 +24,7 @@
 import android.preference.PreferenceScreen;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
+import android.telephony.TelephonyManager;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -36,6 +38,7 @@
 public class GsmUmtsOptions {
     private static final String LOG_TAG = "GsmUmtsOptions";
 
+    private CarrierConfigManager mCarrierConfigManager;
     private RestrictedPreference mButtonAPNExpand;
     private Preference mCategoryAPNExpand;
     Preference mCarrierSettingPref;
@@ -52,8 +55,10 @@
 
     public GsmUmtsOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen,
             final int subId, INetworkQueryService queryService) {
+        final Context context = prefFragment.getContext();
         mPrefFragment = prefFragment;
         mPrefScreen = prefScreen;
+        mCarrierConfigManager = new CarrierConfigManager(context);
         mPrefFragment.addPreferencesFromResource(R.xml.gsm_umts_options);
         mButtonAPNExpand = (RestrictedPreference) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
         mCategoryAPNExpand = mPrefScreen.findPreference(CATEGORY_APN_EXPAND_KEY);
@@ -72,16 +77,17 @@
         boolean addAPNExpand = true;
         boolean addNetworkOperatorsCategory = true;
         boolean addCarrierSettings = true;
+        final TelephonyManager telephonyManager = TelephonyManager.from(mPrefFragment.getContext())
+                .createForSubscriptionId(subId);
         Phone phone = PhoneGlobals.getPhone(subId);
         if (phone == null) return;
-        if (phone.getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
+        if (telephonyManager.getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
             log("Not a GSM phone");
             addAPNExpand = false;
             mNetworkOperator.setEnabled(false);
         } else {
             log("Not a CDMA phone");
-            PersistableBundle carrierConfig =
-                    PhoneGlobals.getInstance().getCarrierConfigForSubId(subId);
+            PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
 
             // Determine which options to display. For GSM these are defaulted to true in
             // CarrierConfigManager, but they maybe overriden by DefaultCarrierConfigService or a
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index fecfc60..5a09744 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -239,15 +239,16 @@
      * doesn't set {@link CarrierConfigManager#KEY_HIDE_ENHANCED_4G_LTE_BOOL} to false.
      */
     public static boolean hideEnhanced4gLteSettings(Context context) {
-        List<SubscriptionInfo> sil =
+        final CarrierConfigManager carrierConfigManager = new CarrierConfigManager(context);
+        final List<SubscriptionInfo> sil =
                 SubscriptionManager.from(context).getActiveSubscriptionInfoList();
         // Check all active subscriptions. We only hide the button if it's disabled for all
         // active subscriptions.
         if (sil != null) {
             for (SubscriptionInfo subInfo : sil) {
                 ImsManager imsManager = ImsManager.getInstance(context, subInfo.getSimSlotIndex());
-                PersistableBundle carrierConfig = PhoneGlobals.getInstance()
-                        .getCarrierConfigForSubId(subInfo.getSubscriptionId());
+                PersistableBundle carrierConfig = carrierConfigManager.getConfigForSubId(
+                        subInfo.getSubscriptionId());
                 if ((imsManager.isVolteEnabledByPlatform()
                         && imsManager.isVolteProvisionedOnDevice())
                         || carrierConfig.getBoolean(
@@ -347,6 +348,7 @@
 
         private SubscriptionManager mSubscriptionManager;
         private TelephonyManager mTelephonyManager;
+        private CarrierConfigManager mCarrierConfigManager;
         private int mSubId;
 
         //UI objects
@@ -399,6 +401,7 @@
                 updateEnhanced4gLteState();
                 updateWiFiCallState();
                 updateVideoCallState();
+                updatePreferredNetworkType();
             }
 
             /**
@@ -788,6 +791,7 @@
             mSubscriptionManager = SubscriptionManager.from(activity);
             mTelephonyManager = (TelephonyManager) activity.getSystemService(
                             Context.TELEPHONY_SERVICE);
+            mCarrierConfigManager = new CarrierConfigManager(getContext());
 
             if (icicle != null) {
                 mExpandAdvancedFields = icicle.getBoolean(EXPAND_ADVANCED_FIELDS, false);
@@ -1052,8 +1056,7 @@
                     android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                     preferredNetworkMode);
 
-            PersistableBundle carrierConfig =
-                    PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
+            PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
             mIsGlobalCdma = isLteOnCdma
                     && carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL);
             if (carrierConfig.getBoolean(
@@ -1107,6 +1110,7 @@
             }
 
             updateEnhanced4gLteState();
+            updatePreferredNetworkType();
             updateCallingCategory();
 
             // Enable link to CMAS app settings depending on the value in config.xml.
@@ -1162,8 +1166,6 @@
                     R.string.enhanced_4g_lte_mode_title_variant :
                     R.string.enhanced_4g_lte_mode_title;
 
-            mButtonPreferredNetworkMode.setEnabled(hasActiveSubscriptions);
-            mButtonEnabledNetworks.setEnabled(hasActiveSubscriptions);
             mButton4glte.setTitle(enhanced4glteModeTitleId);
             mLteDataServicePref.setEnabled(hasActiveSubscriptions);
             Preference ps;
@@ -1200,8 +1202,7 @@
         // Requires that mSubId is up to date
         void updateEnabledNetworksEntries() {
             final int phoneType = mTelephonyManager.getPhoneType();
-            final PersistableBundle carrierConfig =
-                    PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
+            final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
             if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                 final int lteForced = android.provider.Settings.Global.getInt(
                         getContext().getContentResolver(),
@@ -1444,8 +1445,8 @@
 
                 //normally called on the toggle click
                 if (!mButtonDataRoam.isChecked()) {
-                    PersistableBundle carrierConfig =
-                            PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
+                    PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(
+                            mSubId);
                     if (carrierConfig != null && carrierConfig.getBoolean(
                             CarrierConfigManager.KEY_DISABLE_CHARGE_INDICATION_BOOL)) {
                         mTelephonyManager.setDataRoamingEnabled(true);
@@ -1891,8 +1892,7 @@
                 return;
             }
 
-            PersistableBundle carrierConfig = PhoneGlobals.getInstance()
-                    .getCarrierConfigForSubId(mSubId);
+            PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
 
             if ((mImsMgr == null
                     || !mImsMgr.isVolteEnabledByPlatform()
@@ -1915,8 +1915,7 @@
                 return;
             }
 
-            PersistableBundle carrierConfig = PhoneGlobals.getInstance()
-                    .getCarrierConfigForSubId(mSubId);
+            PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
 
             if (mImsMgr != null
                     && mImsMgr.isVtEnabledByPlatform()
@@ -1940,6 +1939,22 @@
             }
         }
 
+        private void updatePreferredNetworkType() {
+            boolean enabled = mTelephonyManager.getCallState(
+                    mSubId) == TelephonyManager.CALL_STATE_IDLE
+                    && hasActiveSubscriptions();
+            Log.i(LOG_TAG, "updatePreferredNetworkType: " + enabled);
+            // TODO: Disentangle enabled networks vs preferred network mode, it looks like
+            // both buttons are shown to the user as "Preferred network type" and the options change
+            // based on what looks like World mode.
+            if (mButtonEnabledNetworks != null) {
+                mButtonEnabledNetworks.setEnabled(enabled);
+            }
+            if (mButtonPreferredNetworkMode != null) {
+                mButtonPreferredNetworkMode.setEnabled(enabled);
+            }
+        }
+
         private void updateCallingCategory() {
             if (mCallingCategory == null) {
                 return;
diff --git a/src/com/android/phone/NetworkOperatorPreference.java b/src/com/android/phone/NetworkOperatorPreference.java
index e582924..09c494c 100644
--- a/src/com/android/phone/NetworkOperatorPreference.java
+++ b/src/com/android/phone/NetworkOperatorPreference.java
@@ -43,16 +43,18 @@
     private CellInfo mCellInfo;
     private List<String> mForbiddenPlmns;
     private int mLevel = -1;
+    private boolean mShow4GForLTE;
 
     // The following constants are used to draw signal icon.
     private static final Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT);
     private static final int NO_CELL_DATA_CONNECTED_ICON = 0;
 
     public NetworkOperatorPreference(
-            CellInfo cellinfo, Context context, List<String> forbiddenPlmns) {
+            CellInfo cellinfo, Context context, List<String> forbiddenPlmns, boolean show4GForLTE) {
         super(context);
         mCellInfo = cellinfo;
         mForbiddenPlmns = forbiddenPlmns;
+        mShow4GForLTE = show4GForLTE;
         refresh();
     }
 
@@ -85,13 +87,15 @@
         updateIcon(level);
     }
 
-    private static int getIconIdForCell(CellInfo ci) {
+    private int getIconIdForCell(CellInfo ci) {
         final int type = ci.getCellIdentity().getType();
         switch (type) {
             case CellInfo.TYPE_GSM: return R.drawable.signal_strength_g;
             case CellInfo.TYPE_WCDMA: // fall through
             case CellInfo.TYPE_TDSCDMA: return R.drawable.signal_strength_3g;
-            case CellInfo.TYPE_LTE: return R.drawable.signal_strength_lte;
+            case CellInfo.TYPE_LTE:
+                return mShow4GForLTE
+                        ? R.drawable.signal_strength_4g : R.drawable.signal_strength_lte;
             case CellInfo.TYPE_CDMA: return R.drawable.signal_strength_1x;
             default: return 0;
         }
diff --git a/src/com/android/phone/NetworkOperators.java b/src/com/android/phone/NetworkOperators.java
index 6d8b30f..6d798b0 100644
--- a/src/com/android/phone/NetworkOperators.java
+++ b/src/com/android/phone/NetworkOperators.java
@@ -29,6 +29,7 @@
 import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.widget.Toast;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -193,25 +194,12 @@
 
     // Used by both mAutoSelect and mNetworkSelect buttons.
     protected void displayNetworkSelectionFailed() {
-        String status = getContext().getResources().getString(R.string.connect_later);
-
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        app.notificationMgr.postTransientNotification(
-                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
-
-        ServiceState ss = mTelephonyManager.getServiceStateForSubscriber(mSubId);
-        if (ss != null) {
-            app.notificationMgr.updateNetworkSelection(ss.getState(), mSubId);
-        }
+        Toast.makeText(getContext(), R.string.connect_later, Toast.LENGTH_LONG).show();
     }
 
     // Used by both mAutoSelect and mNetworkSelect buttons.
     protected void displayNetworkSelectionSucceeded() {
-        String status = getContext().getResources().getString(R.string.registration_done);
-
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        app.notificationMgr.postTransientNotification(
-                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+        Toast.makeText(getContext(), R.string.registration_done, Toast.LENGTH_LONG).show();
     }
 
     private void selectNetworkAutomatic(boolean autoSelect) {
diff --git a/src/com/android/phone/NetworkSelectListPreference.java b/src/com/android/phone/NetworkSelectListPreference.java
index cec914a..5b841c9 100644
--- a/src/com/android/phone/NetworkSelectListPreference.java
+++ b/src/com/android/phone/NetworkSelectListPreference.java
@@ -403,8 +403,7 @@
                 final OperatorInfo operatorInfo = getOperatorInfoFromCellInfo(mCellInfo);
                 if (DBG) logd("manually selected network: " + operatorInfo.toString());
                 boolean isSuccessed = mTelephonyManager.setNetworkSelectionModeManual(
-                        operatorInfo.getOperatorNumeric(), true /* persistSelection */);
-                int mode = mTelephonyManager.getNetworkSelectionMode();
+                        operatorInfo, true /* persistSelection */);
                 Message msg = mHandler.obtainMessage(EVENT_MANUALLY_NETWORK_SELECTION_DONE);
                 msg.obj = isSuccessed;
                 msg.sendToTarget();
diff --git a/src/com/android/phone/NetworkSelectSetting.java b/src/com/android/phone/NetworkSelectSetting.java
index 56f0187..c8a29ce 100644
--- a/src/com/android/phone/NetworkSelectSetting.java
+++ b/src/com/android/phone/NetworkSelectSetting.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
@@ -84,6 +85,7 @@
     private NetworkOperatorPreference mSelectedNetworkOperatorPreference;
     private TelephonyManager mTelephonyManager;
     private List<String> mForbiddenPlmns;
+    private boolean mShow4GForLTE;
 
     private final Runnable mUpdateNetworkOperatorsRunnable = () -> {
         updateNetworkOperatorsPreferenceCategory();
@@ -116,6 +118,15 @@
         mStatusMessagePreference = new Preference(getContext());
         mSelectedNetworkOperatorPreference = null;
         mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
+        try {
+            Context con = getActivity().createPackageContext("com.android.systemui", 0);
+            int id = con.getResources().getIdentifier("config_show4GForLTE",
+                    "bool", "com.android.systemui");
+            mShow4GForLTE = con.getResources().getBoolean(id);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "NameNotFoundException for show4GFotLTE");
+            mShow4GForLTE = false;
+        }
         setRetainInstance(true);
     }
 
@@ -217,7 +228,7 @@
                 ThreadUtils.postOnBackgroundThread(() -> {
                     Message msg = mHandler.obtainMessage(EVENT_SET_NETWORK_SELECTION_MANUALLY_DONE);
                     msg.obj = mTelephonyManager.setNetworkSelectionModeManual(
-                            operatorInfo.getOperatorNumeric(), true /* persistSelection */);
+                            operatorInfo, true /* persistSelection */);
                     msg.sendToTarget();
                 });
 
@@ -268,7 +279,6 @@
                         mSelectedNetworkOperatorPreference.setSummary(R.string.network_connected);
                     } else {
                         if (DBG) logd("manual network selection: failed! ");
-                        updateNetworkSelection();
                         // Set summary as "Couldn't connect" to the selected network.
                         mSelectedNetworkOperatorPreference.setSummary(
                                 R.string.network_could_not_connect);
@@ -393,7 +403,7 @@
         for (int index = 0; index < mCellInfoList.size(); index++) {
             if (!mCellInfoList.get(index).isRegistered()) {
                 NetworkOperatorPreference pref = new NetworkOperatorPreference(
-                        mCellInfoList.get(index), getContext(), mForbiddenPlmns);
+                        mCellInfoList.get(index), getContext(), mForbiddenPlmns, mShow4GForLTE);
                 pref.setKey(CellInfoUtil.getNetworkTitle(mCellInfoList.get(index)));
                 pref.setOrder(index);
                 mNetworkOperatorsPreferences.addPreference(pref);
@@ -431,8 +441,8 @@
             CellInfo cellInfo = CellInfoUtil.wrapCellInfoWithCellIdentity(cellIdentity);
             if (cellInfo != null) {
                 if (DBG) logd("Currently registered cell: " + cellInfo.toString());
-                NetworkOperatorPreference pref =
-                        new NetworkOperatorPreference(cellInfo, getContext(), mForbiddenPlmns);
+                NetworkOperatorPreference pref = new NetworkOperatorPreference(
+                        cellInfo, getContext(), mForbiddenPlmns, mShow4GForLTE);
                 pref.setTitle(mTelephonyManager.getNetworkOperatorName());
                 pref.setSummary(R.string.network_connected);
                 // Update the signal strength icon, since the default signalStrength value would be
@@ -512,8 +522,8 @@
         if (DBG) logd("addConnectedNetworkOperatorPreference");
         // Remove the current ConnectedNetworkOperatorsPreference
         removeConnectedNetworkOperatorPreference();
-        final NetworkOperatorPreference pref =
-                new NetworkOperatorPreference(cellInfo, getContext(), mForbiddenPlmns);
+        final NetworkOperatorPreference pref = new NetworkOperatorPreference(
+                cellInfo, getContext(), mForbiddenPlmns, mShow4GForLTE);
         pref.setSummary(R.string.network_connected);
         mConnectedNetworkOperatorsPreference.addPreference(pref);
         PreferenceScreen preferenceScreen = getPreferenceScreen();
@@ -617,21 +627,6 @@
         }
     }
 
-    /**
-     * Call {@link NotificationMgr#updateNetworkSelection(int, int)} to send notification about
-     * no service of user selected operator
-     */
-    private void updateNetworkSelection() {
-        if (DBG) logd("Update notification about no service of user selected operator");
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
-            ServiceState ss = mTelephonyManager.getServiceState();
-            if (ss != null) {
-                app.notificationMgr.updateNetworkSelection(ss.getState(), mSubId);
-            }
-        }
-    }
-
     private void stopNetworkQuery() {
         // Stop the network query process
         try {
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 1b2d49e..5aa87d0 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -569,6 +569,9 @@
     private void showNetworkSelection(String operator, int subId) {
         if (DBG) log("showNetworkSelection(" + operator + ")...");
 
+        if (!TextUtils.isEmpty(operator)) {
+            operator = String.format(" (%s)", operator);
+        }
         Notification.Builder builder = new Notification.Builder(mContext)
                 .setSmallIcon(android.R.drawable.stat_sys_warning)
                 .setContentTitle(mContext.getString(R.string.notification_network_selection_title))
diff --git a/src/com/android/phone/PhoneApp.java b/src/com/android/phone/PhoneApp.java
index f16d8ce..df151bf 100644
--- a/src/com/android/phone/PhoneApp.java
+++ b/src/com/android/phone/PhoneApp.java
@@ -19,14 +19,13 @@
 import android.app.Application;
 import android.os.UserHandle;
 
-import com.android.services.telephony.TelephonyGlobals;
+import com.android.services.telephony.TelecomAccountRegistry;
 
 /**
  * Top-level Application class for the Phone app.
  */
 public class PhoneApp extends Application {
     PhoneGlobals mPhoneGlobals;
-    TelephonyGlobals mTelephonyGlobals;
 
     public PhoneApp() {
     }
@@ -39,8 +38,7 @@
             mPhoneGlobals = new PhoneGlobals(this);
             mPhoneGlobals.onCreate();
 
-            mTelephonyGlobals = new TelephonyGlobals(this);
-            mTelephonyGlobals.onCreate();
+            TelecomAccountRegistry.getInstance(this).setupOnBoot();
         }
     }
 }
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index b1e061f..3f679ed 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -41,6 +41,7 @@
 import android.os.UserManager;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
+import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
@@ -49,7 +50,6 @@
 import android.util.Log;
 import android.widget.Toast;
 
-import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.MmiCode;
@@ -141,7 +141,6 @@
     public PhoneInterfaceManager phoneMgr;
     CarrierConfigLoader configLoader;
 
-    private CallGatewayManager callGatewayManager;
     private Phone phoneInEcm;
 
     static boolean sVoiceCapable = true;
@@ -320,10 +319,6 @@
 
             if (DBG) Log.d(LOG_TAG, "onCreate: mUpdateLock: " + mUpdateLock);
 
-            CallLogger callLogger = new CallLogger(this, new CallLogAsync());
-
-            callGatewayManager = CallGatewayManager.getInstance();
-
             // Create the CallerInfoCache singleton, which remembers custom ring tone and
             // send-to-voicemail settings.
             //
@@ -345,9 +340,6 @@
             // register for MMI/USSD
             mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
 
-            // register connection tracking to PhoneUtils
-            PhoneUtils.initializeConnectionHandler(mCM);
-
             // Register for misc other intent broadcasts.
             IntentFilter intentFilter =
                     new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
@@ -371,11 +363,6 @@
             PreferenceManager.setDefaultValues(this, R.xml.network_setting_fragment, false);
 
             PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false);
-
-            // Make sure the audio mode (along with some
-            // audio-mode-related state of our own) is initialized
-            // correctly, given the current state of the phone.
-            PhoneUtils.setAudioMode(mCM);
         }
 
         // XXX pre-load the SimProvider so that it's ready
@@ -408,14 +395,6 @@
     }
 
     /**
-     * Returns the singleton instance of the PhoneApp if running as the
-     * primary user, otherwise null.
-     */
-    static PhoneGlobals getInstanceIfPrimary() {
-        return sMe;
-    }
-
-    /**
      * Returns the default phone.
      *
      * WARNING: This method should be used carefully, now that there may be multiple phones.
@@ -495,52 +474,6 @@
     }
 
     /**
-     * Controls whether or not the screen is allowed to sleep.
-     *
-     * Once sleep is allowed (WakeState is SLEEP), it will rely on the
-     * settings for the poke lock to determine when to timeout and let
-     * the device sleep {@link PhoneGlobals#setScreenTimeout}.
-     *
-     * @param ws tells the device to how to wake.
-     */
-    /* package */ void requestWakeState(WakeState ws) {
-        if (VDBG) Log.d(LOG_TAG, "requestWakeState(" + ws + ")...");
-        synchronized (this) {
-            if (mWakeState != ws) {
-                switch (ws) {
-                    case PARTIAL:
-                        // acquire the processor wake lock, and release the FULL
-                        // lock if it is being held.
-                        mPartialWakeLock.acquire();
-                        if (mWakeLock.isHeld()) {
-                            mWakeLock.release();
-                        }
-                        break;
-                    case FULL:
-                        // acquire the full wake lock, and release the PARTIAL
-                        // lock if it is being held.
-                        mWakeLock.acquire();
-                        if (mPartialWakeLock.isHeld()) {
-                            mPartialWakeLock.release();
-                        }
-                        break;
-                    case SLEEP:
-                    default:
-                        // release both the PARTIAL and FULL locks.
-                        if (mWakeLock.isHeld()) {
-                            mWakeLock.release();
-                        }
-                        if (mPartialWakeLock.isHeld()) {
-                            mPartialWakeLock.release();
-                        }
-                        break;
-                }
-                mWakeState = ws;
-            }
-        }
-    }
-
-    /**
      * If we are not currently keeping the screen on, then poke the power
      * manager to wake up the screen for the user activity timeout duration.
      */
@@ -553,52 +486,6 @@
         }
     }
 
-    /**
-     * Sets the wake state and screen timeout based on the current state
-     * of the phone, and the current state of the in-call UI.
-     *
-     * This method is a "UI Policy" wrapper around
-     * {@link PhoneGlobals#requestWakeState} and {@link PhoneGlobals#setScreenTimeout}.
-     *
-     * It's safe to call this method regardless of the state of the Phone
-     * (e.g. whether or not it's idle), and regardless of the state of the
-     * Phone UI (e.g. whether or not the InCallScreen is active.)
-     */
-    /* package */ void updateWakeState() {
-        PhoneConstants.State state = mCM.getState();
-
-        // True if the speakerphone is in use.  (If so, we *always* use
-        // the default timeout.  Since the user is obviously not holding
-        // the phone up to his/her face, we don't need to worry about
-        // false touches, and thus don't need to turn the screen off so
-        // aggressively.)
-        // Note that we need to make a fresh call to this method any
-        // time the speaker state changes.  (That happens in
-        // PhoneUtils.turnOnSpeaker().)
-        boolean isSpeakerInUse = (state == PhoneConstants.State.OFFHOOK) && PhoneUtils.isSpeakerOn(this);
-
-        // TODO (bug 1440854): The screen timeout *might* also need to
-        // depend on the bluetooth state, but this isn't as clear-cut as
-        // the speaker state (since while using BT it's common for the
-        // user to put the phone straight into a pocket, in which case the
-        // timeout should probably still be short.)
-
-        // Decide whether to force the screen on or not.
-        //
-        // Force the screen to be on if the phone is ringing or dialing,
-        // or if we're displaying the "Call ended" UI for a connection in
-        // the "disconnected" state.
-        // However, if the phone is disconnected while the user is in the
-        // middle of selecting a quick response message, we should not force
-        // the screen to be on.
-        //
-        boolean isRinging = (state == PhoneConstants.State.RINGING);
-        boolean isDialing = (mCM.getFgPhone().getForegroundCall().getState() == Call.State.DIALING);
-        boolean keepScreenOn = isRinging || isDialing;
-        // keepScreenOn == true means we'll hold a full wake lock:
-        requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
-    }
-
     KeyguardManager getKeyguardManager() {
         return mKeyguardManager;
     }
@@ -665,7 +552,9 @@
         if (isAirplaneNewlyOn) {
             // If we are trying to turn off the radio, make sure there are no active
             // emergency calls.  If there are, switch airplane mode back to off.
-            if (PhoneUtils.isInEmergencyCall(mCM)) {
+            TelecomManager tm = (TelecomManager) context.getSystemService(TELECOM_SERVICE);
+
+            if (tm != null && tm.isInEmergencyCall()) {
                 // Switch airplane mode back to off.
                 ConnectivityManager.from(this).setAirplaneMode(false);
                 Toast.makeText(this, R.string.radio_off_during_emergency_call, Toast.LENGTH_LONG)
@@ -862,41 +751,20 @@
     }
 
     /**
-     * Dismisses the message waiting (voicemail) indicator.
+     * Called when the network selection on the subscription {@code subId} is changed by the user.
      *
-     * @param subId the subscription id we should dismiss the notification for.
+     * @param subId the subscription id.
      */
-    public void clearMwiIndicator(int subId) {
-        // Setting voiceMessageCount to 0 will remove the current notification and clear the system
-        // cached value.
+    public void onNetworkSelectionChanged(int subId) {
         Phone phone = getPhone(subId);
-        if (phone == null) {
-            Log.w(LOG_TAG, "clearMwiIndicator on null phone, subId:" + subId);
+        if (phone != null) {
+            notificationMgr.updateNetworkSelection(phone.getServiceState().getState(), subId);
         } else {
-            phone.setVoiceMessageCount(0);
+            Log.w(LOG_TAG, "onNetworkSelectionChanged on null phone, subId: " + subId);
         }
     }
 
     /**
-     * Enables or disables the visual voicemail check for message waiting indicator. Default value
-     * is true. MWI is the traditional voicemail notification which should be suppressed if visual
-     * voicemail is active. {@link NotificationMgr#updateMwi(int, boolean, boolean)} currently
-     * checks the {@link android.provider.VoicemailContract.Status#CONFIGURATION_STATE} to suppress
-     * the MWI, but there are several issues. b/31229016 is a bug that when the device boots the
-     * configuration state will be cleared and the MWI for voicemail that arrives when the device
-     * is offline will be cleared, even if the account cannot be activated. A full solution will be
-     * adding a setMwiEnabled() method and stop checking the configuration state, but that is too
-     * risky at this moment. This is a temporary workaround to shut down the configuration state
-     * check if visual voicemail cannot be activated.
-     * <p>TODO(twyen): implement the setMwiEnabled() mentioned above.
-     *
-     * @param subId the account to set the enabled state
-     */
-    public void setShouldCheckVisualVoicemailConfigurationForMwi(int subId, boolean enabled) {
-        notificationMgr.setShouldCheckVisualVoicemailConfigurationForMwi(subId, enabled);
-    }
-
-    /**
      * Dump the state of the object, add calls to other objects as desired.
      *
      * @param fd File descriptor
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 33b83af..cc9dbf1 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -57,6 +57,7 @@
 import android.telephony.CellInfo;
 import android.telephony.CellInfoGsm;
 import android.telephony.CellInfoWcdma;
+import android.telephony.CellLocation;
 import android.telephony.ClientRequestStats;
 import android.telephony.IccOpenLogicalChannelResponse;
 import android.telephony.LocationAccessPolicy;
@@ -75,6 +76,8 @@
 import android.telephony.UiccSlotInfo;
 import android.telephony.UssdResponse;
 import android.telephony.VisualVoicemailSmsFilterSettings;
+import android.telephony.cdma.CdmaCellLocation;
+import android.telephony.gsm.GsmCellLocation;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsMmTelFeature;
 import android.telephony.ims.aidl.IImsRcsFeature;
@@ -200,6 +203,10 @@
     private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
     private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
     private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
+    private static final int CMD_GET_ALL_CELL_INFO = 60;
+    private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
+    private static final int CMD_GET_CELL_LOCATION = 62;
+    private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
 
     // Parameters of select command.
     private static final int SELECT_COMMAND = 0xA4;
@@ -757,7 +764,16 @@
                     break;
 
                 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
-                    handleNullReturnEvent(msg, "setNetworkSelectionModeManual");
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    if (ar.exception == null) {
+                        request.result = true;
+                    } else {
+                        request.result = false;
+                        loge("setNetworkSelectionModeManual " + ar.exception);
+                    }
+                    notifyRequester(request);
+                    mApp.onNetworkSelectionChanged(request.subId);
                     break;
 
                 case CMD_GET_MODEM_ACTIVITY_INFO:
@@ -964,6 +980,47 @@
                     notifyRequester(request);
                     break;
 
+                case CMD_GET_ALL_CELL_INFO:
+                    request = (MainThreadRequest) msg.obj;
+                    Pair<Phone, WorkSource> args = (Pair<Phone, WorkSource>) request.argument;
+                    onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
+                    ((Phone) args.first).getAllCellInfo(args.second, onCompleted);
+                    break;
+
+                case EVENT_GET_ALL_CELL_INFO_DONE:
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    request.result = (ar.exception == null) ? ar.result : new ArrayList<CellInfo>();
+                    synchronized (request) {
+                        request.notifyAll();
+                    }
+                    break;
+
+                case CMD_GET_CELL_LOCATION: {
+                    request = (MainThreadRequest) msg.obj;
+                    WorkSource ws = (WorkSource) request.argument;
+                    Phone phone = getPhoneFromRequest(request);
+                    phone.getCellLocation(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
+                    break;
+                }
+
+                case EVENT_GET_CELL_LOCATION_DONE: {
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    if (ar.exception == null) {
+                        request.result = ar.result;
+                    } else {
+                        Phone phone = getPhoneFromRequest(request);
+                        request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
+                                ? new CdmaCellLocation() : new GsmCellLocation();
+                    }
+
+                    synchronized (request) {
+                        request.notifyAll();
+                    }
+                    break;
+                }
+
                 default:
                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
                     break;
@@ -1121,9 +1178,6 @@
     private Phone getPhone(int subId) {
         return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
     }
-    //
-    // Implementation of the ITelephony interface.
-    //
 
     public void dial(String number) {
         dialForSubscriber(getPreferredVoiceSubscription(), number);
@@ -1201,112 +1255,6 @@
         }
     }
 
-    /**
-     * End a call based on call state
-     * @return true is a call was ended
-     */
-    public boolean endCall() {
-        return false;
-    }
-
-    /**
-     * End a call based on the call state of the subId
-     * @return true is a call was ended
-     */
-    public boolean endCallForSubscriber(int subId) {
-        return false;
-    }
-
-    public void answerRingingCall() {
-        // Deprecated.
-    }
-
-    public void answerRingingCallForSubscriber(int subId) {
-        // Deprecated
-    }
-
-    /**
-     * This method is no longer used and can be removed once TelephonyManager stops referring to it.
-     */
-    public void silenceRinger() {
-        Log.e(LOG_TAG, "silenseRinger not supported");
-    }
-
-    @Override
-    public boolean isOffhook(String callingPackage) {
-        return isOffhookForSubscriber(getDefaultSubscription(), callingPackage);
-    }
-
-    @Override
-    public boolean isOffhookForSubscriber(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isOffhookForSubscriber")) {
-            return false;
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            final Phone phone = getPhone(subId);
-            if (phone != null) {
-                return (phone.getState() == PhoneConstants.State.OFFHOOK);
-            } else {
-                return false;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
-    public boolean isRinging(String callingPackage) {
-        return (isRingingForSubscriber(getDefaultSubscription(), callingPackage));
-    }
-
-    @Override
-    public boolean isRingingForSubscriber(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isRingingForSubscriber")) {
-            return false;
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            final Phone phone = getPhone(subId);
-            if (phone != null) {
-                return (phone.getState() == PhoneConstants.State.RINGING);
-            } else {
-                return false;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
-    public boolean isIdle(String callingPackage) {
-        return isIdleForSubscriber(getDefaultSubscription(), callingPackage);
-    }
-
-    @Override
-    public boolean isIdleForSubscriber(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isIdleForSubscriber")) {
-            return false;
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            final Phone phone = getPhone(subId);
-            if (phone != null) {
-                return (phone.getState() == PhoneConstants.State.IDLE);
-            } else {
-                return false;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
     public boolean supplyPin(String pin) {
         return supplyPinForSubscriber(getDefaultSubscription(), pin);
     }
@@ -1777,12 +1725,9 @@
         try {
             if (DBG_LOC) log("getCellLocation: is active user");
             Bundle data = new Bundle();
-            Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
-            if (phone == null) {
-                return null;
-            }
-
-            phone.getCellLocation(workSource).fillInNotifierBundle(data);
+            int subId = mSubscriptionController.getDefaultDataSubId();
+            CellLocation cl = (CellLocation) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
+            cl.fillInNotifierBundle(data);
             return data;
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -1906,7 +1851,9 @@
         try {
             List<CellInfo> cellInfos = new ArrayList<CellInfo>();
             for (Phone phone : PhoneFactory.getPhones()) {
-                final List<CellInfo> info = phone.getAllCellInfo(workSource);
+                final List<CellInfo> info = (List<CellInfo>) sendRequest(
+                        CMD_GET_ALL_CELL_INFO,
+                        new Pair<Phone, WorkSource>(phone, workSource));
                 if (info != null) cellInfos.addAll(info);
             }
             return cellInfos;
@@ -2537,6 +2484,10 @@
 
     @Override
     public int getNetworkSelectionMode(int subId) {
+        if (!isActiveSubscription(subId)) {
+            return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
+        }
+
         return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
     }
 
@@ -2698,6 +2649,10 @@
         return mSubscriptionController.getDefaultVoiceSubId();
     }
 
+    private boolean isActiveSubscription(int subId) {
+        return mSubscriptionController.isActiveSubId(subId);
+    }
+
     /**
      * @see android.telephony.TelephonyManager.WifiCallingChoices
      */
@@ -3238,6 +3193,10 @@
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
                 mApp, subId, "setNetworkSelectionModeAutomatic");
 
+        if (!isActiveSubscription(subId)) {
+            return;
+        }
+
         final long identity = Binder.clearCallingIdentity();
         try {
             if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
@@ -3247,24 +3206,35 @@
         }
     }
 
-    /**
-     * Set the network selection mode to manual with the selected carrier.
+   /**
+     * Ask the radio to connect to the input network and change selection mode to manual.
+     *
+     * @param subId the id of the subscription.
+     * @param operatorInfo the operator information, included the PLMN, long name and short name of
+     * the operator to attach to.
+     * @param persistSelection whether the selection will persist until reboot. If true, only allows
+     * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
+     * normal network selection next time.
+     * @return {@code true} on success; {@code true} on any failure.
      */
     @Override
-    public boolean setNetworkSelectionModeManual(int subId, String operatorNumeric,
-            boolean persistSelection) {
+    public boolean setNetworkSelectionModeManual(
+            int subId, OperatorInfo operatorInfo, boolean persistSelection) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
                 mApp, subId, "setNetworkSelectionModeManual");
 
+        if (!isActiveSubscription(subId)) {
+            return false;
+        }
+
         final long identity = Binder.clearCallingIdentity();
         try {
-            OperatorInfo operator = new OperatorInfo(
-                /* operatorAlphaLong */ "",
-                /* operatorAlphaShort */ "",
-                    operatorNumeric);
-            if (DBG) log("setNetworkSelectionModeManual: subId:" + subId + " operator:" + operator);
-            ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operator,
+            ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
                     persistSelection);
+            if (DBG) {
+                log("setNetworkSelectionModeManual: subId: " + subId
+                        + " operator: " + operatorInfo);
+            }
             return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
         } finally {
             Binder.restoreCallingIdentity(identity);
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index c5625e9..c1bd1b6 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -23,9 +23,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.media.AudioManager;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
@@ -56,7 +53,6 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.internal.telephony.sip.SipPhone;
 import com.android.phone.CallGatewayManager.RawGatewayInfo;
 
 import java.util.Arrays;
@@ -73,43 +69,15 @@
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
-    /** Control stack trace for Audio Mode settings */
-    private static final boolean DBG_SETAUDIOMODE_STACK = false;
-
-    /** Identifier for the "Add Call" intent extra. */
-    static final String ADD_CALL_MODE_KEY = "add_call_mode";
-
     // Return codes from placeCall()
     public static final int CALL_STATUS_DIALED = 0;  // The number was successfully dialed
     public static final int CALL_STATUS_DIALED_MMI = 1;  // The specified number was an MMI code
     public static final int CALL_STATUS_FAILED = 2;  // The call failed
 
-    // State of the Phone's audio modes
-    // Each state can move to the other states, but within the state only certain
-    //  transitions for AudioManager.setMode() are allowed.
-    static final int AUDIO_IDLE = 0;  /** audio behaviour at phone idle */
-    static final int AUDIO_RINGING = 1;  /** audio behaviour while ringing */
-    static final int AUDIO_OFFHOOK = 2;  /** audio behaviour while in call. */
-
     // USSD string length for MMI operations
     static final int MIN_USSD_LEN = 1;
     static final int MAX_USSD_LEN = 160;
 
-    /** Speaker state, persisting between wired headset connection events */
-    private static boolean sIsSpeakerEnabled = false;
-
-    /** Static handler for the connection/mute tracking */
-    private static ConnectionHandler mConnectionHandler;
-
-    /** Phone state changed event*/
-    private static final int PHONE_STATE_CHANGED = -1;
-
-    /** poll phone DISCONNECTING status interval */
-    private static final int DISCONNECTING_POLLING_INTERVAL_MS = 200;
-
-    /** poll phone DISCONNECTING status times limit */
-    private static final int DISCONNECTING_POLLING_TIMES_LIMIT = 8;
-
     /** Define for not a special CNAP string */
     private static final int CNAP_SPECIAL_CASE_NO = -1;
 
@@ -128,26 +96,6 @@
             new ComponentName("com.android.phone",
                     "com.android.services.telephony.TelephonyConnectionService");
 
-    /**
-     * Handler that tracks the connections and updates the value of the
-     * Mute settings for each connection as needed.
-     */
-    private static class ConnectionHandler extends Handler {
-    }
-
-    /**
-     * Register the ConnectionHandler with the phone, to receive connection events
-     */
-    public static void initializeConnectionHandler(CallManager cm) {
-        if (mConnectionHandler == null) {
-            mConnectionHandler = new ConnectionHandler();
-        }
-
-        // pass over cm as user.obj
-        cm.registerForPreciseCallStateChanged(mConnectionHandler, PHONE_STATE_CHANGED, cm);
-
-    }
-
     /** This class is never instantiated. */
     private PhoneUtils() {
     }
@@ -255,10 +203,6 @@
             numberToDial = number;
         }
 
-        // Remember if the phone state was in IDLE state before this call.
-        // After calling CallManager#dial(), getState() will return different state.
-        final boolean initiallyIdle = app.mCM.getState() == PhoneConstants.State.IDLE;
-
         try {
             connection = app.mCM.dial(phone, numberToDial, VideoProfile.STATE_AUDIO_ONLY);
         } catch (CallStateException ex) {
@@ -279,11 +223,6 @@
         if (null == connection) {
             status = CALL_STATUS_FAILED;
         } else {
-            // Now that the call is successful, we can save the gateway info for the call
-            if (callGateway != null) {
-                callGateway.setGatewayInfoForConnection(connection, gatewayInfo);
-            }
-
             if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                 updateCdmaCallStateOnNewOutgoingCall(app, connection);
             }
@@ -314,8 +253,6 @@
             }
 
             startGetCallerInfo(context, connection, null, null, gatewayInfo);
-
-            setAudioMode();
         }
 
         return status;
@@ -346,15 +283,6 @@
         return builder.toString();
     }
 
-    static void separateCall(Connection c) {
-        try {
-            if (DBG) log("separateCall: " + toLogSafePhoneNumber(c.getAddress()));
-            c.separate();
-        } catch (CallStateException ex) {
-            Log.w(LOG_TAG, "separateCall: caught " + ex, ex);
-        }
-    }
-
     /**
      * Handle the MMIInitiate message and put up an alert that lets
      * the user cancel the operation, if applicable.
@@ -688,64 +616,6 @@
         return canceled;
     }
 
-    public static class VoiceMailNumberMissingException extends Exception {
-        VoiceMailNumberMissingException() {
-            super();
-        }
-
-        VoiceMailNumberMissingException(String msg) {
-            super(msg);
-        }
-    }
-
-    /**
-     * Gets the phone number to be called from an intent.  Requires a Context
-     * to access the contacts database, and a Phone to access the voicemail
-     * number.
-     *
-     * <p>If <code>phone</code> is <code>null</code>, the function will return
-     * <code>null</code> for <code>voicemail:</code> URIs;
-     * if <code>context</code> is <code>null</code>, the function will return
-     * <code>null</code> for person/phone URIs.</p>
-     *
-     * <p>If the intent contains a <code>sip:</code> URI, the returned
-     * "number" is actually the SIP address.
-     *
-     * @param context a context to use (or
-     * @param intent the intent
-     *
-     * @throws VoiceMailNumberMissingException if <code>intent</code> contains
-     *         a <code>voicemail:</code> URI, but <code>phone</code> does not
-     *         have a voicemail number set.
-     *
-     * @return the phone number (or SIP address) that would be called by the intent,
-     *         or <code>null</code> if the number cannot be found.
-     */
-    private static String getNumberFromIntent(Context context, Intent intent)
-            throws VoiceMailNumberMissingException {
-        Uri uri = intent.getData();
-        String scheme = uri.getScheme();
-
-        // The sip: scheme is simple: just treat the rest of the URI as a
-        // SIP address.
-        if (PhoneAccount.SCHEME_SIP.equals(scheme)) {
-            return uri.getSchemeSpecificPart();
-        }
-
-        // Otherwise, let PhoneNumberUtils.getNumberFromIntent() handle
-        // the other cases (i.e. tel: and voicemail: and contact: URIs.)
-
-        final String number = PhoneNumberUtils.getNumberFromIntent(intent, context);
-
-        // Check for a voicemail-dialing request.  If the voicemail number is
-        // empty, throw a VoiceMailNumberMissingException.
-        if (PhoneAccount.SCHEME_VOICEMAIL.equals(scheme) &&
-                (number == null || TextUtils.isEmpty(number)))
-            throw new VoiceMailNumberMissingException();
-
-        return number;
-    }
-
     /**
      * Returns the caller-id info corresponding to the specified Connection.
      * (This is just a simple wrapper around CallerInfo.getCallerInfo(): we
@@ -816,32 +686,6 @@
     }
 
     /**
-     * Start a CallerInfo Query based on the earliest connection in the call.
-     */
-    static CallerInfoToken startGetCallerInfo(Context context, Call call,
-            CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie) {
-        Connection conn = null;
-        int phoneType = call.getPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            conn = call.getLatestConnection();
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)
-                || (phoneType == PhoneConstants.PHONE_TYPE_IMS)
-                || (phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY)) {
-            conn = call.getEarliestConnection();
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-
-        return startGetCallerInfo(context, conn, listener, cookie);
-    }
-
-    static CallerInfoToken startGetCallerInfo(Context context, Connection c,
-            CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie) {
-        return startGetCallerInfo(context, c, listener, cookie, null);
-    }
-
-    /**
      * place a temporary callerinfo object in the hands of the caller and notify
      * caller when the actual query is done.
      */
@@ -1191,145 +1035,6 @@
         return compactName;
     }
 
-    /**
-     * Returns true if the specified Call is a "conference call", meaning
-     * that it owns more than one Connection object.  This information is
-     * used to trigger certain UI changes that appear when a conference
-     * call is active (like displaying the label "Conference call", and
-     * enabling the "Manage conference" UI.)
-     *
-     * Watch out: This method simply checks the number of Connections,
-     * *not* their states.  So if a Call has (for example) one ACTIVE
-     * connection and one DISCONNECTED connection, this method will return
-     * true (which is unintuitive, since the Call isn't *really* a
-     * conference call any more.)
-     *
-     * @return true if the specified call has more than one connection (in any state.)
-     */
-    static boolean isConferenceCall(Call call) {
-        // CDMA phones don't have the same concept of "conference call" as
-        // GSM phones do; there's no special "conference call" state of
-        // the UI or a "manage conference" function.  (Instead, when
-        // you're in a 3-way call, all we can do is display the "generic"
-        // state of the UI.)  So as far as the in-call UI is concerned,
-        // Conference corresponds to generic display.
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        int phoneType = call.getPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            CdmaPhoneCallState.PhoneCallState state = app.cdmaPhoneCallState.getCurrentCallState();
-            if ((state == CdmaPhoneCallState.PhoneCallState.CONF_CALL)
-                    || ((state == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                    && !app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing())) {
-                return true;
-            }
-        } else {
-            List<Connection> connections = call.getConnections();
-            if (connections != null && connections.size() > 1) {
-                return true;
-            }
-        }
-        return false;
-
-        // TODO: We may still want to change the semantics of this method
-        // to say that a given call is only really a conference call if
-        // the number of ACTIVE connections, not the total number of
-        // connections, is greater than one.  (See warning comment in the
-        // javadoc above.)
-        // Here's an implementation of that:
-        //        if (connections == null) {
-        //            return false;
-        //        }
-        //        int numActiveConnections = 0;
-        //        for (Connection conn : connections) {
-        //            if (DBG) log("  - CONN: " + conn + ", state = " + conn.getState());
-        //            if (conn.getState() == Call.State.ACTIVE) numActiveConnections++;
-        //            if (numActiveConnections > 1) {
-        //                return true;
-        //            }
-        //        }
-        //        return false;
-    }
-
-    /**
-     * Launch the Dialer to start a new call.
-     * This is just a wrapper around the ACTION_DIAL intent.
-     */
-    /* package */ static boolean startNewCall(final CallManager cm) {
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-
-        // Sanity-check that this is OK given the current state of the phone.
-        if (!okToAddCall(cm)) {
-            Log.w(LOG_TAG, "startNewCall: can't add a new call in the current state");
-            dumpCallManager();
-            return false;
-        }
-
-        Intent intent = new Intent(Intent.ACTION_DIAL);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // when we request the dialer come up, we also want to inform
-        // it that we're going through the "add call" option from the
-        // InCallScreen / PhoneUtils.
-        intent.putExtra(ADD_CALL_MODE_KEY, true);
-        try {
-            app.startActivity(intent);
-        } catch (ActivityNotFoundException e) {
-            // This is rather rare but possible.
-            // Note: this method is used even when the phone is encrypted. At that moment
-            // the system may not find any Activity which can accept this Intent.
-            Log.e(LOG_TAG, "Activity for adding calls isn't found.");
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Turns on/off speaker.
-     *
-     * @param context Context
-     * @param flag True when speaker should be on. False otherwise.
-     * @param store True when the settings should be stored in the device.
-     */
-    /* package */ static void turnOnSpeaker(Context context, boolean flag, boolean store) {
-        if (DBG) log("turnOnSpeaker(flag=" + flag + ", store=" + store + ")...");
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-
-        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        audioManager.setSpeakerphoneOn(flag);
-
-        // record the speaker-enable value
-        if (store) {
-            sIsSpeakerEnabled = flag;
-        }
-
-        // We also need to make a fresh call to PhoneApp.updateWakeState()
-        // any time the speaker state changes, since the screen timeout is
-        // sometimes different depending on whether or not the speaker is
-        // in use.
-        app.updateWakeState();
-
-        app.mCM.setEchoSuppressionEnabled();
-    }
-
-    /**
-     * Restore the speaker mode, called after a wired headset disconnect
-     * event.
-     */
-    static void restoreSpeakerMode(Context context) {
-        if (DBG) log("restoreSpeakerMode, restoring to: " + sIsSpeakerEnabled);
-
-        // change the mode if needed.
-        if (isSpeakerOn(context) != sIsSpeakerEnabled) {
-            turnOnSpeaker(context, sIsSpeakerEnabled, false);
-        }
-    }
-
-    static boolean isSpeakerOn(Context context) {
-        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        return audioManager.isSpeakerphoneOn();
-    }
-
     static boolean isInEmergencyCall(CallManager cm) {
         Call fgCall = cm.getActiveFgCall();
         // isIdle includes checks for the DISCONNECTING/DISCONNECTED state.
@@ -1344,200 +1049,11 @@
         return false;
     }
 
-    /**
-     * Get the mute state of foreground phone, which has the current
-     * foreground call
-     */
-    static boolean getMute() {
-        return false;
-    }
-
-    /* package */ static void setAudioMode() {
-    }
-
-    /**
-     * Sets the audio mode per current phone state.
-     */
-    /* package */ static void setAudioMode(CallManager cm) {
-    }
-
-    /**
-     * Look for ANY connections on the phone that qualify as being
-     * disconnected.
-     *
-     * @return true if we find a connection that is disconnected over
-     * all the phone's call objects.
-     */
-    /* package */ static boolean hasDisconnectedConnections(Phone phone) {
-        return hasDisconnectedConnections(phone.getForegroundCall()) ||
-                hasDisconnectedConnections(phone.getBackgroundCall()) ||
-                hasDisconnectedConnections(phone.getRingingCall());
-    }
-
-    /**
-     * Iterate over all connections in a call to see if there are any
-     * that are not alive (disconnected or idle).
-     *
-     * @return true if we find a connection that is disconnected, and
-     * pending removal via
-     * {@link com.android.internal.telephony.Call#clearDisconnected()}.
-     */
-    private static final boolean hasDisconnectedConnections(Call call) {
-        // look through all connections for non-active ones.
-        for (Connection c : call.getConnections()) {
-            if (!c.isAlive()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     //
     // Misc UI policy helper functions
     //
 
     /**
-     * @return true if we're allowed to hold calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToHoldCall(CallManager cm) {
-        final Call fgCall = cm.getActiveFgCall();
-        final boolean hasHoldingCall = cm.hasActiveBgCall();
-        final Call.State fgCallState = fgCall.getState();
-
-        // The "Hold" control is disabled entirely if there's
-        // no way to either hold or unhold in the current state.
-        final boolean okToHold = (fgCallState == Call.State.ACTIVE) && !hasHoldingCall;
-        final boolean okToUnhold = cm.hasActiveBgCall() && (fgCallState == Call.State.IDLE);
-        final boolean canHold = okToHold || okToUnhold;
-
-        return canHold;
-    }
-
-    /**
-     * @return true if we support holding calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToSupportHold(CallManager cm) {
-        boolean supportsHold = false;
-
-        final Call fgCall = cm.getActiveFgCall();
-        final boolean hasHoldingCall = cm.hasActiveBgCall();
-        final Call.State fgCallState = fgCall.getState();
-
-        if (TelephonyCapabilities.supportsHoldAndUnhold(fgCall.getPhone())) {
-            // This phone has the concept of explicit "Hold" and "Unhold" actions.
-            supportsHold = true;
-        } else if (hasHoldingCall && (fgCallState == Call.State.IDLE)) {
-            // Even when foreground phone device doesn't support hold/unhold, phone devices
-            // for background holding calls may do.
-            final Call bgCall = cm.getFirstActiveBgCall();
-            if (bgCall != null &&
-                    TelephonyCapabilities.supportsHoldAndUnhold(bgCall.getPhone())) {
-                supportsHold = true;
-            }
-        }
-        return supportsHold;
-    }
-
-    /**
-     * @return true if we're allowed to swap calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToSwapCalls(CallManager cm) {
-        int phoneType = cm.getDefaultPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            // CDMA: "Swap" is enabled only when the phone reaches a *generic*.
-            // state by either accepting a Call Waiting or by merging two calls
-            PhoneGlobals app = PhoneGlobals.getInstance();
-            return (app.cdmaPhoneCallState.getCurrentCallState()
-                    == CdmaPhoneCallState.PhoneCallState.CONF_CALL);
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)
-                || (phoneType == PhoneConstants.PHONE_TYPE_IMS)
-                || (phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY)) {
-            // GSM: "Swap" is available if both lines are in use and there's no
-            // incoming call.  (Actually we need to verify that the active
-            // call really is in the ACTIVE state and the holding call really
-            // is in the HOLDING state, since you *can't* actually swap calls
-            // when the foreground call is DIALING or ALERTING.)
-            return !cm.hasActiveRingingCall()
-                    && (cm.getActiveFgCall().getState() == Call.State.ACTIVE)
-                    && (cm.getFirstActiveBgCall().getState() == Call.State.HOLDING);
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-    }
-
-    /**
-     * @return true if we're allowed to merge calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToMergeCalls(CallManager cm) {
-        int phoneType = cm.getFgPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            // CDMA: "Merge" is enabled only when the user is in a 3Way call.
-            PhoneGlobals app = PhoneGlobals.getInstance();
-            return ((app.cdmaPhoneCallState.getCurrentCallState()
-                    == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                    && !app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing());
-        } else {
-            // GSM: "Merge" is available if both lines are in use and there's no
-            // incoming call, *and* the current conference isn't already
-            // "full".
-            // TODO: shall move all okToMerge logic to CallManager
-            return !cm.hasActiveRingingCall() && cm.hasActiveFgCall()
-                    && cm.hasActiveBgCall()
-                    && cm.canConference(cm.getFirstActiveBgCall());
-        }
-    }
-
-    /**
-     * @return true if the UI should let you add a new call, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToAddCall(CallManager cm) {
-        Phone phone = cm.getActiveFgCall().getPhone();
-
-        // "Add call" is never allowed in emergency callback mode (ECM).
-        if (isPhoneInEcm(phone)) {
-            return false;
-        }
-
-        int phoneType = phone.getPhoneType();
-        final Call.State fgCallState = cm.getActiveFgCall().getState();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-           // CDMA: "Add call" button is only enabled when:
-           // - ForegroundCall is in ACTIVE state
-           // - After 30 seconds of user Ignoring/Missing a Call Waiting call.
-            PhoneGlobals app = PhoneGlobals.getInstance();
-            return ((fgCallState == Call.State.ACTIVE)
-                    && (app.cdmaPhoneCallState.getAddCallMenuStateAfterCallWaiting()));
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)
-                || (phoneType == PhoneConstants.PHONE_TYPE_IMS)
-                || (phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY)) {
-            // GSM: "Add call" is available only if ALL of the following are true:
-            // - There's no incoming ringing call
-            // - There's < 2 lines in use
-            // - The foreground call is ACTIVE or IDLE or DISCONNECTED.
-            //   (We mainly need to make sure it *isn't* DIALING or ALERTING.)
-            final boolean hasRingingCall = cm.hasActiveRingingCall();
-            final boolean hasActiveCall = cm.hasActiveFgCall();
-            final boolean hasHoldingCall = cm.hasActiveBgCall();
-            final boolean allLinesTaken = hasActiveCall && hasHoldingCall;
-
-            return !hasRingingCall
-                    && !allLinesTaken
-                    && ((fgCallState == Call.State.ACTIVE)
-                        || (fgCallState == Call.State.IDLE)
-                        || (fgCallState == Call.State.DISCONNECTED));
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-    }
-
-    /**
      * Based on the input CNAP number string,
      * @return _RESTRICTED or _UNKNOWN for all the special CNAP strings.
      * Otherwise, return CNAP_SPECIAL_CASE_NO.
@@ -1660,47 +1176,6 @@
     }
 
     /**
-     * Returns the most appropriate Phone object to handle a call
-     * to the specified number.
-     *
-     * @param cm the CallManager.
-     * @param scheme the scheme from the data URI that the number originally came from.
-     * @param number the phone number, or SIP address.
-     */
-    public static Phone pickPhoneBasedOnNumber(CallManager cm, String scheme, String number,
-            String primarySipUri, ComponentName thirdPartyCallComponent) {
-        if (DBG) {
-            log("pickPhoneBasedOnNumber: scheme " + scheme
-                    + ", number " + toLogSafePhoneNumber(number)
-                    + ", sipUri "
-                    + (primarySipUri != null ? Uri.parse(primarySipUri).toSafeString() : "null")
-                    + ", thirdPartyCallComponent: " + thirdPartyCallComponent);
-        }
-
-        if (primarySipUri != null) {
-            Phone phone = getSipPhoneFromUri(cm, primarySipUri);
-            if (phone != null) return phone;
-        }
-
-        return cm.getDefaultPhone();
-    }
-
-    public static Phone getSipPhoneFromUri(CallManager cm, String target) {
-        for (Phone phone : cm.getAllPhones()) {
-            if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
-                String sipUri = ((SipPhone) phone).getSipUri();
-                if (target.equals(sipUri)) {
-                    if (DBG) log("- pickPhoneBasedOnNumber:" +
-                            "found SipPhone! obj = " + phone + ", "
-                            + phone.getClass());
-                    return phone;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
      * Returns true when the given call is in INCOMING state and there's no foreground phone call,
      * meaning the call is the first real incoming call the phone is having.
      */
@@ -1708,166 +1183,14 @@
         return (state == Call.State.INCOMING && !PhoneGlobals.getInstance().mCM.hasActiveFgCall());
     }
 
-    public static String getPresentationString(Context context, int presentation) {
-        String name = context.getString(R.string.unknown);
-        if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
-            name = context.getString(R.string.private_num);
-        } else if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
-            name = context.getString(R.string.payphone);
-        }
-        return name;
-    }
-
-    public static void sendViewNotificationAsync(Context context, Uri contactUri) {
-        if (DBG) Log.d(LOG_TAG, "Send view notification to Contacts (uri: " + contactUri + ")");
-        Intent intent = new Intent("com.android.contacts.VIEW_NOTIFICATION", contactUri);
-        intent.setClassName("com.android.contacts",
-                "com.android.contacts.ViewNotificationService");
-        context.startService(intent);
-    }
-
     //
     // General phone and call state debugging/testing code
     //
 
-    /* package */ static void dumpCallState(Phone phone) {
-        PhoneGlobals app = PhoneGlobals.getInstance();
-        Log.d(LOG_TAG, "dumpCallState():");
-        Log.d(LOG_TAG, "- Phone: " + phone + ", name = " + phone.getPhoneName()
-              + ", state = " + phone.getState());
-
-        StringBuilder b = new StringBuilder(128);
-
-        Call call = phone.getForegroundCall();
-        b.setLength(0);
-        b.append("  - FG call: ").append(call.getState());
-        b.append(" isAlive ").append(call.getState().isAlive());
-        b.append(" isRinging ").append(call.getState().isRinging());
-        b.append(" isDialing ").append(call.getState().isDialing());
-        b.append(" isIdle ").append(call.isIdle());
-        b.append(" hasConnections ").append(call.hasConnections());
-        Log.d(LOG_TAG, b.toString());
-
-        call = phone.getBackgroundCall();
-        b.setLength(0);
-        b.append("  - BG call: ").append(call.getState());
-        b.append(" isAlive ").append(call.getState().isAlive());
-        b.append(" isRinging ").append(call.getState().isRinging());
-        b.append(" isDialing ").append(call.getState().isDialing());
-        b.append(" isIdle ").append(call.isIdle());
-        b.append(" hasConnections ").append(call.hasConnections());
-        Log.d(LOG_TAG, b.toString());
-
-        call = phone.getRingingCall();
-        b.setLength(0);
-        b.append("  - RINGING call: ").append(call.getState());
-        b.append(" isAlive ").append(call.getState().isAlive());
-        b.append(" isRinging ").append(call.getState().isRinging());
-        b.append(" isDialing ").append(call.getState().isDialing());
-        b.append(" isIdle ").append(call.isIdle());
-        b.append(" hasConnections ").append(call.hasConnections());
-        Log.d(LOG_TAG, b.toString());
-
-
-        final boolean hasRingingCall = !phone.getRingingCall().isIdle();
-        final boolean hasActiveCall = !phone.getForegroundCall().isIdle();
-        final boolean hasHoldingCall = !phone.getBackgroundCall().isIdle();
-        final boolean allLinesTaken = hasActiveCall && hasHoldingCall;
-        b.setLength(0);
-        b.append("  - hasRingingCall ").append(hasRingingCall);
-        b.append(" hasActiveCall ").append(hasActiveCall);
-        b.append(" hasHoldingCall ").append(hasHoldingCall);
-        b.append(" allLinesTaken ").append(allLinesTaken);
-        Log.d(LOG_TAG, b.toString());
-
-        // On CDMA phones, dump out the CdmaPhoneCallState too:
-        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            if (app.cdmaPhoneCallState != null) {
-                Log.d(LOG_TAG, "  - CDMA call state: "
-                      + app.cdmaPhoneCallState.getCurrentCallState());
-            } else {
-                Log.d(LOG_TAG, "  - CDMA device, but null cdmaPhoneCallState!");
-            }
-        }
-    }
-
     private static void log(String msg) {
         Log.d(LOG_TAG, msg);
     }
 
-    static void dumpCallManager() {
-        Call call;
-        CallManager cm = PhoneGlobals.getInstance().mCM;
-        StringBuilder b = new StringBuilder(128);
-
-
-
-        Log.d(LOG_TAG, "############### dumpCallManager() ##############");
-        // TODO: Don't log "cm" itself, since CallManager.toString()
-        // already spews out almost all this same information.
-        // We should fix CallManager.toString() to be more minimal, and
-        // use an explicit dumpState() method for the verbose dump.
-        // Log.d(LOG_TAG, "CallManager: " + cm
-        //         + ", state = " + cm.getState());
-        Log.d(LOG_TAG, "CallManager: state = " + cm.getState());
-        b.setLength(0);
-        call = cm.getActiveFgCall();
-        b.append(" - FG call: ").append(cm.hasActiveFgCall()? "YES ": "NO ");
-        b.append(call);
-        b.append( "  State: ").append(cm.getActiveFgCallState());
-        b.append( "  Conn: ").append(cm.getFgCallConnections());
-        Log.d(LOG_TAG, b.toString());
-        b.setLength(0);
-        call = cm.getFirstActiveBgCall();
-        b.append(" - BG call: ").append(cm.hasActiveBgCall()? "YES ": "NO ");
-        b.append(call);
-        b.append( "  State: ").append(cm.getFirstActiveBgCall().getState());
-        b.append( "  Conn: ").append(cm.getBgCallConnections());
-        Log.d(LOG_TAG, b.toString());
-        b.setLength(0);
-        call = cm.getFirstActiveRingingCall();
-        b.append(" - RINGING call: ").append(cm.hasActiveRingingCall()? "YES ": "NO ");
-        b.append(call);
-        b.append( "  State: ").append(cm.getFirstActiveRingingCall().getState());
-        Log.d(LOG_TAG, b.toString());
-
-
-
-        for (Phone phone : CallManager.getInstance().getAllPhones()) {
-            if (phone != null) {
-                Log.d(LOG_TAG, "Phone: " + phone + ", name = " + phone.getPhoneName()
-                        + ", state = " + phone.getState());
-                b.setLength(0);
-                call = phone.getForegroundCall();
-                b.append(" - FG call: ").append(call);
-                b.append( "  State: ").append(call.getState());
-                b.append( "  Conn: ").append(call.hasConnections());
-                Log.d(LOG_TAG, b.toString());
-                b.setLength(0);
-                call = phone.getBackgroundCall();
-                b.append(" - BG call: ").append(call);
-                b.append( "  State: ").append(call.getState());
-                b.append( "  Conn: ").append(call.hasConnections());
-                Log.d(LOG_TAG, b.toString());b.setLength(0);
-                call = phone.getRingingCall();
-                b.append(" - RINGING call: ").append(call);
-                b.append( "  State: ").append(call.getState());
-                b.append( "  Conn: ").append(call.hasConnections());
-                Log.d(LOG_TAG, b.toString());
-            }
-        }
-
-        Log.d(LOG_TAG, "############## END dumpCallManager() ###############");
-    }
-
-    /**
-     * @return if the context is in landscape orientation.
-     */
-    public static boolean isLandscape(Context context) {
-        return context.getResources().getConfiguration().orientation
-                == Configuration.ORIENTATION_LANDSCAPE;
-    }
-
     public static PhoneAccountHandle makePstnPhoneAccountHandle(String id) {
         return makePstnPhoneAccountHandleWithPrefix(id, "", false);
     }
@@ -1918,7 +1241,6 @@
         return null;
     }
 
-
     /**
      * Determine if a given phone account corresponds to an active SIM
      *
diff --git a/src/com/android/phone/RoamingDialogFragment.java b/src/com/android/phone/RoamingDialogFragment.java
index d24967b..384a120 100644
--- a/src/com/android/phone/RoamingDialogFragment.java
+++ b/src/com/android/phone/RoamingDialogFragment.java
@@ -35,6 +35,7 @@
 
     public static final String SUB_ID_KEY = "sub_id_key";
 
+    private CarrierConfigManager mCarrierConfigManager;
     private int mSubId;
 
     /**
@@ -52,6 +53,7 @@
         super.onAttach(context);
         Bundle args = getArguments();
         mSubId = args.getInt(SUB_ID_KEY);
+        mCarrierConfigManager = new CarrierConfigManager(context);
 
         // Verify host activity implemented callback interface
         FragmentManager fragmentManager = getFragmentManager();
@@ -68,8 +70,7 @@
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
         int title = R.string.roaming_alert_title;
-        PersistableBundle carrierConfig =
-                PhoneGlobals.getInstance().getCarrierConfigForSubId(mSubId);
+        PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
         if (carrierConfig != null && carrierConfig.getBoolean(
                 CarrierConfigManager.KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL)) {
             title = R.string.roaming_check_price_warning;
diff --git a/src/com/android/phone/settings/VoicemailProviderSettingsUtil.java b/src/com/android/phone/settings/VoicemailProviderSettingsUtil.java
index 8187664..3ccd4a3 100644
--- a/src/com/android/phone/settings/VoicemailProviderSettingsUtil.java
+++ b/src/com/android/phone/settings/VoicemailProviderSettingsUtil.java
@@ -137,7 +137,7 @@
         prefs.edit()
                 .putString(key + VM_NUMBER_TAG, null)
                 .putInt(key + FWD_SETTINGS_TAG + FWD_SETTINGS_LENGTH_TAG, 0)
-                .commit();
+                .apply();
     }
 
     private static SharedPreferences getPrefs(Context context) {
diff --git a/src/com/android/services/telephony/CdmaConferenceController.java b/src/com/android/services/telephony/CdmaConferenceController.java
index 24c3870..5d987f7 100644
--- a/src/com/android/services/telephony/CdmaConferenceController.java
+++ b/src/com/android/services/telephony/CdmaConferenceController.java
@@ -211,6 +211,7 @@
             // 4) Add the conference to the connection service if it is new.
             if (isNewlyCreated) {
                 Log.d(this, "Adding the conference call");
+                mConference.updateCallRadioTechAfterCreation();
                 mConnectionService.addConference(mConference);
             }
         } else if (conferenceConnections.isEmpty()) {
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index b196d57..5722834 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -640,6 +640,7 @@
 
         setState(mConferenceHost.getState());
         updateStatusHints();
+        putExtras(mConferenceHost.getExtras());
     }
 
     /**
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 642af85..6b7a002 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -64,7 +64,7 @@
  * Owns all data we have registered with Telecom including handling dynamic addition and
  * removal of SIMs and SIP accounts.
  */
-final class TelecomAccountRegistry {
+public final class TelecomAccountRegistry {
     private static final boolean DBG = false; /* STOP SHIP if true */
 
     // This icon is the one that is used when the Slot ID that we have for a particular SIM
@@ -659,7 +659,10 @@
         mSubscriptionManager = SubscriptionManager.from(context);
     }
 
-    static synchronized final TelecomAccountRegistry getInstance(Context context) {
+    /**
+     * Get the singleton instance.
+     */
+    public static synchronized TelecomAccountRegistry getInstance(Context context) {
         if (sInstance == null && context != null) {
             sInstance = new TelecomAccountRegistry(context);
         }
@@ -828,7 +831,7 @@
     /**
      * Sets up all the phone accounts for SIMs on first boot.
      */
-    void setupOnBoot() {
+    public void setupOnBoot() {
         // TODO: When this object "finishes" we should unregister by invoking
         // SubscriptionManager.getInstance(mContext).unregister(mOnSubscriptionsChangedListener);
         // This is not strictly necessary because it will be unregistered if the
diff --git a/src/com/android/services/telephony/TelephonyConferenceController.java b/src/com/android/services/telephony/TelephonyConferenceController.java
index e96815c..e9eef46 100644
--- a/src/com/android/services/telephony/TelephonyConferenceController.java
+++ b/src/com/android/services/telephony/TelephonyConferenceController.java
@@ -264,6 +264,7 @@
                                 mTelephonyConference, connection);
                         mTelephonyConference.addConnection(connection);
                     }
+                    mTelephonyConference.updateCallRadioTechAfterCreation();
                     mConnectionService.addConference(mTelephonyConference);
                 } else {
                     Log.d(this, "Trigger recalculate later");
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 31fe68f..3192c75 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -36,6 +36,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsCallProfile;
 import android.text.TextUtils;
@@ -96,6 +97,7 @@
     private static final int MSG_CDMA_VOICE_PRIVACY_ON = 15;
     private static final int MSG_CDMA_VOICE_PRIVACY_OFF = 16;
     private static final int MSG_HANGUP = 17;
+    private static final int MSG_SET_CALL_RADIO_TECH = 18;
 
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
@@ -240,6 +242,31 @@
                     int cause = (int) msg.obj;
                     hangup(cause);
                     break;
+
+                case MSG_SET_CALL_RADIO_TECH:
+                    int vrat = (int) msg.obj;
+                    // Check whether Wi-Fi call tech is changed, it means call radio tech is:
+                    //  a) changed from IWLAN to other value, or
+                    //  b) changed from other value to IWLAN.
+                    //
+                    // In other word, below conditions are all met:
+                    // 1) {@link #getCallRadioTech} is different from new vrat
+                    // 2) Current call radio technology indicates Wi-Fi call, i.e. {@link #isWifi}
+                    //    is true, or new vrat indicates Wi-Fi call.
+                    boolean isWifiTechChange = getCallRadioTech() != vrat
+                            && (isWifi() || vrat == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN);
+
+                    // Step 1) Updates call radio tech firstly, so that afterwards Wi-Fi related
+                    // update actions are taken correctly.
+                    setCallRadioTech(vrat);
+
+                    // Step 2) Handles Wi-Fi call tech change.
+                    if (isWifiTechChange) {
+                        updateConnectionProperties();
+                        updateStatusHints();
+                        refreshDisableAddCall();
+                    }
+                    break;
             }
         }
     };
@@ -421,14 +448,14 @@
         }
 
         /**
-         * Used by {@link com.android.internal.telephony.Connection} to report a change in whether
-         * the call is being made over a wifi network.
+         * Used by {@link com.android.internal.telephony.Connection} to report a change for
+         * the call radio technology.
          *
-         * @param isWifi True if call is made over wifi.
+         * @param vrat the RIL Voice Radio Technology used for current connection.
          */
         @Override
-        public void onWifiChanged(boolean isWifi) {
-            setWifi(isWifi);
+        public void onCallRadioTechChanged(@ServiceState.RilRadioTechnology int vrat) {
+            mHandler.obtainMessage(MSG_SET_CALL_RADIO_TECH, vrat).sendToTarget();
         }
 
         /**
@@ -575,6 +602,11 @@
                 com.android.internal.telephony.Connection newConnection) {
             setOriginalConnection(newConnection);
         }
+
+        @Override
+        public void onIsNetworkEmergencyCallChanged(boolean isEmergencyCall) {
+            setIsNetworkIdentifiedEmergencyCall(isEmergencyCall);
+        }
     };
 
     protected com.android.internal.telephony.Connection mOriginalConnection;
@@ -599,13 +631,6 @@
     private int mOriginalConnectionCapabilities;
 
     /**
-     * Determines if the {@link TelephonyConnection} is using wifi.
-     * This is used when {@link TelephonyConnection#updateConnectionProperties()} is called to
-     * indicate whether a call has the {@link Connection#PROPERTY_WIFI} property.
-     */
-    private boolean mIsWifi;
-
-    /**
      * Determines the audio quality is high for the {@link TelephonyConnection}.
      * This is used when {@link TelephonyConnection#updateConnectionProperties}} is called to
      * indicate whether a call has the {@link Connection#PROPERTY_HIGH_DEF_AUDIO} property.
@@ -620,6 +645,15 @@
     private boolean mTreatAsEmergencyCall;
 
     /**
+     * Indicates whether the network has identified this call as an emergency call.  Where
+     * {@link #mTreatAsEmergencyCall} is based on comparing dialed numbers to a list of known
+     * emergency numbers, this property is based on whether the network itself has identified the
+     * call as an emergency call (which can be the case for an incoming call from emergency
+     * services).
+     */
+    private boolean mIsNetworkIdentifiedEmergencyCall;
+
+    /**
      * For video calls, indicates whether the outgoing video for the call can be paused using
      * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState.
      */
@@ -661,6 +695,11 @@
     private boolean mIsHoldable;
 
     /**
+     * Indicates whether TTY is enabled; used to determine whether a call is VT capable.
+     */
+    private boolean mIsTtyEnabled;
+
+    /**
      * Indicates whether this call is using assisted dialing.
      */
     private boolean mIsUsingAssistedDialing;
@@ -1030,7 +1069,7 @@
 
         newProperties = changeBitmask(newProperties, PROPERTY_HIGH_DEF_AUDIO,
                 hasHighDefAudioProperty());
-        newProperties = changeBitmask(newProperties, PROPERTY_WIFI, mIsWifi);
+        newProperties = changeBitmask(newProperties, PROPERTY_WIFI, isWifi());
         newProperties = changeBitmask(newProperties, PROPERTY_IS_EXTERNAL_CALL,
                 isExternalConnection());
         newProperties = changeBitmask(newProperties, PROPERTY_HAS_CDMA_VOICE_PRIVACY,
@@ -1038,6 +1077,8 @@
         newProperties = changeBitmask(newProperties, PROPERTY_ASSISTED_DIALING_USED,
                 mIsUsingAssistedDialing);
         newProperties = changeBitmask(newProperties, PROPERTY_IS_RTT, isRtt());
+        newProperties = changeBitmask(newProperties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL,
+                isNetworkIdentifiedEmergencyCall());
 
         if (getConnectionProperties() != newProperties) {
             setConnectionProperties(newProperties);
@@ -1117,12 +1158,14 @@
         // Set video state and capabilities
         setVideoState(mOriginalConnection.getVideoState());
         setOriginalConnectionCapabilities(mOriginalConnection.getConnectionCapabilities());
-        setWifi(mOriginalConnection.isWifi());
+        setIsNetworkIdentifiedEmergencyCall(mOriginalConnection.isNetworkIdentifiedEmergencyCall());
         setAudioModeIsVoip(mOriginalConnection.getAudioModeIsVoip());
         setVideoProvider(mOriginalConnection.getVideoProvider());
         setAudioQuality(mOriginalConnection.getAudioQuality());
         setTechnologyTypeExtra();
 
+        setCallRadioTech(mOriginalConnection.getCallRadioTech());
+
         // Post update of extras to the handler; extras are updated via the handler to ensure thread
         // safety. The Extras Bundle is cloned in case the original extras are modified while they
         // are being added to mOriginalConnectionExtras in updateExtras.
@@ -1239,7 +1282,7 @@
 
         if (isCurrentVideoCall) {
             return true;
-        } else if (wasVideoCall && mIsWifi && !isVowifiEnabled) {
+        } else if (wasVideoCall && isWifi() && !isVowifiEnabled) {
             return true;
         }
         return false;
@@ -1274,7 +1317,7 @@
             return false;
         }
 
-        if (mIsWifi && !canWifiCallsBeHdAudio) {
+        if (isWifi() && !canWifiCallsBeHdAudio) {
             return false;
         }
 
@@ -1824,28 +1867,40 @@
         capabilities = changeBitmask(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL,
                 can(mOriginalConnectionCapabilities, Capability.SUPPORTS_VT_REMOTE_BIDIRECTIONAL));
 
+        boolean isLocalVideoSupported = can(mOriginalConnectionCapabilities,
+                Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL) && !mIsTtyEnabled;
         capabilities = changeBitmask(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL,
-                can(mOriginalConnectionCapabilities, Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL));
+                isLocalVideoSupported);
 
         return capabilities;
     }
 
     /**
-     * Sets whether the call is using wifi. Used when rebuilding the capabilities to set or unset
-     * the {@link Connection#PROPERTY_WIFI} property.
-     */
-    public void setWifi(boolean isWifi) {
-        mIsWifi = isWifi;
-        updateConnectionProperties();
-        updateStatusHints();
-        refreshDisableAddCall();
-    }
-
-    /**
      * Whether the call is using wifi.
      */
     boolean isWifi() {
-        return mIsWifi;
+        return getCallRadioTech() == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
+    }
+
+    /**
+     * Sets whether this call has been identified by the network as an emergency call.
+     * @param isNetworkIdentifiedEmergencyCall {@code true} if the network has identified this call
+     * as an emergency call, {@code false} otherwise.
+     */
+    public void setIsNetworkIdentifiedEmergencyCall(boolean isNetworkIdentifiedEmergencyCall) {
+        Log.d(this, "setIsNetworkIdentifiedEmergencyCall; callId=%s, "
+                + "isNetworkIdentifiedEmergencyCall=%b", getTelecomCallId(),
+                isNetworkIdentifiedEmergencyCall);
+        mIsNetworkIdentifiedEmergencyCall = isNetworkIdentifiedEmergencyCall;
+        updateConnectionProperties();
+    }
+
+    /**
+     * @return {@code true} if the network has identified this call as an emergency call,
+     * {@code false} otherwise.
+     */
+    public boolean isNetworkIdentifiedEmergencyCall() {
+        return mIsNetworkIdentifiedEmergencyCall;
     }
 
     /**
@@ -1953,6 +2008,15 @@
     }
 
     /**
+     * Sets whether TTY is enabled or not.
+     * @param isTtyEnabled
+     */
+    public void setTtyEnabled(boolean isTtyEnabled) {
+        mIsTtyEnabled = isTtyEnabled;
+        updateConnectionCapabilities();
+    }
+
+    /**
      * Whether the original connection is an IMS connection.
      * @return {@code True} if the original connection is an IMS connection, {@code false}
      *     otherwise.
@@ -2025,7 +2089,7 @@
     }
 
     private void updateStatusHints() {
-        if (mIsWifi && getPhone() != null) {
+        if (isWifi() && getPhone() != null) {
             int labelId = isValidRingingCall()
                     ? R.string.status_hint_label_incoming_wifi_call
                     : R.string.status_hint_label_wifi_call;
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 195194c..3ec00b9 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -17,9 +17,11 @@
 package com.android.services.telephony;
 
 import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.Settings;
@@ -119,6 +121,23 @@
         }
     };
 
+    private final BroadcastReceiver mTtyBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            Log.v(this, "onReceive, action: %s", action);
+            if (action.equals(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED)) {
+                int newPreferredTtyMode = intent.getIntExtra(
+                        TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
+
+                boolean isTtyNowEnabled = newPreferredTtyMode != TelecomManager.TTY_MODE_OFF;
+                if (isTtyNowEnabled != mIsTtyEnabled) {
+                    handleTtyModeChange(isTtyNowEnabled);
+                }
+            }
+        }
+    };
+
     private final TelephonyConferenceController mTelephonyConferenceController =
             new TelephonyConferenceController(mTelephonyConnectionServiceProxy);
     private final CdmaConferenceController mCdmaConferenceController =
@@ -131,6 +150,7 @@
     private RadioOnHelper mRadioOnHelper;
     private EmergencyTonePlayer mEmergencyTonePlayer;
     private HoldTracker mHoldTracker;
+    private boolean mIsTtyEnabled;
 
     // Contains one TelephonyConnection that has placed a call and a memory of which Phones it has
     // already tried to connect with. There should be only one TelephonyConnection trying to place a
@@ -263,6 +283,17 @@
         mEmergencyTonePlayer = new EmergencyTonePlayer(this);
         TelecomAccountRegistry.getInstance(this).setTelephonyConnectionService(this);
         mHoldTracker = new HoldTracker();
+        mIsTtyEnabled = isTtyModeEnabled(getApplicationContext());
+
+        IntentFilter intentFilter = new IntentFilter(
+                TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
+        registerReceiver(mTtyBroadcastReceiver, intentFilter);
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        unregisterReceiver(mTtyBroadcastReceiver);
+        return super.onUnbind(intent);
     }
 
     @Override
@@ -633,8 +664,9 @@
         }
 
         final Context context = getApplicationContext();
-        if (VideoProfile.isVideo(request.getVideoState()) && isTtyModeEnabled(context) &&
-                !isEmergencyNumber) {
+        final boolean isTtyModeEnabled = isTtyModeEnabled(context);
+        if (VideoProfile.isVideo(request.getVideoState()) && isTtyModeEnabled
+                && !isEmergencyNumber) {
             return Connection.createFailedConnection(DisconnectCauseUtil.toTelecomDisconnectCause(
                     android.telephony.DisconnectCause.VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED,
                     null, phone.getPhoneId()));
@@ -670,7 +702,7 @@
         connection.setInitializing();
         connection.setVideoState(request.getVideoState());
         connection.setRttTextStream(request.getRttTextStream());
-
+        connection.setTtyEnabled(isTtyModeEnabled);
         return connection;
     }
 
@@ -1005,7 +1037,9 @@
         }
 
         Queue<Phone> cachedPhones = mEmergencyRetryCache.second;
-        Phone phoneUsed = c.getPhone();
+        // Need to refer default phone considering ImsPhone because
+        // cachedPhones is a list that contains default phones.
+        Phone phoneUsed = c.getPhone().getDefaultPhone();
         if (phoneUsed == null) {
             return;
         }
@@ -1453,4 +1487,15 @@
             }
         }
     }
+
+    private void handleTtyModeChange(boolean isTtyEnabled) {
+        Log.i(this, "handleTtyModeChange; isTtyEnabled=%b", isTtyEnabled);
+        mIsTtyEnabled = isTtyEnabled;
+        for (Connection connection : getAllConnections()) {
+            if (connection instanceof TelephonyConnection) {
+                TelephonyConnection telephonyConnection = (TelephonyConnection) connection;
+                telephonyConnection.setTtyEnabled(isTtyEnabled);
+            }
+        }
+    }
 }
diff --git a/src/com/android/services/telephony/TelephonyGlobals.java b/src/com/android/services/telephony/TelephonyGlobals.java
deleted file mode 100644
index 02ef639..0000000
--- a/src/com/android/services/telephony/TelephonyGlobals.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2014 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.services.telephony;
-
-import android.content.Context;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Singleton entry point for the telephony-services app. Initializes ongoing systems relating to
- * PSTN calls. This is started when the device starts and will be restarted automatically
- * if it goes away for any reason (e.g., crashes).
- * This is separate from the actual Application class because we only support one instance of this
- * app - running as the default user. {@link com.android.phone.PhoneApp} determines whether or not
- * we are running as the default user and if we are, then initializes and runs this class's
- * {@link #onCreate}.
- */
-public class TelephonyGlobals {
-    private static TelephonyGlobals sInstance;
-
-    /** The application context. */
-    private final Context mContext;
-
-    // For supporting MSIM phone, change Phone and TtyManager as 1 to 1
-    private List<TtyManager> mTtyManagers = new ArrayList<>();
-
-    /**
-     * Persists the specified parameters.
-     *
-     * @param context The application context.
-     */
-    public TelephonyGlobals(Context context) {
-        mContext = context.getApplicationContext();
-    }
-
-    public static synchronized TelephonyGlobals getInstance(Context context) {
-        if (sInstance == null) {
-            sInstance = new TelephonyGlobals(context);
-        }
-        return sInstance;
-    }
-
-    public void onCreate() {
-        // Make this work with Multi-SIM devices
-        Phone[] phones = PhoneFactory.getPhones();
-        for (Phone phone : phones) {
-            mTtyManagers.add(new TtyManager(mContext, phone));
-        }
-
-        TelecomAccountRegistry.getInstance(mContext).setupOnBoot();
-    }
-}
diff --git a/src/com/android/services/telephony/TtyManager.java b/src/com/android/services/telephony/TtyManager.java
deleted file mode 100644
index 3389ce8..0000000
--- a/src/com/android/services/telephony/TtyManager.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2014 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.services.telephony;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-import android.telecom.TelecomManager;
-
-import com.android.internal.telephony.Phone;
-
-final class TtyManager {
-    private final static int MSG_SET_TTY_MODE_RESPONSE = 1;
-    private final static int MSG_GET_TTY_MODE_RESPONSE = 2;
-
-    private final TtyBroadcastReceiver mReceiver = new TtyBroadcastReceiver();
-    private final Phone mPhone;
-    private int mTtyMode;
-    private int mUiTtyMode = -1;
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_SET_TTY_MODE_RESPONSE: {
-                    Log.v(TtyManager.this, "got setTtyMode response");
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        Log.d(TtyManager.this, "setTTYMode exception: %s", ar.exception);
-                    }
-                    mPhone.queryTTYMode(obtainMessage(MSG_GET_TTY_MODE_RESPONSE));
-                    break;
-                }
-                case MSG_GET_TTY_MODE_RESPONSE: {
-                    Log.v(TtyManager.this, "got queryTTYMode response");
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        Log.d(TtyManager.this, "queryTTYMode exception: %s", ar.exception);
-                    } else {
-                        int ttyMode = phoneModeToTelecomMode(((int[]) ar.result)[0]);
-                        if (ttyMode != mTtyMode) {
-                            Log.d(TtyManager.this, "setting TTY mode failed, attempted %d, got: %d",
-                                    mTtyMode, ttyMode);
-                        } else {
-                            Log.d(TtyManager.this, "setting TTY mode to %d succeeded", ttyMode);
-                        }
-                    }
-                    break;
-                }
-            }
-        }
-    };
-
-    TtyManager(Context context, Phone phone) {
-        mPhone = phone;
-
-        IntentFilter intentFilter = new IntentFilter(
-                TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
-        intentFilter.addAction(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
-        context.registerReceiver(mReceiver, intentFilter);
-
-        int ttyMode = TelecomManager.TTY_MODE_OFF;
-        TelecomManager telecomManager = TelecomManager.from(context);
-        if (telecomManager != null) {
-            ttyMode = telecomManager.getCurrentTtyMode();
-        }
-        updateTtyMode(ttyMode);
-        //Get preferred TTY mode from data base as UI Tty mode is always user preferred Tty mode.
-        ttyMode = Settings.Secure.getInt(context.getContentResolver(),
-                Settings.Secure.PREFERRED_TTY_MODE, TelecomManager.TTY_MODE_OFF);
-        updateUiTtyMode(ttyMode);
-    }
-
-    private void updateTtyMode(int ttyMode) {
-        Log.v(this, "updateTtyMode %d -> %d", mTtyMode, ttyMode);
-        mTtyMode = ttyMode;
-        mPhone.setTTYMode(telecomModeToPhoneMode(ttyMode),
-                mHandler.obtainMessage(MSG_SET_TTY_MODE_RESPONSE));
-    }
-
-    private void updateUiTtyMode(int ttyMode) {
-        Log.i(this, "updateUiTtyMode %d -> %d", mUiTtyMode, ttyMode);
-        if(mUiTtyMode != ttyMode) {
-            mUiTtyMode = ttyMode;
-            mPhone.setUiTTYMode(telecomModeToPhoneMode(ttyMode), null);
-        } else {
-           Log.i(this, "ui tty mode didnt change");
-        }
-    }
-
-    private final class TtyBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            Log.v(TtyManager.this, "onReceive, action: %s", action);
-            if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
-                int ttyMode = intent.getIntExtra(
-                        TelecomManager.EXTRA_CURRENT_TTY_MODE, TelecomManager.TTY_MODE_OFF);
-                updateTtyMode(ttyMode);
-            } else if (action.equals(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED)) {
-                int newPreferredTtyMode = intent.getIntExtra(
-                        TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
-                updateUiTtyMode(newPreferredTtyMode);
-            }
-        }
-    }
-
-    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;
-        }
-    }
-
-    private static int phoneModeToTelecomMode(int phoneMode) {
-        switch (phoneMode) {
-            case Phone.TTY_MODE_FULL:
-                return TelecomManager.TTY_MODE_FULL;
-            case Phone.TTY_MODE_VCO:
-                return TelecomManager.TTY_MODE_VCO;
-            case Phone.TTY_MODE_HCO:
-                return TelecomManager.TTY_MODE_HCO;
-            case Phone.TTY_MODE_OFF:
-            default:
-                return TelecomManager.TTY_MODE_OFF;
-        }
-    }
-}
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 3bd2716..a18adb8 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -21,7 +21,6 @@
 import static junit.framework.Assert.fail;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
@@ -817,6 +816,7 @@
         testServiceState.setEmergencyOnly(isEmergencyOnly);
         when(phone.getServiceState()).thenReturn(testServiceState);
         when(phone.getPhoneId()).thenReturn(phoneId);
+        when(phone.getDefaultPhone()).thenReturn(phone);
         return phone;
     }
 
diff --git a/tests/src/com/android/services/telephony/TestTelephonyConnection.java b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
index 9040257..39e4579 100644
--- a/tests/src/com/android/services/telephony/TestTelephonyConnection.java
+++ b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
@@ -74,6 +74,7 @@
                 any(Connection.PostDialListener.class));
         when(mMockPhone.getRingingCall()).thenReturn(mMockCall);
         when(mMockPhone.getContext()).thenReturn(null);
+        when(mMockPhone.getDefaultPhone()).thenReturn(mMockPhone);
         when(mMockCall.getState()).thenReturn(Call.State.ACTIVE);
         when(mMockCall.getPhone()).thenReturn(mMockPhone);
     }
@@ -107,6 +108,11 @@
         mLastConnectionEventExtras.add(extras);
     }
 
+    @Override
+    void clearOriginalConnection() {
+        // Do nothing since the original connection is mock object
+    }
+
     public int getNotifyPhoneAccountChangedCount() {
         return mNotifyPhoneAccountChangedCount;
     }