Remove Call from telephony.common

This API is no longer used.

Change-Id: I979480633f4a9eb649585968e984eaad1e57973d
diff --git a/src/com/android/phone/BluetoothManager.java b/src/com/android/phone/BluetoothManager.java
index 443c950..3f0ce6f 100644
--- a/src/com/android/phone/BluetoothManager.java
+++ b/src/com/android/phone/BluetoothManager.java
@@ -16,413 +16,43 @@
 
 package com.android.phone;
 
-import com.google.android.collect.Lists;
-import com.google.common.base.Preconditions;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothProfile;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Connection;
-import com.android.services.telephony.common.Call;
-
-import java.util.List;
-
-/**
- * Listens to and caches bluetooth headset state.  Used By the AudioRouter for maintaining
- * overall audio state for use in the UI layer. Also provides method for connecting the bluetooth
- * headset to the phone call.
- */
-public class BluetoothManager implements CallModeler.Listener {
-    private static final String LOG_TAG = BluetoothManager.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 final BluetoothAdapter mBluetoothAdapter;
-    private final CallManager mCallManager;
-    private final Context mContext;
-    private final CallModeler mCallModeler;
-
-    private BluetoothHeadset mBluetoothHeadset;
-    private int mBluetoothHeadsetState = BluetoothProfile.STATE_DISCONNECTED;
-    private int mBluetoothHeadsetAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
-    private boolean mShowBluetoothIndication = false;
-    private boolean mBluetoothConnectionPending = false;
-    private long mBluetoothConnectionRequestTime;
-
-    // Broadcast receiver for various intent broadcasts (see onCreate())
-    private final BroadcastReceiver mReceiver = new BluetoothBroadcastReceiver();
-
-    private final List<BluetoothIndicatorListener> mListeners = Lists.newArrayList();
-
-    public BluetoothManager(Context context, CallManager callManager, CallModeler callModeler) {
-        mContext = context;
-        mCallManager = callManager;
-        mCallModeler = callModeler;
-        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-
-        init(mContext);
+public class BluetoothManager {
+    public BluetoothManager() {
     }
 
     /* package */ boolean isBluetoothHeadsetAudioOn() {
-        return (mBluetoothHeadsetAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
-    }
-
-    //
-    // Bluetooth helper methods.
-    //
-    // - BluetoothAdapter is the Bluetooth system service.  If
-    //   getDefaultAdapter() returns null
-    //   then the device is not BT capable.  Use BluetoothDevice.isEnabled()
-    //   to see if BT is enabled on the device.
-    //
-    // - BluetoothHeadset is the API for the control connection to a
-    //   Bluetooth Headset.  This lets you completely connect/disconnect a
-    //   headset (which we don't do from the Phone UI!) but also lets you
-    //   get the address of the currently active headset and see whether
-    //   it's currently connected.
-
-    /**
-     * @return true if the Bluetooth on/off switch in the UI should be
-     *         available to the user (i.e. if the device is BT-capable
-     *         and a headset is connected.)
-     */
-    /* package */ boolean isBluetoothAvailable() {
-        if (VDBG) log("isBluetoothAvailable()...");
-
-        // There's no need to ask the Bluetooth system service if BT is enabled:
-        //
-        //    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        //    if ((adapter == null) || !adapter.isEnabled()) {
-        //        if (DBG) log("  ==> FALSE (BT not enabled)");
-        //        return false;
-        //    }
-        //    if (DBG) log("  - BT enabled!  device name " + adapter.getName()
-        //                 + ", address " + adapter.getAddress());
-        //
-        // ...since we already have a BluetoothHeadset instance.  We can just
-        // call isConnected() on that, and assume it'll be false if BT isn't
-        // enabled at all.
-
-        // Check if there's a connected headset, using the BluetoothHeadset API.
-        boolean isConnected = false;
-        if (mBluetoothHeadset != null) {
-            List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
-
-            if (deviceList.size() > 0) {
-                BluetoothDevice device = deviceList.get(0);
-                isConnected = true;
-
-                if (VDBG) log("  - headset state = " +
-                              mBluetoothHeadset.getConnectionState(device));
-                if (VDBG) log("  - headset address: " + device);
-                if (VDBG) log("  - isConnected: " + isConnected);
-            }
-        }
-
-        if (VDBG) log("  ==> " + isConnected);
-        return isConnected;
-    }
-
-    /**
-     * @return true if a BT Headset is available, and its audio is currently connected.
-     */
-    /* package */ boolean isBluetoothAudioConnected() {
-        if (mBluetoothHeadset == null) {
-            if (VDBG) log("isBluetoothAudioConnected: ==> FALSE (null mBluetoothHeadset)");
-            return false;
-        }
-        List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
-
-        if (deviceList.isEmpty()) {
-            return false;
-        }
-        BluetoothDevice device = deviceList.get(0);
-        boolean isAudioOn = mBluetoothHeadset.isAudioConnected(device);
-        if (VDBG) log("isBluetoothAudioConnected: ==> isAudioOn = " + isAudioOn);
-        return isAudioOn;
-    }
-
-    /**
-     * Helper method used to control the onscreen "Bluetooth" indication;
-     * see InCallControlState.bluetoothIndicatorOn.
-     *
-     * @return true if a BT device is available and its audio is currently connected,
-     *              <b>or</b> if we issued a BluetoothHeadset.connectAudio()
-     *              call within the last 5 seconds (which presumably means
-     *              that the BT audio connection is currently being set
-     *              up, and will be connected soon.)
-     */
-    /* package */ boolean isBluetoothAudioConnectedOrPending() {
-        if (isBluetoothAudioConnected()) {
-            if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> TRUE (really connected)");
-            return true;
-        }
-
-        // If we issued a connectAudio() call "recently enough", even
-        // if BT isn't actually connected yet, let's still pretend BT is
-        // on.  This makes the onscreen indication more responsive.
-        if (mBluetoothConnectionPending) {
-            long timeSinceRequest =
-                    SystemClock.elapsedRealtime() - mBluetoothConnectionRequestTime;
-            if (timeSinceRequest < 5000 /* 5 seconds */) {
-                if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> TRUE (requested "
-                             + timeSinceRequest + " msec ago)");
-                return true;
-            } else {
-                if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> FALSE (request too old: "
-                             + timeSinceRequest + " msec ago)");
-                mBluetoothConnectionPending = false;
-                return false;
-            }
-        }
-
-        if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> FALSE");
         return false;
     }
 
-    /**
-     * @return true if the onscreen UI should currently be showing the
-     * special "bluetooth is active" indication in a couple of places (in
-     * which UI elements turn blue and/or show the bluetooth logo.)
-     *
-     * This depends on the BluetoothHeadset state *and* the current
-     * telephony state; see shouldShowBluetoothIndication().
-     *
-     * @see CallCard
-     * @see NotificationMgr.updateInCallNotification
-     */
-    /* package */ boolean showBluetoothIndication() {
-        return mShowBluetoothIndication;
+    /* package */ boolean isBluetoothAvailable() {
+        return false;
     }
 
-    /**
-     * Recomputes the mShowBluetoothIndication flag based on the current
-     * bluetooth state and current telephony state.
-     *
-     * This needs to be called any time the bluetooth headset state or the
-     * telephony state changes.
-     */
-    /* package */ void updateBluetoothIndication() {
-        mShowBluetoothIndication = shouldShowBluetoothIndication(mBluetoothHeadsetState,
-                                                                 mBluetoothHeadsetAudioState,
-                                                                 mCallManager);
+    /* package */ boolean isBluetoothAudioConnected() {
+        return false;
+    }
 
-        notifyListeners(mShowBluetoothIndication);
+    /* package */ boolean isBluetoothAudioConnectedOrPending() {
+        return false;
+    }
+
+    /* package */ boolean showBluetoothIndication() {
+        return false;
+    }
+
+    /* package */ void updateBluetoothIndication() {
     }
 
     public void addBluetoothIndicatorListener(BluetoothIndicatorListener listener) {
-        if (!mListeners.contains(listener)) {
-            mListeners.add(listener);
-        }
     }
 
     public void removeBluetoothIndicatorListener(BluetoothIndicatorListener listener) {
-        if (mListeners.contains(listener)) {
-            mListeners.remove(listener);
-        }
-    }
-
-    private void notifyListeners(boolean showBluetoothOn) {
-        for (int i = 0; i < mListeners.size(); i++) {
-            mListeners.get(i).onBluetoothIndicationChange(showBluetoothOn, this);
-        }
-    }
-
-    private void init(Context context) {
-        Preconditions.checkNotNull(context);
-
-        if (mBluetoothAdapter != null) {
-            mBluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
-                                    BluetoothProfile.HEADSET);
-        }
-
-        // Register for misc other intent broadcasts.
-        IntentFilter intentFilter =
-                new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
-        intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
-        context.registerReceiver(mReceiver, intentFilter);
-
-        mCallModeler.addListener(this);
-    }
-
-    private void tearDown() {
-        if (mBluetoothHeadset != null) {
-            mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
-            mBluetoothHeadset = null;
-        }
-    }
-
-    private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
-             new BluetoothProfile.ServiceListener() {
-         @Override
-         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-             mBluetoothHeadset = (BluetoothHeadset) proxy;
-             if (VDBG) log("- Got BluetoothHeadset: " + mBluetoothHeadset);
-         }
-
-         @Override
-         public void onServiceDisconnected(int profile) {
-             mBluetoothHeadset = null;
-         }
-    };
-
-    /**
-     * UI policy helper function for the couple of places in the UI that
-     * have some way of indicating that "bluetooth is in use."
-     *
-     * @return true if the onscreen UI should indicate that "bluetooth is in use",
-     *         based on the specified bluetooth headset state, and the
-     *         current state of the phone.
-     * @see showBluetoothIndication()
-     */
-    private static boolean shouldShowBluetoothIndication(int bluetoothState,
-                                                         int bluetoothAudioState,
-                                                         CallManager cm) {
-        // We want the UI to indicate that "bluetooth is in use" in two
-        // slightly different cases:
-        //
-        // (a) The obvious case: if a bluetooth headset is currently in
-        //     use for an ongoing call.
-        //
-        // (b) The not-so-obvious case: if an incoming call is ringing,
-        //     and we expect that audio *will* be routed to a bluetooth
-        //     headset once the call is answered.
-
-        switch (cm.getState()) {
-            case OFFHOOK:
-                // This covers normal active calls, and also the case if
-                // the foreground call is DIALING or ALERTING.  In this
-                // case, bluetooth is considered "active" if a headset
-                // is connected *and* audio is being routed to it.
-                return ((bluetoothState == BluetoothHeadset.STATE_CONNECTED)
-                        && (bluetoothAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED));
-
-            case RINGING:
-                // If an incoming call is ringing, we're *not* yet routing
-                // audio to the headset (since there's no in-call audio
-                // yet!)  In this case, if a bluetooth headset is
-                // connected at all, we assume that it'll become active
-                // once the user answers the phone.
-                return (bluetoothState == BluetoothHeadset.STATE_CONNECTED);
-
-            default:  // Presumably IDLE
-                return false;
-        }
-    }
-
-    private void dumpBluetoothState() {
-        log("============== dumpBluetoothState() =============");
-        log("= isBluetoothAvailable: " + isBluetoothAvailable());
-        log("= isBluetoothAudioConnected: " + isBluetoothAudioConnected());
-        log("= isBluetoothAudioConnectedOrPending: " + isBluetoothAudioConnectedOrPending());
-        log("= PhoneApp.showBluetoothIndication: "
-            + showBluetoothIndication());
-        log("=");
-        if (mBluetoothAdapter != null) {
-            if (mBluetoothHeadset != null) {
-                List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
-
-                if (deviceList.size() > 0) {
-                    BluetoothDevice device = deviceList.get(0);
-                    log("= BluetoothHeadset.getCurrentDevice: " + device);
-                    log("= BluetoothHeadset.State: "
-                        + mBluetoothHeadset.getConnectionState(device));
-                    log("= BluetoothHeadset audio connected: " +
-                        mBluetoothHeadset.isAudioConnected(device));
-                }
-            } else {
-                log("= mBluetoothHeadset is null");
-            }
-        } else {
-            log("= mBluetoothAdapter is null; device is not BT capable");
-        }
     }
 
     /* package */ void connectBluetoothAudio() {
-        if (VDBG) log("connectBluetoothAudio()...");
-        if (mBluetoothHeadset != null) {
-            // TODO(BT) check return
-            mBluetoothHeadset.connectAudio();
-        }
-
-        // Watch out: The bluetooth connection doesn't happen instantly;
-        // the connectAudio() call returns instantly but does its real
-        // work in another thread.  The mBluetoothConnectionPending flag
-        // is just a little trickery to ensure that the onscreen UI updates
-        // instantly. (See isBluetoothAudioConnectedOrPending() above.)
-        mBluetoothConnectionPending = true;
-        mBluetoothConnectionRequestTime = SystemClock.elapsedRealtime();
     }
 
     /* package */ void disconnectBluetoothAudio() {
-        if (VDBG) log("disconnectBluetoothAudio()...");
-        if (mBluetoothHeadset != null) {
-            mBluetoothHeadset.disconnectAudio();
-        }
-        mBluetoothConnectionPending = false;
-    }
-
-    /**
-     * Receiver for misc intent broadcasts the BluetoothManager cares about.
-     */
-    private class BluetoothBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-
-            if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
-                mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
-                                                          BluetoothHeadset.STATE_DISCONNECTED);
-                if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_STATE_CHANGED_ACTION");
-                if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetState);
-                // Also update any visible UI if necessary
-                updateBluetoothIndication();
-            } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
-                mBluetoothHeadsetAudioState =
-                        intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
-                                           BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
-                if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_AUDIO_STATE_CHANGED_ACTION");
-                if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetAudioState);
-                updateBluetoothIndication();
-            }
-        }
-    }
-
-    @Override
-    public void onDisconnect(Call call) {
-        updateBluetoothIndication();
-    }
-
-    @Override
-    public void onIncoming(Call call) {
-        // An incoming call can affect bluetooth indicator, so we update it whenever there is
-        // a change to any of the calls.
-        updateBluetoothIndication();
-    }
-
-    @Override
-    public void onUpdate(List<Call> calls) {
-        updateBluetoothIndication();
-    }
-
-    @Override
-    public void onPostDialAction(Connection.PostDialState state, int callId, String chars, char c) {
-        // no-op
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, msg);
     }
 
     /* package */ interface BluetoothIndicatorListener {
diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
index 0b9482d..c517343 100644
--- a/src/com/android/phone/CallController.java
+++ b/src/com/android/phone/CallController.java
@@ -141,7 +141,8 @@
                     // Reset the mThreeWayCallOrigStateDialing state
                     mApp.cdmaPhoneCallState.setThreeWayCallOrigState(false);
 
-                    mApp.getCallModeler().setCdmaOutgoing3WayCall(null);
+                    // TODO(sail): Remove this code.
+                    //mApp.getCallModeler().setCdmaOutgoing3WayCall(null);
                 }
                 break;
 
diff --git a/src/com/android/phone/CallGatewayManager.java b/src/com/android/phone/CallGatewayManager.java
index 81bee07..893070b 100644
--- a/src/com/android/phone/CallGatewayManager.java
+++ b/src/com/android/phone/CallGatewayManager.java
@@ -37,8 +37,7 @@
  *
  * <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.  This association is later used in CallModeler when building Call objects
- * to send to the UI which require the gateway data to show an alert to users.
+ * data into this class.
  */
 public class CallGatewayManager {
     private static final String LOG_TAG = CallGatewayManager.class.getSimpleName();
@@ -98,8 +97,7 @@
     }
 
     /**
-     * This function sets the current mapping from connection to gatewayInfo so that CallModeler
-     * can request this data when creating Call objects.
+     * 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.
      */
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
deleted file mode 100644
index ae8d251..0000000
--- a/src/com/android/phone/CallModeler.java
+++ /dev/null
@@ -1,879 +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.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.telephony.DisconnectCause;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.CallManager;
-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.internal.telephony.cdma.CdmaCallWaitingNotification;
-import com.android.phone.CallGatewayManager.RawGatewayInfo;
-import com.android.services.telephony.common.Call;
-import com.android.services.telephony.common.Call.Capabilities;
-import com.android.services.telephony.common.Call.State;
-
-import com.google.android.collect.Maps;
-import com.google.android.collect.Sets;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Creates a Call model from Call state and data received from the telephony
- * layer. The telephony layer maintains 3 conceptual objects: Phone, Call,
- * Connection.
- *
- * Phone represents the radio and there is an implementation per technology
- * type such as GSMPhone, SipPhone, CDMAPhone, etc. Generally, we will only ever
- * deal with one instance of this object for the lifetime of this class.
- *
- * There are 3 Call instances that exist for the lifetime of this class which
- * are created by CallTracker. The three are RingingCall, ForegroundCall, and
- * BackgroundCall.
- *
- * A Connection most closely resembles what the layperson would consider a call.
- * A Connection is created when a user dials and it is "owned" by one of the
- * three Call instances.  Which of the three Calls owns the Connection changes
- * as the Connection goes between ACTIVE, HOLD, RINGING, and other states.
- *
- * This class models a new Call class from Connection objects received from
- * the telephony layer. We use Connection references as identifiers for a call;
- * new reference = new call.
- *
- * TODO: Create a new Call class to replace the simple call Id ints
- * being used currently.
- */
-public class CallModeler extends Handler {
-
-    private static final String TAG = CallModeler.class.getSimpleName();
-    private static final boolean DBG =
-            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-
-    private static final int CALL_ID_START_VALUE = 1;
-
-    private final CallStateMonitor mCallStateMonitor;
-    private final CallManager mCallManager;
-    private final CallGatewayManager mCallGatewayManager;
-    private final HashMap<Connection, Call> mCallMap = Maps.newHashMap();
-    private final HashMap<Connection, Call> mConfCallMap = Maps.newHashMap();
-    private final AtomicInteger mNextCallId = new AtomicInteger(CALL_ID_START_VALUE);
-    private final ArrayList<Listener> mListeners = new ArrayList<Listener>();
-    private Connection mCdmaIncomingConnection;
-    private Connection mCdmaOutgoingConnection;
-
-    public CallModeler(CallStateMonitor callStateMonitor, CallManager callManager,
-            CallGatewayManager callGatewayManager) {
-        mCallStateMonitor = callStateMonitor;
-        mCallManager = callManager;
-        mCallGatewayManager = callGatewayManager;
-
-        mCallStateMonitor.addListener(this);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        switch(msg.what) {
-            case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION:
-                // We let the CallNotifier handle the new ringing connection first. When the custom
-                // ringtone and send_to_voicemail settings are retrieved, CallNotifier will directly
-                // call CallModeler's onNewRingingConnection.
-                break;
-            case CallStateMonitor.PHONE_DISCONNECT:
-                onDisconnect((Connection) ((AsyncResult) msg.obj).result);
-                break;
-            case CallStateMonitor.PHONE_UNKNOWN_CONNECTION_APPEARED:
-                // fall through
-            case CallStateMonitor.PHONE_STATE_CHANGED:
-                onPhoneStateChanged((AsyncResult) msg.obj);
-                break;
-            case CallStateMonitor.PHONE_ON_DIAL_CHARS:
-                onPostDialChars((AsyncResult) msg.obj, (char) msg.arg1);
-                break;
-            default:
-                break;
-        }
-    }
-
-    public void addListener(Listener listener) {
-        Preconditions.checkNotNull(listener);
-        Preconditions.checkNotNull(mListeners);
-        if (!mListeners.contains(listener)) {
-            mListeners.add(listener);
-        }
-    }
-
-    public List<Call> getFullList() {
-        final List<Call> calls =
-                Lists.newArrayListWithCapacity(mCallMap.size() + mConfCallMap.size());
-        calls.addAll(mCallMap.values());
-        calls.addAll(mConfCallMap.values());
-        return calls;
-    }
-
-    public CallResult getCallWithId(int callId) {
-        // max 8 connections, so this should be fast even through we are traversing the entire map.
-        for (Entry<Connection, Call> entry : mCallMap.entrySet()) {
-            if (entry.getValue().getCallId() == callId) {
-                return new CallResult(entry.getValue(), entry.getKey());
-            }
-        }
-
-        for (Entry<Connection, Call> entry : mConfCallMap.entrySet()) {
-            if (entry.getValue().getCallId() == callId) {
-                return new CallResult(entry.getValue(), entry.getKey());
-            }
-        }
-        return null;
-    }
-
-    public boolean hasLiveCall() {
-        return hasLiveCallInternal(mCallMap) ||
-            hasLiveCallInternal(mConfCallMap);
-    }
-
-    public void onCdmaCallWaiting(CdmaCallWaitingNotification callWaitingInfo) {
-        // We dont get the traditional onIncomingCall notification for cdma call waiting,
-        // but the Connection does actually exist.  We need to find it in the set of ringing calls
-        // and pass it through our normal incoming logic.
-        final com.android.internal.telephony.Call teleCall =
-            mCallManager.getFirstActiveRingingCall();
-
-        if (teleCall.getState() == com.android.internal.telephony.Call.State.WAITING) {
-            Connection connection = teleCall.getLatestConnection();
-
-            if (connection != null) {
-                String number = connection.getAddress();
-                if (number != null && number.equals(callWaitingInfo.number)) {
-                    Call call = onNewRingingConnection(connection);
-                    mCdmaIncomingConnection = connection;
-                    return;
-                }
-            }
-        }
-
-        Log.e(TAG, "CDMA Call waiting notification without a matching connection.");
-    }
-
-    public void onCdmaCallWaitingReject() {
-        // Cdma call was rejected...
-        if (mCdmaIncomingConnection != null) {
-            onDisconnect(mCdmaIncomingConnection);
-            mCdmaIncomingConnection = null;
-        } else {
-            Log.e(TAG, "CDMA Call waiting rejection without an incoming call.");
-        }
-    }
-
-    /**
-     * CDMA Calls have no sense of "dialing" state. For outgoing calls 3way calls we want to
-     * mimick this state so that the the UI can notify the user that there is a "dialing"
-     * call.
-     */
-    public void setCdmaOutgoing3WayCall(Connection connection) {
-        boolean wasSet = mCdmaOutgoingConnection != null;
-
-        mCdmaOutgoingConnection = connection;
-
-        // If we reset the connection, that mean we can now tell the user that the call is actually
-        // part of the conference call and move it out of the dialing state. To do this, issue a
-        // new update completely.
-        if (wasSet && mCdmaOutgoingConnection == null) {
-            onPhoneStateChanged(null);
-        }
-    }
-
-    private boolean hasLiveCallInternal(HashMap<Connection, Call> map) {
-        for (Call call : map.values()) {
-            final int state = call.getState();
-            if (state == Call.State.ACTIVE ||
-                    state == Call.State.CALL_WAITING ||
-                    state == Call.State.CONFERENCED ||
-                    state == Call.State.DIALING ||
-                    state == Call.State.REDIALING ||
-                    state == Call.State.INCOMING ||
-                    state == Call.State.ONHOLD ||
-                    state == Call.State.DISCONNECTING) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public boolean hasOutstandingActiveOrDialingCall() {
-        return hasOutstandingActiveOrDialingCallInternal(mCallMap) ||
-                hasOutstandingActiveOrDialingCallInternal(mConfCallMap);
-    }
-
-    private static boolean hasOutstandingActiveOrDialingCallInternal(
-            HashMap<Connection, Call> map) {
-        for (Call call : map.values()) {
-            final int state = call.getState();
-            if (state == Call.State.ACTIVE || Call.State.isDialing(state)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-
-    /**
-     * Handles the POST_ON_DIAL_CHARS message from the Phone (see our call to
-     * mPhone.setOnPostDialCharacter() above.)
-     *
-     * TODO: NEED TO TEST THIS SEQUENCE now that we no longer handle "dialable" key events here in
-     * the InCallScreen: we do directly to the Dialer UI instead.  Similarly, we may now need to go
-     * directly to the Dialer to handle POST_ON_DIAL_CHARS too.
-     */
-    private void onPostDialChars(AsyncResult r, char ch) {
-        final Connection c = (Connection) r.result;
-
-        if (c != null) {
-            final Connection.PostDialState state = (Connection.PostDialState) r.userObj;
-
-            switch (state) {
-                case WAIT:
-                    final Call call = getCallFromMap(mCallMap, c, false);
-                    if (call == null) {
-                        Log.i(TAG, "Call no longer exists. Skipping onPostDialWait().");
-                    } else {
-                        for (Listener mListener : mListeners) {
-                            mListener.onPostDialAction(state, call.getCallId(),
-                                    c.getRemainingPostDialString(), ch);
-                        }
-                    }
-                    break;
-                default:
-                    // This is primarily to cause the DTMFTonePlayer to play local tones.
-                    // Other listeners simply perform no-ops.
-                    for (Listener mListener : mListeners) {
-                        mListener.onPostDialAction(state, 0, "", ch);
-                    }
-                    break;
-            }
-        }
-    }
-
-    /* package */ Call onNewRingingConnection(Connection conn) {
-        Log.i(TAG, "onNewRingingConnection");
-        final Call call = getCallFromMap(mCallMap, conn, true);
-
-        if (call != null) {
-            updateCallFromConnection(call, conn, false);
-
-            for (int i = 0; i < mListeners.size(); ++i) {
-                mListeners.get(i).onIncoming(call);
-            }
-        }
-
-        PhoneGlobals.getInstance().updateWakeState();
-        return call;
-    }
-
-    private void onDisconnect(Connection conn) {
-        Log.i(TAG, "onDisconnect");
-        final Call call = getCallFromMap(mCallMap, conn, false);
-
-        if (call != null) {
-            final boolean wasConferenced = call.getState() == State.CONFERENCED;
-
-            updateCallFromConnection(call, conn, false);
-
-            for (int i = 0; i < mListeners.size(); ++i) {
-                mListeners.get(i).onDisconnect(call);
-            }
-
-            // If it was a conferenced call, we need to run the entire update
-            // to make the proper changes to parent conference calls.
-            if (wasConferenced) {
-                onPhoneStateChanged(null);
-            }
-
-            mCallMap.remove(conn);
-        }
-
-        mCallManager.clearDisconnected();
-        PhoneGlobals.getInstance().updateWakeState();
-    }
-
-    /**
-     * Called when the phone state changes.
-     */
-    private void onPhoneStateChanged(AsyncResult r) {
-        Log.i(TAG, "onPhoneStateChanged: ");
-        final List<Call> updatedCalls = Lists.newArrayList();
-        doUpdate(false, updatedCalls);
-
-        if (updatedCalls.size() > 0) {
-            for (int i = 0; i < mListeners.size(); ++i) {
-                mListeners.get(i).onUpdate(updatedCalls);
-            }
-        }
-
-        PhoneGlobals.getInstance().updateWakeState();
-    }
-
-    /**
-     * Go through the Calls from CallManager and return the list of calls that were updated.
-     * Method also finds any orphaned Calls (Connection objects no longer returned by telephony as
-     * either ringing, foreground, or background).  For each orphaned call, it sets the call state
-     * to IDLE and adds it to the list of calls to update.
-     *
-     * @param fullUpdate Add all calls to out parameter including those that have no updates.
-     * @param out List to populate with Calls that have been updated.
-     */
-    private void doUpdate(boolean fullUpdate, List<Call> out) {
-        final List<com.android.internal.telephony.Call> telephonyCalls = Lists.newArrayList();
-        telephonyCalls.addAll(mCallManager.getRingingCalls());
-        telephonyCalls.addAll(mCallManager.getForegroundCalls());
-        telephonyCalls.addAll(mCallManager.getBackgroundCalls());
-
-        // orphanedConnections starts out including all connections we know about.
-        // As we iterate through the connections we get from the telephony layer we
-        // prune this Set down to only the connections we have but telephony no longer
-        // recognizes.
-        final Set<Connection> orphanedConnections = Sets.newHashSet();
-        orphanedConnections.addAll(mCallMap.keySet());
-        orphanedConnections.addAll(mConfCallMap.keySet());
-
-        // Cycle through all the Connections on all the Calls. Update our Call objects
-        // to reflect any new state and send the updated Call objects to the handler service.
-        for (com.android.internal.telephony.Call telephonyCall : telephonyCalls) {
-
-            for (Connection connection : telephonyCall.getConnections()) {
-                if (DBG) Log.d(TAG, "connection: " + connection + connection.getState());
-
-                if (orphanedConnections.contains(connection)) {
-                    orphanedConnections.remove(connection);
-                }
-
-                // We only send updates for live calls which are not incoming (ringing).
-                // Disconnected and incoming calls are handled by onDisconnect and
-                // onNewRingingConnection.
-                final boolean shouldUpdate =
-                        connection.getState() !=
-                                com.android.internal.telephony.Call.State.DISCONNECTED &&
-                        connection.getState() !=
-                                com.android.internal.telephony.Call.State.IDLE &&
-                        !connection.getState().isRinging();
-
-                final boolean isDisconnecting = connection.getState() ==
-                                com.android.internal.telephony.Call.State.DISCONNECTING;
-
-                // For disconnecting calls, we still need to send the update to the UI but we do
-                // not create a new call if the call did not exist.
-                final boolean shouldCreate = shouldUpdate && !isDisconnecting;
-
-                // New connections return a Call with INVALID state, which does not translate to
-                // a state in the internal.telephony.Call object.  This ensures that staleness
-                // check below fails and we always add the item to the update list if it is new.
-                final Call call = getCallFromMap(mCallMap, connection, shouldCreate /* create */);
-
-                if (call == null || !shouldUpdate) {
-                    if (DBG) Log.d(TAG, "update skipped");
-                    continue;
-                }
-
-                boolean changed = updateCallFromConnection(call, connection, false);
-
-                if (fullUpdate || changed) {
-                    out.add(call);
-                }
-            }
-
-            // We do a second loop to address conference call scenarios.  We do this as a separate
-            // loop to ensure all child calls are up to date before we start updating the parent
-            // conference calls.
-            for (Connection connection : telephonyCall.getConnections()) {
-                updateForConferenceCalls(connection, out);
-            }
-        }
-
-        // Iterate through orphaned connections, set them to idle, and remove
-        // them from our internal structures.
-        for (Connection orphanedConnection : orphanedConnections) {
-            if (mCallMap.containsKey(orphanedConnection)) {
-                final Call call = mCallMap.get(orphanedConnection);
-                call.setState(Call.State.IDLE);
-                out.add(call);
-
-                mCallMap.remove(orphanedConnection);
-            }
-
-            if (mConfCallMap.containsKey(orphanedConnection)) {
-                final Call call = mCallMap.get(orphanedConnection);
-                call.setState(Call.State.IDLE);
-                out.add(call);
-
-                mConfCallMap.remove(orphanedConnection);
-            }
-        }
-    }
-
-    /**
-     * Checks to see if the connection is the first connection in a conference call.
-     * If it is a conference call, we will create a new Conference Call object or
-     * update the existing conference call object for that connection.
-     * If it is not a conference call but a previous associated conference call still exists,
-     * we mark it as idle and remove it from the map.
-     * In both cases above, we add the Calls to be updated to the UI.
-     * @param connection The connection object to check.
-     * @param updatedCalls List of 'updated' calls that will be sent to the UI.
-     */
-    private boolean updateForConferenceCalls(Connection connection, List<Call> updatedCalls) {
-        // We consider this connection a conference connection if the call it
-        // belongs to is a multiparty call AND it is the first live connection.
-        final boolean isConferenceCallConnection = isPartOfLiveConferenceCall(connection) &&
-                getEarliestLiveConnection(connection.getCall()) == connection;
-
-        boolean changed = false;
-
-        // If this connection is the main connection for the conference call, then create or update
-        // a Call object for that conference call.
-        if (isConferenceCallConnection) {
-            final Call confCall = getCallFromMap(mConfCallMap, connection, true);
-            changed = updateCallFromConnection(confCall, connection, true);
-
-            if (changed) {
-                updatedCalls.add(confCall);
-            }
-
-            if (DBG) Log.d(TAG, "Updating a conference call: " + confCall);
-
-        // It is possible that through a conference call split, there may be lingering conference
-        // calls where this connection was the main connection.  We clean those up here.
-        } else {
-            final Call oldConfCall = getCallFromMap(mConfCallMap, connection, false);
-
-            // We found a conference call for this connection, which is no longer a conference call.
-            // Kill it!
-            if (oldConfCall != null) {
-                if (DBG) Log.d(TAG, "Cleaning up an old conference call: " + oldConfCall);
-                mConfCallMap.remove(connection);
-                oldConfCall.setState(State.IDLE);
-                changed = true;
-
-                // add to the list of calls to update
-                updatedCalls.add(oldConfCall);
-            }
-        }
-
-        return changed;
-    }
-
-    private Connection getEarliestLiveConnection(com.android.internal.telephony.Call call) {
-        final List<Connection> connections = call.getConnections();
-        final int size = connections.size();
-        Connection earliestConn = null;
-        long earliestTime = Long.MAX_VALUE;
-        for (int i = 0; i < size; i++) {
-            final Connection connection = connections.get(i);
-            if (!connection.isAlive()) continue;
-            final long time = connection.getCreateTime();
-            if (time < earliestTime) {
-                earliestTime = time;
-                earliestConn = connection;
-            }
-        }
-        return earliestConn;
-    }
-
-    /**
-     * Sets the new call state onto the call and performs some additional logic
-     * associated with setting the state.
-     */
-    private void setNewState(Call call, int newState, Connection connection) {
-        Preconditions.checkState(call.getState() != newState);
-
-        // When starting an outgoing call, we need to grab gateway information
-        // for the call, if available, and set it.
-        final RawGatewayInfo info = mCallGatewayManager.getGatewayInfo(connection);
-
-        if (Call.State.isDialing(newState)) {
-            if (!info.isEmpty()) {
-                call.setGatewayNumber(info.getFormattedGatewayNumber());
-                call.setGatewayPackage(info.packageName);
-            }
-        } else if (!Call.State.isConnected(newState)) {
-            mCallGatewayManager.clearGatewayData(connection);
-        }
-
-        call.setState(newState);
-    }
-
-    /**
-     * Updates the Call properties to match the state of the connection object
-     * that it represents.
-     * @param call The call object to update.
-     * @param connection The connection object from which to update call.
-     * @param isForConference There are slight differences in how we populate data for conference
-     *     calls. This boolean tells us which method to use.
-     */
-    private boolean updateCallFromConnection(Call call, Connection connection,
-            boolean isForConference) {
-        boolean changed = false;
-
-        final int newState = translateStateFromTelephony(connection, isForConference);
-
-        if (call.getState() != newState) {
-            setNewState(call, newState, connection);
-            changed = true;
-        }
-
-        final boolean isWifiCall = connection.getCall().getPhone().getPhoneType() ==
-                PhoneConstants.PHONE_TYPE_THIRD_PARTY;
-        if (call.isWifiCall() != isWifiCall) {
-            call.setIsWifiCall(isWifiCall);
-            changed = true;
-        }
-
-        final int newDisconnectCause = connection.getDisconnectCause();
-        if (call.getDisconnectCause() != newDisconnectCause) {
-            call.setDisconnectCause(newDisconnectCause);
-            changed = true;
-        }
-
-        final long oldConnectTime = call.getConnectTime();
-        if (oldConnectTime != connection.getConnectTime()) {
-            call.setConnectTime(connection.getConnectTime());
-            changed = true;
-        }
-
-        if (!isForConference) {
-            // Number
-            final String oldNumber = call.getNumber();
-            String newNumber = connection.getAddress();
-            RawGatewayInfo info = mCallGatewayManager.getGatewayInfo(connection);
-            if (!info.isEmpty()) {
-                newNumber = info.trueNumber;
-            }
-            if (TextUtils.isEmpty(oldNumber) || !oldNumber.equals(newNumber)) {
-                call.setNumber(newNumber);
-                changed = true;
-            }
-
-            // Number presentation
-            final int newNumberPresentation = connection.getNumberPresentation();
-            if (call.getNumberPresentation() != newNumberPresentation) {
-                call.setNumberPresentation(newNumberPresentation);
-                changed = true;
-            }
-
-            // Name
-            final String oldCnapName = call.getCnapName();
-            if (TextUtils.isEmpty(oldCnapName) || !oldCnapName.equals(connection.getCnapName())) {
-                call.setCnapName(connection.getCnapName());
-                changed = true;
-            }
-
-            // Name Presentation
-            final int newCnapNamePresentation = connection.getCnapNamePresentation();
-            if (call.getCnapNamePresentation() != newCnapNamePresentation) {
-                call.setCnapNamePresentation(newCnapNamePresentation);
-                changed = true;
-            }
-        } else {
-
-            // update the list of children by:
-            // 1) Saving the old set
-            // 2) Removing all children
-            // 3) Adding the correct children into the Call
-            // 4) Comparing the new children set with the old children set
-            ImmutableSortedSet<Integer> oldSet = call.getChildCallIds();
-            call.removeAllChildren();
-
-            if (connection.getCall() != null) {
-                for (Connection childConn : connection.getCall().getConnections()) {
-                    final Call childCall = getCallFromMap(mCallMap, childConn, false);
-                    if (childCall != null && childConn.isAlive()) {
-                        call.addChildId(childCall.getCallId());
-                    }
-                }
-            }
-            changed |= !oldSet.equals(call.getChildCallIds());
-        }
-
-        /**
-         * !!! Uses values from connection and call collected above so this part must be last !!!
-         */
-        final int newCapabilities = getCapabilitiesFor(connection, call, isForConference);
-        if (call.getCapabilities() != newCapabilities) {
-            call.setCapabilities(newCapabilities);
-            changed = true;
-        }
-
-        return changed;
-    }
-
-    /**
-     * Returns a mask of capabilities for the connection such as merge, hold, etc.
-     */
-    private int getCapabilitiesFor(Connection connection, Call call, boolean isForConference) {
-        final boolean callIsActive = (call.getState() == Call.State.ACTIVE);
-        final Phone phone = connection.getCall().getPhone();
-
-        boolean canAddCall = false;
-        boolean canMergeCall = false;
-        boolean canSwapCall = false;
-        boolean canRespondViaText = false;
-        boolean canMute = false;
-
-        final boolean supportHold = PhoneUtils.okToSupportHold(mCallManager);
-        final boolean canHold = (supportHold ? PhoneUtils.okToHoldCall(mCallManager) : false);
-        final boolean genericConf = isForConference &&
-                (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA);
-
-        // only applies to active calls
-        if (callIsActive) {
-            canMergeCall = PhoneUtils.okToMergeCalls(mCallManager);
-            canSwapCall = PhoneUtils.okToSwapCalls(mCallManager);
-        }
-
-        canAddCall = PhoneUtils.okToAddCall(mCallManager);
-
-        // "Mute": only enabled when the foreground call is ACTIVE.
-        // (It's meaningless while on hold, or while DIALING/ALERTING.)
-        // It's also explicitly disabled during emergency calls or if
-        // emergency callback mode (ECM) is active.
-        boolean isEmergencyCall = false;
-        if (connection != null) {
-            isEmergencyCall = PhoneNumberUtils.isLocalEmergencyNumber(phone.getContext(),
-                    connection.getAddress());
-        }
-        boolean isECM = PhoneUtils.isPhoneInEcm(phone);
-        if (isEmergencyCall || isECM) {  // disable "Mute" item
-            canMute = false;
-        } else {
-            canMute = callIsActive;
-        }
-
-        canRespondViaText = false /* RejectWithTextMessageManager.allowRespondViaSmsForCall(call,
-                connection) */;
-
-        // special rules section!
-        // CDMA always has Add
-        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            canAddCall = true;
-        }
-
-        int retval = 0x0;
-        if (canHold) {
-            retval |= Capabilities.HOLD;
-        }
-        if (supportHold) {
-            retval |= Capabilities.SUPPORT_HOLD;
-        }
-        if (canAddCall) {
-            retval |= Capabilities.ADD_CALL;
-        }
-        if (canMergeCall) {
-            retval |= Capabilities.MERGE_CALLS;
-        }
-        if (canSwapCall) {
-            retval |= Capabilities.SWAP_CALLS;
-        }
-        if (canRespondViaText) {
-            retval |= Capabilities.RESPOND_VIA_TEXT;
-        }
-        if (canMute) {
-            retval |= Capabilities.MUTE;
-        }
-        if (genericConf) {
-            retval |= Capabilities.GENERIC_CONFERENCE;
-        }
-
-        return retval;
-    }
-
-    /**
-     * Returns true if the Connection is part of a multiparty call.
-     * We do this by checking the isMultiparty() method of the telephony.Call object and also
-     * checking to see if more than one of it's children is alive.
-     */
-    private boolean isPartOfLiveConferenceCall(Connection connection) {
-        if (connection.getCall() != null && connection.getCall().isMultiparty()) {
-            int count = 0;
-            for (Connection currConn : connection.getCall().getConnections()) {
-
-                // Only count connections which are alive and never cound the special
-                // "dialing" 3way call for CDMA calls.
-                if (currConn.isAlive() && currConn != mCdmaOutgoingConnection) {
-                    count++;
-                    if (count >= 2) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    private int translateStateFromTelephony(Connection connection, boolean isForConference) {
-
-        com.android.internal.telephony.Call.State connState = connection.getState();
-
-        // For the "fake" outgoing CDMA call, we need to always treat it as an outgoing call.
-        if (mCdmaOutgoingConnection == connection) {
-            connState = com.android.internal.telephony.Call.State.DIALING;
-        }
-
-        int retval = State.IDLE;
-        switch (connState) {
-            case ACTIVE:
-                retval = State.ACTIVE;
-                break;
-            case INCOMING:
-                retval = State.INCOMING;
-                break;
-            case DIALING:
-            case ALERTING:
-                if (PhoneGlobals.getInstance().notifier.getIsCdmaRedialCall()) {
-                    retval = State.REDIALING;
-                } else {
-                    retval = State.DIALING;
-                }
-                break;
-            case WAITING:
-                retval = State.CALL_WAITING;
-                break;
-            case HOLDING:
-                retval = State.ONHOLD;
-                break;
-            case DISCONNECTING:
-                retval = State.DISCONNECTING;
-                break;
-            case DISCONNECTED:
-                retval = State.DISCONNECTED;
-            default:
-        }
-
-        // If we are dealing with a potential child call (not the parent conference call),
-        // the check to see if we have to set the state to CONFERENCED.
-        if (!isForConference) {
-            // if the connection is part of a multiparty call, and it is live,
-            // annotate it with CONFERENCED state instead.
-            if (isPartOfLiveConferenceCall(connection) && connection.isAlive()) {
-                return State.CONFERENCED;
-            }
-        }
-
-        return retval;
-    }
-
-    /**
-     * Gets an existing callId for a connection, or creates one if none exists.
-     * This function does NOT set any of the Connection data onto the Call class.
-     * A separate call to updateCallFromConnection must be made for that purpose.
-     */
-    private Call getCallFromMap(HashMap<Connection, Call> map, Connection conn,
-            boolean createIfMissing) {
-        Call call = null;
-
-        // Find the call id or create if missing and requested.
-        if (conn != null) {
-            if (map.containsKey(conn)) {
-                call = map.get(conn);
-            } else if (createIfMissing) {
-                call = createNewCall();
-                map.put(conn, call);
-            }
-        }
-        return call;
-    }
-
-    /**
-     * Creates a brand new connection for the call.
-     */
-    private Call createNewCall() {
-        int callId;
-        int newNextCallId;
-        do {
-            callId = mNextCallId.get();
-
-            // protect against overflow
-            newNextCallId = (callId == Integer.MAX_VALUE ?
-                    CALL_ID_START_VALUE : callId + 1);
-
-            // Keep looping if the change was not atomic OR the value is already taken.
-            // The call to containsValue() is linear, however, most devices support a
-            // maximum of 7 connections so it's not expensive.
-        } while (!mNextCallId.compareAndSet(callId, newNextCallId));
-
-        return new Call(callId);
-    }
-
-    /**
-     * Listener interface for changes to Calls.
-     */
-    public interface Listener {
-        void onDisconnect(Call call);
-        void onIncoming(Call call);
-        void onUpdate(List<Call> calls);
-        void onPostDialAction(Connection.PostDialState state, int callId, String remainingChars,
-                char c);
-    }
-
-    /**
-     * Result class for accessing a call by connection.
-     */
-    public static class CallResult {
-        public Call mCall;
-        public Call mActionableCall;
-        public Connection mConnection;
-
-        private CallResult(Call call, Connection connection) {
-            this(call, call, connection);
-        }
-
-        private CallResult(Call call, Call actionableCall, Connection connection) {
-            mCall = call;
-            mActionableCall = actionableCall;
-            mConnection = connection;
-        }
-
-        public Call getCall() {
-            return mCall;
-        }
-
-        // The call that should be used for call actions like hanging up.
-        public Call getActionableCall() {
-            return mActionableCall;
-        }
-
-        public Connection getConnection() {
-            return mConnection;
-        }
-    }
-}
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index babae74..bc19568 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -140,7 +140,6 @@
     private Ringer mRinger;
     private BluetoothHeadset mBluetoothHeadset;
     private CallLogger mCallLogger;
-    private CallModeler mCallModeler;
     private boolean mSilentRingerRequested;
 
     // ToneGenerator instance for playing SignalInfo tones
@@ -175,11 +174,11 @@
      */
     /* package */ static CallNotifier init(PhoneGlobals app, Phone phone, Ringer ringer,
             CallLogger callLogger, CallStateMonitor callStateMonitor,
-            BluetoothManager bluetoothManager, CallModeler callModeler) {
+            BluetoothManager bluetoothManager) {
         synchronized (CallNotifier.class) {
             if (sInstance == null) {
                 sInstance = new CallNotifier(app, phone, ringer, callLogger, callStateMonitor,
-                        bluetoothManager, callModeler);
+                        bluetoothManager);
             } else {
                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
             }
@@ -189,13 +188,11 @@
 
     /** Private constructor; @see init() */
     private CallNotifier(PhoneGlobals app, Phone phone, Ringer ringer, CallLogger callLogger,
-            CallStateMonitor callStateMonitor, BluetoothManager bluetoothManager,
-            CallModeler callModeler) {
+            CallStateMonitor callStateMonitor, BluetoothManager bluetoothManager) {
         mApplication = app;
         mCM = app.mCM;
         mCallLogger = callLogger;
         mBluetoothManager = bluetoothManager;
-        mCallModeler = callModeler;
 
         mAudioManager = (AudioManager) mApplication.getSystemService(Context.AUDIO_SERVICE);
 
@@ -631,7 +628,7 @@
         }
 
         // If the ringing call still does not have any connection anymore, do not send the
-        // notification to the CallModeler.
+        // notification.
         final Call ringingCall = mCM.getFirstActiveRingingCall();
 
         if (ringingCall != null && ringingCall.getLatestConnection() == c) {
@@ -650,7 +647,6 @@
     }
 
     /**
-     * Notifies the Call Modeler that there is a new ringing connection.
      * If it is not a waiting call (there is no other active call in foreground), we will ring the
      * ringtone. Otherwise we will play the call waiting tone instead.
      * @param c The new ringing connection.
@@ -665,7 +661,6 @@
                 mCallWaitingTonePlayer.start();
             }
         }
-        mCallModeler.onNewRingingConnection(c);
     }
 
     /**
@@ -706,11 +701,8 @@
         // There's no need to force a UI update since we update the
         // in-call notification ourselves (below), and the InCallScreen
         // listens for phone state changes itself.
-        // TODO: Have BluetoothManager listen to CallModeler instead of relying on
-        // CallNotifier
         mBluetoothManager.updateBluetoothIndication();
 
-
         // Update the phone state and other sensor/lock.
         mApplication.updatePhoneState(state);
 
@@ -1588,7 +1580,8 @@
             new SignalInfoTonePlayer(toneID).start();
         }
 
-        mCallModeler.onCdmaCallWaiting(infoCW);
+        // TODO(sail): Remove this.
+        //mCallModeler.onCdmaCallWaiting(infoCW);
     }
 
     /**
@@ -1641,7 +1634,8 @@
 
         // Call modeler needs to know about this event regardless of the
         // state conditionals in the previous code.
-        mCallModeler.onCdmaCallWaitingReject();
+        // TODO(sail): Remove this.
+        //mCallModeler.onCdmaCallWaitingReject();
     }
 
     /**
diff --git a/src/com/android/phone/CallStateMonitor.java b/src/com/android/phone/CallStateMonitor.java
index b93d7e1..c978e26 100644
--- a/src/com/android/phone/CallStateMonitor.java
+++ b/src/com/android/phone/CallStateMonitor.java
@@ -98,9 +98,8 @@
                 Log.d(LOG_TAG, "Adding Handler: " + handler);
             }
 
-            // Commented out so that the two listeners do not get phone events:
-            // 1) CallModeler - drives in-call UI, DTMF sessions, Bluetooth.
-            // 2) CallNotifier - Incoming-call sequence (ringer, etc.)
+            // Commented out so that the listener does not get phone events:
+            // 1) CallNotifier - Incoming-call sequence (ringer, etc.)
             //
             // NOTE: This can be deleted, but is left here for documentation purposes until this
             // entire file can be deleted (once we are sure we've addressed each of the events we
diff --git a/src/com/android/phone/DTMFTonePlayer.java b/src/com/android/phone/DTMFTonePlayer.java
deleted file mode 100644
index 2b04415..0000000
--- a/src/com/android/phone/DTMFTonePlayer.java
+++ /dev/null
@@ -1,408 +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 com.google.common.collect.ImmutableMap;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.media.ToneGenerator;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Connection.PostDialState;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.services.telephony.common.Call;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-
-/**
- * Playing DTMF tones through the CallManager.
- */
-public class DTMFTonePlayer implements CallModeler.Listener {
-    private static final String LOG_TAG = DTMFTonePlayer.class.getSimpleName();
-    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
-    private static final int DTMF_SEND_CNF = 100;
-    private static final int DTMF_STOP = 101;
-
-    /** Hash Map to map a character to a tone*/
-    private static final Map<Character, Integer> mToneMap =
-            ImmutableMap.<Character, Integer>builder()
-                    .put('1', ToneGenerator.TONE_DTMF_1)
-                    .put('2', ToneGenerator.TONE_DTMF_2)
-                    .put('3', ToneGenerator.TONE_DTMF_3)
-                    .put('4', ToneGenerator.TONE_DTMF_4)
-                    .put('5', ToneGenerator.TONE_DTMF_5)
-                    .put('6', ToneGenerator.TONE_DTMF_6)
-                    .put('7', ToneGenerator.TONE_DTMF_7)
-                    .put('8', ToneGenerator.TONE_DTMF_8)
-                    .put('9', ToneGenerator.TONE_DTMF_9)
-                    .put('0', ToneGenerator.TONE_DTMF_0)
-                    .put('#', ToneGenerator.TONE_DTMF_P)
-                    .put('*', ToneGenerator.TONE_DTMF_S)
-                    .build();
-
-    private final CallManager mCallManager;
-    private final CallModeler mCallModeler;
-    private final Object mToneGeneratorLock = new Object();
-    private ToneGenerator mToneGenerator;
-    private boolean mLocalToneEnabled;
-
-    // indicates that we are using automatically shortened DTMF tones
-    boolean mShortTone;
-
-    // indicate if the confirmation from TelephonyFW is pending.
-    private boolean mDTMFBurstCnfPending = false;
-
-    // Queue to queue the short dtmf characters.
-    private Queue<Character> mDTMFQueue = new LinkedList<Character>();
-
-    //  Short Dtmf tone duration
-    private static final int DTMF_DURATION_MS = 120;
-
-    /**
-     * Our own handler to take care of the messages from the phone state changes
-     */
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case DTMF_SEND_CNF:
-                    logD("dtmf confirmation received from FW.");
-                    // handle burst dtmf confirmation
-                    handleBurstDtmfConfirmation();
-                    break;
-                case DTMF_STOP:
-                    logD("dtmf stop received");
-                    stopDtmfTone();
-                    break;
-            }
-        }
-    };
-
-    public DTMFTonePlayer(CallManager callManager, CallModeler callModeler) {
-        mCallManager = callManager;
-        mCallModeler = callModeler;
-        mCallModeler.addListener(this);
-    }
-
-    @Override
-    public void onDisconnect(Call call) {
-        logD("Call disconnected");
-        checkCallState();
-    }
-
-    @Override
-    public void onIncoming(Call call) {
-    }
-
-    @Override
-    public void onUpdate(List<Call> calls) {
-        logD("Call updated");
-        checkCallState();
-    }
-
-    @Override
-    public void onPostDialAction(PostDialState state, int callId, String remainingChars,
-            char currentChar) {
-        switch (state) {
-            case STARTED:
-                stopLocalToneIfNeeded();
-                if (!mToneMap.containsKey(currentChar)) {
-                    return;
-                }
-                startLocalToneIfNeeded(currentChar);
-                break;
-            case PAUSE:
-            case WAIT:
-            case WILD:
-            case COMPLETE:
-                stopLocalToneIfNeeded();
-                break;
-            default:
-                break;
-        }
-    }
-
-    /**
-     * Allocates some resources we keep around during a "dialer session".
-     *
-     * (Currently, a "dialer session" just means any situation where we
-     * might need to play local DTMF tones, which means that we need to
-     * keep a ToneGenerator instance around.  A ToneGenerator instance
-     * keeps an AudioTrack resource busy in AudioFlinger, so we don't want
-     * to keep it around forever.)
-     *
-     * Call {@link stopDialerSession} to release the dialer session
-     * resources.
-     */
-    public void startDialerSession() {
-        logD("startDialerSession()... this = " + this);
-
-        // see if we need to play local tones.
-        if (PhoneGlobals.getInstance().getResources().getBoolean(R.bool.allow_local_dtmf_tones)) {
-            mLocalToneEnabled = Settings.System.getInt(
-                    PhoneGlobals.getInstance().getContentResolver(),
-                    Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
-        } else {
-            mLocalToneEnabled = false;
-        }
-        logD("- startDialerSession: mLocalToneEnabled = " + mLocalToneEnabled);
-
-        // create the tone generator
-        // if the mToneGenerator creation fails, just continue without it.  It is
-        // a local audio signal, and is not as important as the dtmf tone itself.
-        if (mLocalToneEnabled) {
-            synchronized (mToneGeneratorLock) {
-                if (mToneGenerator == null) {
-                    try {
-                        mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF, 80);
-                    } catch (RuntimeException e) {
-                        Log.e(LOG_TAG, "Exception caught while creating local tone generator", e);
-                        mToneGenerator = null;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Releases resources we keep around during a "dialer session"
-     * (see {@link startDialerSession}).
-     *
-     * It's safe to call this even without a corresponding
-     * startDialerSession call.
-     */
-    public void stopDialerSession() {
-        // release the tone generator.
-        synchronized (mToneGeneratorLock) {
-            if (mToneGenerator != null) {
-                mToneGenerator.release();
-                mToneGenerator = null;
-            }
-        }
-
-        mHandler.removeMessages(DTMF_SEND_CNF);
-        synchronized (mDTMFQueue) {
-            mDTMFBurstCnfPending = false;
-            mDTMFQueue.clear();
-        }
-    }
-
-    /**
-     * Starts playback of the dtmf tone corresponding to the parameter.
-     */
-    public void playDtmfTone(char c, boolean timedShortTone) {
-        // Only play the tone if it exists.
-        if (!mToneMap.containsKey(c)) {
-            return;
-        }
-
-        if (!okToDialDtmfTones()) {
-            return;
-        }
-
-        PhoneGlobals.getInstance().pokeUserActivity();
-
-        // Read the settings as it may be changed by the user during the call
-        Phone phone = mCallManager.getFgPhone();
-
-        // Before we go ahead and start a tone, we need to make sure that any pending
-        // stop-tone message is processed.
-        if (mHandler.hasMessages(DTMF_STOP)) {
-            mHandler.removeMessages(DTMF_STOP);
-            stopDtmfTone();
-        }
-
-        mShortTone = useShortDtmfTones(phone, phone.getContext());
-        logD("startDtmfTone()...");
-
-        // For Short DTMF we need to play the local tone for fixed duration
-        if (mShortTone) {
-            sendShortDtmfToNetwork(c);
-        } else {
-            // Pass as a char to be sent to network
-            logD("send long dtmf for " + c);
-            mCallManager.startDtmf(c);
-
-            // If it is a timed tone, queue up the stop command in DTMF_DURATION_MS.
-            if (timedShortTone) {
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(DTMF_STOP), DTMF_DURATION_MS);
-            }
-        }
-
-        startLocalToneIfNeeded(c);
-    }
-
-    /**
-     * Sends the dtmf character over the network for short DTMF settings
-     * When the characters are entered in quick succession,
-     * the characters are queued before sending over the network.
-     */
-    private void sendShortDtmfToNetwork(char dtmfDigit) {
-        synchronized (mDTMFQueue) {
-            if (mDTMFBurstCnfPending == true) {
-                // Insert the dtmf char to the queue
-                mDTMFQueue.add(new Character(dtmfDigit));
-            } else {
-                String dtmfStr = Character.toString(dtmfDigit);
-                mCallManager.sendBurstDtmf(dtmfStr, 0, 0, mHandler.obtainMessage(DTMF_SEND_CNF));
-                // Set flag to indicate wait for Telephony confirmation.
-                mDTMFBurstCnfPending = true;
-            }
-        }
-    }
-
-    /**
-     * Handles Burst Dtmf Confirmation from the Framework.
-     */
-    void handleBurstDtmfConfirmation() {
-        Character dtmfChar = null;
-        synchronized (mDTMFQueue) {
-            mDTMFBurstCnfPending = false;
-            if (!mDTMFQueue.isEmpty()) {
-                dtmfChar = mDTMFQueue.remove();
-                Log.i(LOG_TAG, "The dtmf character removed from queue" + dtmfChar);
-            }
-        }
-        if (dtmfChar != null) {
-            sendShortDtmfToNetwork(dtmfChar);
-        }
-    }
-
-    public void stopDtmfTone() {
-        if (!mShortTone) {
-            mCallManager.stopDtmf();
-            stopLocalToneIfNeeded();
-        }
-    }
-
-    /**
-     * Plays the local tone based the phone type, optionally forcing a short
-     * tone.
-     */
-    private void startLocalToneIfNeeded(char c) {
-        if (mLocalToneEnabled) {
-            synchronized (mToneGeneratorLock) {
-                if (mToneGenerator == null) {
-                    logD("startDtmfTone: mToneGenerator == null, tone: " + c);
-                } else {
-                    logD("starting local tone " + c);
-                    int toneDuration = -1;
-                    if (mShortTone) {
-                        toneDuration = DTMF_DURATION_MS;
-                    }
-                    mToneGenerator.startTone(mToneMap.get(c), toneDuration);
-                }
-            }
-        }
-    }
-
-    /**
-     * Stops the local tone based on the phone type.
-     */
-    public void stopLocalToneIfNeeded() {
-        if (!mShortTone) {
-            // if local tone playback is enabled, stop it.
-            logD("trying to stop local tone...");
-            if (mLocalToneEnabled) {
-                synchronized (mToneGeneratorLock) {
-                    if (mToneGenerator == null) {
-                        logD("stopLocalTone: mToneGenerator == null");
-                    } else {
-                        logD("stopping local tone.");
-                        mToneGenerator.stopTone();
-                    }
-                }
-            }
-        }
-    }
-
-    private boolean okToDialDtmfTones() {
-        boolean hasActiveCall = false;
-        boolean hasIncomingCall = false;
-
-        final List<Call> calls = mCallModeler.getFullList();
-        final int len = calls.size();
-
-        for (int i = 0; i < len; i++) {
-            // We can also dial while in DIALING state because there are
-            // some connections that never update to an ACTIVE state (no
-            // indication from the network).
-            hasActiveCall |= (calls.get(i).getState() == Call.State.ACTIVE)
-                    || (calls.get(i).getState() == Call.State.DIALING);
-            hasIncomingCall |= (calls.get(i).getState() == Call.State.INCOMING);
-        }
-
-        return hasActiveCall && !hasIncomingCall;
-    }
-
-    /**
-     * On GSM devices, we never use short tones.
-     * On CDMA devices, it depends upon the settings.
-     */
-    private static boolean useShortDtmfTones(Phone phone, Context context) {
-        int phoneType = phone.getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_GSM
-                || phoneType == PhoneConstants.PHONE_TYPE_SIP
-                || phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY) {
-            return false;
-        } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            int toneType = android.provider.Settings.System.getInt(
-                    context.getContentResolver(),
-                    Settings.System.DTMF_TONE_TYPE_WHEN_DIALING,
-                    Constants.DTMF_TONE_TYPE_NORMAL);
-            if (toneType == Constants.DTMF_TONE_TYPE_NORMAL) {
-                return true;
-            } else {
-                return false;
-            }
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-    }
-
-    /**
-     * Checks to see if there are any active calls. If there are, then we want to allocate the tone
-     * resources for playing DTMF tone, otherwise release them.
-     */
-    private void checkCallState() {
-        logD("checkCallState");
-        if (mCallModeler.hasOutstandingActiveOrDialingCall()) {
-            startDialerSession();
-        } else {
-            stopDialerSession();
-        }
-    }
-
-    /**
-     * static logging method
-     */
-    private static void logD(String msg) {
-        if (DBG) {
-            Log.d(LOG_TAG, msg);
-        }
-    }
-}
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 7e26c0e..0c29bc9 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -148,9 +148,7 @@
     private AudioRouter audioRouter;
     private BluetoothManager bluetoothManager;
     private CallGatewayManager callGatewayManager;
-    private CallModeler callModeler;
     private CallStateMonitor callStateMonitor;
-    private DTMFTonePlayer dtmfTonePlayer;
     private IBluetoothHeadsetPhone mBluetoothPhone;
     private Ringer ringer;
     private WiredHeadsetManager wiredHeadsetManager;
@@ -436,18 +434,12 @@
             // Monitors call activity from the telephony layer
             callStateMonitor = new CallStateMonitor(mCM);
 
-            // Creates call models.
-            callModeler = new CallModeler(callStateMonitor, mCM, callGatewayManager);
-
-            // Plays DTMF Tones
-            dtmfTonePlayer = new DTMFTonePlayer(mCM, callModeler);
-
             // Manages wired headset state
             wiredHeadsetManager = new WiredHeadsetManager(this);
             wiredHeadsetManager.addWiredHeadsetListener(this);
 
             // Bluetooth manager
-            bluetoothManager = new BluetoothManager(this, mCM, callModeler);
+            bluetoothManager = new BluetoothManager();
 
             ringer = Ringer.init(this, bluetoothManager);
 
@@ -461,7 +453,7 @@
             // launching the incoming-call UI when an incoming call comes
             // in.)
             notifier = CallNotifier.init(this, phone, ringer, callLogger, callStateMonitor,
-                    bluetoothManager, callModeler);
+                    bluetoothManager);
 
             // register for ICC status
             IccCard sim = phone.getIccCard();
@@ -589,10 +581,6 @@
         return audioRouter;
     }
 
-    public CallModeler getCallModeler() {
-        return callModeler;
-    }
-
     /* package */ CallManager getCallManager() {
         return mCM;
     }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index c90d833..507cbcb 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -60,7 +60,6 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.util.HexDump;
-import com.android.services.telephony.common.Call;
 
 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
 
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 291789d..f446d36 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -629,7 +629,8 @@
             app.cdmaPhoneCallState.setCurrentCallState(
                 CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE);
 
-            app.getCallModeler().setCdmaOutgoing3WayCall(connection);
+            // TODO(sail): Remove this code.
+            //app.getCallModeler().setCdmaOutgoing3WayCall(connection);
         }
     }