diff --git a/src/com/android/server/telecom/AsyncResultCallback.java b/src/com/android/server/telecom/AsyncResultCallback.java
new file mode 100644
index 0000000..edbda3b
--- /dev/null
+++ b/src/com/android/server/telecom/AsyncResultCallback.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 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.server.telecom;
+
+/**
+ * Generic result interface for use with async method callback.
+ */
+interface AsyncResultCallback<T> {
+    void onResult(T result, int errorCode, String errorMsg);
+}
diff --git a/src/com/android/server/telecom/AsyncRingtonePlayer.java b/src/com/android/server/telecom/AsyncRingtonePlayer.java
new file mode 100644
index 0000000..ad57b00
--- /dev/null
+++ b/src/com/android/server/telecom/AsyncRingtonePlayer.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.provider.Settings;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Plays the default ringtone. Uses {@link Ringtone} in a separate thread so that this class can be
+ * used from the main thread.
+ */
+class AsyncRingtonePlayer {
+    // Message codes used with the ringtone thread.
+    static final int EVENT_PLAY = 1;
+    static final int EVENT_STOP = 2;
+
+    /** Handler running on the ringtone thread. */
+    private Handler mHandler;
+
+    /** The current ringtone. Only used by the ringtone thread. */
+    private Ringtone mRingtone;
+
+    /** Plays the ringtone. */
+    void play(Uri ringtone) {
+        Log.d(this, "Posting play.");
+        postMessage(EVENT_PLAY, true /* shouldCreateHandler */, ringtone);
+    }
+
+    /** Stops playing the ringtone. */
+    void stop() {
+        Log.d(this, "Posting stop.");
+        postMessage(EVENT_STOP, false /* shouldCreateHandler */, null);
+    }
+
+    /**
+     * Posts a message to the ringtone-thread handler. Creates the handler if specified by the
+     * parameter shouldCreateHandler.
+     *
+     * @param messageCode The message to post.
+     * @param shouldCreateHandler True when a handler should be created to handle this message.
+     */
+    private void postMessage(int messageCode, boolean shouldCreateHandler, Uri ringtone) {
+        synchronized(this) {
+            if (mHandler == null && shouldCreateHandler) {
+                mHandler = getNewHandler();
+            }
+
+            if (mHandler == null) {
+                Log.d(this, "Message %d skipped because there is no handler.", messageCode);
+            } else {
+                mHandler.obtainMessage(messageCode, ringtone).sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * Creates a new ringtone Handler running in its own thread.
+     */
+    private Handler getNewHandler() {
+        Preconditions.checkState(mHandler == null);
+
+        HandlerThread thread = new HandlerThread("ringtone-player");
+        thread.start();
+
+        return new Handler(thread.getLooper()) {
+            @Override
+            public void handleMessage(Message msg) {
+                switch(msg.what) {
+                    case EVENT_PLAY:
+                        handlePlay((Uri) msg.obj);
+                        break;
+                    case EVENT_STOP:
+                        handleStop();
+                        break;
+                }
+            }
+        };
+    }
+
+    /**
+     * Starts the actual playback of the ringtone. Executes on ringtone-thread.
+     */
+    private void handlePlay(Uri ringtoneUri) {
+        ThreadUtil.checkNotOnMainThread();
+        Log.i(this, "Play ringtone.");
+
+        if (mRingtone == null) {
+            mRingtone = getRingtone(ringtoneUri);
+
+            // Cancel everything if there is no ringtone.
+            if (mRingtone == null) {
+                handleStop();
+                return;
+            }
+        }
+
+        if (mRingtone.isPlaying()) {
+            Log.d(this, "Ringtone already playing.");
+        } else {
+            mRingtone.play();
+            Log.d(this, "Ringtone.play() invoked.");
+        }
+    }
+
+    /**
+     * Stops the playback of the ringtone. Executes on the ringtone-thread.
+     */
+    private void handleStop() {
+        ThreadUtil.checkNotOnMainThread();
+        Log.i(this, "Stop ringtone.");
+
+        if (mRingtone != null) {
+            Log.d(this, "Ringtone.stop() invoked.");
+            mRingtone.stop();
+            mRingtone = null;
+        }
+
+        synchronized(this) {
+            if (mHandler.hasMessages(EVENT_PLAY)) {
+                Log.v(this, "Keeping alive ringtone thread for pending messages.");
+            } else {
+                mHandler.removeMessages(EVENT_STOP);
+                mHandler.getLooper().quitSafely();
+                mHandler = null;
+                Log.v(this, "Handler cleared.");
+            }
+        }
+    }
+
+    private Ringtone getRingtone(Uri ringtoneUri) {
+        if (ringtoneUri == null) {
+            ringtoneUri = Settings.System.DEFAULT_RINGTONE_URI;
+        }
+
+        Ringtone ringtone = RingtoneManager.getRingtone(TelecomApp.getInstance(), ringtoneUri);
+        ringtone.setStreamType(AudioManager.STREAM_RING);
+        return ringtone;
+    }
+}
diff --git a/src/com/android/server/telecom/BluetoothManager.java b/src/com/android/server/telecom/BluetoothManager.java
new file mode 100644
index 0000000..9b5fd26
--- /dev/null
+++ b/src/com/android/server/telecom/BluetoothManager.java
@@ -0,0 +1,273 @@
+/*
+ * 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.server.telecom;
+
+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 java.util.List;
+
+/**
+ * Listens to and caches bluetooth headset state.  Used By the CallAudioManager for maintaining
+ * overall audio state. Also provides method for connecting the bluetooth headset to the phone call.
+ */
+public class BluetoothManager {
+
+    private final BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
+            new BluetoothProfile.ServiceListener() {
+                @Override
+                public void onServiceConnected(int profile, BluetoothProfile proxy) {
+                    mBluetoothHeadset = (BluetoothHeadset) proxy;
+                    Log.v(this, "- Got BluetoothHeadset: " + mBluetoothHeadset);
+                }
+
+                @Override
+                public void onServiceDisconnected(int profile) {
+                    mBluetoothHeadset = null;
+                }
+           };
+
+    /**
+     * Receiver for misc intent broadcasts the BluetoothManager cares about.
+     */
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+
+            if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
+                int bluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
+                                                          BluetoothHeadset.STATE_DISCONNECTED);
+                Log.d(this, "mReceiver: HEADSET_STATE_CHANGED_ACTION");
+                Log.d(this, "==> new state: %s ", bluetoothHeadsetState);
+                updateBluetoothState();
+            } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
+                int bluetoothHeadsetAudioState =
+                        intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
+                                           BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
+                Log.d(this, "mReceiver: HEADSET_AUDIO_STATE_CHANGED_ACTION");
+                Log.d(this, "==> new state: %s", bluetoothHeadsetAudioState);
+                updateBluetoothState();
+            }
+        }
+    };
+
+    private final BluetoothAdapter mBluetoothAdapter;
+    private final CallAudioManager mCallAudioManager;
+
+    private BluetoothHeadset mBluetoothHeadset;
+    private boolean mBluetoothConnectionPending = false;
+    private long mBluetoothConnectionRequestTime;
+
+
+    public BluetoothManager(Context context, CallAudioManager callAudioManager) {
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        mCallAudioManager = callAudioManager;
+
+        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);
+    }
+
+    //
+    // 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.)
+     */
+    boolean isBluetoothAvailable() {
+        Log.v(this, "isBluetoothAvailable()...");
+
+        // There's no need to ask the Bluetooth system service if BT is enabled:
+        //
+        //    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        //    if ((adapter == null) || !adapter.isEnabled()) {
+        //        Log.d(this, "  ==> FALSE (BT not enabled)");
+        //        return false;
+        //    }
+        //    Log.d(this, "  - 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) {
+                isConnected = true;
+                for (int i = 0; i < deviceList.size(); i++) {
+                    BluetoothDevice device = deviceList.get(i);
+                    Log.v(this, "state = " + mBluetoothHeadset.getConnectionState(device)
+                            + "for headset: " + device);
+                }
+            }
+        }
+
+        Log.v(this, "  ==> " + isConnected);
+        return isConnected;
+    }
+
+    /**
+     * @return true if a BT Headset is available, and its audio is currently connected.
+     */
+    boolean isBluetoothAudioConnected() {
+        if (mBluetoothHeadset == null) {
+            Log.v(this, "isBluetoothAudioConnected: ==> FALSE (null mBluetoothHeadset)");
+            return false;
+        }
+        List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
+
+        if (deviceList.isEmpty()) {
+            return false;
+        }
+        for (int i = 0; i < deviceList.size(); i++) {
+            BluetoothDevice device = deviceList.get(i);
+            boolean isAudioOn = mBluetoothHeadset.isAudioConnected(device);
+            Log.v(this, "isBluetoothAudioConnected: ==> isAudioOn = " + isAudioOn
+                    + "for headset: " + device);
+            if (isAudioOn) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Helper method used to control the onscreen "Bluetooth" indication;
+     *
+     * @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()) {
+            Log.v(this, "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 */) {
+                Log.v(this, "isBluetoothAudioConnectedOrPending: ==> TRUE (requested "
+                             + timeSinceRequest + " msec ago)");
+                return true;
+            } else {
+                Log.v(this, "isBluetoothAudioConnectedOrPending: ==> FALSE (request too old: "
+                             + timeSinceRequest + " msec ago)");
+                mBluetoothConnectionPending = false;
+                return false;
+            }
+        }
+
+        Log.v(this, "isBluetoothAudioConnectedOrPending: ==> FALSE");
+        return false;
+    }
+
+    /**
+     * Notified audio manager of a change to the bluetooth state.
+     */
+    void updateBluetoothState() {
+        mCallAudioManager.onBluetoothStateChange(this);
+    }
+
+    void connectBluetoothAudio() {
+        Log.v(this, "connectBluetoothAudio()...");
+        if (mBluetoothHeadset != null) {
+            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();
+    }
+
+    void disconnectBluetoothAudio() {
+        Log.v(this, "disconnectBluetoothAudio()...");
+        if (mBluetoothHeadset != null) {
+            mBluetoothHeadset.disconnectAudio();
+        }
+        mBluetoothConnectionPending = false;
+    }
+
+    private void dumpBluetoothState() {
+        Log.d(this, "============== dumpBluetoothState() =============");
+        Log.d(this, "= isBluetoothAvailable: " + isBluetoothAvailable());
+        Log.d(this, "= isBluetoothAudioConnected: " + isBluetoothAudioConnected());
+        Log.d(this, "= isBluetoothAudioConnectedOrPending: " +
+                isBluetoothAudioConnectedOrPending());
+        Log.d(this, "=");
+        if (mBluetoothAdapter != null) {
+            if (mBluetoothHeadset != null) {
+                List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
+
+                if (deviceList.size() > 0) {
+                    BluetoothDevice device = deviceList.get(0);
+                    Log.d(this, "= BluetoothHeadset.getCurrentDevice: " + device);
+                    Log.d(this, "= BluetoothHeadset.State: "
+                        + mBluetoothHeadset.getConnectionState(device));
+                    Log.d(this, "= BluetoothHeadset audio connected: " +
+                        mBluetoothHeadset.isAudioConnected(device));
+                }
+            } else {
+                Log.d(this, "= mBluetoothHeadset is null");
+            }
+        } else {
+            Log.d(this, "= mBluetoothAdapter is null; device is not BT capable");
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
new file mode 100644
index 0000000..6f7177b
--- /dev/null
+++ b/src/com/android/server/telecom/Call.java
@@ -0,0 +1,1232 @@
+/*
+ * 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.server.telecom;
+
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.ContactsContract.Contacts;
+import android.telecom.CallState;
+import android.telecom.Connection;
+import android.telecom.GatewayInfo;
+import android.telecom.ParcelableConnection;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.PhoneCapabilities;
+import android.telecom.Response;
+import android.telecom.StatusHints;
+import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
+import android.telephony.DisconnectCause;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+
+import com.android.internal.telecom.IVideoProvider;
+import com.android.internal.telephony.CallerInfo;
+import com.android.internal.telephony.CallerInfoAsyncQuery;
+import com.android.internal.telephony.CallerInfoAsyncQuery.OnQueryCompleteListener;
+import com.android.internal.telephony.SmsApplication;
+import com.android.server.telecom.ContactsAsyncHelper.OnImageLoadCompleteListener;
+
+import com.google.common.base.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ *  Encapsulates all aspects of a given phone call throughout its lifecycle, starting
+ *  from the time the call intent was received by Telecom (vs. the time the call was
+ *  connected etc).
+ */
+final class Call implements CreateConnectionResponse {
+    /**
+     * Listener for events on the call.
+     */
+    interface Listener {
+        void onSuccessfulOutgoingCall(Call call, int callState);
+        void onFailedOutgoingCall(Call call, int errorCode, String errorMsg);
+        void onSuccessfulIncomingCall(Call call);
+        void onFailedIncomingCall(Call call);
+        void onRingbackRequested(Call call, boolean ringbackRequested);
+        void onPostDialWait(Call call, String remaining);
+        void onCallCapabilitiesChanged(Call call);
+        void onParentChanged(Call call);
+        void onChildrenChanged(Call call);
+        void onCannedSmsResponsesLoaded(Call call);
+        void onVideoCallProviderChanged(Call call);
+        void onCallerInfoChanged(Call call);
+        void onIsVoipAudioModeChanged(Call call);
+        void onStatusHintsChanged(Call call);
+        void onHandleChanged(Call call);
+        void onCallerDisplayNameChanged(Call call);
+        void onVideoStateChanged(Call call);
+        void onTargetPhoneAccountChanged(Call call);
+        void onConnectionManagerPhoneAccountChanged(Call call);
+        void onPhoneAccountChanged(Call call);
+        void onConferenceableCallsChanged(Call call);
+    }
+
+    abstract static class ListenerBase implements Listener {
+        @Override
+        public void onSuccessfulOutgoingCall(Call call, int callState) {}
+        @Override
+        public void onFailedOutgoingCall(Call call, int errorCode, String errorMsg) {}
+        @Override
+        public void onSuccessfulIncomingCall(Call call) {}
+        @Override
+        public void onFailedIncomingCall(Call call) {}
+        @Override
+        public void onRingbackRequested(Call call, boolean ringbackRequested) {}
+        @Override
+        public void onPostDialWait(Call call, String remaining) {}
+        @Override
+        public void onCallCapabilitiesChanged(Call call) {}
+        @Override
+        public void onParentChanged(Call call) {}
+        @Override
+        public void onChildrenChanged(Call call) {}
+        @Override
+        public void onCannedSmsResponsesLoaded(Call call) {}
+        @Override
+        public void onVideoCallProviderChanged(Call call) {}
+        @Override
+        public void onCallerInfoChanged(Call call) {}
+        @Override
+        public void onIsVoipAudioModeChanged(Call call) {}
+        @Override
+        public void onStatusHintsChanged(Call call) {}
+        @Override
+        public void onHandleChanged(Call call) {}
+        @Override
+        public void onCallerDisplayNameChanged(Call call) {}
+        @Override
+        public void onVideoStateChanged(Call call) {}
+        @Override
+        public void onTargetPhoneAccountChanged(Call call) {}
+        @Override
+        public void onConnectionManagerPhoneAccountChanged(Call call) {}
+        @Override
+        public void onPhoneAccountChanged(Call call) {}
+        @Override
+        public void onConferenceableCallsChanged(Call call) {}
+    }
+
+    private static final OnQueryCompleteListener sCallerInfoQueryListener =
+            new OnQueryCompleteListener() {
+                /** ${inheritDoc} */
+                @Override
+                public void onQueryComplete(int token, Object cookie, CallerInfo callerInfo) {
+                    if (cookie != null) {
+                        ((Call) cookie).setCallerInfo(callerInfo, token);
+                    }
+                }
+            };
+
+    private static final OnImageLoadCompleteListener sPhotoLoadListener =
+            new OnImageLoadCompleteListener() {
+                /** ${inheritDoc} */
+                @Override
+                public void onImageLoadComplete(
+                        int token, Drawable photo, Bitmap photoIcon, Object cookie) {
+                    if (cookie != null) {
+                        ((Call) cookie).setPhoto(photo, photoIcon, token);
+                    }
+                }
+            };
+
+    private final Runnable mDirectToVoicemailRunnable = new Runnable() {
+        @Override
+        public void run() {
+            processDirectToVoicemail();
+        }
+    };
+
+    /** True if this is an incoming call. */
+    private final boolean mIsIncoming;
+
+    /**
+     * The time this call was created. Beyond logging and such, may also be used for bookkeeping
+     * and specifically for marking certain call attempts as failed attempts.
+     */
+    private final long mCreationTimeMillis = System.currentTimeMillis();
+
+    /** The gateway information associated with this call. This stores the original call handle
+     * that the user is attempting to connect to via the gateway, the actual handle to dial in
+     * order to connect the call via the gateway, as well as the package name of the gateway
+     * service. */
+    private GatewayInfo mGatewayInfo;
+
+    private PhoneAccountHandle mConnectionManagerPhoneAccountHandle;
+
+    private PhoneAccountHandle mTargetPhoneAccountHandle;
+
+    private final Handler mHandler = new Handler();
+
+    private final List<Call> mConferenceableCalls = new ArrayList<>();
+
+    private PhoneAccountHandle mPhoneAccountHandle;
+
+    private long mConnectTimeMillis = 0;
+
+    /** The state of the call. */
+    private int mState;
+
+    /** The handle with which to establish this call. */
+    private Uri mHandle;
+
+    /**
+     * The presentation requirements for the handle. See {@link TelecomManager} for valid values.
+     */
+    private int mHandlePresentation;
+
+    /** The caller display name (CNAP) set by the connection service. */
+    private String mCallerDisplayName;
+
+    /**
+     * The presentation requirements for the handle. See {@link TelecomManager} for valid values.
+     */
+    private int mCallerDisplayNamePresentation;
+
+    /**
+     * The connection service which is attempted or already connecting this call.
+     */
+    private ConnectionServiceWrapper mConnectionService;
+
+    private boolean mIsEmergencyCall;
+
+    private boolean mSpeakerphoneOn;
+
+    /**
+     * Tracks the video states which were applicable over the duration of a call.
+     * See {@link VideoProfile} for a list of valid video states.
+     */
+    private int mVideoStateHistory;
+
+    private int mVideoState;
+
+    /**
+     * Disconnect cause for the call. Only valid if the state of the call is STATE_DISCONNECTED.
+     * See {@link android.telephony.DisconnectCause}.
+     */
+    private int mDisconnectCause = DisconnectCause.NOT_VALID;
+
+    /**
+     * Additional disconnect information provided by the connection service.
+     */
+    private String mDisconnectMessage;
+
+    /** Info used by the connection services. */
+    private Bundle mExtras = Bundle.EMPTY;
+
+    /** Set of listeners on this call.
+     *
+     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
+     * load factor before resizing, 1 means we only expect a single thread to
+     * access the map so make only a single shard
+     */
+    private final Set<Listener> mListeners = Collections.newSetFromMap(
+            new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
+
+    private CreateConnectionProcessor mCreateConnectionProcessor;
+
+    /** Caller information retrieved from the latest contact query. */
+    private CallerInfo mCallerInfo;
+
+    /** The latest token used with a contact info query. */
+    private int mQueryToken = 0;
+
+    /** Whether this call is requesting that Telecom play the ringback tone on its behalf. */
+    private boolean mRingbackRequested = false;
+
+    /** Whether direct-to-voicemail query is pending. */
+    private boolean mDirectToVoicemailQueryPending;
+
+    private int mCallCapabilities;
+
+    private boolean mIsConference = false;
+
+    private Call mParentCall = null;
+
+    private List<Call> mChildCalls = new LinkedList<>();
+
+    /** Set of text message responses allowed for this call, if applicable. */
+    private List<String> mCannedSmsResponses = Collections.EMPTY_LIST;
+
+    /** Whether an attempt has been made to load the text message responses. */
+    private boolean mCannedSmsResponsesLoadingStarted = false;
+
+    private IVideoProvider mVideoProvider;
+
+    private boolean mIsVoipAudioMode;
+    private StatusHints mStatusHints;
+    private final ConnectionServiceRepository mRepository;
+
+    /**
+     * Persists the specified parameters and initializes the new instance.
+     *
+     * @param handle The handle to dial.
+     * @param gatewayInfo Gateway information to use for the call.
+     * @param connectionManagerPhoneAccountHandle Account to use for the service managing the call.
+     *         This account must be one that was registered with the
+     *         {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag.
+     * @param targetPhoneAccountHandle Account information to use for the call. This account must be
+     *         one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag.
+     * @param isIncoming True if this is an incoming call.
+     */
+    Call(
+            ConnectionServiceRepository repository,
+            Uri handle,
+            GatewayInfo gatewayInfo,
+            PhoneAccountHandle connectionManagerPhoneAccountHandle,
+            PhoneAccountHandle targetPhoneAccountHandle,
+            boolean isIncoming,
+            boolean isConference) {
+        mState = isConference ? CallState.ACTIVE : CallState.NEW;
+        mRepository = repository;
+        setHandle(handle);
+        setHandle(handle, TelecomManager.PRESENTATION_ALLOWED);
+        mGatewayInfo = gatewayInfo;
+        mConnectionManagerPhoneAccountHandle = connectionManagerPhoneAccountHandle;
+        mTargetPhoneAccountHandle = targetPhoneAccountHandle;
+        mIsIncoming = isIncoming;
+        mIsConference = isConference;
+        maybeLoadCannedSmsResponses();
+    }
+
+    void addListener(Listener listener) {
+        mListeners.add(listener);
+    }
+
+    void removeListener(Listener listener) {
+        if (listener != null) {
+            mListeners.remove(listener);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        String component = null;
+        if (mConnectionService != null && mConnectionService.getComponentName() != null) {
+            component = mConnectionService.getComponentName().flattenToShortString();
+        }
+
+        return String.format(Locale.US, "[%s, %s, %s, %s, %d]", System.identityHashCode(this),
+                mState, component, Log.piiHandle(mHandle), getVideoState());
+    }
+
+    int getState() {
+        return mState;
+    }
+
+    /**
+     * Sets the call state. Although there exists the notion of appropriate state transitions
+     * (see {@link CallState}), in practice those expectations break down when cellular systems
+     * misbehave and they do this very often. The result is that we do not enforce state transitions
+     * and instead keep the code resilient to unexpected state changes.
+     */
+    void setState(int newState) {
+        if (mState != newState) {
+            Log.v(this, "setState %s -> %s", mState, newState);
+            mState = newState;
+            maybeLoadCannedSmsResponses();
+
+            if (mState == CallState.DISCONNECTED) {
+                fixParentAfterDisconnect();
+            }
+        }
+    }
+
+    void setRingbackRequested(boolean ringbackRequested) {
+        mRingbackRequested = ringbackRequested;
+        for (Listener l : mListeners) {
+            l.onRingbackRequested(this, mRingbackRequested);
+        }
+    }
+
+    boolean isRingbackRequested() {
+        return mRingbackRequested;
+    }
+
+    boolean isConference() {
+        return mIsConference;
+    }
+
+    Uri getHandle() {
+        return mHandle;
+    }
+
+    int getHandlePresentation() {
+        return mHandlePresentation;
+    }
+
+
+    void setHandle(Uri handle) {
+        setHandle(handle, TelecomManager.PRESENTATION_ALLOWED);
+    }
+
+    void setHandle(Uri handle, int presentation) {
+        if (!Objects.equals(handle, mHandle) || presentation != mHandlePresentation) {
+            mHandle = handle;
+            mHandlePresentation = presentation;
+            mIsEmergencyCall = mHandle != null && PhoneNumberUtils.isLocalEmergencyNumber(
+                    TelecomApp.getInstance(), mHandle.getSchemeSpecificPart());
+            startCallerInfoLookup();
+            for (Listener l : mListeners) {
+                l.onHandleChanged(this);
+            }
+        }
+    }
+
+    String getCallerDisplayName() {
+        return mCallerDisplayName;
+    }
+
+    int getCallerDisplayNamePresentation() {
+        return mCallerDisplayNamePresentation;
+    }
+
+    void setCallerDisplayName(String callerDisplayName, int presentation) {
+        if (!TextUtils.equals(callerDisplayName, mCallerDisplayName) ||
+                presentation != mCallerDisplayNamePresentation) {
+            mCallerDisplayName = callerDisplayName;
+            mCallerDisplayNamePresentation = presentation;
+            for (Listener l : mListeners) {
+                l.onCallerDisplayNameChanged(this);
+            }
+        }
+    }
+
+    String getName() {
+        return mCallerInfo == null ? null : mCallerInfo.name;
+    }
+
+    Bitmap getPhotoIcon() {
+        return mCallerInfo == null ? null : mCallerInfo.cachedPhotoIcon;
+    }
+
+    Drawable getPhoto() {
+        return mCallerInfo == null ? null : mCallerInfo.cachedPhoto;
+    }
+
+    /**
+     * @param disconnectCause The reason for the disconnection, any of
+     *         {@link android.telephony.DisconnectCause}.
+     * @param disconnectMessage Optional message about the disconnect.
+     */
+    void setDisconnectCause(int disconnectCause, String disconnectMessage) {
+        // TODO: Consider combining this method with a setDisconnected() method that is totally
+        // separate from setState.
+        mDisconnectCause = disconnectCause;
+        mDisconnectMessage = disconnectMessage;
+    }
+
+    int getDisconnectCause() {
+        return mDisconnectCause;
+    }
+
+    String getDisconnectMessage() {
+        return mDisconnectMessage;
+    }
+
+    boolean isEmergencyCall() {
+        return mIsEmergencyCall;
+    }
+
+    /**
+     * @return The original handle this call is associated with. In-call services should use this
+     * handle when indicating in their UI the handle that is being called.
+     */
+    public Uri getOriginalHandle() {
+        if (mGatewayInfo != null && !mGatewayInfo.isEmpty()) {
+            return mGatewayInfo.getOriginalAddress();
+        }
+        return getHandle();
+    }
+
+    GatewayInfo getGatewayInfo() {
+        return mGatewayInfo;
+    }
+
+    void setGatewayInfo(GatewayInfo gatewayInfo) {
+        mGatewayInfo = gatewayInfo;
+    }
+
+    PhoneAccountHandle getConnectionManagerPhoneAccount() {
+        return mConnectionManagerPhoneAccountHandle;
+    }
+
+    void setConnectionManagerPhoneAccount(PhoneAccountHandle accountHandle) {
+        if (!Objects.equals(mConnectionManagerPhoneAccountHandle, accountHandle)) {
+            mConnectionManagerPhoneAccountHandle = accountHandle;
+            for (Listener l : mListeners) {
+                l.onConnectionManagerPhoneAccountChanged(this);
+            }
+        }
+
+    }
+
+    PhoneAccountHandle getTargetPhoneAccount() {
+        return mTargetPhoneAccountHandle;
+    }
+
+    void setTargetPhoneAccount(PhoneAccountHandle accountHandle) {
+        if (!Objects.equals(mTargetPhoneAccountHandle, accountHandle)) {
+            mTargetPhoneAccountHandle = accountHandle;
+            for (Listener l : mListeners) {
+                l.onTargetPhoneAccountChanged(this);
+            }
+        }
+    }
+
+    boolean isIncoming() {
+        return mIsIncoming;
+    }
+
+    /**
+     * @return The "age" of this call object in milliseconds, which typically also represents the
+     *     period since this call was added to the set pending outgoing calls, see
+     *     mCreationTimeMillis.
+     */
+    long getAgeMillis() {
+        return System.currentTimeMillis() - mCreationTimeMillis;
+    }
+
+    /**
+     * @return The time when this call object was created and added to the set of pending outgoing
+     *     calls.
+     */
+    long getCreationTimeMillis() {
+        return mCreationTimeMillis;
+    }
+
+    long getConnectTimeMillis() {
+        return mConnectTimeMillis;
+    }
+
+    void setConnectTimeMillis(long connectTimeMillis) {
+        mConnectTimeMillis = connectTimeMillis;
+    }
+
+    int getCallCapabilities() {
+        return mCallCapabilities;
+    }
+
+    void setCallCapabilities(int callCapabilities) {
+        Log.v(this, "setCallCapabilities: %s", PhoneCapabilities.toString(callCapabilities));
+        if (mCallCapabilities != callCapabilities) {
+           mCallCapabilities = callCapabilities;
+            for (Listener l : mListeners) {
+                l.onCallCapabilitiesChanged(this);
+            }
+        }
+    }
+
+    Call getParentCall() {
+        return mParentCall;
+    }
+
+    List<Call> getChildCalls() {
+        return mChildCalls;
+    }
+
+    ConnectionServiceWrapper getConnectionService() {
+        return mConnectionService;
+    }
+
+    void setConnectionService(ConnectionServiceWrapper service) {
+        Preconditions.checkNotNull(service);
+
+        clearConnectionService();
+
+        service.incrementAssociatedCallCount();
+        mConnectionService = service;
+        mConnectionService.addCall(this);
+    }
+
+    /**
+     * Clears the associated connection service.
+     */
+    void clearConnectionService() {
+        if (mConnectionService != null) {
+            ConnectionServiceWrapper serviceTemp = mConnectionService;
+            mConnectionService = null;
+            serviceTemp.removeCall(this);
+
+            // Decrementing the count can cause the service to unbind, which itself can trigger the
+            // service-death code.  Since the service death code tries to clean up any associated
+            // calls, we need to make sure to remove that information (e.g., removeCall()) before
+            // we decrement. Technically, invoking removeCall() prior to decrementing is all that is
+            // necessary, but cleaning up mConnectionService prior to triggering an unbind is good
+            // to do.
+            decrementAssociatedCallCount(serviceTemp);
+        }
+    }
+
+    private void processDirectToVoicemail() {
+        if (mDirectToVoicemailQueryPending) {
+            if (mCallerInfo != null && mCallerInfo.shouldSendToVoicemail) {
+                Log.i(this, "Directing call to voicemail: %s.", this);
+                // TODO: Once we move State handling from CallsManager to Call, we
+                // will not need to set STATE_RINGING state prior to calling reject.
+                setState(CallState.RINGING);
+                reject(false, null);
+            } else {
+                // TODO: Make this class (not CallsManager) responsible for changing
+                // the call state to STATE_RINGING.
+
+                // TODO: Replace this with state transition to STATE_RINGING.
+                for (Listener l : mListeners) {
+                    l.onSuccessfulIncomingCall(this);
+                }
+            }
+
+            mDirectToVoicemailQueryPending = false;
+        }
+    }
+
+    /**
+     * Starts the create connection sequence. Upon completion, there should exist an active
+     * connection through a connection service (or the call will have failed).
+     */
+    void startCreateConnection() {
+        Preconditions.checkState(mCreateConnectionProcessor == null);
+        mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this);
+        mCreateConnectionProcessor.process();
+    }
+
+    @Override
+    public void handleCreateConnectionSuccess(
+            CallIdMapper idMapper,
+            ParcelableConnection connection) {
+        Log.v(this, "handleCreateConnectionSuccessful %s", connection);
+        mCreateConnectionProcessor = null;
+        setTargetPhoneAccount(connection.getPhoneAccount());
+        setHandle(connection.getHandle(), connection.getHandlePresentation());
+        setCallerDisplayName(
+                connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation());
+        setCallCapabilities(connection.getCapabilities());
+        setVideoProvider(connection.getVideoProvider());
+        setVideoState(connection.getVideoState());
+        setRingbackRequested(connection.isRingbackRequested());
+        setIsVoipAudioMode(connection.getIsVoipAudioMode());
+        setStatusHints(connection.getStatusHints());
+
+        mConferenceableCalls.clear();
+        for (String id : connection.getConferenceableConnectionIds()) {
+            mConferenceableCalls.add(idMapper.getCall(id));
+        }
+
+        if (mIsIncoming) {
+            // We do not handle incoming calls immediately when they are verified by the connection
+            // service. We allow the caller-info-query code to execute first so that we can read the
+            // direct-to-voicemail property before deciding if we want to show the incoming call to
+            // the user or if we want to reject the call.
+            mDirectToVoicemailQueryPending = true;
+
+            // Timeout the direct-to-voicemail lookup execution so that we dont wait too long before
+            // showing the user the incoming call screen.
+            mHandler.postDelayed(mDirectToVoicemailRunnable, Timeouts.getDirectToVoicemailMillis());
+        } else {
+            for (Listener l : mListeners) {
+                l.onSuccessfulOutgoingCall(this,
+                        getStateFromConnectionState(connection.getState()));
+            }
+        }
+    }
+
+    @Override
+    public void handleCreateConnectionFailure(int code, String msg) {
+        mCreateConnectionProcessor = null;
+        clearConnectionService();
+        setDisconnectCause(code, msg);
+        CallsManager.getInstance().markCallAsDisconnected(this, code, msg);
+
+        if (mIsIncoming) {
+            for (Listener listener : mListeners) {
+                listener.onFailedIncomingCall(this);
+            }
+        } else {
+            for (Listener listener : mListeners) {
+                listener.onFailedOutgoingCall(this, code, msg);
+            }
+        }
+    }
+
+    /**
+     * Plays the specified DTMF tone.
+     */
+    void playDtmfTone(char digit) {
+        if (mConnectionService == null) {
+            Log.w(this, "playDtmfTone() request on a call without a connection service.");
+        } else {
+            Log.i(this, "Send playDtmfTone to connection service for call %s", this);
+            mConnectionService.playDtmfTone(this, digit);
+        }
+    }
+
+    /**
+     * Stops playing any currently playing DTMF tone.
+     */
+    void stopDtmfTone() {
+        if (mConnectionService == null) {
+            Log.w(this, "stopDtmfTone() request on a call without a connection service.");
+        } else {
+            Log.i(this, "Send stopDtmfTone to connection service for call %s", this);
+            mConnectionService.stopDtmfTone(this);
+        }
+    }
+
+    /**
+     * Attempts to disconnect the call through the connection service.
+     */
+    void disconnect() {
+        if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT ||
+                mState == CallState.CONNECTING) {
+            Log.v(this, "Aborting call %s", this);
+            abort();
+        } else if (mState != CallState.ABORTED && mState != CallState.DISCONNECTED) {
+            if (mConnectionService == null) {
+                Log.e(this, new Exception(), "disconnect() request on a call without a"
+                        + " connection service.");
+            } else {
+                Log.i(this, "Send disconnect to connection service for call: %s", this);
+                // The call isn't officially disconnected until the connection service
+                // confirms that the call was actually disconnected. Only then is the
+                // association between call and connection service severed, see
+                // {@link CallsManager#markCallAsDisconnected}.
+                mConnectionService.disconnect(this);
+            }
+        }
+    }
+
+    void abort() {
+        if (mCreateConnectionProcessor != null) {
+            mCreateConnectionProcessor.abort();
+        } else if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT
+                || mState == CallState.CONNECTING) {
+            handleCreateConnectionFailure(DisconnectCause.OUTGOING_CANCELED, null);
+        } else {
+            Log.v(this, "Cannot abort a call which isn't either PRE_DIAL_WAIT or CONNECTING");
+        }
+    }
+
+    /**
+     * Answers the call if it is ringing.
+     *
+     * @param videoState The video state in which to answer the call.
+     */
+    void answer(int videoState) {
+        Preconditions.checkNotNull(mConnectionService);
+
+        // Check to verify that the call is still in the ringing state. A call can change states
+        // between the time the user hits 'answer' and Telecom receives the command.
+        if (isRinging("answer")) {
+            // At this point, we are asking the connection service to answer but we don't assume
+            // that it will work. Instead, we wait until confirmation from the connectino service
+            // that the call is in a non-STATE_RINGING state before changing the UI. See
+            // {@link ConnectionServiceAdapter#setActive} and other set* methods.
+            mConnectionService.answer(this, videoState);
+        }
+    }
+
+    /**
+     * Rejects the call if it is ringing.
+     *
+     * @param rejectWithMessage Whether to send a text message as part of the call rejection.
+     * @param textMessage An optional text message to send as part of the rejection.
+     */
+    void reject(boolean rejectWithMessage, String textMessage) {
+        Preconditions.checkNotNull(mConnectionService);
+
+        // Check to verify that the call is still in the ringing state. A call can change states
+        // between the time the user hits 'reject' and Telecomm receives the command.
+        if (isRinging("reject")) {
+            mConnectionService.reject(this);
+        }
+    }
+
+    /**
+     * Puts the call on hold if it is currently active.
+     */
+    void hold() {
+        Preconditions.checkNotNull(mConnectionService);
+
+        if (mState == CallState.ACTIVE) {
+            mConnectionService.hold(this);
+        }
+    }
+
+    /**
+     * Releases the call from hold if it is currently active.
+     */
+    void unhold() {
+        Preconditions.checkNotNull(mConnectionService);
+
+        if (mState == CallState.ON_HOLD) {
+            mConnectionService.unhold(this);
+        }
+    }
+
+    /** Checks if this is a live call or not. */
+    boolean isAlive() {
+        switch (mState) {
+            case CallState.NEW:
+            case CallState.RINGING:
+            case CallState.DISCONNECTED:
+            case CallState.ABORTED:
+                return false;
+            default:
+                return true;
+        }
+    }
+
+    boolean isActive() {
+        return mState == CallState.ACTIVE;
+    }
+
+    Bundle getExtras() {
+        return mExtras;
+    }
+
+    void setExtras(Bundle extras) {
+        mExtras = extras;
+    }
+
+    /**
+     * @return the uri of the contact associated with this call.
+     */
+    Uri getContactUri() {
+        if (mCallerInfo == null || !mCallerInfo.contactExists) {
+            return null;
+        }
+        return Contacts.getLookupUri(mCallerInfo.contactIdOrZero, mCallerInfo.lookupKey);
+    }
+
+    Uri getRingtone() {
+        return mCallerInfo == null ? null : mCallerInfo.contactRingtoneUri;
+    }
+
+    void onPostDialWait(String remaining) {
+        for (Listener l : mListeners) {
+            l.onPostDialWait(this, remaining);
+        }
+    }
+
+    void postDialContinue(boolean proceed) {
+        mConnectionService.onPostDialContinue(this, proceed);
+    }
+
+    void conferenceWith(Call otherCall) {
+        if (mConnectionService == null) {
+            Log.w(this, "conference requested on a call without a connection service.");
+        } else {
+            mConnectionService.conference(this, otherCall);
+        }
+    }
+
+    void splitFromConference() {
+        if (mConnectionService == null) {
+            Log.w(this, "splitting from conference call without a connection service");
+        } else {
+            mConnectionService.splitFromConference(this);
+        }
+    }
+
+    void mergeConference() {
+        if (mConnectionService == null) {
+            Log.w(this, "merging conference calls without a connection service.");
+        } else if (can(PhoneCapabilities.MERGE_CONFERENCE)) {
+            mConnectionService.mergeConference(this);
+        }
+    }
+
+    void swapConference() {
+        if (mConnectionService == null) {
+            Log.w(this, "swapping conference calls without a connection service.");
+        } else if (can(PhoneCapabilities.SWAP_CONFERENCE)) {
+            mConnectionService.swapConference(this);
+        }
+    }
+
+    void setParentCall(Call parentCall) {
+        if (parentCall == this) {
+            Log.e(this, new Exception(), "setting the parent to self");
+            return;
+        }
+        if (parentCall == mParentCall) {
+            // nothing to do
+            return;
+        }
+        Preconditions.checkState(parentCall == null || mParentCall == null);
+
+        Call oldParent = mParentCall;
+        if (mParentCall != null) {
+            mParentCall.removeChildCall(this);
+        }
+        mParentCall = parentCall;
+        if (mParentCall != null) {
+            mParentCall.addChildCall(this);
+        }
+
+        for (Listener l : mListeners) {
+            l.onParentChanged(this);
+        }
+    }
+
+    void setConferenceableCalls(List<Call> conferenceableCalls) {
+        mConferenceableCalls.clear();
+        mConferenceableCalls.addAll(conferenceableCalls);
+    }
+
+    List<Call> getConferenceableCalls() {
+        return mConferenceableCalls;
+    }
+
+    private boolean can(int capability) {
+        return (mCallCapabilities & capability) == capability;
+    }
+
+    private void addChildCall(Call call) {
+        if (!mChildCalls.contains(call)) {
+            mChildCalls.add(call);
+
+            for (Listener l : mListeners) {
+                l.onChildrenChanged(this);
+            }
+        }
+    }
+
+    private void removeChildCall(Call call) {
+        if (mChildCalls.remove(call)) {
+            for (Listener l : mListeners) {
+                l.onChildrenChanged(this);
+            }
+        }
+    }
+
+    /**
+     * Return whether the user can respond to this {@code Call} via an SMS message.
+     *
+     * @return true if the "Respond via SMS" feature should be enabled
+     * for this incoming call.
+     *
+     * The general rule is that we *do* allow "Respond via SMS" except for
+     * the few (relatively rare) cases where we know for sure it won't
+     * work, namely:
+     *   - a bogus or blank incoming number
+     *   - a call from a SIP address
+     *   - a "call presentation" that doesn't allow the number to be revealed
+     *
+     * In all other cases, we allow the user to respond via SMS.
+     *
+     * Note that this behavior isn't perfect; for example we have no way
+     * to detect whether the incoming call is from a landline (with most
+     * networks at least), so we still enable this feature even though
+     * SMSes to that number will silently fail.
+     */
+    boolean isRespondViaSmsCapable() {
+        if (mState != CallState.RINGING) {
+            return false;
+        }
+
+        if (getHandle() == null) {
+            // No incoming number known or call presentation is "PRESENTATION_RESTRICTED", in
+            // other words, the user should not be able to see the incoming phone number.
+            return false;
+        }
+
+        if (PhoneNumberUtils.isUriNumber(getHandle().toString())) {
+            // The incoming number is actually a URI (i.e. a SIP address),
+            // not a regular PSTN phone number, and we can't send SMSes to
+            // SIP addresses.
+            // (TODO: That might still be possible eventually, though. Is
+            // there some SIP-specific equivalent to sending a text message?)
+            return false;
+        }
+
+        // Is there a valid SMS application on the phone?
+        if (SmsApplication.getDefaultRespondViaMessageApplication(TelecomApp.getInstance(),
+                true /*updateIfNeeded*/) == null) {
+            return false;
+        }
+
+        // TODO: with some carriers (in certain countries) you *can* actually
+        // tell whether a given number is a mobile phone or not. So in that
+        // case we could potentially return false here if the incoming call is
+        // from a land line.
+
+        // If none of the above special cases apply, it's OK to enable the
+        // "Respond via SMS" feature.
+        return true;
+    }
+
+    List<String> getCannedSmsResponses() {
+        return mCannedSmsResponses;
+    }
+
+    /**
+     * We need to make sure that before we move a call to the disconnected state, it no
+     * longer has any parent/child relationships.  We want to do this to ensure that the InCall
+     * Service always has the right data in the right order.  We also want to do it in telecom so
+     * that the insurance policy lives in the framework side of things.
+     */
+    private void fixParentAfterDisconnect() {
+        setParentCall(null);
+    }
+
+    /**
+     * @return True if the call is ringing, else logs the action name.
+     */
+    private boolean isRinging(String actionName) {
+        if (mState == CallState.RINGING) {
+            return true;
+        }
+
+        Log.i(this, "Request to %s a non-ringing call %s", actionName, this);
+        return false;
+    }
+
+    @SuppressWarnings("rawtypes")
+    private void decrementAssociatedCallCount(ServiceBinder binder) {
+        if (binder != null) {
+            binder.decrementAssociatedCallCount();
+        }
+    }
+
+    /**
+     * Looks up contact information based on the current handle.
+     */
+    private void startCallerInfoLookup() {
+        String number = mHandle == null ? null : mHandle.getSchemeSpecificPart();
+
+        mQueryToken++;  // Updated so that previous queries can no longer set the information.
+        mCallerInfo = null;
+        if (!TextUtils.isEmpty(number)) {
+            Log.v(this, "Looking up information for: %s.", Log.piiHandle(number));
+            CallerInfoAsyncQuery.startQuery(
+                    mQueryToken,
+                    TelecomApp.getInstance(),
+                    number,
+                    sCallerInfoQueryListener,
+                    this);
+        }
+    }
+
+    /**
+     * Saves the specified caller info if the specified token matches that of the last query
+     * that was made.
+     *
+     * @param callerInfo The new caller information to set.
+     * @param token The token used with this query.
+     */
+    private void setCallerInfo(CallerInfo callerInfo, int token) {
+        Preconditions.checkNotNull(callerInfo);
+
+        if (mQueryToken == token) {
+            mCallerInfo = callerInfo;
+            Log.i(this, "CallerInfo received for %s: %s", Log.piiHandle(mHandle), callerInfo);
+
+            if (mCallerInfo.contactDisplayPhotoUri != null) {
+                Log.d(this, "Searching person uri %s for call %s",
+                        mCallerInfo.contactDisplayPhotoUri, this);
+                ContactsAsyncHelper.startObtainPhotoAsync(
+                        token,
+                        TelecomApp.getInstance(),
+                        mCallerInfo.contactDisplayPhotoUri,
+                        sPhotoLoadListener,
+                        this);
+                // Do not call onCallerInfoChanged yet in this case.  We call it in setPhoto().
+            } else {
+                for (Listener l : mListeners) {
+                    l.onCallerInfoChanged(this);
+                }
+            }
+
+            processDirectToVoicemail();
+        }
+    }
+
+    CallerInfo getCallerInfo() {
+        return mCallerInfo;
+    }
+
+    /**
+     * Saves the specified photo information if the specified token matches that of the last query.
+     *
+     * @param photo The photo as a drawable.
+     * @param photoIcon The photo as a small icon.
+     * @param token The token used with this query.
+     */
+    private void setPhoto(Drawable photo, Bitmap photoIcon, int token) {
+        if (mQueryToken == token) {
+            mCallerInfo.cachedPhoto = photo;
+            mCallerInfo.cachedPhotoIcon = photoIcon;
+
+            for (Listener l : mListeners) {
+                l.onCallerInfoChanged(this);
+            }
+        }
+    }
+
+    private void maybeLoadCannedSmsResponses() {
+        if (mIsIncoming && isRespondViaSmsCapable() && !mCannedSmsResponsesLoadingStarted) {
+            Log.d(this, "maybeLoadCannedSmsResponses: starting task to load messages");
+            mCannedSmsResponsesLoadingStarted = true;
+            RespondViaSmsManager.getInstance().loadCannedTextMessages(
+                    new Response<Void, List<String>>() {
+                        @Override
+                        public void onResult(Void request, List<String>... result) {
+                            if (result.length > 0) {
+                                Log.d(this, "maybeLoadCannedSmsResponses: got %s", result[0]);
+                                mCannedSmsResponses = result[0];
+                                for (Listener l : mListeners) {
+                                    l.onCannedSmsResponsesLoaded(Call.this);
+                                }
+                            }
+                        }
+
+                        @Override
+                        public void onError(Void request, int code, String msg) {
+                            Log.w(Call.this, "Error obtaining canned SMS responses: %d %s", code,
+                                    msg);
+                        }
+                    }
+            );
+        } else {
+            Log.d(this, "maybeLoadCannedSmsResponses: doing nothing");
+        }
+    }
+
+    /**
+     * Sets speakerphone option on when call begins.
+     */
+    public void setStartWithSpeakerphoneOn(boolean startWithSpeakerphone) {
+        mSpeakerphoneOn = startWithSpeakerphone;
+    }
+
+    /**
+     * Returns speakerphone option.
+     *
+     * @return Whether or not speakerphone should be set automatically when call begins.
+     */
+    public boolean getStartWithSpeakerphoneOn() {
+        return mSpeakerphoneOn;
+    }
+
+    /**
+     * Sets a video call provider for the call.
+     */
+    public void setVideoProvider(IVideoProvider videoProvider) {
+        mVideoProvider = videoProvider;
+        for (Listener l : mListeners) {
+            l.onVideoCallProviderChanged(Call.this);
+        }
+    }
+
+    /**
+     * @return Return the {@link Connection.VideoProvider} binder.
+     */
+    public IVideoProvider getVideoProvider() {
+        return mVideoProvider;
+    }
+
+    /**
+     * The current video state for the call.
+     * Valid values: see {@link VideoProfile.VideoState}.
+     */
+    public int getVideoState() {
+        return mVideoState;
+    }
+
+    /**
+     * Returns the video states which were applicable over the duration of a call.
+     * See {@link VideoProfile} for a list of valid video states.
+     *
+     * @return The video states applicable over the duration of the call.
+     */
+    public int getVideoStateHistory() {
+        return mVideoStateHistory;
+    }
+
+    /**
+     * Determines the current video state for the call.
+     * For an outgoing call determines the desired video state for the call.
+     * Valid values: see {@link VideoProfile.VideoState}
+     *
+     * @param videoState The video state for the call.
+     */
+    public void setVideoState(int videoState) {
+        // Track which video states were applicable over the duration of the call.
+        mVideoStateHistory = mVideoStateHistory | videoState;
+
+        mVideoState = videoState;
+        for (Listener l : mListeners) {
+            l.onVideoStateChanged(this);
+        }
+    }
+
+    public boolean getIsVoipAudioMode() {
+        return mIsVoipAudioMode;
+    }
+
+    public void setIsVoipAudioMode(boolean audioModeIsVoip) {
+        mIsVoipAudioMode = audioModeIsVoip;
+        for (Listener l : mListeners) {
+            l.onIsVoipAudioModeChanged(this);
+        }
+    }
+
+    public StatusHints getStatusHints() {
+        return mStatusHints;
+    }
+
+    public void setStatusHints(StatusHints statusHints) {
+        mStatusHints = statusHints;
+        for (Listener l : mListeners) {
+            l.onStatusHintsChanged(this);
+        }
+    }
+
+    static int getStateFromConnectionState(int state) {
+        switch (state) {
+            case Connection.STATE_INITIALIZING:
+                return CallState.CONNECTING;
+            case Connection.STATE_ACTIVE:
+                return CallState.ACTIVE;
+            case Connection.STATE_DIALING:
+                return CallState.DIALING;
+            case Connection.STATE_DISCONNECTED:
+                return CallState.DISCONNECTED;
+            case Connection.STATE_HOLDING:
+                return CallState.ON_HOLD;
+            case Connection.STATE_NEW:
+                return CallState.NEW;
+            case Connection.STATE_RINGING:
+                return CallState.RINGING;
+        }
+        return CallState.DISCONNECTED;
+    }
+}
diff --git a/src/com/android/server/telecom/CallActivity.java b/src/com/android/server/telecom/CallActivity.java
new file mode 100644
index 0000000..96ffb96
--- /dev/null
+++ b/src/com/android/server/telecom/CallActivity.java
@@ -0,0 +1,245 @@
+/*
+ * 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.server.telecom;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.DisconnectCause;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.widget.Toast;
+
+/**
+ * Activity that handles system CALL actions and forwards them to {@link CallsManager}.
+ * Handles all three CALL action types: CALL, CALL_PRIVILEGED, and CALL_EMERGENCY.
+ *
+ * Pre-L, the only way apps were were allowed to make outgoing emergency calls was the
+ * ACTION_CALL_PRIVILEGED action (which requires the system only CALL_PRIVILEGED permission).
+ *
+ * In L, any app that has the CALL_PRIVILEGED permission can continue to make outgoing emergency
+ * calls via ACTION_CALL_PRIVILEGED.
+ *
+ * In addition, the default dialer (identified via {@link android.telecom.TelecomManager#getDefaultPhoneApp()}
+ * will also be granted the ability to make emergency outgoing calls using the CALL action. In
+ * order to do this, it must call startActivityForResult on the CALL intent to allow its package
+ * name to be passed to {@link CallActivity}. Calling startActivity will continue to work on all
+ * non-emergency numbers just like it did pre-L.
+ */
+public class CallActivity extends Activity {
+
+    private CallsManager mCallsManager = CallsManager.getInstance();
+    private boolean mIsVoiceCapable;
+
+    /**
+     * {@inheritDoc}
+     *
+     * This method is the single point of entry for the CALL intent, which is used by built-in apps
+     * like Contacts & Dialer, as well as 3rd party apps to initiate outgoing calls.
+     */
+    @Override
+    protected void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+
+        mIsVoiceCapable = isVoiceCapable();
+
+        // TODO: This activity will be displayed until the next screen which could be
+        // the in-call UI and error dialog or potentially a call-type selection dialog.
+        // Traditionally, this has been a black screen with a spinner. We need to reevaluate if this
+        // is still desired and add back if necessary. Currently, the activity is set to NoDisplay
+        // theme which means it shows no UI.
+
+        Intent intent = getIntent();
+        Configuration configuration = getResources().getConfiguration();
+
+        Log.d(this, "onCreate: this = %s, bundle = %s", this, bundle);
+        Log.d(this, " - intent = %s", intent);
+        Log.d(this, " - configuration = %s", configuration);
+
+        // TODO: Figure out if there is something to restore from bundle.
+        // See OutgoingCallBroadcaster in services/Telephony for more.
+
+        processIntent(intent);
+
+        // This activity does not have associated UI, so close.
+        finish();
+
+        Log.d(this, "onCreate: end");
+    }
+
+    /**
+     * Processes intents sent to the activity.
+     *
+     * @param intent The intent.
+     */
+    private void processIntent(Intent intent) {
+        // Ensure call intents are not processed on devices that are not capable of calling.
+        if (!mIsVoiceCapable) {
+            setResult(RESULT_CANCELED);
+            return;
+        }
+
+        String action = intent.getAction();
+
+        // TODO: Check for non-voice capable devices before reading any intents.
+
+        if (Intent.ACTION_CALL.equals(action) ||
+                Intent.ACTION_CALL_PRIVILEGED.equals(action) ||
+                Intent.ACTION_CALL_EMERGENCY.equals(action)) {
+            processOutgoingCallIntent(intent);
+        } else if (TelecomManager.ACTION_INCOMING_CALL.equals(action)) {
+            processIncomingCallIntent(intent);
+        }
+    }
+
+    /**
+     * Processes CALL, CALL_PRIVILEGED, and CALL_EMERGENCY intents.
+     *
+     * @param intent Call intent containing data about the handle to call.
+     */
+    private void processOutgoingCallIntent(Intent intent) {
+        Uri handle = intent.getData();
+        String scheme = handle.getScheme();
+        String uriString = handle.getSchemeSpecificPart();
+
+        if (!PhoneAccount.SCHEME_VOICEMAIL.equals(scheme)) {
+            handle = Uri.fromParts(PhoneNumberUtils.isUriNumber(uriString) ?
+                    PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL, uriString, null);
+        }
+
+        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        if (userManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS)
+                && !TelephonyUtil.shouldProcessAsEmergency(this, handle)) {
+            // Only emergency calls are allowed for users with the DISALLOW_OUTGOING_CALLS
+            // restriction.
+            Toast.makeText(this, getResources().getString(R.string.outgoing_call_not_allowed),
+                    Toast.LENGTH_SHORT).show();
+            Log.d(this, "Rejecting non-emergency phone call due to DISALLOW_OUTGOING_CALLS "
+                    + "restriction");
+            return;
+        }
+
+        PhoneAccountHandle phoneAccountHandle = intent.getParcelableExtra(
+                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
+
+        Bundle clientExtras = null;
+        if (intent.hasExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS)) {
+            clientExtras = intent.getBundleExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS);
+        }
+        if (clientExtras == null) {
+            clientExtras = Bundle.EMPTY;
+        }
+
+        // Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns
+        Call call = mCallsManager.startOutgoingCall(handle, phoneAccountHandle, clientExtras);
+
+        if (call == null) {
+            setResult(RESULT_CANCELED);
+        } else {
+            NewOutgoingCallIntentBroadcaster broadcaster = new NewOutgoingCallIntentBroadcaster(
+                    mCallsManager, call, intent, isDefaultDialer());
+            final int result = broadcaster.processIntent();
+            final boolean success = result == DisconnectCause.NOT_DISCONNECTED;
+
+            if (!success && call != null) {
+                disconnectCallAndShowErrorDialog(call, result);
+            }
+            setResult(success ? RESULT_OK : RESULT_CANCELED);
+        }
+    }
+
+    /**
+     * Processes INCOMING_CALL intents. Grabs the connection service information from the intent
+     * extra and forwards that to the CallsManager to start the incoming call flow.
+     *
+     * @param intent The incoming call intent.
+     */
+    private void processIncomingCallIntent(Intent intent) {
+        PhoneAccountHandle phoneAccountHandle = intent.getParcelableExtra(
+                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
+        if (phoneAccountHandle == null) {
+            Log.w(this, "Rejecting incoming call due to null phone account");
+            return;
+        }
+        if (phoneAccountHandle.getComponentName() == null) {
+            Log.w(this, "Rejecting incoming call due to null component name");
+            return;
+        }
+
+        Bundle clientExtras = null;
+        if (intent.hasExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS)) {
+            clientExtras = intent.getBundleExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS);
+        }
+        if (clientExtras == null) {
+            clientExtras = Bundle.EMPTY;
+        }
+
+        Log.d(this, "Processing incoming call from connection service [%s]",
+                phoneAccountHandle.getComponentName());
+        mCallsManager.processIncomingCallIntent(phoneAccountHandle, clientExtras);
+    }
+
+    private boolean isDefaultDialer() {
+        final String packageName = getCallingPackage();
+        if (TextUtils.isEmpty(packageName)) {
+            return false;
+        }
+
+        final TelecomManager telecomManager =
+                (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
+        final ComponentName defaultPhoneApp = telecomManager.getDefaultPhoneApp();
+        return (defaultPhoneApp != null
+                && TextUtils.equals(defaultPhoneApp.getPackageName(), packageName));
+    }
+
+    /**
+     * Returns whether the device is voice-capable (e.g. a phone vs a tablet).
+     *
+     * @return {@code True} if the device is voice-capable.
+     */
+    private boolean isVoiceCapable() {
+        return getApplicationContext().getResources().getBoolean(
+                com.android.internal.R.bool.config_voice_capable);
+    }
+
+    private void disconnectCallAndShowErrorDialog(Call call, int errorCode) {
+        call.disconnect();
+        final Intent errorIntent = new Intent(this, ErrorDialogActivity.class);
+        int errorMessageId = -1;
+        switch (errorCode) {
+            case DisconnectCause.INVALID_NUMBER:
+                errorMessageId = R.string.outgoing_call_error_no_phone_number_supplied;
+                break;
+            case DisconnectCause.VOICEMAIL_NUMBER_MISSING:
+                errorIntent.putExtra(ErrorDialogActivity.SHOW_MISSING_VOICEMAIL_NO_DIALOG_EXTRA,
+                        true);
+                break;
+        }
+        if (errorMessageId != -1) {
+            errorIntent.putExtra(ErrorDialogActivity.ERROR_MESSAGE_ID_EXTRA, errorMessageId);
+        }
+        startActivity(errorIntent);
+    }
+}
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
new file mode 100644
index 0000000..312f58f
--- /dev/null
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -0,0 +1,495 @@
+/*
+ * 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.server.telecom;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.telecom.AudioState;
+import android.telecom.CallState;
+
+import com.google.common.base.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * This class manages audio modes, streams and other properties.
+ */
+final class CallAudioManager extends CallsManagerListenerBase
+        implements WiredHeadsetManager.Listener {
+    private static final int STREAM_NONE = -1;
+
+    private final StatusBarNotifier mStatusBarNotifier;
+    private final AudioManager mAudioManager;
+    private final BluetoothManager mBluetoothManager;
+    private final WiredHeadsetManager mWiredHeadsetManager;
+
+    private AudioState mAudioState;
+    private int mAudioFocusStreamType;
+    private boolean mIsRinging;
+    private boolean mIsTonePlaying;
+    private boolean mWasSpeakerOn;
+    private int mMostRecentlyUsedMode = AudioManager.MODE_IN_CALL;
+
+    CallAudioManager(Context context, StatusBarNotifier statusBarNotifier,
+            WiredHeadsetManager wiredHeadsetManager) {
+        mStatusBarNotifier = statusBarNotifier;
+        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        mBluetoothManager = new BluetoothManager(context, this);
+        mWiredHeadsetManager = wiredHeadsetManager;
+        mWiredHeadsetManager.addListener(this);
+
+        saveAudioState(getInitialAudioState(null));
+        mAudioFocusStreamType = STREAM_NONE;
+    }
+
+    AudioState getAudioState() {
+        return mAudioState;
+    }
+
+    @Override
+    public void onCallAdded(Call call) {
+        onCallUpdated(call);
+
+        if (hasFocus() && getForegroundCall() == call) {
+            if (!call.isIncoming()) {
+                // Unmute new outgoing call.
+                setSystemAudioState(false, mAudioState.route, mAudioState.supportedRouteMask);
+            }
+        }
+    }
+
+    @Override
+    public void onCallRemoved(Call call) {
+        // If we didn't already have focus, there's nothing to do.
+        if (hasFocus()) {
+            if (CallsManager.getInstance().getCalls().isEmpty()) {
+                Log.v(this, "all calls removed, reseting system audio to default state");
+                setInitialAudioState(null, false /* force */);
+                mWasSpeakerOn = false;
+            }
+            updateAudioStreamAndMode();
+        }
+    }
+
+    @Override
+    public void onCallStateChanged(Call call, int oldState, int newState) {
+        onCallUpdated(call);
+    }
+
+    @Override
+    public void onIncomingCallAnswered(Call call) {
+        int route = mAudioState.route;
+
+        // We do two things:
+        // (1) If this is the first call, then we can to turn on bluetooth if available.
+        // (2) Unmute the audio for the new incoming call.
+        boolean isOnlyCall = CallsManager.getInstance().getCalls().size() == 1;
+        if (isOnlyCall && mBluetoothManager.isBluetoothAvailable()) {
+            mBluetoothManager.connectBluetoothAudio();
+            route = AudioState.ROUTE_BLUETOOTH;
+        }
+
+        setSystemAudioState(false /* isMute */, route, mAudioState.supportedRouteMask);
+    }
+
+    @Override
+    public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
+        onCallUpdated(newForegroundCall);
+        // Ensure that the foreground call knows about the latest audio state.
+        updateAudioForForegroundCall();
+    }
+
+    @Override
+    public void onIsVoipAudioModeChanged(Call call) {
+        updateAudioStreamAndMode();
+    }
+
+    /**
+      * Updates the audio route when the headset plugged in state changes. For example, if audio is
+      * being routed over speakerphone and a headset is plugged in then switch to wired headset.
+      */
+    @Override
+    public void onWiredHeadsetPluggedInChanged(boolean oldIsPluggedIn, boolean newIsPluggedIn) {
+        // This can happen even when there are no calls and we don't have focus.
+        if (!hasFocus()) {
+            return;
+        }
+
+        int newRoute = AudioState.ROUTE_EARPIECE;
+        if (newIsPluggedIn) {
+            newRoute = AudioState.ROUTE_WIRED_HEADSET;
+        } else if (mWasSpeakerOn) {
+            Call call = getForegroundCall();
+            if (call != null && call.isAlive()) {
+                // Restore the speaker state.
+                newRoute = AudioState.ROUTE_SPEAKER;
+            }
+        }
+        setSystemAudioState(mAudioState.isMuted, newRoute, calculateSupportedRoutes());
+    }
+
+    void toggleMute() {
+        mute(!mAudioState.isMuted);
+    }
+
+    void mute(boolean shouldMute) {
+        if (!hasFocus()) {
+            return;
+        }
+
+        Log.v(this, "mute, shouldMute: %b", shouldMute);
+
+        // Don't mute if there are any emergency calls.
+        if (CallsManager.getInstance().hasEmergencyCall()) {
+            shouldMute = false;
+            Log.v(this, "ignoring mute for emergency call");
+        }
+
+        if (mAudioState.isMuted != shouldMute) {
+            setSystemAudioState(shouldMute, mAudioState.route, mAudioState.supportedRouteMask);
+        }
+    }
+
+    /**
+     * Changed the audio route, for example from earpiece to speaker phone.
+     *
+     * @param route The new audio route to use. See {@link AudioState}.
+     */
+    void setAudioRoute(int route) {
+        // This can happen even when there are no calls and we don't have focus.
+        if (!hasFocus()) {
+            return;
+        }
+
+        Log.v(this, "setAudioRoute, route: %s", AudioState.audioRouteToString(route));
+
+        // Change ROUTE_WIRED_OR_EARPIECE to a single entry.
+        int newRoute = selectWiredOrEarpiece(route, mAudioState.supportedRouteMask);
+
+        // If route is unsupported, do nothing.
+        if ((mAudioState.supportedRouteMask | newRoute) == 0) {
+            Log.wtf(this, "Asking to set to a route that is unsupported: %d", newRoute);
+            return;
+        }
+
+        if (mAudioState.route != newRoute) {
+            // Remember the new speaker state so it can be restored when the user plugs and unplugs
+            // a headset.
+            mWasSpeakerOn = newRoute == AudioState.ROUTE_SPEAKER;
+            setSystemAudioState(mAudioState.isMuted, newRoute, mAudioState.supportedRouteMask);
+        }
+    }
+
+    void setIsRinging(boolean isRinging) {
+        if (mIsRinging != isRinging) {
+            Log.v(this, "setIsRinging %b -> %b", mIsRinging, isRinging);
+            mIsRinging = isRinging;
+            updateAudioStreamAndMode();
+        }
+    }
+
+    /**
+     * Sets the tone playing status. Some tones can play even when there are no live calls and this
+     * status indicates that we should keep audio focus even for tones that play beyond the life of
+     * calls.
+     *
+     * @param isPlayingNew The status to set.
+     */
+    void setIsTonePlaying(boolean isPlayingNew) {
+        ThreadUtil.checkOnMainThread();
+
+        if (mIsTonePlaying != isPlayingNew) {
+            Log.v(this, "mIsTonePlaying %b -> %b.", mIsTonePlaying, isPlayingNew);
+            mIsTonePlaying = isPlayingNew;
+            updateAudioStreamAndMode();
+        }
+    }
+
+    /**
+     * Updates the audio routing according to the bluetooth state.
+     */
+    void onBluetoothStateChange(BluetoothManager bluetoothManager) {
+        // This can happen even when there are no calls and we don't have focus.
+        if (!hasFocus()) {
+            return;
+        }
+
+        int supportedRoutes = calculateSupportedRoutes();
+        int newRoute = mAudioState.route;
+        if (bluetoothManager.isBluetoothAudioConnectedOrPending()) {
+            newRoute = AudioState.ROUTE_BLUETOOTH;
+        } else if (mAudioState.route == AudioState.ROUTE_BLUETOOTH) {
+            newRoute = selectWiredOrEarpiece(AudioState.ROUTE_WIRED_OR_EARPIECE, supportedRoutes);
+            // Do not switch to speaker when bluetooth disconnects.
+            mWasSpeakerOn = false;
+        }
+
+        setSystemAudioState(mAudioState.isMuted, newRoute, supportedRoutes);
+    }
+
+    boolean isBluetoothAudioOn() {
+        return mBluetoothManager.isBluetoothAudioConnected();
+    }
+
+    boolean isBluetoothDeviceAvailable() {
+        return mBluetoothManager.isBluetoothAvailable();
+    }
+
+    private void saveAudioState(AudioState audioState) {
+        mAudioState = audioState;
+        mStatusBarNotifier.notifyMute(mAudioState.isMuted);
+        mStatusBarNotifier.notifySpeakerphone(mAudioState.route == AudioState.ROUTE_SPEAKER);
+    }
+
+    private void onCallUpdated(Call call) {
+        boolean wasNotVoiceCall = mAudioFocusStreamType != AudioManager.STREAM_VOICE_CALL;
+        updateAudioStreamAndMode();
+
+        // If we transition from not voice call to voice call, we need to set an initial state.
+        if (wasNotVoiceCall && mAudioFocusStreamType == AudioManager.STREAM_VOICE_CALL) {
+            setInitialAudioState(call, true /* force */);
+        }
+    }
+
+    private void setSystemAudioState(boolean isMuted, int route, int supportedRouteMask) {
+        setSystemAudioState(false /* force */, isMuted, route, supportedRouteMask);
+    }
+
+    private void setSystemAudioState(
+            boolean force, boolean isMuted, int route, int supportedRouteMask) {
+        if (!hasFocus()) {
+            return;
+        }
+
+        AudioState oldAudioState = mAudioState;
+        saveAudioState(new AudioState(isMuted, route, supportedRouteMask));
+        if (!force && Objects.equals(oldAudioState, mAudioState)) {
+            return;
+        }
+        Log.i(this, "changing audio state from %s to %s", oldAudioState, mAudioState);
+
+        // Mute.
+        if (mAudioState.isMuted != mAudioManager.isMicrophoneMute()) {
+            Log.i(this, "changing microphone mute state to: %b", mAudioState.isMuted);
+            mAudioManager.setMicrophoneMute(mAudioState.isMuted);
+        }
+
+        // Audio route.
+        if (mAudioState.route == AudioState.ROUTE_BLUETOOTH) {
+            turnOnSpeaker(false);
+            turnOnBluetooth(true);
+        } else if (mAudioState.route == AudioState.ROUTE_SPEAKER) {
+            turnOnBluetooth(false);
+            turnOnSpeaker(true);
+        } else if (mAudioState.route == AudioState.ROUTE_EARPIECE ||
+                mAudioState.route == AudioState.ROUTE_WIRED_HEADSET) {
+            turnOnBluetooth(false);
+            turnOnSpeaker(false);
+        }
+
+        if (!oldAudioState.equals(mAudioState)) {
+            CallsManager.getInstance().onAudioStateChanged(oldAudioState, mAudioState);
+            updateAudioForForegroundCall();
+        }
+    }
+
+    private void turnOnSpeaker(boolean on) {
+        // Wired headset and earpiece work the same way
+        if (mAudioManager.isSpeakerphoneOn() != on) {
+            Log.i(this, "turning speaker phone %s", on);
+            mAudioManager.setSpeakerphoneOn(on);
+        }
+    }
+
+    private void turnOnBluetooth(boolean on) {
+        if (mBluetoothManager.isBluetoothAvailable()) {
+            boolean isAlreadyOn = mBluetoothManager.isBluetoothAudioConnectedOrPending();
+            if (on != isAlreadyOn) {
+                Log.i(this, "connecting bluetooth %s", on);
+                if (on) {
+                    mBluetoothManager.connectBluetoothAudio();
+                } else {
+                    mBluetoothManager.disconnectBluetoothAudio();
+                }
+            }
+        }
+    }
+
+    private void updateAudioStreamAndMode() {
+        Log.v(this, "updateAudioStreamAndMode, mIsRinging: %b, mIsTonePlaying: %b", mIsRinging,
+                mIsTonePlaying);
+        if (mIsRinging) {
+            requestAudioFocusAndSetMode(AudioManager.STREAM_RING, AudioManager.MODE_RINGTONE);
+        } else {
+            Call call = getForegroundCall();
+            if (call != null) {
+                int mode = call.getIsVoipAudioMode() ?
+                        AudioManager.MODE_IN_COMMUNICATION : AudioManager.MODE_IN_CALL;
+                requestAudioFocusAndSetMode(AudioManager.STREAM_VOICE_CALL, mode);
+            } else if (mIsTonePlaying) {
+                // There is no call, however, we are still playing a tone, so keep focus.
+                // Since there is no call from which to determine the mode, use the most
+                // recently used mode instead.
+                requestAudioFocusAndSetMode(
+                        AudioManager.STREAM_VOICE_CALL, mMostRecentlyUsedMode);
+            } else if (!hasRingingForegroundCall()) {
+                abandonAudioFocus();
+            } else {
+                // mIsRinging is false, but there is a foreground ringing call present. Don't
+                // abandon audio focus immediately to prevent audio focus from getting lost between
+                // the time it takes for the foreground call to transition from RINGING to ACTIVE/
+                // DISCONNECTED. When the call eventually transitions to the next state, audio
+                // focus will be correctly abandoned by the if clause above.
+            }
+        }
+    }
+
+    private void requestAudioFocusAndSetMode(int stream, int mode) {
+        Log.v(this, "requestAudioFocusAndSetMode, stream: %d -> %d", mAudioFocusStreamType, stream);
+        Preconditions.checkState(stream != STREAM_NONE);
+
+        // Even if we already have focus, if the stream is different we update audio manager to give
+        // it a hint about the purpose of our focus.
+        if (mAudioFocusStreamType != stream) {
+            Log.v(this, "requesting audio focus for stream: %d", stream);
+            mAudioManager.requestAudioFocusForCall(stream,
+                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+        }
+        mAudioFocusStreamType = stream;
+
+        setMode(mode);
+    }
+
+    private void abandonAudioFocus() {
+        if (hasFocus()) {
+            setMode(AudioManager.MODE_NORMAL);
+            Log.v(this, "abandoning audio focus");
+            mAudioManager.abandonAudioFocusForCall();
+            mAudioFocusStreamType = STREAM_NONE;
+        }
+    }
+
+    /**
+     * Sets the audio mode.
+     *
+     * @param newMode Mode constant from AudioManager.MODE_*.
+     */
+    private void setMode(int newMode) {
+        Preconditions.checkState(hasFocus());
+        int oldMode = mAudioManager.getMode();
+        Log.v(this, "Request to change audio mode from %d to %d", oldMode, newMode);
+        if (oldMode != newMode) {
+            mAudioManager.setMode(newMode);
+            mMostRecentlyUsedMode = newMode;
+        }
+    }
+
+    private int selectWiredOrEarpiece(int route, int supportedRouteMask) {
+        // Since they are mutually exclusive and one is ALWAYS valid, we allow a special input of
+        // ROUTE_WIRED_OR_EARPIECE so that callers dont have to make a call to check which is
+        // supported before calling setAudioRoute.
+        if (route == AudioState.ROUTE_WIRED_OR_EARPIECE) {
+            route = AudioState.ROUTE_WIRED_OR_EARPIECE & supportedRouteMask;
+            if (route == 0) {
+                Log.wtf(this, "One of wired headset or earpiece should always be valid.");
+                // assume earpiece in this case.
+                route = AudioState.ROUTE_EARPIECE;
+            }
+        }
+        return route;
+    }
+
+    private int calculateSupportedRoutes() {
+        int routeMask = AudioState.ROUTE_SPEAKER;
+
+        if (mWiredHeadsetManager.isPluggedIn()) {
+            routeMask |= AudioState.ROUTE_WIRED_HEADSET;
+        } else {
+            routeMask |= AudioState.ROUTE_EARPIECE;
+        }
+
+        if (mBluetoothManager.isBluetoothAvailable()) {
+            routeMask |=  AudioState.ROUTE_BLUETOOTH;
+        }
+
+        return routeMask;
+    }
+
+    private AudioState getInitialAudioState(Call call) {
+        int supportedRouteMask = calculateSupportedRoutes();
+        int route = selectWiredOrEarpiece(
+                AudioState.ROUTE_WIRED_OR_EARPIECE, supportedRouteMask);
+
+        // 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. In this case, just
+        //     check if the headset is available. Note this only applies when we are dealing with
+        //     the first call.
+        if (call != null && mBluetoothManager.isBluetoothAvailable()) {
+            switch(call.getState()) {
+                case CallState.ACTIVE:
+                case CallState.ON_HOLD:
+                case CallState.DIALING:
+                case CallState.RINGING:
+                    route = AudioState.ROUTE_BLUETOOTH;
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        return new AudioState(false, route, supportedRouteMask);
+    }
+
+    private void setInitialAudioState(Call call, boolean force) {
+        AudioState audioState = getInitialAudioState(call);
+        Log.v(this, "setInitialAudioState %s, %s", audioState, call);
+        setSystemAudioState(
+                force, audioState.isMuted, audioState.route, audioState.supportedRouteMask);
+    }
+
+    private void updateAudioForForegroundCall() {
+        Call call = CallsManager.getInstance().getForegroundCall();
+        if (call != null && call.getConnectionService() != null) {
+            call.getConnectionService().onAudioStateChanged(call, mAudioState);
+        }
+    }
+
+    /**
+     * Returns the current foreground call in order to properly set the audio mode.
+     */
+    private Call getForegroundCall() {
+        Call call = CallsManager.getInstance().getForegroundCall();
+
+        // We ignore any foreground call that is in the ringing state because we deal with ringing
+        // calls exclusively through the mIsRinging variable set by {@link Ringer}.
+        if (call != null && call.getState() == CallState.RINGING) {
+            call = null;
+        }
+        return call;
+    }
+
+    private boolean hasRingingForegroundCall() {
+        Call call = CallsManager.getInstance().getForegroundCall();
+        return call != null && call.getState() == CallState.RINGING;
+    }
+
+    private boolean hasFocus() {
+        return mAudioFocusStreamType != STREAM_NONE;
+    }
+}
diff --git a/src/com/android/server/telecom/CallIdMapper.java b/src/com/android/server/telecom/CallIdMapper.java
new file mode 100644
index 0000000..40a50a5
--- /dev/null
+++ b/src/com/android/server/telecom/CallIdMapper.java
@@ -0,0 +1,105 @@
+/*
+ * 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.server.telecom;
+
+import com.google.common.collect.HashBiMap;
+
+/** Utility to map {@link Call} objects to unique IDs. IDs are generated when a call is added. */
+class CallIdMapper {
+    private final HashBiMap<String, Call> mCalls = HashBiMap.create();
+    private final String mCallIdPrefix;
+    private static int sIdCount;
+
+    CallIdMapper(String callIdPrefix) {
+        ThreadUtil.checkOnMainThread();
+        mCallIdPrefix = callIdPrefix + "@";
+    }
+
+    void replaceCall(Call newCall, Call callToReplace) {
+        ThreadUtil.checkOnMainThread();
+
+        // Use the old call's ID for the new call.
+        String callId = getCallId(callToReplace);
+        mCalls.put(callId, newCall);
+    }
+
+    void addCall(Call call, String id) {
+        if (call == null) {
+            return;
+        }
+        ThreadUtil.checkOnMainThread();
+        mCalls.put(id, call);
+    }
+
+    void addCall(Call call) {
+        ThreadUtil.checkOnMainThread();
+        addCall(call, getNewId());
+    }
+
+    void removeCall(Call call) {
+        if (call == null) {
+            return;
+        }
+        ThreadUtil.checkOnMainThread();
+        mCalls.inverse().remove(call);
+    }
+
+    void removeCall(String callId) {
+        ThreadUtil.checkOnMainThread();
+        mCalls.remove(callId);
+    }
+
+    String getCallId(Call call) {
+        if (call == null) {
+            return null;
+        }
+        ThreadUtil.checkOnMainThread();
+        return mCalls.inverse().get(call);
+    }
+
+    Call getCall(Object objId) {
+        ThreadUtil.checkOnMainThread();
+
+        String callId = null;
+        if (objId instanceof String) {
+            callId = (String) objId;
+        }
+        if (!isValidCallId(callId) && !isValidConferenceId(callId)) {
+            return null;
+        }
+
+        return mCalls.get(callId);
+    }
+
+    void clear() {
+        mCalls.clear();
+    }
+
+    boolean isValidCallId(String callId) {
+        // Note, no need for thread check, this method is thread safe.
+        return callId != null && callId.startsWith(mCallIdPrefix);
+    }
+
+    boolean isValidConferenceId(String callId) {
+        return callId != null;
+    }
+
+    String getNewId() {
+        sIdCount++;
+        return mCallIdPrefix + sIdCount;
+    }
+}
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
new file mode 100644
index 0000000..a29ef54
--- /dev/null
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.provider.CallLog.Calls;
+import android.telecom.CallState;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.VideoProfile;
+import android.telephony.DisconnectCause;
+import android.telephony.PhoneNumberUtils;
+
+import com.android.internal.telephony.CallerInfo;
+import com.android.internal.telephony.PhoneConstants;
+
+/**
+ * Helper class that provides functionality to write information about calls and their associated
+ * caller details to the call log. All logging activity will be performed asynchronously in a
+ * background thread to avoid blocking on the main thread.
+ */
+final class CallLogManager extends CallsManagerListenerBase {
+    /**
+     * Parameter object to hold the arguments to add a call in the call log DB.
+     */
+    private static class AddCallArgs {
+        /**
+         * @param callerInfo Caller details.
+         * @param number The phone number to be logged.
+         * @param presentation Number presentation of the phone number to be logged.
+         * @param callType The type of call (e.g INCOMING_TYPE). @see
+         *     {@link android.provider.CallLog} for the list of values.
+         * @param features The features of the call (e.g. FEATURES_VIDEO). @see
+         *     {@link android.provider.CallLog} for the list of values.
+         * @param creationDate Time when the call was created (milliseconds since epoch).
+         * @param durationInMillis Duration of the call (milliseconds).
+         * @param dataUsage Data usage in bytes, or null if not applicable.
+         */
+        public AddCallArgs(Context context, CallerInfo callerInfo, String number,
+                int presentation, int callType, int features, PhoneAccountHandle accountHandle,
+                long creationDate, long durationInMillis, Long dataUsage) {
+            this.context = context;
+            this.callerInfo = callerInfo;
+            this.number = number;
+            this.presentation = presentation;
+            this.callType = callType;
+            this.features = features;
+            this.accountHandle = accountHandle;
+            this.timestamp = creationDate;
+            this.durationInSec = (int)(durationInMillis / 1000);
+            this.dataUsage = dataUsage;
+        }
+        // Since the members are accessed directly, we don't use the
+        // mXxxx notation.
+        public final Context context;
+        public final CallerInfo callerInfo;
+        public final String number;
+        public final int presentation;
+        public final int callType;
+        public final int features;
+        public final PhoneAccountHandle accountHandle;
+        public final long timestamp;
+        public final int durationInSec;
+        public final Long dataUsage;
+    }
+
+    private static final String TAG = CallLogManager.class.getSimpleName();
+
+    private final Context mContext;
+
+    public CallLogManager(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public void onCallStateChanged(Call call, int oldState, int newState) {
+        boolean isNewlyDisconnected =
+                newState == CallState.DISCONNECTED || newState == CallState.ABORTED;
+        boolean isCallCanceled = isNewlyDisconnected &&
+                call.getDisconnectCause() == DisconnectCause.OUTGOING_CANCELED;
+
+        // Log newly disconnected calls only if:
+        // 1) It was not in the "choose account" phase when disconnected
+        // 2) It is a conference call
+        // 3) Call was not explicitly canceled
+        if (isNewlyDisconnected &&
+                (oldState != CallState.PRE_DIAL_WAIT &&
+                 !call.isConference() &&
+                 !isCallCanceled)) {
+            int type;
+            if (!call.isIncoming()) {
+                type = Calls.OUTGOING_TYPE;
+            } else if (oldState == CallState.RINGING) {
+                type = Calls.MISSED_TYPE;
+            } else {
+                type = Calls.INCOMING_TYPE;
+            }
+            logCall(call, type);
+        }
+    }
+
+    /**
+     * Logs a call to the call log based on the {@link Call} object passed in.
+     *
+     * @param call The call object being logged
+     * @param callLogType The type of call log entry to log this call as. See:
+     *     {@link android.provider.CallLog.Calls#INCOMING_TYPE}
+     *     {@link android.provider.CallLog.Calls#OUTGOING_TYPE}
+     *     {@link android.provider.CallLog.Calls#MISSED_TYPE}
+     */
+    private void logCall(Call call, int callLogType) {
+        final long creationTime = call.getCreationTimeMillis();
+        final long age = call.getAgeMillis();
+
+        final String logNumber = getLogNumber(call);
+
+        Log.d(TAG, "logNumber set to: %s", Log.pii(logNumber));
+
+        final int presentation = getPresentation(call);
+        final PhoneAccountHandle accountHandle = call.getTargetPhoneAccount();
+
+        // TODO(vt): Once data usage is available, wire it up here.
+        int callFeatures = getCallFeatures(call.getVideoStateHistory());
+        logCall(call.getCallerInfo(), logNumber, presentation, callLogType, callFeatures,
+                accountHandle, creationTime, age, null);
+    }
+
+    /**
+     * Inserts a call into the call log, based on the parameters passed in.
+     *
+     * @param callerInfo Caller details.
+     * @param number The number the call was made to or from.
+     * @param presentation
+     * @param callType The type of call.
+     * @param features The features of the call.
+     * @param start The start time of the call, in milliseconds.
+     * @param duration The duration of the call, in milliseconds.
+     * @param dataUsage The data usage for the call, null if not applicable.
+     */
+    private void logCall(
+            CallerInfo callerInfo,
+            String number,
+            int presentation,
+            int callType,
+            int features,
+            PhoneAccountHandle accountHandle,
+            long start,
+            long duration,
+            Long dataUsage) {
+        boolean isEmergencyNumber = PhoneNumberUtils.isLocalEmergencyNumber(mContext, number);
+
+        // On some devices, to avoid accidental redialing of emergency numbers, we *never* log
+        // emergency calls to the Call Log.  (This behavior is set on a per-product basis, based
+        // on carrier requirements.)
+        final boolean okToLogEmergencyNumber =
+                mContext.getResources().getBoolean(R.bool.allow_emergency_numbers_in_call_log);
+
+        // Don't log emergency numbers if the device doesn't allow it.
+        final boolean isOkToLogThisCall = !isEmergencyNumber || okToLogEmergencyNumber;
+
+        if (isOkToLogThisCall) {
+            Log.d(TAG, "Logging Calllog entry: " + callerInfo + ", "
+                    + Log.pii(number) + "," + presentation + ", " + callType
+                    + ", " + start + ", " + duration);
+            AddCallArgs args = new AddCallArgs(mContext, callerInfo, number, presentation,
+                    callType, features, accountHandle, start, duration, dataUsage);
+            logCallAsync(args);
+        } else {
+          Log.d(TAG, "Not adding emergency call to call log.");
+        }
+    }
+
+    /**
+     * Based on the video state of the call, determines the call features applicable for the call.
+     *
+     * @param videoState The video state.
+     * @return The call features.
+     */
+    private static int getCallFeatures(int videoState) {
+        if ((videoState & VideoProfile.VideoState.TX_ENABLED)
+                == VideoProfile.VideoState.TX_ENABLED) {
+            return Calls.FEATURES_VIDEO;
+        }
+        return 0;
+    }
+
+    /**
+     * Retrieve the phone number from the call, and then process it before returning the
+     * actual number that is to be logged.
+     *
+     * @param call The phone connection.
+     * @return the phone number to be logged.
+     */
+    private String getLogNumber(Call call) {
+        Uri handle = call.getOriginalHandle();
+
+        if (handle == null) {
+            return null;
+        }
+
+        String handleString = handle.getSchemeSpecificPart();
+        if (!PhoneNumberUtils.isUriNumber(handleString)) {
+            handleString = PhoneNumberUtils.stripSeparators(handleString);
+        }
+        return handleString;
+    }
+
+    /**
+     * Gets the presentation from the {@link Call}.
+     *
+     * TODO: There needs to be a way to pass information from
+     * Connection.getNumberPresentation() into a {@link Call} object. Until then, always return
+     * PhoneConstants.PRESENTATION_ALLOWED. On top of that, we might need to introduce
+     * getNumberPresentation to the ContactInfo object as well.
+     *
+     * @param call The call object to retrieve caller details from.
+     * @return The number presentation constant to insert into the call logs.
+     */
+    private int getPresentation(Call call) {
+        return PhoneConstants.PRESENTATION_ALLOWED;
+    }
+
+    /**
+     * Adds the call defined by the parameters in the provided AddCallArgs to the CallLogProvider
+     * using an AsyncTask to avoid blocking the main thread.
+     *
+     * @param args Prepopulated call details.
+     * @return A handle to the AsyncTask that will add the call to the call log asynchronously.
+     */
+    public AsyncTask<AddCallArgs, Void, Uri[]> logCallAsync(AddCallArgs args) {
+        return new LogCallAsyncTask().execute(args);
+    }
+
+    /**
+     * Helper AsyncTask to access the call logs database asynchronously since database operations
+     * can take a long time depending on the system's load. Since it extends AsyncTask, it uses
+     * its own thread pool.
+     */
+    private class LogCallAsyncTask extends AsyncTask<AddCallArgs, Void, Uri[]> {
+        @Override
+        protected Uri[] doInBackground(AddCallArgs... callList) {
+            int count = callList.length;
+            Uri[] result = new Uri[count];
+            for (int i = 0; i < count; i++) {
+                AddCallArgs c = callList[i];
+
+                try {
+                    // May block.
+                    result[i] = Calls.addCall(c.callerInfo, c.context, c.number, c.presentation,
+                            c.callType, c.features, c.accountHandle, c.timestamp, c.durationInSec,
+                            c.dataUsage, true /* addForAllUsers */);
+                } catch (Exception e) {
+                    // This is very rare but may happen in legitimate cases.
+                    // E.g. If the phone is encrypted and thus write request fails, it may cause
+                    // some kind of Exception (right now it is IllegalArgumentException, but this
+                    // might change).
+                    //
+                    // We don't want to crash the whole process just because of that, so just log
+                    // it instead.
+                    Log.e(TAG, e, "Exception raised during adding CallLog entry.");
+                    result[i] = null;
+                }
+            }
+            return result;
+        }
+
+        /**
+         * Performs a simple sanity check to make sure the call was written in the database.
+         * Typically there is only one result per call so it is easy to identify which one failed.
+         */
+        @Override
+        protected void onPostExecute(Uri[] result) {
+            for (Uri uri : result) {
+                if (uri == null) {
+                    Log.w(TAG, "Failed to write call to the log.");
+                }
+            }
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
new file mode 100644
index 0000000..d0aa49f
--- /dev/null
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -0,0 +1,871 @@
+/*
+ * 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.server.telecom;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.telecom.AudioState;
+import android.telecom.CallState;
+import android.telecom.GatewayInfo;
+import android.telecom.ParcelableConference;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.DisconnectCause;
+import android.telephony.TelephonyManager;
+
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableList;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Singleton.
+ *
+ * NOTE: by design most APIs are package private, use the relevant adapter/s to allow
+ * access from other packages specifically refraining from passing the CallsManager instance
+ * beyond the com.android.server.telecom package boundary.
+ */
+public final class CallsManager extends Call.ListenerBase {
+
+    // TODO: Consider renaming this CallsManagerPlugin.
+    interface CallsManagerListener {
+        void onCallAdded(Call call);
+        void onCallRemoved(Call call);
+        void onCallStateChanged(Call call, int oldState, int newState);
+        void onConnectionServiceChanged(
+                Call call,
+                ConnectionServiceWrapper oldService,
+                ConnectionServiceWrapper newService);
+        void onIncomingCallAnswered(Call call);
+        void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage);
+        void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall);
+        void onAudioStateChanged(AudioState oldAudioState, AudioState newAudioState);
+        void onRingbackRequested(Call call, boolean ringback);
+        void onIsConferencedChanged(Call call);
+        void onIsVoipAudioModeChanged(Call call);
+        void onVideoStateChanged(Call call);
+    }
+
+    private static final CallsManager INSTANCE = new CallsManager();
+
+    /**
+     * The main call repository. Keeps an instance of all live calls. New incoming and outgoing
+     * calls are added to the map and removed when the calls move to the disconnected state.
+    *
+     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
+     * load factor before resizing, 1 means we only expect a single thread to
+     * access the map so make only a single shard
+     */
+    private final Set<Call> mCalls = Collections.newSetFromMap(
+            new ConcurrentHashMap<Call, Boolean>(8, 0.9f, 1));
+
+    private final ConnectionServiceRepository mConnectionServiceRepository =
+            new ConnectionServiceRepository();
+    private final DtmfLocalTonePlayer mDtmfLocalTonePlayer = new DtmfLocalTonePlayer();
+    private final InCallController mInCallController = new InCallController();
+    private final CallAudioManager mCallAudioManager;
+    private final Ringer mRinger;
+    // For this set initial table size to 16 because we add 13 listeners in
+    // the CallsManager constructor.
+    private final Set<CallsManagerListener> mListeners = Collections.newSetFromMap(
+            new ConcurrentHashMap<CallsManagerListener, Boolean>(16, 0.9f, 1));
+    private final HeadsetMediaButton mHeadsetMediaButton;
+    private final WiredHeadsetManager mWiredHeadsetManager;
+    private final TtyManager mTtyManager;
+    private final ProximitySensorManager mProximitySensorManager;
+
+    /**
+     * The call the user is currently interacting with. This is the call that should have audio
+     * focus and be visible in the in-call UI.
+     */
+    private Call mForegroundCall;
+
+    /** Singleton accessor. */
+    static CallsManager getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * Initializes the required Telecom components.
+     */
+    private CallsManager() {
+        TelecomApp app = TelecomApp.getInstance();
+
+        StatusBarNotifier statusBarNotifier = new StatusBarNotifier(app, this);
+        mWiredHeadsetManager = new WiredHeadsetManager(app);
+        mCallAudioManager = new CallAudioManager(app, statusBarNotifier, mWiredHeadsetManager);
+        InCallTonePlayer.Factory playerFactory = new InCallTonePlayer.Factory(mCallAudioManager);
+        mRinger = new Ringer(mCallAudioManager, this, playerFactory, app);
+        mHeadsetMediaButton = new HeadsetMediaButton(app, this);
+        mTtyManager = new TtyManager(app, mWiredHeadsetManager);
+        mProximitySensorManager = new ProximitySensorManager(app);
+
+        mListeners.add(statusBarNotifier);
+        mListeners.add(new CallLogManager(app));
+        mListeners.add(new PhoneStateBroadcaster());
+        mListeners.add(mInCallController);
+        mListeners.add(mRinger);
+        mListeners.add(new RingbackPlayer(this, playerFactory));
+        mListeners.add(new InCallToneMonitor(playerFactory, this));
+        mListeners.add(mCallAudioManager);
+        mListeners.add(app.getMissedCallNotifier());
+        mListeners.add(mDtmfLocalTonePlayer);
+        mListeners.add(mHeadsetMediaButton);
+        mListeners.add(RespondViaSmsManager.getInstance());
+        mListeners.add(mProximitySensorManager);
+    }
+
+    @Override
+    public void onSuccessfulOutgoingCall(Call call, int callState) {
+        Log.v(this, "onSuccessfulOutgoingCall, %s", call);
+
+        setCallState(call, callState);
+        if (!mCalls.contains(call)) {
+            // Call was not added previously in startOutgoingCall due to it being a potential MMI
+            // code, so add it now.
+            addCall(call);
+        }
+
+        // The call's ConnectionService has been updated.
+        for (CallsManagerListener listener : mListeners) {
+            listener.onConnectionServiceChanged(call, null, call.getConnectionService());
+        }
+
+        markCallAsDialing(call);
+    }
+
+    @Override
+    public void onFailedOutgoingCall(Call call, int errorCode, String errorMsg) {
+        Log.v(this, "onFailedOutgoingCall, call: %s", call);
+
+        // TODO: Replace disconnect cause with more specific disconnect causes.
+        markCallAsDisconnected(call, errorCode, errorMsg);
+    }
+
+    @Override
+    public void onSuccessfulIncomingCall(Call call) {
+        Log.d(this, "onSuccessfulIncomingCall");
+        setCallState(call, CallState.RINGING);
+        addCall(call);
+    }
+
+    @Override
+    public void onFailedIncomingCall(Call call) {
+        setCallState(call, CallState.DISCONNECTED);
+        call.removeListener(this);
+    }
+
+    @Override
+    public void onRingbackRequested(Call call, boolean ringback) {
+        for (CallsManagerListener listener : mListeners) {
+            listener.onRingbackRequested(call, ringback);
+        }
+    }
+
+    @Override
+    public void onPostDialWait(Call call, String remaining) {
+        mInCallController.onPostDialWait(call, remaining);
+    }
+
+    @Override
+    public void onParentChanged(Call call) {
+        for (CallsManagerListener listener : mListeners) {
+            listener.onIsConferencedChanged(call);
+        }
+    }
+
+    @Override
+    public void onChildrenChanged(Call call) {
+        for (CallsManagerListener listener : mListeners) {
+            listener.onIsConferencedChanged(call);
+        }
+    }
+
+    @Override
+    public void onIsVoipAudioModeChanged(Call call) {
+        for (CallsManagerListener listener : mListeners) {
+            listener.onIsVoipAudioModeChanged(call);
+        }
+    }
+
+    @Override
+    public void onVideoStateChanged(Call call) {
+        for (CallsManagerListener listener : mListeners) {
+            listener.onVideoStateChanged(call);
+        }
+    }
+
+    ImmutableCollection<Call> getCalls() {
+        return ImmutableList.copyOf(mCalls);
+    }
+
+    Call getForegroundCall() {
+        return mForegroundCall;
+    }
+
+    Ringer getRinger() {
+        return mRinger;
+    }
+
+    InCallController getInCallController() {
+        return mInCallController;
+    }
+
+    boolean hasEmergencyCall() {
+        for (Call call : mCalls) {
+            if (call.isEmergencyCall()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    AudioState getAudioState() {
+        return mCallAudioManager.getAudioState();
+    }
+
+    boolean isTtySupported() {
+        return mTtyManager.isTtySupported();
+    }
+
+    int getCurrentTtyMode() {
+        return mTtyManager.getCurrentTtyMode();
+    }
+
+    /**
+     * Starts the process to attach the call to a connection service.
+     *
+     * @param phoneAccountHandle The phone account which contains the component name of the
+     *        connection service to use for this call.
+     * @param extras The optional extras Bundle passed with the intent used for the incoming call.
+     */
+    void processIncomingCallIntent(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
+        Log.d(this, "processIncomingCallIntent");
+        Uri handle = extras.getParcelable(TelephonyManager.EXTRA_INCOMING_NUMBER);
+        Call call = new Call(
+                mConnectionServiceRepository,
+                handle,
+                null /* gatewayInfo */,
+                null /* connectionManagerPhoneAccount */,
+                phoneAccountHandle,
+                true /* isIncoming */,
+                false /* isConference */);
+
+        call.setExtras(extras);
+        // TODO: Move this to be a part of addCall()
+        call.addListener(this);
+        call.startCreateConnection();
+    }
+
+    /**
+     * Kicks off the first steps to creating an outgoing call so that InCallUI can launch.
+     *
+     * @param handle Handle to connect the call with.
+     * @param phoneAccountHandle The phone account which contains the component name of the
+     *        connection service to use for this call.
+     * @param extras The optional extras Bundle passed with the intent used for the incoming call.
+     */
+    Call startOutgoingCall(Uri handle, PhoneAccountHandle phoneAccountHandle, Bundle extras) {
+        // We only allow a single outgoing call at any given time. Before placing a call, make sure
+        // there doesn't already exist another outgoing call.
+        Call call = getFirstCallWithState(CallState.NEW, CallState.DIALING,
+                CallState.CONNECTING, CallState.PRE_DIAL_WAIT);
+
+        if (call != null) {
+            Log.i(this, "Canceling simultaneous outgoing call.");
+            return null;
+        }
+
+        TelecomApp app = TelecomApp.getInstance();
+
+        // Only dial with the requested phoneAccount if it is still valid. Otherwise treat this call
+        // as if a phoneAccount was not specified (does the default behavior instead).
+        // Note: We will not attempt to dial with a requested phoneAccount if it is disabled.
+        if (phoneAccountHandle != null) {
+            List<PhoneAccountHandle> enabledAccounts =
+                    app.getPhoneAccountRegistrar().getEnabledPhoneAccounts(handle.getScheme());
+            if (!enabledAccounts.contains(phoneAccountHandle)) {
+                phoneAccountHandle = null;
+            }
+        }
+
+        if (phoneAccountHandle == null) {
+            // No preset account, check if default exists that supports the URI scheme for the
+            // handle.
+            PhoneAccountHandle defaultAccountHandle =
+                    app.getPhoneAccountRegistrar().getDefaultOutgoingPhoneAccount(
+                            handle.getScheme());
+            if (defaultAccountHandle != null) {
+                phoneAccountHandle = defaultAccountHandle;
+            }
+        }
+
+        // Create a call with original handle. The handle may be changed when the call is attached
+        // to a connection service, but in most cases will remain the same.
+        call = new Call(
+                mConnectionServiceRepository,
+                handle,
+                null /* gatewayInfo */,
+                null /* connectionManagerPhoneAccount */,
+                phoneAccountHandle,
+                false /* isIncoming */,
+                false /* isConference */);
+        call.setExtras(extras);
+
+        final boolean emergencyCall = TelephonyUtil.shouldProcessAsEmergency(app, call.getHandle());
+        if (phoneAccountHandle == null && !emergencyCall) {
+            // This is the state where the user is expected to select an account
+            call.setState(CallState.PRE_DIAL_WAIT);
+        } else {
+            call.setState(CallState.CONNECTING);
+        }
+
+        if (!isPotentialMMICode(handle)) {
+            addCall(call);
+        } else {
+            call.addListener(this);
+        }
+
+        return call;
+    }
+
+    /**
+     * Attempts to issue/connect the specified call.
+     *
+     * @param handle Handle to connect the call with.
+     * @param gatewayInfo Optional gateway information that can be used to route the call to the
+     *        actual dialed handle via a gateway provider. May be null.
+     * @param speakerphoneOn Whether or not to turn the speakerphone on once the call connects.
+     * @param videoState The desired video state for the outgoing call.
+     */
+    void placeOutgoingCall(Call call, Uri handle, GatewayInfo gatewayInfo, boolean speakerphoneOn,
+            int videoState) {
+        if (call == null) {
+            // don't do anything if the call no longer exists
+            Log.i(this, "Canceling unknown call.");
+            return;
+        }
+
+        final Uri uriHandle = (gatewayInfo == null) ? handle : gatewayInfo.getGatewayAddress();
+
+        if (gatewayInfo == null) {
+            Log.i(this, "Creating a new outgoing call with handle: %s", Log.piiHandle(uriHandle));
+        } else {
+            Log.i(this, "Creating a new outgoing call with gateway handle: %s, original handle: %s",
+                    Log.pii(uriHandle), Log.pii(handle));
+        }
+
+        call.setHandle(uriHandle);
+        call.setGatewayInfo(gatewayInfo);
+        call.setStartWithSpeakerphoneOn(speakerphoneOn);
+        call.setVideoState(videoState);
+
+        TelecomApp app = TelecomApp.getInstance();
+        final boolean emergencyCall = TelephonyUtil.shouldProcessAsEmergency(app, call.getHandle());
+        if (emergencyCall) {
+            // Emergency -- CreateConnectionProcessor will choose accounts automatically
+            call.setTargetPhoneAccount(null);
+        }
+
+        if (call.getTargetPhoneAccount() != null || emergencyCall) {
+            // If the account has been set, proceed to place the outgoing call.
+            // Otherwise the connection will be initiated when the account is set by the user.
+            call.startCreateConnection();
+        }
+    }
+
+    /**
+     * Attempts to start a conference call for the specified call.
+     *
+     * @param call The call to conference.
+     * @param otherCall The other call to conference with.
+     */
+    void conference(Call call, Call otherCall) {
+        call.conferenceWith(otherCall);
+    }
+
+    /**
+     * Instructs Telecom to answer the specified call. Intended to be invoked by the in-call
+     * app through {@link InCallAdapter} after Telecom notifies it of an incoming call followed by
+     * the user opting to answer said call.
+     *
+     * @param call The call to answer.
+     * @param videoState The video state in which to answer the call.
+     */
+    void answerCall(Call call, int videoState) {
+        if (!mCalls.contains(call)) {
+            Log.i(this, "Request to answer a non-existent call %s", call);
+        } else {
+            // If the foreground call is not the ringing call and it is currently isActive() or
+            // STATE_DIALING, put it on hold before answering the call.
+            if (mForegroundCall != null && mForegroundCall != call &&
+                    (mForegroundCall.isActive() ||
+                     mForegroundCall.getState() == CallState.DIALING)) {
+                Log.v(this, "Holding active/dialing call %s before answering incoming call %s.",
+                        mForegroundCall, call);
+                mForegroundCall.hold();
+                // TODO: Wait until we get confirmation of the active call being
+                // on-hold before answering the new call.
+                // TODO: Import logic from CallManager.acceptCall()
+            }
+
+            for (CallsManagerListener listener : mListeners) {
+                listener.onIncomingCallAnswered(call);
+            }
+
+            // We do not update the UI until we get confirmation of the answer() through
+            // {@link #markCallAsActive}.
+            call.answer(videoState);
+        }
+    }
+
+    /**
+     * Instructs Telecom to reject the specified call. Intended to be invoked by the in-call
+     * app through {@link InCallAdapter} after Telecom notifies it of an incoming call followed by
+     * the user opting to reject said call.
+     */
+    void rejectCall(Call call, boolean rejectWithMessage, String textMessage) {
+        if (!mCalls.contains(call)) {
+            Log.i(this, "Request to reject a non-existent call %s", call);
+        } else {
+            for (CallsManagerListener listener : mListeners) {
+                listener.onIncomingCallRejected(call, rejectWithMessage, textMessage);
+            }
+            call.reject(rejectWithMessage, textMessage);
+        }
+    }
+
+    /**
+     * Instructs Telecom to play the specified DTMF tone within the specified call.
+     *
+     * @param digit The DTMF digit to play.
+     */
+    void playDtmfTone(Call call, char digit) {
+        if (!mCalls.contains(call)) {
+            Log.i(this, "Request to play DTMF in a non-existent call %s", call);
+        } else {
+            call.playDtmfTone(digit);
+            mDtmfLocalTonePlayer.playTone(call, digit);
+        }
+    }
+
+    /**
+     * Instructs Telecom to stop the currently playing DTMF tone, if any.
+     */
+    void stopDtmfTone(Call call) {
+        if (!mCalls.contains(call)) {
+            Log.i(this, "Request to stop DTMF in a non-existent call %s", call);
+        } else {
+            call.stopDtmfTone();
+            mDtmfLocalTonePlayer.stopTone(call);
+        }
+    }
+
+    /**
+     * Instructs Telecom to continue (or not) the current post-dial DTMF string, if any.
+     */
+    void postDialContinue(Call call, boolean proceed) {
+        if (!mCalls.contains(call)) {
+            Log.i(this, "Request to continue post-dial string in a non-existent call %s", call);
+        } else {
+            call.postDialContinue(proceed);
+        }
+    }
+
+    /**
+     * Instructs Telecom to disconnect the specified call. Intended to be invoked by the
+     * in-call app through {@link InCallAdapter} for an ongoing call. This is usually triggered by
+     * the user hitting the end-call button.
+     */
+    void disconnectCall(Call call) {
+        Log.v(this, "disconnectCall %s", call);
+
+        if (!mCalls.contains(call)) {
+            Log.w(this, "Unknown call (%s) asked to disconnect", call);
+        } else {
+            call.disconnect();
+        }
+    }
+
+    /**
+     * Instructs Telecom to disconnect all calls.
+     */
+    void disconnectAllCalls() {
+        Log.v(this, "disconnectAllCalls");
+
+        for (Call call : mCalls) {
+            disconnectCall(call);
+        }
+    }
+
+
+    /**
+     * Instructs Telecom to put the specified call on hold. Intended to be invoked by the
+     * in-call app through {@link InCallAdapter} for an ongoing call. This is usually triggered by
+     * the user hitting the hold button during an active call.
+     */
+    void holdCall(Call call) {
+        if (!mCalls.contains(call)) {
+            Log.w(this, "Unknown call (%s) asked to be put on hold", call);
+        } else {
+            Log.d(this, "Putting call on hold: (%s)", call);
+            call.hold();
+        }
+    }
+
+    /**
+     * Instructs Telecom to release the specified call from hold. Intended to be invoked by
+     * the in-call app through {@link InCallAdapter} for an ongoing call. This is usually triggered
+     * by the user hitting the hold button during a held call.
+     */
+    void unholdCall(Call call) {
+        if (!mCalls.contains(call)) {
+            Log.w(this, "Unknown call (%s) asked to be removed from hold", call);
+        } else {
+            Log.d(this, "unholding call: (%s)", call);
+            for (Call c : mCalls) {
+                if (c != null && c.isAlive() && c != call) {
+                    c.hold();
+                }
+            }
+            call.unhold();
+        }
+    }
+
+    /** Called by the in-call UI to change the mute state. */
+    void mute(boolean shouldMute) {
+        mCallAudioManager.mute(shouldMute);
+    }
+
+    /**
+      * Called by the in-call UI to change the audio route, for example to change from earpiece to
+      * speaker phone.
+      */
+    void setAudioRoute(int route) {
+        mCallAudioManager.setAudioRoute(route);
+    }
+
+    /** Called by the in-call UI to turn the proximity sensor on. */
+    void turnOnProximitySensor() {
+        mProximitySensorManager.turnOn();
+    }
+
+    /**
+     * Called by the in-call UI to turn the proximity sensor off.
+     * @param screenOnImmediately If true, the screen will be turned on immediately. Otherwise,
+     *        the screen will be kept off until the proximity sensor goes negative.
+     */
+    void turnOffProximitySensor(boolean screenOnImmediately) {
+        mProximitySensorManager.turnOff(screenOnImmediately);
+    }
+
+    void phoneAccountSelected(Call call, PhoneAccountHandle account) {
+        if (!mCalls.contains(call)) {
+            Log.i(this, "Attemped to add account to unknown call %s", call);
+        } else {
+            call.setTargetPhoneAccount(account);
+            call.startCreateConnection();
+        }
+    }
+
+    /** Called when the audio state changes. */
+    void onAudioStateChanged(AudioState oldAudioState, AudioState newAudioState) {
+        Log.v(this, "onAudioStateChanged, audioState: %s -> %s", oldAudioState, newAudioState);
+        for (CallsManagerListener listener : mListeners) {
+            listener.onAudioStateChanged(oldAudioState, newAudioState);
+        }
+    }
+
+    void markCallAsRinging(Call call) {
+        setCallState(call, CallState.RINGING);
+    }
+
+    void markCallAsDialing(Call call) {
+        setCallState(call, CallState.DIALING);
+    }
+
+    void markCallAsActive(Call call) {
+        if (call.getConnectTimeMillis() == 0) {
+            call.setConnectTimeMillis(System.currentTimeMillis());
+        }
+        setCallState(call, CallState.ACTIVE);
+
+        if (call.getStartWithSpeakerphoneOn()) {
+            setAudioRoute(AudioState.ROUTE_SPEAKER);
+        }
+    }
+
+    void markCallAsOnHold(Call call) {
+        setCallState(call, CallState.ON_HOLD);
+    }
+
+    /**
+     * Marks the specified call as STATE_DISCONNECTED and notifies the in-call app. If this was the last
+     * live call, then also disconnect from the in-call controller.
+     *
+     * @param disconnectCause The disconnect reason, see {@link android.telephony.DisconnectCause}.
+     * @param disconnectMessage Optional message about the disconnect.
+     */
+    void markCallAsDisconnected(Call call, int disconnectCause, String disconnectMessage) {
+        call.setDisconnectCause(disconnectCause, disconnectMessage);
+        setCallState(call, CallState.DISCONNECTED);
+        removeCall(call);
+    }
+
+    /**
+     * Removes an existing disconnected call, and notifies the in-call app.
+     */
+    void markCallAsRemoved(Call call) {
+        removeCall(call);
+    }
+
+    /**
+     * Cleans up any calls currently associated with the specified connection service when the
+     * service binder disconnects unexpectedly.
+     *
+     * @param service The connection service that disconnected.
+     */
+    void handleConnectionServiceDeath(ConnectionServiceWrapper service) {
+        if (service != null) {
+            for (Call call : mCalls) {
+                if (call.getConnectionService() == service) {
+                    markCallAsDisconnected(call, DisconnectCause.ERROR_UNSPECIFIED, null);
+                }
+            }
+        }
+    }
+
+    boolean hasAnyCalls() {
+        return !mCalls.isEmpty();
+    }
+
+    boolean hasActiveOrHoldingCall() {
+        return getFirstCallWithState(CallState.ACTIVE, CallState.ON_HOLD) != null;
+    }
+
+    boolean hasRingingCall() {
+        return getFirstCallWithState(CallState.RINGING) != null;
+    }
+
+    boolean onMediaButton(int type) {
+        if (hasAnyCalls()) {
+            if (HeadsetMediaButton.SHORT_PRESS == type) {
+                Call ringingCall = getFirstCallWithState(CallState.RINGING);
+                if (ringingCall == null) {
+                    mCallAudioManager.toggleMute();
+                    return true;
+                } else {
+                    ringingCall.answer(ringingCall.getVideoState());
+                    return true;
+                }
+            } else if (HeadsetMediaButton.LONG_PRESS == type) {
+                Log.d(this, "handleHeadsetHook: longpress -> hangup");
+                Call callToHangup = getFirstCallWithState(
+                        CallState.RINGING, CallState.DIALING, CallState.ACTIVE, CallState.ON_HOLD);
+                if (callToHangup != null) {
+                    callToHangup.disconnect();
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks to see if the specified call is the only high-level call and if so, enable the
+     * "Add-call" button. We allow you to add a second call but not a third or beyond.
+     *
+     * @param call The call to test for add-call.
+     * @return Whether the add-call feature should be enabled for the call.
+     */
+    protected boolean isAddCallCapable(Call call) {
+        if (call.getParentCall() != null) {
+            // Never true for child calls.
+            return false;
+        }
+
+        // Loop through all the other calls and there exists a top level (has no parent) call
+        // that is not the specified call, return false.
+        for (Call otherCall : mCalls) {
+            if (call != otherCall && otherCall.getParentCall() == null) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the first call that it finds with the given states. The states are treated as having
+     * priority order so that any call with the first state will be returned before any call with
+     * states listed later in the parameter list.
+     */
+    Call getFirstCallWithState(int... states) {
+        for (int currentState : states) {
+            // check the foreground first
+            if (mForegroundCall != null && mForegroundCall.getState() == currentState) {
+                return mForegroundCall;
+            }
+
+            for (Call call : mCalls) {
+                if (currentState == call.getState()) {
+                    return call;
+                }
+            }
+        }
+        return null;
+    }
+
+    Call createConferenceCall(
+            PhoneAccountHandle phoneAccount,
+            ParcelableConference parcelableConference) {
+        Call call = new Call(
+                mConnectionServiceRepository,
+                null /* handle */,
+                null /* gatewayInfo */,
+                null /* connectionManagerPhoneAccount */,
+                phoneAccount,
+                false /* isIncoming */,
+                true /* isConference */);
+
+        setCallState(call, Call.getStateFromConnectionState(parcelableConference.getState()));
+        if (call.getState() == CallState.ACTIVE) {
+            call.setConnectTimeMillis(System.currentTimeMillis());
+        }
+        call.setCallCapabilities(parcelableConference.getCapabilities());
+
+        // TODO: Move this to be a part of addCall()
+        call.addListener(this);
+        addCall(call);
+        return call;
+    }
+
+
+    /**
+     * Adds the specified call to the main list of live calls.
+     *
+     * @param call The call to add.
+     */
+    private void addCall(Call call) {
+        Log.v(this, "addCall(%s)", call);
+
+        call.addListener(this);
+        mCalls.add(call);
+
+        // TODO: Update mForegroundCall prior to invoking
+        // onCallAdded for calls which immediately take the foreground (like the first call).
+        for (CallsManagerListener listener : mListeners) {
+            listener.onCallAdded(call);
+        }
+        updateForegroundCall();
+    }
+
+    private void removeCall(Call call) {
+        Log.v(this, "removeCall(%s)", call);
+
+        call.setParentCall(null);  // need to clean up parent relationship before destroying.
+        call.removeListener(this);
+        call.clearConnectionService();
+
+        boolean shouldNotify = false;
+        if (mCalls.contains(call)) {
+            mCalls.remove(call);
+            shouldNotify = true;
+        }
+
+        // Only broadcast changes for calls that are being tracked.
+        if (shouldNotify) {
+            for (CallsManagerListener listener : mListeners) {
+                listener.onCallRemoved(call);
+            }
+            updateForegroundCall();
+        }
+    }
+
+    /**
+     * Sets the specified state on the specified call.
+     *
+     * @param call The call.
+     * @param newState The new state of the call.
+     */
+    private void setCallState(Call call, int newState) {
+        if (call == null) {
+            return;
+        }
+        int oldState = call.getState();
+        Log.i(this, "setCallState %s -> %s, call: %s", CallState.toString(oldState),
+                CallState.toString(newState), call);
+        if (newState != oldState) {
+            // Unfortunately, in the telephony world the radio is king. So if the call notifies
+            // us that the call is in a particular state, we allow it even if it doesn't make
+            // sense (e.g., STATE_ACTIVE -> STATE_RINGING).
+            // TODO: Consider putting a stop to the above and turning CallState
+            // into a well-defined state machine.
+            // TODO: Define expected state transitions here, and log when an
+            // unexpected transition occurs.
+            call.setState(newState);
+
+            // Only broadcast state change for calls that are being tracked.
+            if (mCalls.contains(call)) {
+                for (CallsManagerListener listener : mListeners) {
+                    listener.onCallStateChanged(call, oldState, newState);
+                }
+                updateForegroundCall();
+            }
+        }
+    }
+
+    /**
+     * Checks which call should be visible to the user and have audio focus.
+     */
+    private void updateForegroundCall() {
+        Call newForegroundCall = null;
+        for (Call call : mCalls) {
+            // TODO: Foreground-ness needs to be explicitly set. No call, regardless
+            // of its state will be foreground by default and instead the connection service should
+            // be notified when its calls enter and exit foreground state. Foreground will mean that
+            // the call should play audio and listen to microphone if it wants.
+
+            // Active calls have priority.
+            if (call.isActive()) {
+                newForegroundCall = call;
+                break;
+            }
+
+            if (call.isAlive() || call.getState() == CallState.RINGING) {
+                newForegroundCall = call;
+                // Don't break in case there's an active call that has priority.
+            }
+        }
+
+        if (newForegroundCall != mForegroundCall) {
+            Log.v(this, "Updating foreground call, %s -> %s.", mForegroundCall, newForegroundCall);
+            Call oldForegroundCall = mForegroundCall;
+            mForegroundCall = newForegroundCall;
+
+            for (CallsManagerListener listener : mListeners) {
+                listener.onForegroundCallChanged(oldForegroundCall, mForegroundCall);
+            }
+        }
+    }
+
+    private boolean isPotentialMMICode(Uri handle) {
+        return (handle != null && handle.getSchemeSpecificPart() != null
+                && handle.getSchemeSpecificPart().contains("#"));
+    }
+}
diff --git a/src/com/android/server/telecom/CallsManagerListenerBase.java b/src/com/android/server/telecom/CallsManagerListenerBase.java
new file mode 100644
index 0000000..93b2a24
--- /dev/null
+++ b/src/com/android/server/telecom/CallsManagerListenerBase.java
@@ -0,0 +1,75 @@
+/*
+ * 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.server.telecom;
+
+import android.telecom.AudioState;
+
+/**
+ * Provides a default implementation for listeners of CallsManager.
+ */
+class CallsManagerListenerBase implements CallsManager.CallsManagerListener {
+    @Override
+    public void onCallAdded(Call call) {
+    }
+
+    @Override
+    public void onCallRemoved(Call call) {
+    }
+
+    @Override
+    public void onCallStateChanged(Call call, int oldState, int newState) {
+    }
+
+    @Override
+    public void onConnectionServiceChanged(
+            Call call,
+            ConnectionServiceWrapper oldService,
+            ConnectionServiceWrapper newService) {
+    }
+
+    @Override
+    public void onIncomingCallAnswered(Call call) {
+    }
+
+    @Override
+    public void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage) {
+    }
+
+    @Override
+    public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
+    }
+
+    @Override
+    public void onAudioStateChanged(AudioState oldAudioState, AudioState newAudioState) {
+    }
+
+    @Override
+    public void onRingbackRequested(Call call, boolean ringback) {
+    }
+
+    @Override
+    public void onIsConferencedChanged(Call call) {
+    }
+
+    @Override
+    public void onIsVoipAudioModeChanged(Call call) {
+    }
+
+    @Override
+    public void onVideoStateChanged(Call call) {
+    }
+}
diff --git a/src/com/android/server/telecom/ConnectionServiceRepository.java b/src/com/android/server/telecom/ConnectionServiceRepository.java
new file mode 100644
index 0000000..d7a6d3e
--- /dev/null
+++ b/src/com/android/server/telecom/ConnectionServiceRepository.java
@@ -0,0 +1,56 @@
+/*
+ * 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.server.telecom;
+
+import android.content.ComponentName;
+
+import java.util.HashMap;
+
+/**
+ * Searches for and returns connection services.
+ */
+final class ConnectionServiceRepository
+        implements ServiceBinder.Listener<ConnectionServiceWrapper> {
+    private final HashMap<ComponentName, ConnectionServiceWrapper> mServiceCache =
+            new HashMap<ComponentName, ConnectionServiceWrapper>();
+
+    ConnectionServiceRepository() {
+    }
+
+    ConnectionServiceWrapper getService(ComponentName componentName) {
+        ConnectionServiceWrapper service = mServiceCache.get(componentName);
+        if (service == null) {
+            service = new ConnectionServiceWrapper(
+                    componentName,
+                    this,
+                    TelecomApp.getInstance().getPhoneAccountRegistrar());
+            service.addListener(this);
+            mServiceCache.put(componentName, service);
+        }
+        return service;
+    }
+
+    /**
+     * Removes the specified service from the cache when the service unbinds.
+     *
+     * {@inheritDoc}
+     */
+    @Override
+    public void onUnbind(ConnectionServiceWrapper service) {
+        mServiceCache.remove(service.getComponentName());
+    }
+}
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
new file mode 100644
index 0000000..669f9a5
--- /dev/null
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -0,0 +1,1003 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.content.ComponentName;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.telecom.AudioState;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.ConnectionService;
+import android.telecom.GatewayInfo;
+import android.telecom.ParcelableConference;
+import android.telecom.ParcelableConnection;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.StatusHints;
+import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
+import android.telephony.DisconnectCause;
+
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telecom.IConnectionService;
+import com.android.internal.telecom.IConnectionServiceAdapter;
+import com.android.internal.telecom.IVideoProvider;
+import com.android.internal.telecom.RemoteServiceCallback;
+import com.google.common.base.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Wrapper for {@link IConnectionService}s, handles binding to {@link IConnectionService} and keeps
+ * track of when the object can safely be unbound. Other classes should not use
+ * {@link IConnectionService} directly and instead should use this class to invoke methods of
+ * {@link IConnectionService}.
+ */
+final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
+    private static final int MSG_HANDLE_CREATE_CONNECTION_COMPLETE = 1;
+    private static final int MSG_SET_ACTIVE = 2;
+    private static final int MSG_SET_RINGING = 3;
+    private static final int MSG_SET_DIALING = 4;
+    private static final int MSG_SET_DISCONNECTED = 5;
+    private static final int MSG_SET_ON_HOLD = 6;
+    private static final int MSG_SET_RINGBACK_REQUESTED = 7;
+    private static final int MSG_SET_CALL_CAPABILITIES = 8;
+    private static final int MSG_SET_IS_CONFERENCED = 9;
+    private static final int MSG_ADD_CONFERENCE_CALL = 10;
+    private static final int MSG_REMOVE_CALL = 11;
+    private static final int MSG_ON_POST_DIAL_WAIT = 12;
+    private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 13;
+    private static final int MSG_SET_VIDEO_PROVIDER = 14;
+    private static final int MSG_SET_IS_VOIP_AUDIO_MODE = 15;
+    private static final int MSG_SET_STATUS_HINTS = 16;
+    private static final int MSG_SET_ADDRESS = 17;
+    private static final int MSG_SET_CALLER_DISPLAY_NAME = 18;
+    private static final int MSG_SET_VIDEO_STATE = 19;
+    private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 20;
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            Call call;
+            switch (msg.what) {
+                case MSG_HANDLE_CREATE_CONNECTION_COMPLETE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        String callId = (String) args.arg1;
+                        ConnectionRequest request = (ConnectionRequest) args.arg2;
+                        ParcelableConnection connection = (ParcelableConnection) args.arg3;
+                        handleCreateConnectionComplete(callId, request, connection);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_ACTIVE:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.markCallAsActive(call);
+                    } else {
+                        //Log.w(this, "setActive, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_SET_RINGING:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.markCallAsRinging(call);
+                    } else {
+                        //Log.w(this, "setRinging, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_SET_DIALING:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.markCallAsDialing(call);
+                    } else {
+                        //Log.w(this, "setDialing, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_SET_DISCONNECTED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        String disconnectMessage = (String) args.arg2;
+                        int disconnectCause = args.argi1;
+                        Log.d(this, "disconnect call %s %s", args.arg1, call);
+                        if (call != null) {
+                            mCallsManager.markCallAsDisconnected(call, disconnectCause,
+                                    disconnectMessage);
+                        } else {
+                            //Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_ON_HOLD:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.markCallAsOnHold(call);
+                    } else {
+                        //Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_SET_RINGBACK_REQUESTED: {
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        call.setRingbackRequested(msg.arg1 == 1);
+                    } else {
+                        //Log.w(this, "setRingback, unknown call id: %s", args.arg1);
+                    }
+                    break;
+                }
+                case MSG_SET_CALL_CAPABILITIES: {
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        call.setCallCapabilities(msg.arg1);
+                    } else {
+                        //Log.w(ConnectionServiceWrapper.this,
+                        //      "setCallCapabilities, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                }
+                case MSG_SET_IS_CONFERENCED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Call childCall = mCallIdMapper.getCall(args.arg1);
+                        Log.d(this, "SET_IS_CONFERENCE: %s %s", args.arg1, args.arg2);
+                        if (childCall != null) {
+                            String conferenceCallId = (String) args.arg2;
+                            if (conferenceCallId == null) {
+                                Log.d(this, "unsetting parent: %s", args.arg1);
+                                childCall.setParentCall(null);
+                            } else {
+                                Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
+                                childCall.setParentCall(conferenceCall);
+                            }
+                        } else {
+                            //Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_ADD_CONFERENCE_CALL: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        String id = (String) args.arg1;
+                        if (mCallIdMapper.getCall(id) != null) {
+                            Log.w(this, "Attempting to add a conference call using an existing " +
+                                    "call id %s", id);
+                            break;
+                        }
+                        ParcelableConference parcelableConference =
+                                (ParcelableConference) args.arg2;
+                        // need to create a new Call
+                        Call conferenceCall = mCallsManager.createConferenceCall(
+                                null, parcelableConference);
+                        mCallIdMapper.addCall(conferenceCall, id);
+                        conferenceCall.setConnectionService(ConnectionServiceWrapper.this);
+
+                        Log.d(this, "adding children to conference %s",
+                                parcelableConference.getConnectionIds());
+                        for (String callId : parcelableConference.getConnectionIds()) {
+                            Call childCall = mCallIdMapper.getCall(callId);
+                            Log.d(this, "found child: %s", callId);
+                            if (childCall != null) {
+                                childCall.setParentCall(conferenceCall);
+                            }
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_REMOVE_CALL: {
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        if (call.isActive()) {
+                            mCallsManager.markCallAsDisconnected(
+                                    call, DisconnectCause.NORMAL, null);
+                        } else {
+                            mCallsManager.markCallAsRemoved(call);
+                        }
+                    }
+                    break;
+                }
+                case MSG_ON_POST_DIAL_WAIT: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null) {
+                            String remaining = (String) args.arg2;
+                            call.onPostDialWait(remaining);
+                        } else {
+                            //Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_QUERY_REMOTE_CALL_SERVICES: {
+                    queryRemoteConnectionServices((RemoteServiceCallback) msg.obj);
+                    break;
+                }
+                case MSG_SET_VIDEO_PROVIDER: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        IVideoProvider videoProvider = (IVideoProvider) args.arg2;
+                        if (call != null) {
+                            call.setVideoProvider(videoProvider);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_IS_VOIP_AUDIO_MODE: {
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        call.setIsVoipAudioMode(msg.arg1 == 1);
+                    }
+                    break;
+                }
+                case MSG_SET_STATUS_HINTS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        StatusHints statusHints = (StatusHints) args.arg2;
+                        if (call != null) {
+                            call.setStatusHints(statusHints);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_ADDRESS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null) {
+                            call.setHandle((Uri) args.arg2, args.argi1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_CALLER_DISPLAY_NAME: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null) {
+                            call.setCallerDisplayName((String) args.arg2, args.argi1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_VIDEO_STATE: {
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        call.setVideoState(msg.arg1);
+                    }
+                    break;
+                }
+                case MSG_SET_CONFERENCEABLE_CONNECTIONS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null ){
+                            @SuppressWarnings("unchecked")
+                            List<String> conferenceableIds = (List<String>) args.arg2;
+                            List<Call> conferenceableCalls =
+                                    new ArrayList<>(conferenceableIds.size());
+                            for (String otherId : (List<String>) args.arg2) {
+                                Call otherCall = mCallIdMapper.getCall(otherId);
+                                if (otherCall != null && otherCall != call) {
+                                    conferenceableCalls.add(otherCall);
+                                }
+                            }
+                            call.setConferenceableCalls(conferenceableCalls);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+            }
+        }
+    };
+
+    private final class Adapter extends IConnectionServiceAdapter.Stub {
+
+        @Override
+        public void handleCreateConnectionComplete(
+                String callId,
+                ConnectionRequest request,
+                ParcelableConnection connection) {
+            logIncoming("handleCreateConnectionComplete %s", request);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = request;
+                args.arg3 = connection;
+                mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_COMPLETE, args)
+                        .sendToTarget();
+            }
+        }
+
+        @Override
+        public void setActive(String callId) {
+            logIncoming("setActive %s", callId);
+            if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper.isValidConferenceId(callId)) {
+                mHandler.obtainMessage(MSG_SET_ACTIVE, callId).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setRinging(String callId) {
+            logIncoming("setRinging %s", callId);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                mHandler.obtainMessage(MSG_SET_RINGING, callId).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setVideoProvider(String callId, IVideoProvider videoProvider) {
+            logIncoming("setVideoProvider %s", callId);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = videoProvider;
+                mHandler.obtainMessage(MSG_SET_VIDEO_PROVIDER, args).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setDialing(String callId) {
+            logIncoming("setDialing %s", callId);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                mHandler.obtainMessage(MSG_SET_DIALING, callId).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setDisconnected(
+                String callId, int disconnectCause, String disconnectMessage) {
+            logIncoming("setDisconnected %s %d %s", callId, disconnectCause, disconnectMessage);
+            if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper.isValidConferenceId(callId)) {
+                Log.d(this, "disconnect call %s", callId);
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = disconnectMessage;
+                args.argi1 = disconnectCause;
+                mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setOnHold(String callId) {
+            logIncoming("setOnHold %s", callId);
+            if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper.isValidConferenceId(callId)) {
+                mHandler.obtainMessage(MSG_SET_ON_HOLD, callId).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setRingbackRequested(String callId, boolean ringback) {
+            logIncoming("setRingbackRequested %s %b", callId, ringback);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                mHandler.obtainMessage(MSG_SET_RINGBACK_REQUESTED, ringback ? 1 : 0, 0, callId)
+                        .sendToTarget();
+            }
+        }
+
+        @Override
+        public void removeCall(String callId) {
+            logIncoming("removeCall %s", callId);
+            if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper.isValidConferenceId(callId)) {
+                mHandler.obtainMessage(MSG_REMOVE_CALL, callId).sendToTarget();
+                mHandler.obtainMessage(MSG_REMOVE_CALL, callId);
+            }
+        }
+
+        @Override
+        public void setCallCapabilities(String callId, int callCapabilities) {
+            logIncoming("setCallCapabilities %s %d", callId, callCapabilities);
+            if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper.isValidConferenceId(callId)) {
+                mHandler.obtainMessage(MSG_SET_CALL_CAPABILITIES, callCapabilities, 0, callId)
+                        .sendToTarget();
+            } else {
+                Log.w(this, "ID not valid for setCallCapabilities");
+            }
+        }
+
+        @Override
+        public void setIsConferenced(String callId, String conferenceCallId) {
+            logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = conferenceCallId;
+                mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
+            }
+        }
+
+        @Override
+        public void addConferenceCall(String callId, ParcelableConference parcelableConference) {
+            logIncoming("addConferenceCall %s %s", callId, parcelableConference);
+            // We do not check call Ids here because we do not yet know the call ID for new
+            // conference calls.
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = parcelableConference;
+            mHandler.obtainMessage(MSG_ADD_CONFERENCE_CALL, args).sendToTarget();
+        }
+
+        @Override
+        public void onPostDialWait(String callId, String remaining) throws RemoteException {
+            logIncoming("onPostDialWait %s %s", callId, remaining);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = remaining;
+                mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
+            }
+        }
+
+        @Override
+        public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
+            logIncoming("queryRemoteCSs");
+            mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
+        }
+
+        @Override
+        public void setVideoState(String callId, int videoState) {
+            logIncoming("setVideoState %s %d", callId, videoState);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                mHandler.obtainMessage(MSG_SET_VIDEO_STATE, videoState, 0, callId).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setIsVoipAudioMode(String callId, boolean isVoip) {
+            logIncoming("setIsVoipAudioMode %s %b", callId, isVoip);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                mHandler.obtainMessage(MSG_SET_IS_VOIP_AUDIO_MODE, isVoip ? 1 : 0, 0,
+                        callId).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setStatusHints(String callId, StatusHints statusHints) {
+            logIncoming("setStatusHints %s %s", callId, statusHints);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = statusHints;
+                mHandler.obtainMessage(MSG_SET_STATUS_HINTS, args).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setAddress(String callId, Uri address, int presentation) {
+            logIncoming("setAddress %s %s %d", callId, address, presentation);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = address;
+                args.argi1 = presentation;
+                mHandler.obtainMessage(MSG_SET_ADDRESS, args).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setCallerDisplayName(
+                String callId, String callerDisplayName, int presentation) {
+            logIncoming("setCallerDisplayName %s %s %d", callId, callerDisplayName, presentation);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = callerDisplayName;
+                args.argi1 = presentation;
+                mHandler.obtainMessage(MSG_SET_CALLER_DISPLAY_NAME, args).sendToTarget();
+            }
+        }
+
+        @Override
+        public void setConferenceableConnections(
+                String callId, List<String> conferenceableCallIds) {
+            logIncoming("setConferenceableConnections %s %s", callId, conferenceableCallIds);
+            if (mCallIdMapper.isValidCallId(callId)) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = conferenceableCallIds;
+                mHandler.obtainMessage(MSG_SET_CONFERENCEABLE_CONNECTIONS, args).sendToTarget();
+            }
+        }
+    }
+
+    private final Adapter mAdapter = new Adapter();
+    private final CallsManager mCallsManager = CallsManager.getInstance();
+    /**
+     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
+     * load factor before resizing, 1 means we only expect a single thread to
+     * access the map so make only a single shard
+     */
+    private final Set<Call> mPendingConferenceCalls = Collections.newSetFromMap(
+            new ConcurrentHashMap<Call, Boolean>(8, 0.9f, 1));
+    private final CallIdMapper mCallIdMapper = new CallIdMapper("ConnectionService");
+    private final Map<String, CreateConnectionResponse> mPendingResponses = new HashMap<>();
+
+    private Binder mBinder = new Binder();
+    private IConnectionService mServiceInterface;
+    private final ConnectionServiceRepository mConnectionServiceRepository;
+
+    /**
+     * Creates a connection service.
+     *
+     * @param componentName The component name of the service with which to bind.
+     * @param connectionServiceRepository Connection service repository.
+     * @param phoneAccountRegistrar Phone account registrar
+     */
+    ConnectionServiceWrapper(
+            ComponentName componentName,
+            ConnectionServiceRepository connectionServiceRepository,
+            PhoneAccountRegistrar phoneAccountRegistrar) {
+        super(ConnectionService.SERVICE_INTERFACE, componentName);
+        mConnectionServiceRepository = connectionServiceRepository;
+        phoneAccountRegistrar.addListener(new PhoneAccountRegistrar.Listener() {
+            // TODO -- Upon changes to PhoneAccountRegistrar, need to re-wire connections
+            // To do this, we must proxy remote ConnectionService objects
+        });
+    }
+
+    /** See {@link IConnectionService#addConnectionServiceAdapter}. */
+    private void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
+        if (isServiceValid("addConnectionServiceAdapter")) {
+            try {
+                logOutgoing("addConnectionServiceAdapter %s", adapter);
+                mServiceInterface.addConnectionServiceAdapter(adapter);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /**
+     * Creates a new connection for a new outgoing call or to attach to an existing incoming call.
+     */
+    void createConnection(final Call call, final CreateConnectionResponse response) {
+        Log.d(this, "createConnection(%s) via %s.", call, getComponentName());
+        BindCallback callback = new BindCallback() {
+            @Override
+            public void onSuccess() {
+                String callId = mCallIdMapper.getCallId(call);
+                mPendingResponses.put(callId, response);
+
+                GatewayInfo gatewayInfo = call.getGatewayInfo();
+                Bundle extras = call.getExtras();
+                if (gatewayInfo != null && gatewayInfo.getGatewayProviderPackageName() != null &&
+                        gatewayInfo.getOriginalAddress() != null) {
+                    extras = (Bundle) extras.clone();
+                    extras.putString(
+                            TelecomManager.GATEWAY_PROVIDER_PACKAGE,
+                            gatewayInfo.getGatewayProviderPackageName());
+                    extras.putParcelable(
+                            TelecomManager.GATEWAY_ORIGINAL_ADDRESS,
+                            gatewayInfo.getOriginalAddress());
+                }
+
+                try {
+                    mServiceInterface.createConnection(
+                            call.getConnectionManagerPhoneAccount(),
+                            callId,
+                            new ConnectionRequest(
+                                    call.getTargetPhoneAccount(),
+                                    call.getHandle(),
+                                    extras,
+                                    call.getVideoState()),
+                            call.isIncoming());
+                } catch (RemoteException e) {
+                    Log.e(this, e, "Failure to createConnection -- %s", getComponentName());
+                    mPendingResponses.remove(callId).handleCreateConnectionFailure(
+                            DisconnectCause.OUTGOING_FAILURE, e.toString());
+                }
+            }
+
+            @Override
+            public void onFailure() {
+                Log.e(this, new Exception(), "Failure to call %s", getComponentName());
+                response.handleCreateConnectionFailure(DisconnectCause.OUTGOING_FAILURE, null);
+            }
+        };
+
+        mBinder.bind(callback);
+    }
+
+    /** @see ConnectionService#abort(String) */
+    void abort(Call call) {
+        // Clear out any pending outgoing call data
+        final String callId = mCallIdMapper.getCallId(call);
+
+        // If still bound, tell the connection service to abort.
+        if (callId != null && isServiceValid("abort")) {
+            try {
+                logOutgoing("abort %s", callId);
+                mServiceInterface.abort(callId);
+            } catch (RemoteException e) {
+            }
+        }
+
+        removeCall(call, DisconnectCause.LOCAL, null);
+    }
+
+    /** @see ConnectionService#hold(String) */
+    void hold(Call call) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("hold")) {
+            try {
+                logOutgoing("hold %s", callId);
+                mServiceInterface.hold(callId);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#unhold(String) */
+    void unhold(Call call) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("unhold")) {
+            try {
+                logOutgoing("unhold %s", callId);
+                mServiceInterface.unhold(callId);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#onAudioStateChanged(String,AudioState) */
+    void onAudioStateChanged(Call activeCall, AudioState audioState) {
+        final String callId = mCallIdMapper.getCallId(activeCall);
+        if (callId != null && isServiceValid("onAudioStateChanged")) {
+            try {
+                logOutgoing("onAudioStateChanged %s %s", callId, audioState);
+                mServiceInterface.onAudioStateChanged(callId, audioState);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#disconnect(String) */
+    void disconnect(Call call) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("disconnect")) {
+            try {
+                logOutgoing("disconnect %s", callId);
+                mServiceInterface.disconnect(callId);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#answer(String,int) */
+    void answer(Call call, int videoState) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("answer")) {
+            try {
+                logOutgoing("answer %s %d", callId, videoState);
+                if (videoState == VideoProfile.VideoState.AUDIO_ONLY) {
+                    mServiceInterface.answer(callId);
+                } else {
+                    mServiceInterface.answerVideo(callId, videoState);
+                }
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#reject(String) */
+    void reject(Call call) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("reject")) {
+            try {
+                logOutgoing("reject %s", callId);
+                mServiceInterface.reject(callId);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#playDtmfTone(String,char) */
+    void playDtmfTone(Call call, char digit) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("playDtmfTone")) {
+            try {
+                logOutgoing("playDtmfTone %s %c", callId, digit);
+                mServiceInterface.playDtmfTone(callId, digit);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @see ConnectionService#stopDtmfTone(String) */
+    void stopDtmfTone(Call call) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("stopDtmfTone")) {
+            try {
+                logOutgoing("stopDtmfTone %s",callId);
+                mServiceInterface.stopDtmfTone(callId);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    void addCall(Call call) {
+        if (mCallIdMapper.getCallId(call) == null) {
+            mCallIdMapper.addCall(call);
+        }
+    }
+
+    /**
+     * Associates newCall with this connection service by replacing callToReplace.
+     */
+    void replaceCall(Call newCall, Call callToReplace) {
+        Preconditions.checkState(callToReplace.getConnectionService() == this);
+        mCallIdMapper.replaceCall(newCall, callToReplace);
+    }
+
+    void removeCall(Call call) {
+        removeCall(call, DisconnectCause.ERROR_UNSPECIFIED, null);
+    }
+
+    void removeCall(String callId, int disconnectCause, String disconnectMessage) {
+        CreateConnectionResponse response = mPendingResponses.remove(callId);
+        if (response != null) {
+            response.handleCreateConnectionFailure(disconnectCause, disconnectMessage);
+        }
+
+        mCallIdMapper.removeCall(callId);
+    }
+
+    void removeCall(Call call, int disconnectCause, String disconnectMessage) {
+        CreateConnectionResponse response = mPendingResponses.remove(mCallIdMapper.getCallId(call));
+        if (response != null) {
+            response.handleCreateConnectionFailure(disconnectCause, disconnectMessage);
+        }
+
+        mCallIdMapper.removeCall(call);
+    }
+
+    void onPostDialContinue(Call call, boolean proceed) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("onPostDialContinue")) {
+            try {
+                logOutgoing("onPostDialContinue %s %b", callId, proceed);
+                mServiceInterface.onPostDialContinue(callId, proceed);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    void conference(final Call call, Call otherCall) {
+        final String callId = mCallIdMapper.getCallId(call);
+        final String otherCallId = mCallIdMapper.getCallId(otherCall);
+        if (callId != null && otherCallId != null && isServiceValid("conference")) {
+            try {
+                logOutgoing("conference %s %s", callId, otherCallId);
+                mServiceInterface.conference(callId, otherCallId);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    void splitFromConference(Call call) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("splitFromConference")) {
+            try {
+                logOutgoing("splitFromConference %s", callId);
+                mServiceInterface.splitFromConference(callId);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    void mergeConference(Call call) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("mergeConference")) {
+            try {
+                logOutgoing("mergeConference %s", callId);
+                mServiceInterface.mergeConference(callId);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    void swapConference(Call call) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("swapConference")) {
+            try {
+                logOutgoing("swapConference %s", callId);
+                mServiceInterface.swapConference(callId);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void setServiceInterface(IBinder binder) {
+        if (binder == null) {
+            // We have lost our service connection. Notify the world that this service is done.
+            // We must notify the adapter before CallsManager. The adapter will force any pending
+            // outgoing calls to try the next service. This needs to happen before CallsManager
+            // tries to clean up any calls still associated with this service.
+            handleConnectionServiceDeath();
+            CallsManager.getInstance().handleConnectionServiceDeath(this);
+            mServiceInterface = null;
+        } else {
+            mServiceInterface = IConnectionService.Stub.asInterface(binder);
+            addConnectionServiceAdapter(mAdapter);
+        }
+    }
+
+    private void handleCreateConnectionComplete(
+            String callId,
+            ConnectionRequest request,
+            ParcelableConnection connection) {
+        // TODO: Note we are not using parameter "request", which is a side effect of our tacit
+        // assumption that we have at most one outgoing connection attempt per ConnectionService.
+        // This may not continue to be the case.
+        if (connection.getState() == Connection.STATE_DISCONNECTED) {
+            // A connection that begins in the DISCONNECTED state is an indication of
+            // failure to connect; we handle all failures uniformly
+            removeCall(callId, connection.getDisconnectCause(), connection.getDisconnectMessage());
+        } else {
+            // Successful connection
+            if (mPendingResponses.containsKey(callId)) {
+                mPendingResponses.remove(callId)
+                        .handleCreateConnectionSuccess(mCallIdMapper, connection);
+            }
+        }
+    }
+
+    /**
+     * Called when the associated connection service dies.
+     */
+    private void handleConnectionServiceDeath() {
+        if (!mPendingResponses.isEmpty()) {
+            CreateConnectionResponse[] responses = mPendingResponses.values().toArray(
+                    new CreateConnectionResponse[mPendingResponses.values().size()]);
+            mPendingResponses.clear();
+            for (int i = 0; i < responses.length; i++) {
+                responses[i].handleCreateConnectionFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
+            }
+        }
+        mCallIdMapper.clear();
+    }
+
+    private void logIncoming(String msg, Object... params) {
+        Log.d(this, "ConnectionService -> Telecom: " + msg, params);
+    }
+
+    private void logOutgoing(String msg, Object... params) {
+        Log.d(this, "Telecom -> ConnectionService: " + msg, params);
+    }
+
+    private void queryRemoteConnectionServices(final RemoteServiceCallback callback) {
+        PhoneAccountRegistrar registrar = TelecomApp.getInstance().getPhoneAccountRegistrar();
+
+        // Only give remote connection services to this connection service if it is listed as
+        // the connection manager.
+        PhoneAccountHandle simCallManager = registrar.getSimCallManager();
+        Log.d(this, "queryRemoteConnectionServices finds simCallManager = %s", simCallManager);
+        if (simCallManager == null ||
+                !simCallManager.getComponentName().equals(getComponentName())) {
+            noRemoteServices(callback);
+            return;
+        }
+
+        // Make a list of ConnectionServices that are listed as being associated with SIM accounts
+        final Set<ConnectionServiceWrapper> simServices = Collections.newSetFromMap(
+                new ConcurrentHashMap<ConnectionServiceWrapper, Boolean>(8, 0.9f, 1));
+        for (PhoneAccountHandle handle : registrar.getEnabledPhoneAccounts()) {
+            PhoneAccount account = registrar.getPhoneAccount(handle);
+            if ((account.getCapabilities() & PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0) {
+                ConnectionServiceWrapper service =
+                        mConnectionServiceRepository.getService(handle.getComponentName());
+                if (service != null) {
+                    simServices.add(service);
+                }
+            }
+        }
+
+        final List<ComponentName> simServiceComponentNames = new ArrayList<>();
+        final List<IBinder> simServiceBinders = new ArrayList<>();
+
+        Log.v(this, "queryRemoteConnectionServices, simServices = %s", simServices);
+
+        for (ConnectionServiceWrapper simService : simServices) {
+            if (simService == this) {
+                // Only happens in the unlikely case that a SIM service is also a SIM call manager
+                continue;
+            }
+
+            final ConnectionServiceWrapper currentSimService = simService;
+
+            currentSimService.mBinder.bind(new BindCallback() {
+                @Override
+                public void onSuccess() {
+                    Log.d(this, "Adding simService %s", currentSimService.getComponentName());
+                    simServiceComponentNames.add(currentSimService.getComponentName());
+                    simServiceBinders.add(currentSimService.mServiceInterface.asBinder());
+                    maybeComplete();
+                }
+
+                @Override
+                public void onFailure() {
+                    Log.d(this, "Failed simService %s", currentSimService.getComponentName());
+                    // We know maybeComplete() will always be a no-op from now on, so go ahead and
+                    // signal failure of the entire request
+                    noRemoteServices(callback);
+                }
+
+                private void maybeComplete() {
+                    if (simServiceComponentNames.size() == simServices.size()) {
+                        setRemoteServices(callback, simServiceComponentNames, simServiceBinders);
+                    }
+                }
+            });
+        }
+    }
+
+    private void setRemoteServices(
+            RemoteServiceCallback callback,
+            List<ComponentName> componentNames,
+            List<IBinder> binders) {
+        try {
+            callback.onResult(componentNames, binders);
+        } catch (RemoteException e) {
+            Log.e(this, e, "Contacting ConnectionService %s",
+                    ConnectionServiceWrapper.this.getComponentName());
+        }
+    }
+
+    private void noRemoteServices(RemoteServiceCallback callback) {
+        try {
+            callback.onResult(Collections.EMPTY_LIST, Collections.EMPTY_LIST);
+        } catch (RemoteException e) {
+            Log.e(this, e, "Contacting ConnectionService %s", this.getComponentName());
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/Constants.java b/src/com/android/server/telecom/Constants.java
new file mode 100644
index 0000000..bc6e350
--- /dev/null
+++ b/src/com/android/server/telecom/Constants.java
@@ -0,0 +1,32 @@
+/*
+ * 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.server.telecom;
+
+/**
+ * App-wide constants for the phone app.
+ *
+ * Any constants that need to be shared between two or more classes within
+ * the com.android.phone package should be defined here.  (Constants that
+ * are private to only one class can go in that class's .java file.)
+ */
+public class Constants {
+    //
+    // URI schemes
+    //
+
+    public static final String SCHEME_SMSTO = "smsto";
+}
diff --git a/src/com/android/server/telecom/ContactsAsyncHelper.java b/src/com/android/server/telecom/ContactsAsyncHelper.java
new file mode 100644
index 0000000..aa99ac3
--- /dev/null
+++ b/src/com/android/server/telecom/ContactsAsyncHelper.java
@@ -0,0 +1,247 @@
+/*
+ * 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.server.telecom;
+
+import android.app.Notification;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Helper class for loading contacts photo asynchronously.
+ */
+public final class ContactsAsyncHelper {
+    private static final String LOG_TAG = ContactsAsyncHelper.class.getSimpleName();
+
+    /**
+     * Interface for a WorkerHandler result return.
+     */
+    public interface OnImageLoadCompleteListener {
+        /**
+         * Called when the image load is complete.
+         *
+         * @param token Integer passed in {@link ContactsAsyncHelper#startObtainPhotoAsync(int,
+         * Context, Uri, OnImageLoadCompleteListener, Object)}.
+         * @param photo Drawable object obtained by the async load.
+         * @param photoIcon Bitmap object obtained by the async load.
+         * @param cookie Object passed in {@link ContactsAsyncHelper#startObtainPhotoAsync(int,
+         * Context, Uri, OnImageLoadCompleteListener, Object)}. Can be null iff. the original
+         * cookie is null.
+         */
+        public void onImageLoadComplete(int token, Drawable photo, Bitmap photoIcon,
+                Object cookie);
+    }
+
+    // constants
+    private static final int EVENT_LOAD_IMAGE = 1;
+
+    private static final Handler sResultHandler = new Handler(Looper.getMainLooper()) {
+        /** Called when loading is done. */
+        @Override
+        public void handleMessage(Message msg) {
+            WorkerArgs args = (WorkerArgs) msg.obj;
+            switch (msg.arg1) {
+                case EVENT_LOAD_IMAGE:
+                    if (args.listener != null) {
+                        Log.d(this, "Notifying listener: " + args.listener.toString() +
+                                " image: " + args.displayPhotoUri + " completed");
+                        args.listener.onImageLoadComplete(msg.what, args.photo, args.photoIcon,
+                                args.cookie);
+                    }
+                    break;
+                default:
+            }
+        }
+    };
+
+    /** Handler run on a worker thread to load photo asynchronously. */
+    private static final Handler sThreadHandler;
+
+    static {
+        HandlerThread thread = new HandlerThread("ContactsAsyncWorker");
+        thread.start();
+        sThreadHandler = new WorkerHandler(thread.getLooper());
+    }
+
+    private ContactsAsyncHelper() {}
+
+    private static final class WorkerArgs {
+        public Context context;
+        public Uri displayPhotoUri;
+        public Drawable photo;
+        public Bitmap photoIcon;
+        public Object cookie;
+        public OnImageLoadCompleteListener listener;
+    }
+
+    /**
+     * Thread worker class that handles the task of opening the stream and loading
+     * the images.
+     */
+    private static class WorkerHandler extends Handler {
+        public WorkerHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            WorkerArgs args = (WorkerArgs) msg.obj;
+
+            switch (msg.arg1) {
+                case EVENT_LOAD_IMAGE:
+                    InputStream inputStream = null;
+                    try {
+                        try {
+                            inputStream = args.context.getContentResolver()
+                                    .openInputStream(args.displayPhotoUri);
+                        } catch (Exception e) {
+                            Log.e(this, e, "Error opening photo input stream");
+                        }
+
+                        if (inputStream != null) {
+                            args.photo = Drawable.createFromStream(inputStream,
+                                    args.displayPhotoUri.toString());
+
+                            // This assumes Drawable coming from contact database is usually
+                            // BitmapDrawable and thus we can have (down)scaled version of it.
+                            args.photoIcon = getPhotoIconWhenAppropriate(args.context, args.photo);
+
+                            Log.d(this, "Loading image: " + msg.arg1 +
+                                    " token: " + msg.what + " image URI: " + args.displayPhotoUri);
+                        } else {
+                            args.photo = null;
+                            args.photoIcon = null;
+                            Log.d(this, "Problem with image: " + msg.arg1 +
+                                    " token: " + msg.what + " image URI: " + args.displayPhotoUri +
+                                    ", using default image.");
+                        }
+                    } finally {
+                        if (inputStream != null) {
+                            try {
+                                inputStream.close();
+                            } catch (IOException e) {
+                                Log.e(this, e, "Unable to close input stream.");
+                            }
+                        }
+                    }
+                    break;
+                default:
+            }
+
+            // send the reply to the enclosing class.
+            Message reply = sResultHandler.obtainMessage(msg.what);
+            reply.arg1 = msg.arg1;
+            reply.obj = msg.obj;
+            reply.sendToTarget();
+        }
+
+        /**
+         * Returns a Bitmap object suitable for {@link Notification}'s large icon. This might
+         * return null when the given Drawable isn't BitmapDrawable, or if the system fails to
+         * create a scaled Bitmap for the Drawable.
+         */
+        private Bitmap getPhotoIconWhenAppropriate(Context context, Drawable photo) {
+            if (!(photo instanceof BitmapDrawable)) {
+                return null;
+            }
+            int iconSize = context.getResources()
+                    .getDimensionPixelSize(R.dimen.notification_icon_size);
+            Bitmap orgBitmap = ((BitmapDrawable) photo).getBitmap();
+            int orgWidth = orgBitmap.getWidth();
+            int orgHeight = orgBitmap.getHeight();
+            int longerEdge = orgWidth > orgHeight ? orgWidth : orgHeight;
+            // We want downscaled one only when the original icon is too big.
+            if (longerEdge > iconSize) {
+                float ratio = ((float) longerEdge) / iconSize;
+                int newWidth = (int) (orgWidth / ratio);
+                int newHeight = (int) (orgHeight / ratio);
+                // If the longer edge is much longer than the shorter edge, the latter may
+                // become 0 which will cause a crash.
+                if (newWidth <= 0 || newHeight <= 0) {
+                    Log.w(this, "Photo icon's width or height become 0.");
+                    return null;
+                }
+
+                // It is sure ratio >= 1.0f in any case and thus the newly created Bitmap
+                // should be smaller than the original.
+                return Bitmap.createScaledBitmap(orgBitmap, newWidth, newHeight, true);
+            } else {
+                return orgBitmap;
+            }
+        }
+    }
+
+    /**
+     * Starts an asynchronous image load. After finishing the load,
+     * {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable, Bitmap, Object)}
+     * will be called.
+     *
+     * @param token Arbitrary integer which will be returned as the first argument of
+     * {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable, Bitmap, Object)}
+     * @param context Context object used to do the time-consuming operation.
+     * @param displayPhotoUri Uri to be used to fetch the photo
+     * @param listener Callback object which will be used when the asynchronous load is done.
+     * Can be null, which means only the asynchronous load is done while there's no way to
+     * obtain the loaded photos.
+     * @param cookie Arbitrary object the caller wants to remember, which will become the
+     * fourth argument of {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable,
+     * Bitmap, Object)}. Can be null, at which the callback will also has null for the argument.
+     */
+    public static final void startObtainPhotoAsync(int token, Context context, Uri displayPhotoUri,
+            OnImageLoadCompleteListener listener, Object cookie) {
+        ThreadUtil.checkOnMainThread();
+
+        // in case the source caller info is null, the URI will be null as well.
+        // just update using the placeholder image in this case.
+        if (displayPhotoUri == null) {
+            Log.wtf(LOG_TAG, "Uri is missing");
+            return;
+        }
+
+        // Added additional Cookie field in the callee to handle arguments
+        // sent to the callback function.
+
+        // setup arguments
+        WorkerArgs args = new WorkerArgs();
+        args.cookie = cookie;
+        args.context = context;
+        args.displayPhotoUri = displayPhotoUri;
+        args.listener = listener;
+
+        // setup message arguments
+        Message msg = sThreadHandler.obtainMessage(token);
+        msg.arg1 = EVENT_LOAD_IMAGE;
+        msg.obj = args;
+
+        Log.d(LOG_TAG, "Begin loading image: " + args.displayPhotoUri +
+                ", displaying default image for now.");
+
+        // notify the thread to begin working
+        sThreadHandler.sendMessage(msg);
+    }
+
+
+}
diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java
new file mode 100644
index 0000000..e4c5463
--- /dev/null
+++ b/src/com/android/server/telecom/CreateConnectionProcessor.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.content.Context;
+import android.telecom.ParcelableConnection;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.DisconnectCause;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * This class creates connections to place new outgoing calls to attached to an existing incoming
+ * call. In either case, this class cycles through a set of connection services until:
+ *   - a connection service returns a newly created connection in which case the call is displayed
+ *     to the user
+ *   - a connection service cancels the process, in which case the call is aborted
+ */
+final class CreateConnectionProcessor {
+
+    // Describes information required to attempt to make a phone call
+    private static class CallAttemptRecord {
+        // The PhoneAccount describing the target connection service which we will
+        // contact in order to process an attempt
+        public final PhoneAccountHandle connectionManagerPhoneAccount;
+        // The PhoneAccount which we will tell the target connection service to use
+        // for attempting to make the actual phone call
+        public final PhoneAccountHandle targetPhoneAccount;
+
+        public CallAttemptRecord(
+                PhoneAccountHandle connectionManagerPhoneAccount,
+                PhoneAccountHandle targetPhoneAccount) {
+            this.connectionManagerPhoneAccount = connectionManagerPhoneAccount;
+            this.targetPhoneAccount = targetPhoneAccount;
+        }
+
+        @Override
+        public String toString() {
+            return "CallAttemptRecord("
+                    + Objects.toString(connectionManagerPhoneAccount) + ","
+                    + Objects.toString(targetPhoneAccount) + ")";
+        }
+
+        /**
+         * Determines if this instance of {@code CallAttemptRecord} has the same underlying
+         * {@code PhoneAccountHandle}s as another instance.
+         *
+         * @param obj The other instance to compare against.
+         * @return {@code True} if the {@code CallAttemptRecord}s are equal.
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof CallAttemptRecord) {
+                CallAttemptRecord other = (CallAttemptRecord) obj;
+                return Objects.equals(connectionManagerPhoneAccount,
+                        other.connectionManagerPhoneAccount) &&
+                        Objects.equals(targetPhoneAccount, other.targetPhoneAccount);
+            }
+            return false;
+        }
+    }
+
+    private final Call mCall;
+    private final ConnectionServiceRepository mRepository;
+    private List<CallAttemptRecord> mAttemptRecords;
+    private Iterator<CallAttemptRecord> mAttemptRecordIterator;
+    private CreateConnectionResponse mResponse;
+    private int mLastErrorCode = DisconnectCause.OUTGOING_FAILURE;
+    private String mLastErrorMsg;
+
+    CreateConnectionProcessor(
+            Call call, ConnectionServiceRepository repository, CreateConnectionResponse response) {
+        mCall = call;
+        mRepository = repository;
+        mResponse = response;
+    }
+
+    void process() {
+        Log.v(this, "process");
+        mAttemptRecords = new ArrayList<>();
+        if (mCall.getTargetPhoneAccount() != null) {
+            mAttemptRecords.add(new CallAttemptRecord(
+                    mCall.getTargetPhoneAccount(), mCall.getTargetPhoneAccount()));
+        }
+        adjustAttemptsForConnectionManager();
+        adjustAttemptsForEmergency();
+        mAttemptRecordIterator = mAttemptRecords.iterator();
+        attemptNextPhoneAccount();
+    }
+
+    void abort() {
+        Log.v(this, "abort");
+
+        // Clear the response first to prevent attemptNextConnectionService from attempting any
+        // more services.
+        CreateConnectionResponse response = mResponse;
+        mResponse = null;
+
+        ConnectionServiceWrapper service = mCall.getConnectionService();
+        if (service != null) {
+            service.abort(mCall);
+            mCall.clearConnectionService();
+        }
+        if (response != null) {
+            response.handleCreateConnectionFailure(DisconnectCause.OUTGOING_CANCELED, null);
+        }
+    }
+
+    private void attemptNextPhoneAccount() {
+        Log.v(this, "attemptNextPhoneAccount");
+        PhoneAccountRegistrar registrar = TelecomApp.getInstance().getPhoneAccountRegistrar();
+        CallAttemptRecord attempt = null;
+        if (mAttemptRecordIterator.hasNext()) {
+            attempt = mAttemptRecordIterator.next();
+
+            if (!registrar.phoneAccountHasPermission(attempt.connectionManagerPhoneAccount)) {
+                Log.w(this,
+                        "Connection mgr does not have BIND_CONNECTION_SERVICE for attempt: %s",
+                        attempt);
+                attemptNextPhoneAccount();
+                return;
+            }
+
+            // If the target PhoneAccount differs from the ConnectionManager phone acount, ensure it
+            // also has BIND_CONNECTION_SERVICE permission.
+            if (!attempt.connectionManagerPhoneAccount.equals(attempt.targetPhoneAccount) &&
+                    !registrar.phoneAccountHasPermission(attempt.targetPhoneAccount)) {
+                Log.w(this,
+                        "Target PhoneAccount does not have BIND_CONNECTION_SERVICE for attempt: %s",
+                        attempt);
+                attemptNextPhoneAccount();
+                return;
+            }
+        }
+
+        if (mResponse != null && attempt != null) {
+            Log.i(this, "Trying attempt %s", attempt);
+            ConnectionServiceWrapper service =
+                    mRepository.getService(
+                            attempt.connectionManagerPhoneAccount.getComponentName());
+            if (service == null) {
+                Log.i(this, "Found no connection service for attempt %s", attempt);
+                attemptNextPhoneAccount();
+            } else {
+                mCall.setConnectionManagerPhoneAccount(attempt.connectionManagerPhoneAccount);
+                mCall.setTargetPhoneAccount(attempt.targetPhoneAccount);
+                mCall.setConnectionService(service);
+                Log.i(this, "Attempting to call from %s", service.getComponentName());
+                service.createConnection(mCall, new Response(service));
+            }
+        } else {
+            Log.v(this, "attemptNextPhoneAccount, no more accounts, failing");
+            if (mResponse != null) {
+                mResponse.handleCreateConnectionFailure(mLastErrorCode, mLastErrorMsg);
+                mResponse = null;
+                mCall.clearConnectionService();
+            }
+        }
+    }
+
+    private boolean shouldSetConnectionManager() {
+        Context context = TelecomApp.getInstance();
+        if (!context.getResources().getBoolean(R.bool.connection_manager_enabled)) {
+            // Connection Manager support has been turned off, disregard.
+            return false;
+        }
+
+        if (mAttemptRecords.size() == 0) {
+            return false;
+        }
+
+        if (mAttemptRecords.size() > 1) {
+            Log.d(this, "shouldSetConnectionManager, error, mAttemptRecords should not have more "
+                    + "than 1 record");
+            return false;
+        }
+
+        PhoneAccountRegistrar registrar = TelecomApp.getInstance().getPhoneAccountRegistrar();
+        PhoneAccountHandle connectionManager = registrar.getSimCallManager();
+        if (connectionManager == null) {
+            return false;
+        }
+
+        PhoneAccountHandle targetPhoneAccountHandle = mAttemptRecords.get(0).targetPhoneAccount;
+        if (Objects.equals(connectionManager, targetPhoneAccountHandle)) {
+            return false;
+        }
+
+        // Connection managers are only allowed to manage SIM subscriptions.
+        PhoneAccount targetPhoneAccount = registrar.getPhoneAccount(targetPhoneAccountHandle);
+        boolean isSimSubscription = (targetPhoneAccount.getCapabilities() &
+                PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0;
+        if (!isSimSubscription) {
+            return false;
+        }
+
+        return true;
+    }
+
+    // If there exists a registered connection manager then use it.
+    private void adjustAttemptsForConnectionManager() {
+        if (shouldSetConnectionManager()) {
+            CallAttemptRecord record = new CallAttemptRecord(
+                    TelecomApp.getInstance().getPhoneAccountRegistrar().getSimCallManager(),
+                    mAttemptRecords.get(0).targetPhoneAccount);
+            Log.v(this, "setConnectionManager, changing %s -> %s",
+                    mAttemptRecords.get(0).targetPhoneAccount, record);
+            mAttemptRecords.set(0, record);
+        } else {
+            Log.v(this, "setConnectionManager, not changing");
+        }
+    }
+
+    // If we are possibly attempting to call a local emergency number, ensure that the
+    // plain PSTN connection services are listed, and nothing else.
+    private void adjustAttemptsForEmergency()  {
+        if (TelephonyUtil.shouldProcessAsEmergency(TelecomApp.getInstance(), mCall.getHandle())) {
+            Log.i(this, "Emergency number detected");
+            mAttemptRecords.clear();
+            List<PhoneAccount> allAccounts = TelecomApp.getInstance()
+                    .getPhoneAccountRegistrar().getAllPhoneAccounts();
+            // First, add SIM phone accounts which can place emergency calls.
+            for (PhoneAccount phoneAccount : allAccounts) {
+                if (phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS) &&
+                        phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
+                    Log.i(this, "Will try PSTN account %s for emergency",
+                            phoneAccount.getAccountHandle());
+                    mAttemptRecords.add(
+                            new CallAttemptRecord(
+                                    phoneAccount.getAccountHandle(),
+                                    phoneAccount.getAccountHandle()));
+                }
+            }
+
+            // Next, add the connection manager account as a backup if it can place emergency calls.
+            PhoneAccountHandle callManagerHandle = TelecomApp.getInstance()
+                    .getPhoneAccountRegistrar().getSimCallManager();
+            if (callManagerHandle != null) {
+                PhoneAccount callManager = TelecomApp.getInstance()
+                        .getPhoneAccountRegistrar().getPhoneAccount(callManagerHandle);
+                if (callManager.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)) {
+                    CallAttemptRecord callAttemptRecord = new CallAttemptRecord(callManagerHandle,
+                            TelecomApp.getInstance().getPhoneAccountRegistrar().
+                                    getDefaultOutgoingPhoneAccount(mCall.getHandle().getScheme())
+                    );
+
+                    if (!mAttemptRecords.contains(callAttemptRecord)) {
+                        Log.i(this, "Will try Connection Manager account %s for emergency",
+                                callManager);
+                        mAttemptRecords.add(callAttemptRecord);
+                    }
+                }
+            }
+        }
+    }
+
+    private class Response implements CreateConnectionResponse {
+        private final ConnectionServiceWrapper mService;
+
+        Response(ConnectionServiceWrapper service) {
+            mService = service;
+        }
+
+        @Override
+        public void handleCreateConnectionSuccess(
+                CallIdMapper idMapper,
+                ParcelableConnection connection) {
+            if (mResponse == null) {
+                // Nobody is listening for this connection attempt any longer; ask the responsible
+                // ConnectionService to tear down any resources associated with the call
+                mService.abort(mCall);
+            } else {
+                // Success -- share the good news and remember that we are no longer interested
+                // in hearing about any more attempts
+                mResponse.handleCreateConnectionSuccess(idMapper, connection);
+                mResponse = null;
+            }
+        }
+
+        @Override
+        public void handleCreateConnectionFailure(int code, String msg) {
+            // Failure of some sort; record the reasons for failure and try again if possible
+            Log.d(CreateConnectionProcessor.this, "Connection failed: %d (%s)", code, msg);
+            mLastErrorCode = code;
+            mLastErrorMsg = msg;
+            attemptNextPhoneAccount();
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/CreateConnectionResponse.java b/src/com/android/server/telecom/CreateConnectionResponse.java
new file mode 100644
index 0000000..a1ffa38
--- /dev/null
+++ b/src/com/android/server/telecom/CreateConnectionResponse.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.telecom.ParcelableConnection;
+
+/**
+ * A callback for providing the result of creating a connection.
+ */
+interface CreateConnectionResponse {
+    void handleCreateConnectionSuccess(CallIdMapper idMapper, ParcelableConnection connection);
+    void handleCreateConnectionFailure(int code, String message);
+}
diff --git a/src/com/android/server/telecom/DtmfLocalTonePlayer.java b/src/com/android/server/telecom/DtmfLocalTonePlayer.java
new file mode 100644
index 0000000..eb3f9a0
--- /dev/null
+++ b/src/com/android/server/telecom/DtmfLocalTonePlayer.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.media.AudioManager;
+import android.media.ToneGenerator;
+import android.provider.Settings;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
+
+/**
+ * Plays DTMF tones locally for the caller to hear. In order to reduce (1) the amount of times we
+ * check the "play local tones" setting and (2) the length of time we keep the tone generator, this
+ * class employs a concept of a call "session" that starts and stops when the foreground call
+ * changes.
+ */
+class DtmfLocalTonePlayer extends CallsManagerListenerBase {
+    private static final Map<Character, Integer> TONE_MAP =
+            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();
+
+    /** Generator used to actually play the tone. */
+    private ToneGenerator mToneGenerator;
+
+    /** The current call associated with an existing dtmf session. */
+    private Call mCall;
+
+    /** {@inheritDoc} */
+    @Override
+    public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
+        endDtmfSession(oldForegroundCall);
+        startDtmfSession(newForegroundCall);
+    }
+
+    /**
+     * Starts playing the dtmf tone specified by c.
+     *
+     * @param call The associated call.
+     * @param c The digit to play.
+     */
+    void playTone(Call call, char c) {
+        // Do nothing if it is not the right call.
+        if (mCall != call) {
+            return;
+        }
+
+        if (mToneGenerator == null) {
+            Log.d(this, "playTone: mToneGenerator == null, %c.", c);
+        } else {
+            Log.d(this, "starting local tone: %c.", c);
+            if (TONE_MAP.containsKey(c)) {
+                mToneGenerator.startTone(TONE_MAP.get(c), -1 /* toneDuration */);
+            }
+        }
+    }
+
+    /**
+     * Stops any currently playing dtmf tone.
+     *
+     * @param call The associated call.
+     */
+    void stopTone(Call call) {
+        // Do nothing if it's not the right call.
+        if (mCall != call) {
+            return;
+        }
+
+        if (mToneGenerator == null) {
+            Log.d(this, "stopTone: mToneGenerator == null.");
+        } else {
+            Log.d(this, "stopping local tone.");
+            mToneGenerator.stopTone();
+        }
+    }
+
+    /**
+     * Runs initialization requires to play local tones during a call.
+     *
+     * @param call The call associated with this dtmf session.
+     */
+    private void startDtmfSession(Call call) {
+        if (call == null) {
+            return;
+        }
+        TelecomApp app = TelecomApp.getInstance();
+
+        final boolean areLocalTonesEnabled;
+        if (app.getResources().getBoolean(R.bool.allow_local_dtmf_tones)) {
+            areLocalTonesEnabled = Settings.System.getInt(
+                    app.getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
+        } else {
+            areLocalTonesEnabled = false;
+        }
+
+        mCall = call;
+
+        if (areLocalTonesEnabled) {
+            if (mToneGenerator == null) {
+                try {
+                    mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF, 80);
+                } catch (RuntimeException e) {
+                    Log.e(this, e, "Error creating local tone generator.");
+                    mToneGenerator = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * Releases resources needed for playing local dtmf tones.
+     *
+     * @param call The call associated with the session to end.
+     */
+    private void endDtmfSession(Call call) {
+        if (call != null && mCall == call) {
+            // Do a stopTone() in case the sessions ends before we are told to stop the tone.
+            stopTone(call);
+
+            mCall = null;
+
+            if (mToneGenerator != null) {
+                mToneGenerator.release();
+                mToneGenerator = null;
+            }
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/ErrorDialogActivity.java b/src/com/android/server/telecom/ErrorDialogActivity.java
new file mode 100644
index 0000000..0e6bca0
--- /dev/null
+++ b/src/com/android/server/telecom/ErrorDialogActivity.java
@@ -0,0 +1,126 @@
+/*
+ * 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.server.telecom;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * Used to display an error dialog from within the Telecom service when an outgoing call fails
+ */
+public class ErrorDialogActivity extends Activity {
+    private static final String TAG = ErrorDialogActivity.class.getSimpleName();
+
+    public static final String SHOW_MISSING_VOICEMAIL_NO_DIALOG_EXTRA = "show_missing_voicemail";
+    public static final String ERROR_MESSAGE_ID_EXTRA = "error_message_id";
+
+    /**
+     * Intent action to bring up Voicemail Provider settings.
+     */
+    public static final String ACTION_ADD_VOICEMAIL =
+            "com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final boolean showVoicemailDialog = getIntent().getBooleanExtra(
+                SHOW_MISSING_VOICEMAIL_NO_DIALOG_EXTRA, false);
+
+        if (showVoicemailDialog) {
+            showMissingVoicemailErrorDialog();
+        } else {
+            final int error = getIntent().getIntExtra(ERROR_MESSAGE_ID_EXTRA, -1);
+            if (error == -1) {
+                Log.w(TAG, "ErrorDialogActivity called with no error type extra.");
+                finish();
+            } else {
+                showGenericErrorDialog(error);
+            }
+        }
+    }
+
+    private void showGenericErrorDialog(int resid) {
+        final CharSequence msg = getResources().getText(resid);
+        final DialogInterface.OnClickListener clickListener;
+        final DialogInterface.OnCancelListener cancelListener;
+
+        clickListener = new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                finish();
+            }
+        };
+
+        cancelListener = new DialogInterface.OnCancelListener() {
+            @Override
+            public void onCancel(DialogInterface dialog) {
+                finish();
+            }
+        };
+
+        final AlertDialog errorDialog = new AlertDialog.Builder(this)
+                .setMessage(msg).setPositiveButton(android.R.string.ok, clickListener)
+                        .setOnCancelListener(cancelListener).create();
+
+        errorDialog.show();
+    }
+
+    private void showMissingVoicemailErrorDialog() {
+        new AlertDialog.Builder(this)
+                .setTitle(R.string.no_vm_number)
+                .setMessage(R.string.no_vm_number_msg)
+                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            finish();
+                        }})
+                .setNegativeButton(R.string.add_vm_number_str,
+                        new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialog, int which) {
+                                    addVoiceMailNumberPanel(dialog);
+                                }})
+                .setOnCancelListener(new DialogInterface.OnCancelListener() {
+                        @Override
+                        public void onCancel(DialogInterface dialog) {
+                            finish();
+                        }}).show();
+    }
+
+
+    private void addVoiceMailNumberPanel(DialogInterface dialog) {
+        if (dialog != null) {
+            dialog.dismiss();
+        }
+
+        // Navigate to the Voicemail setting in the Call Settings activity.
+        Intent intent = new Intent(ACTION_ADD_VOICEMAIL);
+        startActivity(intent);
+        finish();
+    }
+
+    @Override
+    public void finish() {
+        super.finish();
+        // Don't show the return to previous task animation to avoid showing a black screen.
+        // Just dismiss the dialog and undim the previous activity immediately.
+        overridePendingTransition(0, 0);
+    }
+}
diff --git a/src/com/android/server/telecom/HeadsetMediaButton.java b/src/com/android/server/telecom/HeadsetMediaButton.java
new file mode 100644
index 0000000..f0ea1e9
--- /dev/null
+++ b/src/com/android/server/telecom/HeadsetMediaButton.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioAttributes;
+import android.media.session.MediaSession;
+import android.view.KeyEvent;
+
+/**
+ * Static class to handle listening to the headset media buttons.
+ */
+final class HeadsetMediaButton extends CallsManagerListenerBase {
+
+    // Types of media button presses
+    static final int SHORT_PRESS = 1;
+    static final int LONG_PRESS = 2;
+
+    private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
+            .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
+            .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build();
+
+    private final MediaSession.Callback mSessionCallback = new MediaSession.Callback() {
+        @Override
+        public boolean onMediaButtonEvent(Intent intent) {
+            KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+            Log.v(this, "SessionCallback.onMediaButton()...  event = %s.", event);
+            if ((event != null) && (event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)) {
+                Log.v(this, "SessionCallback: HEADSETHOOK");
+                boolean consumed = handleHeadsetHook(event);
+                Log.v(this, "==> handleHeadsetHook(): consumed = %b.", consumed);
+                return consumed;
+            }
+            return true;
+        }
+    };
+
+    private final CallsManager mCallsManager;
+
+    private final MediaSession mSession;
+
+    HeadsetMediaButton(Context context, CallsManager callsManager) {
+        mCallsManager = callsManager;
+
+        // Create a MediaSession but don't enable it yet. This is a
+        // replacement for MediaButtonReceiver
+        mSession = new MediaSession(context, HeadsetMediaButton.class.getSimpleName());
+        mSession.setCallback(mSessionCallback);
+        mSession.setFlags(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY
+                | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS);
+        mSession.setPlaybackToLocal(AUDIO_ATTRIBUTES);
+    }
+
+    /**
+     * Handles the wired headset button while in-call.
+     *
+     * @return true if we consumed the event.
+     */
+    private boolean handleHeadsetHook(KeyEvent event) {
+        Log.d(this, "handleHeadsetHook()...%s %s", event.getAction(), event.getRepeatCount());
+
+        if (event.isLongPress()) {
+            return mCallsManager.onMediaButton(LONG_PRESS);
+        } else if (event.getAction() == KeyEvent.ACTION_UP && event.getRepeatCount() == 0) {
+            return mCallsManager.onMediaButton(SHORT_PRESS);
+        }
+
+        return true;
+    }
+
+    /** ${inheritDoc} */
+    @Override
+    public void onCallAdded(Call call) {
+        if (!mSession.isActive()) {
+            mSession.setActive(true);
+        }
+    }
+
+    /** ${inheritDoc} */
+    @Override
+    public void onCallRemoved(Call call) {
+        if (!mCallsManager.hasAnyCalls()) {
+            if (mSession.isActive()) {
+                mSession.setActive(false);
+            }
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/InCallAdapter.java b/src/com/android/server/telecom/InCallAdapter.java
new file mode 100644
index 0000000..5a93464
--- /dev/null
+++ b/src/com/android/server/telecom/InCallAdapter.java
@@ -0,0 +1,347 @@
+/*
+ * 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.server.telecom;
+
+import android.os.Handler;
+import android.os.Message;
+import android.telecom.PhoneAccountHandle;
+
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telecom.IInCallAdapter;
+
+/**
+ * Receives call commands and updates from in-call app and passes them through to CallsManager.
+ * {@link InCallController} creates an instance of this class and passes it to the in-call app after
+ * binding to it. This adapter can receive commands and updates until the in-call app is unbound.
+ */
+class InCallAdapter extends IInCallAdapter.Stub {
+    private static final int MSG_ANSWER_CALL = 0;
+    private static final int MSG_REJECT_CALL = 1;
+    private static final int MSG_PLAY_DTMF_TONE = 2;
+    private static final int MSG_STOP_DTMF_TONE = 3;
+    private static final int MSG_POST_DIAL_CONTINUE = 4;
+    private static final int MSG_DISCONNECT_CALL = 5;
+    private static final int MSG_HOLD_CALL = 6;
+    private static final int MSG_UNHOLD_CALL = 7;
+    private static final int MSG_MUTE = 8;
+    private static final int MSG_SET_AUDIO_ROUTE = 9;
+    private static final int MSG_CONFERENCE = 10;
+    private static final int MSG_SPLIT_FROM_CONFERENCE = 11;
+    private static final int MSG_SWAP_WITH_BACKGROUND_CALL = 12;
+    private static final int MSG_PHONE_ACCOUNT_SELECTED = 13;
+    private static final int MSG_TURN_ON_PROXIMITY_SENSOR = 14;
+    private static final int MSG_TURN_OFF_PROXIMITY_SENSOR = 15;
+    private static final int MSG_MERGE_CONFERENCE = 16;
+    private static final int MSG_SWAP_CONFERENCE = 17;
+
+    private final class InCallAdapterHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            Call call;
+            switch (msg.what) {
+                case MSG_ANSWER_CALL: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        int videoState = (int) args.arg2;
+                        if (call != null) {
+                            mCallsManager.answerCall(call, videoState);
+                        } else {
+                            Log.w(this, "answerCall, unknown call id: %s", msg.obj);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_REJECT_CALL: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        boolean rejectWithMessage = args.argi1 == 1;
+                        String textMessage = (String) args.arg2;
+                        if (call != null) {
+                            mCallsManager.rejectCall(call, rejectWithMessage, textMessage);
+                        } else {
+                            Log.w(this, "setRingback, unknown call id: %s", args.arg1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_PLAY_DTMF_TONE:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.playDtmfTone(call, (char) msg.arg1);
+                    } else {
+                        Log.w(this, "playDtmfTone, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_STOP_DTMF_TONE:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.stopDtmfTone(call);
+                    } else {
+                        Log.w(this, "stopDtmfTone, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_POST_DIAL_CONTINUE:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    mCallsManager.postDialContinue(call, msg.arg1 == 1);
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.postDialContinue(call, msg.arg1 == 1);
+                    } else {
+                        Log.w(this, "postDialContinue, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_DISCONNECT_CALL:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.disconnectCall(call);
+                    } else {
+                        Log.w(this, "disconnectCall, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_HOLD_CALL:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.holdCall(call);
+                    } else {
+                        Log.w(this, "holdCall, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_UNHOLD_CALL:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mCallsManager.unholdCall(call);
+                    } else {
+                        Log.w(this, "unholdCall, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_PHONE_ACCOUNT_SELECTED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null) {
+                            mCallsManager.phoneAccountSelected(call, (PhoneAccountHandle) args.arg2);
+                        } else {
+                            Log.w(this, "phoneAccountSelected, unknown call id: %s", args.arg1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_MUTE:
+                    mCallsManager.mute(msg.arg1 == 1);
+                    break;
+                case MSG_SET_AUDIO_ROUTE:
+                    mCallsManager.setAudioRoute(msg.arg1);
+                    break;
+                case MSG_CONFERENCE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        Call otherCall = mCallIdMapper.getCall(args.arg2);
+                        if (call != null && otherCall != null) {
+                            mCallsManager.conference(call, otherCall);
+                        } else {
+                            Log.w(this, "conference, unknown call id: %s", msg.obj);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SPLIT_FROM_CONFERENCE:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        call.splitFromConference();
+                    } else {
+                        Log.w(this, "splitFromConference, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_TURN_ON_PROXIMITY_SENSOR:
+                    mCallsManager.turnOnProximitySensor();
+                    break;
+                case MSG_TURN_OFF_PROXIMITY_SENSOR:
+                    mCallsManager.turnOffProximitySensor((boolean) msg.obj);
+                    break;
+                case MSG_MERGE_CONFERENCE:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        call.mergeConference();
+                    } else {
+                        Log.w(this, "mergeConference, unknown call id: %s", msg.obj);
+                    }
+                    break;
+                case MSG_SWAP_CONFERENCE:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        call.swapConference();
+                    } else {
+                        Log.w(this, "swapConference, unknown call id: %s", msg.obj);
+                    }
+                    break;
+            }
+        }
+    }
+
+    private final CallsManager mCallsManager;
+    private final Handler mHandler = new InCallAdapterHandler();
+    private final CallIdMapper mCallIdMapper;
+
+    /** Persists the specified parameters. */
+    public InCallAdapter(CallsManager callsManager, CallIdMapper callIdMapper) {
+        ThreadUtil.checkOnMainThread();
+        mCallsManager = callsManager;
+        mCallIdMapper = callIdMapper;
+    }
+
+    @Override
+    public void answerCall(String callId, int videoState) {
+        Log.d(this, "answerCall(%s,%d)", callId, videoState);
+        if (mCallIdMapper.isValidCallId(callId)) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = videoState;
+            mHandler.obtainMessage(MSG_ANSWER_CALL, args).sendToTarget();
+        }
+    }
+
+    @Override
+    public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
+        Log.d(this, "rejectCall(%s,%b,%s)", callId, rejectWithMessage, textMessage);
+        if (mCallIdMapper.isValidCallId(callId)) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.argi1 = rejectWithMessage ? 1 : 0;
+            args.arg2 = textMessage;
+            mHandler.obtainMessage(MSG_REJECT_CALL, args).sendToTarget();
+        }
+    }
+
+    @Override
+    public void playDtmfTone(String callId, char digit) {
+        Log.d(this, "playDtmfTone(%s,%c)", callId, digit);
+        if (mCallIdMapper.isValidCallId(callId)) {
+            mHandler.obtainMessage(MSG_PLAY_DTMF_TONE, (int) digit, 0, callId).sendToTarget();
+        }
+    }
+
+    @Override
+    public void stopDtmfTone(String callId) {
+        Log.d(this, "stopDtmfTone(%s)", callId);
+        if (mCallIdMapper.isValidCallId(callId)) {
+            mHandler.obtainMessage(MSG_STOP_DTMF_TONE, callId).sendToTarget();
+        }
+    }
+
+    @Override
+    public void postDialContinue(String callId, boolean proceed) {
+        Log.d(this, "postDialContinue(%s)", callId);
+        if (mCallIdMapper.isValidCallId(callId)) {
+            mHandler.obtainMessage(MSG_POST_DIAL_CONTINUE, proceed ? 1 : 0, 0, callId).sendToTarget();
+        }
+    }
+
+    @Override
+    public void disconnectCall(String callId) {
+        Log.v(this, "disconnectCall: %s", callId);
+        if (mCallIdMapper.isValidCallId(callId)) {
+            mHandler.obtainMessage(MSG_DISCONNECT_CALL, callId).sendToTarget();
+        }
+    }
+
+    @Override
+    public void holdCall(String callId) {
+        if (mCallIdMapper.isValidCallId(callId)) {
+            mHandler.obtainMessage(MSG_HOLD_CALL, callId).sendToTarget();
+        }
+    }
+
+    @Override
+    public void unholdCall(String callId) {
+        if (mCallIdMapper.isValidCallId(callId)) {
+            mHandler.obtainMessage(MSG_UNHOLD_CALL, callId).sendToTarget();
+        }
+    }
+
+    @Override
+    public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle) {
+        if (mCallIdMapper.isValidCallId(callId)) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = accountHandle;
+            mHandler.obtainMessage(MSG_PHONE_ACCOUNT_SELECTED, args).sendToTarget();
+        }
+    }
+
+    @Override
+    public void mute(boolean shouldMute) {
+        mHandler.obtainMessage(MSG_MUTE, shouldMute ? 1 : 0, 0).sendToTarget();
+    }
+
+    @Override
+    public void setAudioRoute(int route) {
+        mHandler.obtainMessage(MSG_SET_AUDIO_ROUTE, route, 0).sendToTarget();
+    }
+
+    @Override
+    public void conference(String callId, String otherCallId) {
+        if (mCallIdMapper.isValidCallId(callId) &&
+                mCallIdMapper.isValidCallId(otherCallId)) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = otherCallId;
+            mHandler.obtainMessage(MSG_CONFERENCE, args).sendToTarget();
+        }
+    }
+
+    @Override
+    public void splitFromConference(String callId) {
+        if (mCallIdMapper.isValidCallId(callId)) {
+            mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, callId).sendToTarget();
+        }
+    }
+
+    @Override
+    public void mergeConference(String callId) {
+        if (mCallIdMapper.isValidCallId(callId)) {
+            mHandler.obtainMessage(MSG_MERGE_CONFERENCE, callId).sendToTarget();
+        }
+    }
+
+    @Override
+    public void swapConference(String callId) {
+        if (mCallIdMapper.isValidCallId(callId)) {
+            mHandler.obtainMessage(MSG_SWAP_CONFERENCE, callId).sendToTarget();
+        }
+    }
+
+    @Override
+    public void turnOnProximitySensor() {
+        mHandler.obtainMessage(MSG_TURN_ON_PROXIMITY_SENSOR).sendToTarget();
+    }
+
+    @Override
+    public void turnOffProximitySensor(boolean screenOnImmediately) {
+        mHandler.obtainMessage(MSG_TURN_OFF_PROXIMITY_SENSOR, screenOnImmediately).sendToTarget();
+    }
+}
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
new file mode 100644
index 0000000..26ac4a5
--- /dev/null
+++ b/src/com/android/server/telecom/InCallController.java
@@ -0,0 +1,514 @@
+/*
+ * 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.server.telecom;
+
+import android.Manifest;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.telecom.AudioState;
+import android.telecom.CallProperties;
+import android.telecom.CallState;
+import android.telecom.InCallService;
+import android.telecom.ParcelableCall;
+import android.telecom.PhoneCapabilities;
+import android.telecom.TelecomManager;
+import android.util.ArrayMap;
+
+import com.android.internal.telecom.IInCallService;
+import com.google.common.collect.ImmutableCollection;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Binds to {@link IInCallService} and provides the service to {@link CallsManager} through which it
+ * can send updates to the in-call app. This class is created and owned by CallsManager and retains
+ * a binding to the {@link IInCallService} (implemented by the in-call app).
+ */
+public final class InCallController extends CallsManagerListenerBase {
+    /**
+     * Used to bind to the in-call app and triggers the start of communication between
+     * this class and in-call app.
+     */
+    private class InCallServiceConnection implements ServiceConnection {
+        /** {@inheritDoc} */
+        @Override public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.d(this, "onServiceConnected: %s", name);
+            onConnected(name, service);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onServiceDisconnected(ComponentName name) {
+            Log.d(this, "onDisconnected: %s", name);
+            onDisconnected(name);
+        }
+    }
+
+    private final Call.Listener mCallListener = new Call.ListenerBase() {
+        @Override
+        public void onCallCapabilitiesChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onCannedSmsResponsesLoaded(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onVideoCallProviderChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onStatusHintsChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onHandleChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onCallerDisplayNameChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onVideoStateChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onTargetPhoneAccountChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onConferenceableCallsChanged(Call call) {
+            updateCall(call);
+        }
+    };
+
+    /**
+     * Maintains a binding connection to the in-call app(s).
+     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
+     * load factor before resizing, 1 means we only expect a single thread to
+     * access the map so make only a single shard
+     */
+    private final Map<ComponentName, InCallServiceConnection> mServiceConnections =
+            new ConcurrentHashMap<ComponentName, InCallServiceConnection>(8, 0.9f, 1);
+
+    /** The in-call app implementations, see {@link IInCallService}. */
+    private final Map<ComponentName, IInCallService> mInCallServices = new ArrayMap<>();
+
+    private final CallIdMapper mCallIdMapper = new CallIdMapper("InCall");
+
+    /** The {@link ComponentName} of the default InCall UI. */
+    private final ComponentName mInCallComponentName;
+
+    public InCallController() {
+        Context context = TelecomApp.getInstance();
+        Resources resources = context.getResources();
+
+        mInCallComponentName = new ComponentName(
+                resources.getString(R.string.ui_default_package),
+                resources.getString(R.string.incall_default_class));
+    }
+
+    @Override
+    public void onCallAdded(Call call) {
+        if (mInCallServices.isEmpty()) {
+            bind();
+        } else {
+            Log.i(this, "onCallAdded: %s", call);
+            // Track the call if we don't already know about it.
+            addCall(call);
+
+            for (Map.Entry<ComponentName, IInCallService> entry : mInCallServices.entrySet()) {
+                ComponentName componentName = entry.getKey();
+                IInCallService inCallService = entry.getValue();
+
+                ParcelableCall parcelableCall = toParcelableCall(call,
+                        componentName.equals(mInCallComponentName) /* includeVideoProvider */);
+                try {
+                    inCallService.addCall(parcelableCall);
+                } catch (RemoteException ignored) {
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onCallRemoved(Call call) {
+        Log.i(this, "onCallRemoved: %s", call);
+        if (CallsManager.getInstance().getCalls().isEmpty()) {
+            // TODO: Wait for all messages to be delivered to the service before unbinding.
+            unbind();
+        }
+        call.removeListener(mCallListener);
+        mCallIdMapper.removeCall(call);
+    }
+
+    @Override
+    public void onCallStateChanged(Call call, int oldState, int newState) {
+        updateCall(call);
+    }
+
+    @Override
+    public void onConnectionServiceChanged(
+            Call call,
+            ConnectionServiceWrapper oldService,
+            ConnectionServiceWrapper newService) {
+        updateCall(call);
+    }
+
+    @Override
+    public void onAudioStateChanged(AudioState oldAudioState, AudioState newAudioState) {
+        if (!mInCallServices.isEmpty()) {
+            Log.i(this, "Calling onAudioStateChanged, audioState: %s -> %s", oldAudioState,
+                    newAudioState);
+            for (IInCallService inCallService : mInCallServices.values()) {
+                try {
+                    inCallService.onAudioStateChanged(newAudioState);
+                } catch (RemoteException ignored) {
+                }
+            }
+        }
+    }
+
+    void onPostDialWait(Call call, String remaining) {
+        if (!mInCallServices.isEmpty()) {
+            Log.i(this, "Calling onPostDialWait, remaining = %s", remaining);
+            for (IInCallService inCallService : mInCallServices.values()) {
+                try {
+                    inCallService.setPostDialWait(mCallIdMapper.getCallId(call), remaining);
+                } catch (RemoteException ignored) {
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onIsConferencedChanged(Call call) {
+        Log.d(this, "onIsConferencedChanged %s", call);
+        updateCall(call);
+    }
+
+    void bringToForeground(boolean showDialpad) {
+        if (!mInCallServices.isEmpty()) {
+            for (IInCallService inCallService : mInCallServices.values()) {
+                try {
+                    inCallService.bringToForeground(showDialpad);
+                } catch (RemoteException ignored) {
+                }
+            }
+        } else {
+            Log.w(this, "Asking to bring unbound in-call UI to foreground.");
+        }
+    }
+
+    /**
+     * Unbinds an existing bound connection to the in-call app.
+     */
+    private void unbind() {
+        ThreadUtil.checkOnMainThread();
+        Iterator<Map.Entry<ComponentName, InCallServiceConnection>> iterator =
+            mServiceConnections.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Log.i(this, "Unbinding from InCallService %s");
+            TelecomApp.getInstance().unbindService(iterator.next().getValue());
+            iterator.remove();
+        }
+        mInCallServices.clear();
+    }
+
+    /**
+     * Binds to the in-call app if not already connected by binding directly to the saved
+     * component name of the {@link IInCallService} implementation.
+     */
+    private void bind() {
+        ThreadUtil.checkOnMainThread();
+        if (mInCallServices.isEmpty()) {
+            mServiceConnections.clear();
+            Context context = TelecomApp.getInstance();
+            PackageManager packageManager = TelecomApp.getInstance().getPackageManager();
+            Intent serviceIntent = new Intent(InCallService.SERVICE_INTERFACE);
+
+            for (ResolveInfo entry : packageManager.queryIntentServices(serviceIntent, 0)) {
+                ServiceInfo serviceInfo = entry.serviceInfo;
+                if (serviceInfo != null) {
+                    boolean hasServiceBindPermission = serviceInfo.permission != null &&
+                            serviceInfo.permission.equals(
+                                    Manifest.permission.BIND_INCALL_SERVICE);
+                    boolean hasControlInCallPermission = packageManager.checkPermission(
+                            Manifest.permission.CONTROL_INCALL_EXPERIENCE,
+                            serviceInfo.packageName) == PackageManager.PERMISSION_GRANTED;
+
+                    if (!hasServiceBindPermission) {
+                        Log.w(this, "InCallService does not have BIND_INCALL_SERVICE permission: " +
+                                serviceInfo.packageName);
+                        continue;
+                    }
+
+                    if (!hasControlInCallPermission) {
+                        Log.w(this,
+                                "InCall UI does not have CONTROL_INCALL_EXPERIENCE permission: " +
+                                        serviceInfo.packageName);
+                        continue;
+                    }
+
+                    Log.i(this, "Attempting to bind to InCall " + serviceInfo.packageName);
+                    InCallServiceConnection inCallServiceConnection = new InCallServiceConnection();
+                    ComponentName componentName = new ComponentName(serviceInfo.packageName,
+                            serviceInfo.name);
+
+                    if (!mServiceConnections.containsKey(componentName)) {
+                        Intent intent = new Intent(InCallService.SERVICE_INTERFACE);
+                        intent.setComponent(componentName);
+
+                        if (context.bindServiceAsUser(intent, inCallServiceConnection,
+                                Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {
+                            mServiceConnections.put(componentName, inCallServiceConnection);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Persists the {@link IInCallService} instance and starts the communication between
+     * this class and in-call app by sending the first update to in-call app. This method is
+     * called after a successful binding connection is established.
+     *
+     * @param componentName The service {@link ComponentName}.
+     * @param service The {@link IInCallService} implementation.
+     */
+    private void onConnected(ComponentName componentName, IBinder service) {
+        ThreadUtil.checkOnMainThread();
+
+        Log.i(this, "onConnected to %s", componentName);
+
+        IInCallService inCallService = IInCallService.Stub.asInterface(service);
+
+        try {
+            inCallService.setInCallAdapter(new InCallAdapter(CallsManager.getInstance(),
+                    mCallIdMapper));
+            mInCallServices.put(componentName, inCallService);
+        } catch (RemoteException e) {
+            Log.e(this, e, "Failed to set the in-call adapter.");
+            return;
+        }
+
+        // Upon successful connection, send the state of the world to the service.
+        ImmutableCollection<Call> calls = CallsManager.getInstance().getCalls();
+        if (!calls.isEmpty()) {
+            Log.i(this, "Adding %s calls to InCallService after onConnected: %s", calls.size(),
+                    componentName);
+            for (Call call : calls) {
+                try {
+                    // Track the call if we don't already know about it.
+                    Log.i(this, "addCall after binding: %s", call);
+                    addCall(call);
+
+                    inCallService.addCall(toParcelableCall(call,
+                            componentName.equals(mInCallComponentName) /* includeVideoProvider */));
+                } catch (RemoteException ignored) {
+                }
+            }
+            onAudioStateChanged(null, CallsManager.getInstance().getAudioState());
+        } else {
+            unbind();
+        }
+    }
+
+    /**
+     * Cleans up an instance of in-call app after the service has been unbound.
+     *
+     * @param disconnectedComponent The {@link ComponentName} of the service which disconnected.
+     */
+    private void onDisconnected(ComponentName disconnectedComponent) {
+        Log.i(this, "onDisconnected from %s", disconnectedComponent);
+        ThreadUtil.checkOnMainThread();
+        Context context = TelecomApp.getInstance();
+
+        if (mInCallServices.containsKey(disconnectedComponent)) {
+            mInCallServices.remove(disconnectedComponent);
+        }
+
+        if (mServiceConnections.containsKey(disconnectedComponent)) {
+            // One of the services that we were bound to has disconnected. If the default in-call UI
+            // has disconnected, disconnect all calls and un-bind all other InCallService
+            // implementations.
+            if (disconnectedComponent.equals(mInCallComponentName)) {
+                Log.i(this, "In-call UI %s disconnected.", disconnectedComponent);
+                CallsManager.getInstance().disconnectAllCalls();
+                unbind();
+            } else {
+                Log.i(this, "In-Call Service %s suddenly disconnected", disconnectedComponent);
+                // Else, if it wasn't the default in-call UI, then one of the other in-call services
+                // disconnected and, well, that's probably their fault.  Clear their state and
+                // ignore.
+                InCallServiceConnection serviceConnection =
+                        mServiceConnections.get(disconnectedComponent);
+
+                // We still need to call unbind even though it disconnected.
+                context.unbindService(serviceConnection);
+
+                mServiceConnections.remove(disconnectedComponent);
+                mInCallServices.remove(disconnectedComponent);
+            }
+        }
+    }
+
+    /**
+     * Informs all {@link InCallService} instances of the updated call information.  Changes to the
+     * video provider are only communicated to the default in-call UI.
+     *
+     * @param call The {@link Call}.
+     */
+    private void updateCall(Call call) {
+        if (!mInCallServices.isEmpty()) {
+            for (Map.Entry<ComponentName, IInCallService> entry : mInCallServices.entrySet()) {
+                ComponentName componentName = entry.getKey();
+                IInCallService inCallService = entry.getValue();
+                ParcelableCall parcelableCall = toParcelableCall(call,
+                        componentName.equals(mInCallComponentName) /* includeVideoProvider */);
+
+                Log.v(this, "updateCall %s ==> %s", call, parcelableCall);
+                try {
+                    inCallService.updateCall(parcelableCall);
+                } catch (RemoteException ignored) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Parcels all information for a {@link Call} into a new {@link ParcelableCall} instance.
+     *
+     * @param call The {@link Call} to parcel.
+     * @param includeVideoProvider When {@code true}, the {@link IVideoProvider} is included in the
+     *      parcelled call.  When {@code false}, the {@link IVideoProvider} is not included.
+     * @return The {@link ParcelableCall} containing all call information from the {@link Call}.
+     */
+    private ParcelableCall toParcelableCall(Call call, boolean includeVideoProvider) {
+        String callId = mCallIdMapper.getCallId(call);
+
+        int capabilities = call.getCallCapabilities();
+        if (CallsManager.getInstance().isAddCallCapable(call)) {
+            capabilities |= PhoneCapabilities.ADD_CALL;
+        }
+
+        // Disable mute and add call for emergency calls.
+        if (call.isEmergencyCall()) {
+            capabilities &= ~PhoneCapabilities.MUTE;
+            capabilities &= ~PhoneCapabilities.ADD_CALL;
+        }
+
+        int properties = call.isConference() ? CallProperties.CONFERENCE : 0;
+
+        int state = call.getState();
+        if (state == CallState.ABORTED) {
+            state = CallState.DISCONNECTED;
+        }
+
+        String parentCallId = null;
+        Call parentCall = call.getParentCall();
+        if (parentCall != null) {
+            parentCallId = mCallIdMapper.getCallId(parentCall);
+        }
+
+        long connectTimeMillis = call.getConnectTimeMillis();
+        List<Call> childCalls = call.getChildCalls();
+        List<String> childCallIds = new ArrayList<>();
+        if (!childCalls.isEmpty()) {
+            connectTimeMillis = Long.MAX_VALUE;
+            for (Call child : childCalls) {
+                connectTimeMillis = Math.min(child.getConnectTimeMillis(), connectTimeMillis);
+                childCallIds.add(mCallIdMapper.getCallId(child));
+            }
+        }
+
+        if (call.isRespondViaSmsCapable()) {
+            capabilities |= PhoneCapabilities.RESPOND_VIA_TEXT;
+        }
+
+        Uri handle = call.getHandlePresentation() == TelecomManager.PRESENTATION_ALLOWED ?
+                call.getHandle() : null;
+        String callerDisplayName = call.getCallerDisplayNamePresentation() ==
+                TelecomManager.PRESENTATION_ALLOWED ?  call.getCallerDisplayName() : null;
+
+        List<Call> conferenceableCalls = call.getConferenceableCalls();
+        List<String> conferenceableCallIds = new ArrayList<String>(conferenceableCalls.size());
+        for (Call otherCall : conferenceableCalls) {
+            String otherId = mCallIdMapper.getCallId(otherCall);
+            if (otherId != null) {
+                conferenceableCallIds.add(otherId);
+            }
+        }
+
+        return new ParcelableCall(
+                callId,
+                state,
+                call.getDisconnectCause(),
+                call.getDisconnectMessage(),
+                call.getCannedSmsResponses(),
+                capabilities,
+                properties,
+                connectTimeMillis,
+                handle,
+                call.getHandlePresentation(),
+                callerDisplayName,
+                call.getCallerDisplayNamePresentation(),
+                call.getGatewayInfo(),
+                call.getTargetPhoneAccount(),
+                includeVideoProvider ? call.getVideoProvider() : null,
+                parentCallId,
+                childCallIds,
+                call.getStatusHints(),
+                call.getVideoState(),
+                conferenceableCallIds,
+                call.getExtras());
+    }
+
+    /**
+     * Adds the call to the list of calls tracked by the {@link InCallController}.
+     * @param call The call to add.
+     */
+    private void addCall(Call call) {
+        if (mCallIdMapper.getCallId(call) == null) {
+            mCallIdMapper.addCall(call);
+            call.addListener(mCallListener);
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/InCallToneMonitor.java b/src/com/android/server/telecom/InCallToneMonitor.java
new file mode 100644
index 0000000..2ffb499
--- /dev/null
+++ b/src/com/android/server/telecom/InCallToneMonitor.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.telecom.CallState;
+import android.telephony.DisconnectCause;
+
+import java.util.Collection;
+
+/**
+ * Monitors events from CallsManager and plays in-call tones for events which require them, such as
+ * different type of call disconnections (busy tone, congestion tone, etc).
+ */
+public final class InCallToneMonitor extends CallsManagerListenerBase {
+    private final InCallTonePlayer.Factory mPlayerFactory;
+
+    private final CallsManager mCallsManager;
+
+    InCallToneMonitor(InCallTonePlayer.Factory playerFactory, CallsManager callsManager) {
+        mPlayerFactory = playerFactory;
+        mCallsManager = callsManager;
+    }
+
+    @Override
+    public void onCallStateChanged(Call call, int oldState, int newState) {
+        if (mCallsManager.getForegroundCall() != call) {
+            // We only play tones for foreground calls.
+            return;
+        }
+
+        if (newState == CallState.DISCONNECTED) {
+            int toneToPlay = InCallTonePlayer.TONE_INVALID;
+
+            Log.v(this, "Disconnect cause: %d.", call.getDisconnectCause());
+
+            switch(call.getDisconnectCause()) {
+                case DisconnectCause.BUSY:
+                    toneToPlay = InCallTonePlayer.TONE_BUSY;
+                    break;
+                case DisconnectCause.CONGESTION:
+                    toneToPlay = InCallTonePlayer.TONE_CONGESTION;
+                    break;
+                case DisconnectCause.CDMA_REORDER:
+                    toneToPlay = InCallTonePlayer.TONE_REORDER;
+                    break;
+                case DisconnectCause.CDMA_INTERCEPT:
+                    toneToPlay = InCallTonePlayer.TONE_INTERCEPT;
+                    break;
+                case DisconnectCause.CDMA_DROP:
+                    toneToPlay = InCallTonePlayer.TONE_CDMA_DROP;
+                    break;
+                case DisconnectCause.OUT_OF_SERVICE:
+                    toneToPlay = InCallTonePlayer.TONE_OUT_OF_SERVICE;
+                    break;
+                case DisconnectCause.UNOBTAINABLE_NUMBER:
+                    toneToPlay = InCallTonePlayer.TONE_UNOBTAINABLE_NUMBER;
+                    break;
+                case DisconnectCause.ERROR_UNSPECIFIED:
+                    toneToPlay = InCallTonePlayer.TONE_CALL_ENDED;
+                    break;
+                case DisconnectCause.NORMAL:
+                case DisconnectCause.LOCAL:
+                    // Only play the disconnect sound on normal disconnects if there are no other
+                    // calls present beyond the one that is currently disconnected.
+                    Collection<Call> allCalls = mCallsManager.getCalls();
+                    if (allCalls.size() == 1) {
+                        if (!allCalls.contains(call)) {
+                            Log.wtf(this, "Disconnecting call not found %s.", call);
+                        }
+                        toneToPlay = InCallTonePlayer.TONE_CALL_ENDED;
+                    }
+                    break;
+            }
+
+            Log.d(this, "Found a disconnected call with tone to play %d.", toneToPlay);
+
+            if (toneToPlay != InCallTonePlayer.TONE_INVALID) {
+                mPlayerFactory.createPlayer(toneToPlay).startTone();
+            }
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/InCallTonePlayer.java b/src/com/android/server/telecom/InCallTonePlayer.java
new file mode 100644
index 0000000..2ffe599
--- /dev/null
+++ b/src/com/android/server/telecom/InCallTonePlayer.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.media.AudioManager;
+import android.media.ToneGenerator;
+import android.os.Handler;
+import android.os.Looper;
+
+/**
+ * Play a call-related tone (ringback, busy signal, etc.) through ToneGenerator. To use, create an
+ * instance using InCallTonePlayer.Factory (passing in the TONE_* constant for the tone you want)
+ * and start() it. Implemented on top of {@link Thread} so that the tone plays in its own thread.
+ */
+public final class InCallTonePlayer extends Thread {
+
+    /**
+     * Factory used to create InCallTonePlayers. Exists to aid with testing mocks.
+     */
+    public static class Factory {
+        private final CallAudioManager mCallAudioManager;
+
+        Factory(CallAudioManager callAudioManager) {
+            mCallAudioManager = callAudioManager;
+        }
+
+        InCallTonePlayer createPlayer(int tone) {
+            return new InCallTonePlayer(tone, mCallAudioManager);
+        }
+    }
+
+    // The possible tones that we can play.
+    public static final int TONE_INVALID = 0;
+    public static final int TONE_BUSY = 1;
+    public static final int TONE_CALL_ENDED = 2;
+    public static final int TONE_OTA_CALL_ENDED = 3;
+    public static final int TONE_CALL_WAITING = 4;
+    public static final int TONE_CDMA_DROP = 5;
+    public static final int TONE_CONGESTION = 6;
+    public static final int TONE_INTERCEPT = 7;
+    public static final int TONE_OUT_OF_SERVICE = 8;
+    public static final int TONE_REDIAL = 9;
+    public static final int TONE_REORDER = 10;
+    public static final int TONE_RING_BACK = 11;
+    public static final int TONE_UNOBTAINABLE_NUMBER = 12;
+    public static final int TONE_VOICE_PRIVACY = 13;
+
+    private static final int RELATIVE_VOLUME_EMERGENCY = 100;
+    private static final int RELATIVE_VOLUME_HIPRI = 80;
+    private static final int RELATIVE_VOLUME_LOPRI = 50;
+
+    // Buffer time (in msec) to add on to the tone timeout value. Needed mainly when the timeout
+    // value for a tone is exact duration of the tone itself.
+    private static final int TIMEOUT_BUFFER_MILLIS = 20;
+
+    // The tone state.
+    private static final int STATE_OFF = 0;
+    private static final int STATE_ON = 1;
+    private static final int STATE_STOPPED = 2;
+
+    /**
+     * Keeps count of the number of actively playing tones so that we can notify CallAudioManager
+     * when we need focus and when it can be release. This should only be manipulated from the main
+     * thread.
+     */
+    private static int sTonesPlaying = 0;
+
+    private final CallAudioManager mCallAudioManager;
+
+    private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
+
+    /** The ID of the tone to play. */
+    private final int mToneId;
+
+    /** Current state of the tone player. */
+    private int mState;
+
+    /**
+     * Initializes the tone player. Private; use the {@link Factory} to create tone players.
+     *
+     * @param toneId ID of the tone to play, see TONE_* constants.
+     */
+    private InCallTonePlayer(int toneId, CallAudioManager callAudioManager) {
+        mState = STATE_OFF;
+        mToneId = toneId;
+        mCallAudioManager = callAudioManager;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void run() {
+        ToneGenerator toneGenerator = null;
+        try {
+            Log.d(this, "run(toneId = %s)", mToneId);
+
+            final int toneType;  // Passed to ToneGenerator.startTone.
+            final int toneVolume;  // Passed to the ToneGenerator constructor.
+            final int toneLengthMillis;
+
+            switch (mToneId) {
+                case TONE_BUSY:
+                    // TODO: CDMA-specific tones
+                    toneType = ToneGenerator.TONE_SUP_BUSY;
+                    toneVolume = RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = 4000;
+                    break;
+                case TONE_CALL_ENDED:
+                    toneType = ToneGenerator.TONE_PROP_PROMPT;
+                    toneVolume = RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = 4000;
+                    break;
+                case TONE_OTA_CALL_ENDED:
+                    // TODO: fill in
+                    throw new IllegalStateException("OTA Call ended NYI.");
+                case TONE_CALL_WAITING:
+                    toneType = ToneGenerator.TONE_SUP_CALL_WAITING;
+                    toneVolume = RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = Integer.MAX_VALUE - TIMEOUT_BUFFER_MILLIS;
+                    break;
+                case TONE_CDMA_DROP:
+                    toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE;
+                    toneVolume = RELATIVE_VOLUME_LOPRI;
+                    toneLengthMillis = 375;
+                    break;
+                case TONE_CONGESTION:
+                    toneType = ToneGenerator.TONE_SUP_CONGESTION;
+                    toneVolume = RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = 4000;
+                    break;
+                case TONE_INTERCEPT:
+                    toneType = ToneGenerator.TONE_CDMA_ABBR_INTERCEPT;
+                    toneVolume = RELATIVE_VOLUME_LOPRI;
+                    toneLengthMillis = 500;
+                    break;
+                case TONE_OUT_OF_SERVICE:
+                    toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE;
+                    toneVolume = RELATIVE_VOLUME_LOPRI;
+                    toneLengthMillis = 375;
+                    break;
+                case TONE_REDIAL:
+                    toneType = ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE;
+                    toneVolume = RELATIVE_VOLUME_LOPRI;
+                    toneLengthMillis = 5000;
+                    break;
+                case TONE_REORDER:
+                    toneType = ToneGenerator.TONE_CDMA_REORDER;
+                    toneVolume = RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = 5000;
+                    break;
+                case TONE_RING_BACK:
+                    toneType = ToneGenerator.TONE_SUP_RINGTONE;
+                    toneVolume = RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = Integer.MAX_VALUE - TIMEOUT_BUFFER_MILLIS;
+                    break;
+                case TONE_UNOBTAINABLE_NUMBER:
+                    toneType = ToneGenerator.TONE_SUP_ERROR;
+                    toneVolume = RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = 4000;
+                    break;
+                case TONE_VOICE_PRIVACY:
+                    // TODO: fill in.
+                    throw new IllegalStateException("Voice privacy tone NYI.");
+                default:
+                    throw new IllegalStateException("Bad toneId: " + mToneId);
+            }
+
+            int stream = AudioManager.STREAM_VOICE_CALL;
+            if (mCallAudioManager.isBluetoothAudioOn()) {
+                stream = AudioManager.STREAM_BLUETOOTH_SCO;
+            }
+
+            // If the ToneGenerator creation fails, just continue without it. It is a local audio
+            // signal, and is not as important.
+            try {
+                Log.v(this, "Creating generator");
+                toneGenerator = new ToneGenerator(stream, toneVolume);
+            } catch (RuntimeException e) {
+                Log.w(this, "Failed to create ToneGenerator.", e);
+                return;
+            }
+
+            // TODO: Certain CDMA tones need to check the ringer-volume state before
+            // playing. See CallNotifier.InCallTonePlayer.
+
+            // TODO: Some tones play through the end of a call so we need to inform
+            // CallAudioManager that we want focus the same way that Ringer does.
+
+            synchronized (this) {
+                if (mState != STATE_STOPPED) {
+                    mState = STATE_ON;
+                    toneGenerator.startTone(toneType);
+                    try {
+                        Log.v(this, "Starting tone %d...waiting for %d ms.", mToneId,
+                                toneLengthMillis + TIMEOUT_BUFFER_MILLIS);
+                        wait(toneLengthMillis + TIMEOUT_BUFFER_MILLIS);
+                    } catch (InterruptedException e) {
+                        Log.w(this, "wait interrupted", e);
+                    }
+                }
+            }
+            mState = STATE_OFF;
+        } finally {
+            if (toneGenerator != null) {
+                toneGenerator.release();
+            }
+            cleanUpTonePlayer();
+        }
+    }
+
+    void startTone() {
+        ThreadUtil.checkOnMainThread();
+
+        sTonesPlaying++;
+        if (sTonesPlaying == 1) {
+            mCallAudioManager.setIsTonePlaying(true);
+        }
+
+        start();
+    }
+
+    /**
+     * Stops the tone.
+     */
+    void stopTone() {
+        synchronized (this) {
+            if (mState == STATE_ON) {
+                Log.d(this, "Stopping the tone %d.", mToneId);
+                notify();
+            }
+            mState = STATE_STOPPED;
+        }
+    }
+
+    private void cleanUpTonePlayer() {
+        // Release focus on the main thread.
+        mMainThreadHandler.post(new Runnable() {
+            @Override public void run() {
+                if (sTonesPlaying == 0) {
+                    Log.wtf(this, "Over-releasing focus for tone player.");
+                } else if (--sTonesPlaying == 0) {
+                    mCallAudioManager.setIsTonePlaying(false);
+                }
+            }
+        });
+    }
+}
diff --git a/src/com/android/server/telecom/Log.java b/src/com/android/server/telecom/Log.java
new file mode 100644
index 0000000..ff3c8ce
--- /dev/null
+++ b/src/com/android/server/telecom/Log.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.net.Uri;
+import android.telecom.PhoneAccount;
+import android.telephony.PhoneNumberUtils;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.IllegalFormatException;
+import java.util.Locale;
+
+/**
+ * Manages logging for the entire module.
+ */
+public class Log {
+
+    // Generic tag for all In Call logging
+    private static final String TAG = "Telecom";
+
+    public static final boolean FORCE_LOGGING = false; /* STOP SHIP if true */
+    public static final boolean DEBUG = isLoggable(android.util.Log.DEBUG);
+    public static final boolean INFO = isLoggable(android.util.Log.INFO);
+    public static final boolean VERBOSE = isLoggable(android.util.Log.VERBOSE);
+    public static final boolean WARN = isLoggable(android.util.Log.WARN);
+    public static final boolean ERROR = isLoggable(android.util.Log.ERROR);
+
+    private Log() {}
+
+    public static boolean isLoggable(int level) {
+        return FORCE_LOGGING || android.util.Log.isLoggable(TAG, level);
+    }
+
+    public static void d(String prefix, String format, Object... args) {
+        if (DEBUG) {
+            android.util.Log.d(TAG, buildMessage(prefix, format, args));
+        }
+    }
+
+    public static void d(Object objectPrefix, String format, Object... args) {
+        if (DEBUG) {
+            android.util.Log.d(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
+        }
+    }
+
+    public static void i(String prefix, String format, Object... args) {
+        if (INFO) {
+            android.util.Log.i(TAG, buildMessage(prefix, format, args));
+        }
+    }
+
+    public static void i(Object objectPrefix, String format, Object... args) {
+        if (INFO) {
+            android.util.Log.i(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
+        }
+    }
+
+    public static void v(String prefix, String format, Object... args) {
+        if (VERBOSE) {
+            android.util.Log.v(TAG, buildMessage(prefix, format, args));
+        }
+    }
+
+    public static void v(Object objectPrefix, String format, Object... args) {
+        if (VERBOSE) {
+            android.util.Log.v(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
+        }
+    }
+
+    public static void w(String prefix, String format, Object... args) {
+        if (WARN) {
+            android.util.Log.w(TAG, buildMessage(prefix, format, args));
+        }
+    }
+
+    public static void w(Object objectPrefix, String format, Object... args) {
+        if (WARN) {
+            android.util.Log.w(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args));
+        }
+    }
+
+    public static void e(String prefix, Throwable tr, String format, Object... args) {
+        if (ERROR) {
+            android.util.Log.e(TAG, buildMessage(prefix, format, args), tr);
+        }
+    }
+
+    public static void e(Object objectPrefix, Throwable tr, String format, Object... args) {
+        if (ERROR) {
+            android.util.Log.e(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args),
+                    tr);
+        }
+    }
+
+    public static void wtf(String prefix, Throwable tr, String format, Object... args) {
+        android.util.Log.wtf(TAG, buildMessage(prefix, format, args), tr);
+    }
+
+    public static void wtf(Object objectPrefix, Throwable tr, String format, Object... args) {
+        android.util.Log.wtf(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args),
+                tr);
+    }
+
+    public static void wtf(String prefix, String format, Object... args) {
+        String msg = buildMessage(prefix, format, args);
+        android.util.Log.wtf(TAG, msg, new IllegalStateException(msg));
+    }
+
+    public static void wtf(Object objectPrefix, String format, Object... args) {
+        String msg = buildMessage(getPrefixFromObject(objectPrefix), format, args);
+        android.util.Log.wtf(TAG, msg, new IllegalStateException(msg));
+    }
+
+    public static String piiHandle(Object pii) {
+        if (pii == null || VERBOSE) {
+            return String.valueOf(pii);
+        }
+
+        if (pii instanceof Uri) {
+            Uri uri = (Uri) pii;
+
+            // All Uri's which are not "tel" go through normal pii() method.
+            if (!PhoneAccount.SCHEME_TEL.equals(uri.getScheme())) {
+                return pii(pii);
+            } else {
+                pii = uri.getSchemeSpecificPart();
+            }
+        }
+
+        String originalString = String.valueOf(pii);
+        StringBuilder stringBuilder = new StringBuilder(originalString.length());
+        for (char c : originalString.toCharArray()) {
+            if (PhoneNumberUtils.isDialable(c)) {
+                stringBuilder.append('*');
+            } else {
+                stringBuilder.append(c);
+            }
+        }
+        return stringBuilder.toString();
+    }
+
+    /**
+     * Redact personally identifiable information for production users.
+     * If we are running in verbose mode, return the original string, otherwise
+     * return a SHA-1 hash of the input string.
+     */
+    public static String pii(Object pii) {
+        if (pii == null || VERBOSE) {
+            return String.valueOf(pii);
+        }
+        return "[" + secureHash(String.valueOf(pii).getBytes()) + "]";
+    }
+
+    private static String secureHash(byte[] input) {
+        MessageDigest messageDigest;
+        try {
+            messageDigest = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException e) {
+            return null;
+        }
+        messageDigest.update(input);
+        byte[] result = messageDigest.digest();
+        return encodeHex(result);
+    }
+
+    private static String encodeHex(byte[] bytes) {
+        StringBuffer hex = new StringBuffer(bytes.length * 2);
+
+        for (int i = 0; i < bytes.length; i++) {
+            int byteIntValue = bytes[i] & 0xff;
+            if (byteIntValue < 0x10) {
+                hex.append("0");
+            }
+            hex.append(Integer.toString(byteIntValue, 16));
+        }
+
+        return hex.toString();
+    }
+
+    private static String getPrefixFromObject(Object obj) {
+        return obj == null ? "<null>" : obj.getClass().getSimpleName();
+    }
+
+    private static String buildMessage(String prefix, String format, Object... args) {
+        String msg;
+        try {
+            msg = (args == null || args.length == 0) ? format
+                    : String.format(Locale.US, format, args);
+        } catch (IllegalFormatException ife) {
+            e("Log", ife, "IllegalFormatException: formatString='%s' numArgs=%d", format,
+                    args.length);
+            msg = format + " (An error occurred while formatting the message.)";
+        }
+        return String.format(Locale.US, "%s: %s", prefix, msg);
+    }
+}
diff --git a/src/com/android/server/telecom/MissedCallNotifier.java b/src/com/android/server/telecom/MissedCallNotifier.java
new file mode 100644
index 0000000..553d2e1
--- /dev/null
+++ b/src/com/android/server/telecom/MissedCallNotifier.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.TaskStackBuilder;
+import android.content.AsyncQueryHandler;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.CallLog;
+import android.provider.CallLog.Calls;
+import android.telecom.CallState;
+import android.telephony.DisconnectCause;
+import android.text.BidiFormatter;
+import android.text.TextDirectionHeuristics;
+import android.text.TextUtils;
+
+/**
+ * Creates a notification for calls that the user missed (neither answered nor rejected).
+ * TODO: Make TelephonyManager.clearMissedCalls call into this class.
+ * STOPSHIP: Resolve b/13769374 about moving this class to InCall.
+ */
+class MissedCallNotifier extends CallsManagerListenerBase {
+
+    private static final String[] CALL_LOG_PROJECTION = new String[] {
+        Calls._ID,
+        Calls.NUMBER,
+        Calls.NUMBER_PRESENTATION,
+        Calls.DATE,
+        Calls.DURATION,
+        Calls.TYPE,
+    };
+    private static final int MISSED_CALL_NOTIFICATION_ID = 1;
+
+    private final Context mContext;
+    private final NotificationManager mNotificationManager;
+
+    // Used to track the number of missed calls.
+    private int mMissedCallCount = 0;
+
+    MissedCallNotifier(Context context) {
+        mContext = context;
+        mNotificationManager =
+                (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+
+        updateOnStartup();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onCallStateChanged(Call call, int oldState, int newState) {
+        if (oldState == CallState.RINGING && newState == CallState.DISCONNECTED &&
+                call.getDisconnectCause() == DisconnectCause.INCOMING_MISSED) {
+            showMissedCallNotification(call);
+        }
+    }
+
+    /** Clears missed call notification and marks the call log's missed calls as read. */
+    void clearMissedCalls() {
+        // Clear the list of new missed calls from the call log.
+        ContentValues values = new ContentValues();
+        values.put(Calls.NEW, 0);
+        values.put(Calls.IS_READ, 1);
+        StringBuilder where = new StringBuilder();
+        where.append(Calls.NEW);
+        where.append(" = 1 AND ");
+        where.append(Calls.TYPE);
+        where.append(" = ?");
+        mContext.getContentResolver().update(Calls.CONTENT_URI, values, where.toString(),
+                new String[]{ Integer.toString(Calls.MISSED_TYPE) });
+
+        cancelMissedCallNotification();
+    }
+
+    /**
+     * Create a system notification for the missed call.
+     *
+     * @param call The missed call.
+     */
+    private void showMissedCallNotification(Call call) {
+        mMissedCallCount++;
+
+        final int titleResId;
+        final String expandedText;  // The text in the notification's line 1 and 2.
+
+        // Display the first line of the notification:
+        // 1 missed call: <caller name || handle>
+        // More than 1 missed call: <number of calls> + "missed calls"
+        if (mMissedCallCount == 1) {
+            titleResId = R.string.notification_missedCallTitle;
+            expandedText = getNameForCall(call);
+        } else {
+            titleResId = R.string.notification_missedCallsTitle;
+            expandedText =
+                    mContext.getString(R.string.notification_missedCallsMsg, mMissedCallCount);
+        }
+
+        // Create the notification.
+        Notification.Builder builder = new Notification.Builder(mContext);
+        builder.setSmallIcon(android.R.drawable.stat_notify_missed_call)
+                .setColor(mContext.getResources().getColor(R.color.theme_color))
+                .setWhen(call.getCreationTimeMillis())
+                .setContentTitle(mContext.getText(titleResId))
+                .setContentText(expandedText)
+                .setContentIntent(createCallLogPendingIntent())
+                .setAutoCancel(true)
+                .setDeleteIntent(createClearMissedCallsPendingIntent());
+
+        Uri handleUri = call.getHandle();
+        String handle = handleUri == null ? null : handleUri.getSchemeSpecificPart();
+
+        // Add additional actions when there is only 1 missed call, like call-back and SMS.
+        if (mMissedCallCount == 1) {
+            Log.d(this, "Add actions with number %s.", Log.piiHandle(handle));
+
+            if (!TextUtils.isEmpty(handle)
+                    && !TextUtils.equals(handle, mContext.getString(R.string.handle_restricted))) {
+                builder.addAction(R.drawable.stat_sys_phone_call,
+                        mContext.getString(R.string.notification_missedCall_call_back),
+                        createCallBackPendingIntent(handleUri));
+
+                builder.addAction(R.drawable.ic_text_holo_dark,
+                        mContext.getString(R.string.notification_missedCall_message),
+                        createSendSmsFromNotificationPendingIntent(handleUri));
+            }
+
+            Bitmap photoIcon = call.getPhotoIcon();
+            if (photoIcon != null) {
+                builder.setLargeIcon(photoIcon);
+            } else {
+                Drawable photo = call.getPhoto();
+                if (photo != null && photo instanceof BitmapDrawable) {
+                    builder.setLargeIcon(((BitmapDrawable) photo).getBitmap());
+                }
+            }
+        } else {
+            Log.d(this, "Suppress actions. handle: %s, missedCalls: %d.", Log.piiHandle(handle),
+                    mMissedCallCount);
+        }
+
+        Notification notification = builder.build();
+        configureLedOnNotification(notification);
+
+        Log.i(this, "Adding missed call notification for %s.", call);
+        mNotificationManager.notify(MISSED_CALL_NOTIFICATION_ID, notification);
+    }
+
+    /** Cancels the "missed call" notification. */
+    private void cancelMissedCallNotification() {
+        // Reset the number of missed calls to 0.
+        mMissedCallCount = 0;
+        mNotificationManager.cancel(MISSED_CALL_NOTIFICATION_ID);
+    }
+
+    /**
+     * Returns the name to use in the missed call notification.
+     */
+    private String getNameForCall(Call call) {
+        String handle = call.getHandle() == null ? null : call.getHandle().getSchemeSpecificPart();
+        String name = call.getName();
+
+        if (!TextUtils.isEmpty(name) && TextUtils.isGraphic(name)) {
+            return name;
+        } else if (!TextUtils.isEmpty(handle)) {
+            // A handle should always be displayed LTR using {@link BidiFormatter} regardless of the
+            // content of the rest of the notification.
+            // TODO: Does this apply to SIP addresses?
+            BidiFormatter bidiFormatter = BidiFormatter.getInstance();
+            return bidiFormatter.unicodeWrap(handle, TextDirectionHeuristics.LTR);
+        } else {
+            // Use "unknown" if the call is unidentifiable.
+            return mContext.getString(R.string.unknown);
+        }
+    }
+
+    /**
+     * Creates a new pending intent that sends the user to the call log.
+     *
+     * @return The pending intent.
+     */
+    private PendingIntent createCallLogPendingIntent() {
+        Intent intent = new Intent(Intent.ACTION_VIEW, null);
+        intent.setType(CallLog.Calls.CONTENT_TYPE);
+
+        TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(mContext);
+        taskStackBuilder.addNextIntent(intent);
+
+        return taskStackBuilder.getPendingIntent(0, 0);
+    }
+
+    /**
+     * Creates an intent to be invoked when the missed call notification is cleared.
+     */
+    private PendingIntent createClearMissedCallsPendingIntent() {
+        return createTelecomPendingIntent(
+                TelecomBroadcastReceiver.ACTION_CLEAR_MISSED_CALLS, null);
+    }
+
+    /**
+     * Creates an intent to be invoked when the user opts to "call back" from the missed call
+     * notification.
+     *
+     * @param handle The handle to call back.
+     */
+    private PendingIntent createCallBackPendingIntent(Uri handle) {
+        return createTelecomPendingIntent(
+                TelecomBroadcastReceiver.ACTION_CALL_BACK_FROM_NOTIFICATION, handle);
+    }
+
+    /**
+     * Creates an intent to be invoked when the user opts to "send sms" from the missed call
+     * notification.
+     */
+    private PendingIntent createSendSmsFromNotificationPendingIntent(Uri handle) {
+        return createTelecomPendingIntent(
+                TelecomBroadcastReceiver.ACTION_SEND_SMS_FROM_NOTIFICATION,
+                Uri.fromParts(Constants.SCHEME_SMSTO, handle.getSchemeSpecificPart(), null));
+    }
+
+    /**
+     * Creates generic pending intent from the specified parameters to be received by
+     * {@link TelecomBroadcastReceiver}.
+     *
+     * @param action The intent action.
+     * @param data The intent data.
+     */
+    private PendingIntent createTelecomPendingIntent(String action, Uri data) {
+        Intent intent = new Intent(action, data, mContext, TelecomBroadcastReceiver.class);
+        return PendingIntent.getBroadcast(mContext, 0, intent, 0);
+    }
+
+    /**
+     * Configures a notification to emit the blinky notification light.
+     */
+    private void configureLedOnNotification(Notification notification) {
+        notification.flags |= Notification.FLAG_SHOW_LIGHTS;
+        notification.defaults |= Notification.DEFAULT_LIGHTS;
+    }
+
+    /**
+     * Adds the missed call notification on startup if there are unread missed calls.
+     */
+    private void updateOnStartup() {
+        Log.d(this, "updateOnStartup()...");
+
+        // instantiate query handler
+        AsyncQueryHandler queryHandler = new AsyncQueryHandler(mContext.getContentResolver()) {
+            @Override
+            protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+                Log.d(MissedCallNotifier.this, "onQueryComplete()...");
+                if (cursor != null) {
+                    try {
+                        while (cursor.moveToNext()) {
+                            // Get data about the missed call from the cursor
+                            Uri handle = Uri.parse(cursor.getString(
+                                    cursor.getColumnIndexOrThrow(Calls.NUMBER)));
+                            int presentation = cursor.getInt(cursor.getColumnIndexOrThrow(
+                                    Calls.NUMBER_PRESENTATION));
+
+                            if (presentation != Calls.PRESENTATION_ALLOWED) {
+                                handle = null;
+                            }
+
+                            // Convert the data to a call object
+                            Call call = new Call(null, null, null, null, null, true, false);
+                            call.setDisconnectCause(DisconnectCause.INCOMING_MISSED, "");
+                            call.setState(CallState.DISCONNECTED);
+
+                            // Listen for the update to the caller information before posting the
+                            // notification so that we have the contact info and photo.
+                            call.addListener(new Call.ListenerBase() {
+                                @Override
+                                public void onCallerInfoChanged(Call call) {
+                                    call.removeListener(this);  // No longer need to listen to call
+                                                                // changes after the contact info
+                                                                // is retrieved.
+                                    showMissedCallNotification(call);
+                                }
+                            });
+                            // Set the handle here because that is what triggers the contact info
+                            // query.
+                            call.setHandle(handle, presentation);
+                        }
+                    } finally {
+                        cursor.close();
+                    }
+                }
+            }
+        };
+
+        // setup query spec, look for all Missed calls that are new.
+        StringBuilder where = new StringBuilder("type=");
+        where.append(Calls.MISSED_TYPE);
+        where.append(" AND new=1");
+
+        // start the query
+        queryHandler.startQuery(0, null, Calls.CONTENT_URI, CALL_LOG_PROJECTION,
+                where.toString(), null, Calls.DEFAULT_SORT_ORDER);
+    }
+}
diff --git a/src/com/android/server/telecom/MultiLineTitleEditTextPreference.java b/src/com/android/server/telecom/MultiLineTitleEditTextPreference.java
new file mode 100644
index 0000000..d94dc60
--- /dev/null
+++ b/src/com/android/server/telecom/MultiLineTitleEditTextPreference.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2011 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.server.telecom;
+
+import android.content.Context;
+import android.preference.EditTextPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * Ultra-simple subclass of EditTextPreference that allows the "title" to wrap
+ * onto multiple lines.
+ *
+ * (By default, the title of an EditTextPreference is singleLine="true"; see
+ * preference_holo.xml under frameworks/base.  But in the "Respond via SMS"
+ * settings UI we want titles to be multi-line, since the customized messages
+ * might be fairly long, and should be able to wrap.)
+ *
+ * TODO: This is pretty cumbersome; it would be nicer for the framework to
+ * either allow modifying the title's attributes in XML, or at least provide
+ * some way from Java (given an EditTextPreference) to reach inside and get a
+ * handle to the "title" TextView.
+ *
+ * TODO: Also, it would reduce clutter if this could be an inner class in
+ * RespondViaSmsManager.java, but then there would be no way to reference the
+ * class from XML.  That's because
+ *    <com.android.server.telecom.MultiLineTitleEditTextPreference ... />
+ * isn't valid XML syntax due to the "$" character.  And Preference
+ * elements don't have a "class" attribute, so you can't do something like
+ * <view class="com.android.server.telecom.Foo$Bar"> as you can with regular views.
+ */
+public class MultiLineTitleEditTextPreference extends EditTextPreference {
+    public MultiLineTitleEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    public MultiLineTitleEditTextPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public MultiLineTitleEditTextPreference(Context context) {
+        super(context);
+    }
+
+    // The "title" TextView inside an EditTextPreference defaults to
+    // singleLine="true" (see preference_holo.xml under frameworks/base.)
+    // We override onBindView() purely to look up that TextView and call
+    // setSingleLine(false) on it.
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+
+        TextView textView = (TextView) view.findViewById(com.android.internal.R.id.title);
+        if (textView != null) {
+            textView.setSingleLine(false);
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
new file mode 100644
index 0000000..3fbe498
--- /dev/null
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -0,0 +1,419 @@
+/*
+ * 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.server.telecom;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.telecom.GatewayInfo;
+import android.telecom.PhoneAccount;
+import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
+import android.telephony.DisconnectCause;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+
+/**
+ * OutgoingCallIntentBroadcaster receives CALL and CALL_PRIVILEGED Intents, and broadcasts the
+ * ACTION_NEW_OUTGOING_CALL intent. ACTION_NEW_OUTGOING_CALL is an ordered broadcast intent which
+ * contains the phone number being dialed. Applications can use this intent to (1) see which numbers
+ * are being dialed, (2) redirect a call (change the number being dialed), or (3) prevent a call
+ * from being placed.
+ *
+ * After the other applications have had a chance to see the ACTION_NEW_OUTGOING_CALL intent, it
+ * finally reaches the {@link NewOutgoingCallBroadcastIntentReceiver}.
+ *
+ * Calls where no number is present (like for a CDMA "empty flash" or a nonexistent voicemail
+ * number) are exempt from being broadcast.
+ *
+ * Calls to emergency numbers are still broadcast for informative purposes. The call is placed
+ * prior to sending ACTION_NEW_OUTGOING_CALL and cannot be redirected nor prevented.
+ */
+class NewOutgoingCallIntentBroadcaster {
+    /** Required permission for any app that wants to consume ACTION_NEW_OUTGOING_CALL. */
+    private static final String PERMISSION = android.Manifest.permission.PROCESS_OUTGOING_CALLS;
+
+    private static final String EXTRA_ACTUAL_NUMBER_TO_DIAL =
+            "android.telecom.extra.ACTUAL_NUMBER_TO_DIAL";
+
+    /**
+     * Legacy string constants used to retrieve gateway provider extras from intents. These still
+     * need to be copied from the source call intent to the destination intent in order to
+     * support third party gateway providers that are still using old string constants in
+     * Telephony.
+     */
+    public static final String EXTRA_GATEWAY_PROVIDER_PACKAGE =
+            "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE";
+    public static final String EXTRA_GATEWAY_URI = "com.android.phone.extra.GATEWAY_URI";
+    public static final String EXTRA_GATEWAY_ORIGINAL_URI =
+            "com.android.phone.extra.GATEWAY_ORIGINAL_URI";
+
+    private final CallsManager mCallsManager;
+    private final Call mCall;
+    private final Intent mIntent;
+    /*
+     * Whether or not the outgoing call intent originated from the default phone application. If
+     * so, it will be allowed to make emergency calls, even with the ACTION_CALL intent.
+     */
+    private final boolean mIsDefaultOrSystemPhoneApp;
+
+    NewOutgoingCallIntentBroadcaster(CallsManager callsManager, Call call, Intent intent,
+            boolean isDefaultPhoneApp) {
+        mCallsManager = callsManager;
+        mCall = call;
+        mIntent = intent;
+        mIsDefaultOrSystemPhoneApp = isDefaultPhoneApp;
+    }
+
+    /**
+     * Processes the result of the outgoing call broadcast intent, and performs callbacks to
+     * the OutgoingCallIntentBroadcasterListener as necessary.
+     */
+    private class NewOutgoingCallBroadcastIntentReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.v(this, "onReceive: %s", intent);
+
+            // Once the NEW_OUTGOING_CALL broadcast is finished, the resultData is used as the
+            // actual number to call. (If null, no call will be placed.)
+            String resultNumber = getResultData();
+            Log.v(this, "- got number from resultData: %s", Log.pii(resultNumber));
+
+            boolean endEarly = false;
+            if (resultNumber == null) {
+                Log.v(this, "Call cancelled (null number), returning...");
+                endEarly = true;
+            } else if (PhoneNumberUtils.isPotentialLocalEmergencyNumber(context, resultNumber)) {
+                Log.w(this, "Cannot modify outgoing call to emergency number %s.", resultNumber);
+                endEarly = true;
+            }
+
+            if (endEarly) {
+                if (mCall != null) {
+                    mCall.disconnect();
+                }
+                return;
+            }
+
+            Uri resultHandleUri = Uri.fromParts(PhoneNumberUtils.isUriNumber(resultNumber) ?
+                    PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL, resultNumber, null);
+
+            Uri originalUri = mIntent.getData();
+
+            if (originalUri.getSchemeSpecificPart().equals(resultNumber)) {
+                Log.v(this, "Call number unmodified after new outgoing call intent broadcast.");
+            } else {
+                Log.v(this, "Retrieved modified handle after outgoing call intent broadcast: "
+                        + "Original: %s, Modified: %s",
+                        Log.pii(originalUri),
+                        Log.pii(resultHandleUri));
+            }
+
+            GatewayInfo gatewayInfo = getGateWayInfoFromIntent(intent, resultHandleUri);
+            mCallsManager.placeOutgoingCall(mCall, resultHandleUri, gatewayInfo,
+                    mIntent.getBooleanExtra(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE,
+                            false),
+                    mIntent.getIntExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
+                            VideoProfile.VideoState.AUDIO_ONLY));
+        }
+    }
+
+    /**
+     * Processes the supplied intent and starts the outgoing call broadcast process relevant to the
+     * intent.
+     *
+     * This method will handle three kinds of actions:
+     *
+     * - CALL (intent launched by all third party dialers)
+     * - CALL_PRIVILEGED (intent launched by system apps e.g. system Dialer, voice Dialer)
+     * - CALL_EMERGENCY (intent launched by lock screen emergency dialer)
+     *
+     * @return {@link CallActivity#OUTGOING_CALL_SUCCEEDED} if the call succeeded, and an
+     *         appropriate {@link DisconnectCause} if the call did not, describing why it failed.
+     */
+    int processIntent() {
+        Log.v(this, "Processing call intent in OutgoingCallIntentBroadcaster.");
+
+        final Context context = TelecomApp.getInstance();
+
+        Intent intent = mIntent;
+        String action = intent.getAction();
+        final Uri handle = intent.getData();
+
+        if (handle == null) {
+            Log.w(this, "Empty handle obtained from the call intent.");
+            return DisconnectCause.INVALID_NUMBER;
+        }
+
+        boolean isVoicemailNumber = PhoneAccount.SCHEME_VOICEMAIL.equals(handle.getScheme());
+        if (isVoicemailNumber) {
+            if (Intent.ACTION_CALL.equals(action)) {
+                // Voicemail calls will be handled directly by the telephony connection manager
+                Log.i(this, "Placing call immediately instead of waiting for "
+                        + " OutgoingCallBroadcastReceiver: %s", intent);
+
+                boolean speakerphoneOn = mIntent.getBooleanExtra(
+                        TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, false);
+                mCallsManager.placeOutgoingCall(mCall, handle, null, speakerphoneOn,
+                        VideoProfile.VideoState.AUDIO_ONLY);
+
+                return DisconnectCause.NOT_DISCONNECTED;
+            } else {
+                Log.i(this, "Unhandled intent %s. Ignoring and not placing call.", intent);
+                return DisconnectCause.OUTGOING_CANCELED;
+            }
+        }
+
+        String number = PhoneNumberUtils.getNumberFromIntent(intent, context);
+        if (TextUtils.isEmpty(number)) {
+            Log.w(this, "Empty number obtained from the call intent.");
+            return DisconnectCause.NO_PHONE_NUMBER_SUPPLIED;
+        }
+
+        boolean isUriNumber = PhoneNumberUtils.isUriNumber(number);
+        if (!isUriNumber) {
+            number = PhoneNumberUtils.convertKeypadLettersToDigits(number);
+            number = PhoneNumberUtils.stripSeparators(number);
+        }
+
+        final boolean isPotentialEmergencyNumber = isPotentialEmergencyNumber(context, number);
+        Log.v(this, "isPotentialEmergencyNumber = %s", isPotentialEmergencyNumber);
+
+        rewriteCallIntentAction(intent, isPotentialEmergencyNumber);
+        action = intent.getAction();
+        // True for certain types of numbers that are not intended to be intercepted or modified
+        // by third parties (e.g. emergency numbers).
+        boolean callImmediately = false;
+
+        if (Intent.ACTION_CALL.equals(action)) {
+            if (isPotentialEmergencyNumber) {
+                if (!mIsDefaultOrSystemPhoneApp) {
+                    Log.w(this, "Cannot call potential emergency number %s with CALL Intent %s "
+                            + "unless caller is system or default dialer.", number, intent);
+                    launchSystemDialer(context, intent.getData());
+                    return DisconnectCause.OUTGOING_CANCELED;
+                } else {
+                    callImmediately = true;
+                }
+            }
+        } else if (Intent.ACTION_CALL_EMERGENCY.equals(action)) {
+            if (!isPotentialEmergencyNumber) {
+                Log.w(this, "Cannot call non-potential-emergency number %s with EMERGENCY_CALL "
+                        + "Intent %s.", number, intent);
+                return DisconnectCause.OUTGOING_CANCELED;
+            }
+            callImmediately = true;
+        } else {
+            Log.w(this, "Unhandled Intent %s. Ignoring and not placing call.", intent);
+            return DisconnectCause.INVALID_NUMBER;
+        }
+
+        if (callImmediately) {
+            Log.i(this, "Placing call immediately instead of waiting for "
+                    + " OutgoingCallBroadcastReceiver: %s", intent);
+            String scheme = isUriNumber ? PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL;
+            boolean speakerphoneOn = mIntent.getBooleanExtra(
+                    TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, false);
+            int videoState = mIntent.getIntExtra(
+                    TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
+                    VideoProfile.VideoState.AUDIO_ONLY);
+            mCallsManager.placeOutgoingCall(mCall, Uri.fromParts(scheme, number, null), null,
+                    speakerphoneOn, videoState);
+
+            // Don't return but instead continue and send the ACTION_NEW_OUTGOING_CALL broadcast
+            // so that third parties can still inspect (but not intercept) the outgoing call. When
+            // the broadcast finally reaches the OutgoingCallBroadcastReceiver, we'll know not to
+            // initiate the call again because of the presence of the EXTRA_ALREADY_CALLED extra.
+        }
+
+        broadcastIntent(intent, number, context, !callImmediately);
+        return DisconnectCause.NOT_DISCONNECTED;
+    }
+
+    /**
+     * Sends a new outgoing call ordered broadcast so that third party apps can cancel the
+     * placement of the call or redirect it to a different number.
+     *
+     * @param originalCallIntent The original call intent.
+     * @param number Call number that was stored in the original call intent.
+     * @param context Valid context to send the ordered broadcast using.
+     * @param receiverRequired Whether or not the result from the ordered broadcast should be
+     *     processed using a {@link NewOutgoingCallIntentBroadcaster}.
+     */
+    private void broadcastIntent(
+            Intent originalCallIntent,
+            String number,
+            Context context,
+            boolean receiverRequired) {
+        Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
+        if (number != null) {
+            broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
+        }
+
+        // Force receivers of this broadcast intent to run at foreground priority because we
+        // want to finish processing the broadcast intent as soon as possible.
+        broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        Log.v(this, "Broadcasting intent: %s.", broadcastIntent);
+
+        checkAndCopyProviderExtras(originalCallIntent, broadcastIntent);
+
+        context.sendOrderedBroadcastAsUser(
+                broadcastIntent,
+                UserHandle.OWNER,
+                PERMISSION,
+                receiverRequired ? new NewOutgoingCallBroadcastIntentReceiver() : null,
+                null,  // scheduler
+                Activity.RESULT_OK,  // initialCode
+                number,  // initialData: initial value for the result data (number to be modified)
+                null);  // initialExtras
+    }
+
+    /**
+     * Copy all the expected extras set when a 3rd party gateway provider is to be used, from the
+     * source intent to the destination one.
+     *
+     * @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 void checkAndCopyProviderExtras(Intent src, Intent dst) {
+        if (src == null) {
+            return;
+        }
+        if (hasGatewayProviderExtras(src)) {
+            dst.putExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE,
+                    src.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE));
+            dst.putExtra(EXTRA_GATEWAY_URI,
+                    src.getStringExtra(EXTRA_GATEWAY_URI));
+            Log.d(this, "Found and copied gateway provider extras to broadcast intent.");
+            return;
+        }
+
+        Log.d(this, "No provider extras found in call intent.");
+    }
+
+    /**
+     * Check if valid gateway provider information is stored as extras in the intent
+     *
+     * @param intent to check for
+     * @return true if the intent has all the gateway information extras needed.
+     */
+    private boolean hasGatewayProviderExtras(Intent intent) {
+        final String name = intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE);
+        final String uriString = intent.getStringExtra(EXTRA_GATEWAY_URI);
+
+        return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(uriString);
+    }
+
+    private static Uri getGatewayUriFromString(String gatewayUriString) {
+        return TextUtils.isEmpty(gatewayUriString) ? null : Uri.parse(gatewayUriString);
+    }
+
+    /**
+     * Extracts gateway provider information from a provided intent..
+     *
+     * @param intent to extract gateway provider information from.
+     * @param trueHandle The actual call handle that the user is trying to dial
+     * @return GatewayInfo object containing extracted gateway provider information as well as
+     *     the actual handle the user is trying to dial.
+     */
+    public static GatewayInfo getGateWayInfoFromIntent(Intent intent, Uri trueHandle) {
+        if (intent == null) {
+            return null;
+        }
+
+        // Check if gateway extras are present.
+        String gatewayPackageName = intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE);
+        Uri gatewayUri = getGatewayUriFromString(intent.getStringExtra(EXTRA_GATEWAY_URI));
+        if (!TextUtils.isEmpty(gatewayPackageName) && gatewayUri != null) {
+            return new GatewayInfo(gatewayPackageName, gatewayUri, trueHandle);
+        }
+
+        return null;
+    }
+
+    private void launchSystemDialer(Context context, Uri handle) {
+        Intent systemDialerIntent = new Intent();
+        final Resources resources = context.getResources();
+        systemDialerIntent.setClassName(
+                resources.getString(R.string.ui_default_package),
+                resources.getString(R.string.dialer_default_class));
+        systemDialerIntent.setAction(Intent.ACTION_DIAL);
+        systemDialerIntent.setData(handle);
+        systemDialerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        Log.v(this, "calling startActivity for default dialer: %s", systemDialerIntent);
+        context.startActivity(systemDialerIntent);
+    }
+
+    /**
+     * Check whether or not this is an emergency number, in order to enforce the restriction
+     * that only the CALL_PRIVILEGED and CALL_EMERGENCY intents are allowed to make emergency
+     * calls.
+     *
+     * To prevent malicious 3rd party apps from making emergency calls by passing in an
+     * "invalid" number like "9111234" (that isn't technically an emergency number but might
+     * still result in an emergency call with some networks), we use
+     * isPotentialLocalEmergencyNumber instead of isLocalEmergencyNumber.
+     *
+     * @param context Valid context
+     * @param number number to inspect in order to determine whether or not an emergency number
+     * is potentially being dialed
+     * @return True if the handle is potentially an emergency number.
+     */
+    private boolean isPotentialEmergencyNumber(Context context, String number) {
+        Log.v(this, "Checking restrictions for number : %s", Log.pii(number));
+        return (number != null) && PhoneNumberUtils.isPotentialLocalEmergencyNumber(context,number);
+    }
+
+    /**
+     * Given a call intent and whether or not the number to dial is an emergency number, rewrite
+     * the call intent action to an appropriate one.
+     *
+     * @param intent Intent to rewrite the action for
+     * @param isPotentialEmergencyNumber Whether or not the number is potentially an emergency
+     * number.
+     */
+    private void rewriteCallIntentAction(Intent intent, boolean isPotentialEmergencyNumber) {
+        if (CallActivity.class.getName().equals(intent.getComponent().getClassName())) {
+            // If we were launched directly from the CallActivity, not one of its more privileged
+            // aliases, then make sure that only the non-privileged actions are allowed.
+            if (!Intent.ACTION_CALL.equals(intent.getAction())) {
+                Log.w(this, "Attempt to deliver non-CALL action; forcing to CALL");
+                intent.setAction(Intent.ACTION_CALL);
+            }
+        }
+
+        String action = intent.getAction();
+
+        /* Change CALL_PRIVILEGED into CALL or CALL_EMERGENCY as needed. */
+        if (Intent.ACTION_CALL_PRIVILEGED.equals(action)) {
+            if (isPotentialEmergencyNumber) {
+                Log.i(this, "ACTION_CALL_PRIVILEGED is used while the number is a potential"
+                        + " emergency number. Using ACTION_CALL_EMERGENCY as an action instead.");
+                action = Intent.ACTION_CALL_EMERGENCY;
+            } else {
+                action = Intent.ACTION_CALL;
+            }
+            Log.v(this, " - updating action from CALL_PRIVILEGED to %s", action);
+            intent.setAction(action);
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/PhoneAccountBroadcastReceiver.java b/src/com/android/server/telecom/PhoneAccountBroadcastReceiver.java
new file mode 100644
index 0000000..6152bef
--- /dev/null
+++ b/src/com/android/server/telecom/PhoneAccountBroadcastReceiver.java
@@ -0,0 +1,76 @@
+/*
+ * 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.server.telecom;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+
+import java.lang.String;
+
+/**
+ * Captures {@code android.intent.action.ACTION_PACKAGE_FULLY_REMOVED} intents and triggers the
+ * removal of associated {@link android.telecom.PhoneAccount}s via the
+ * {@link com.android.telecom.PhoneAccountRegistrar}.
+ * Note: This class listens for the {@code PACKAGE_FULLY_REMOVED} intent rather than
+ * {@code PACKAGE_REMOVED} as {@code PACKAGE_REMOVED} is triggered on re-installation of the same
+ * package, where {@code PACKAGE_FULLY_REMOVED} is triggered only when an application is completely
+ * uninstalled.  This is desirable as we do not wish to un-register all
+ * {@link android.telecom.PhoneAccount}s associated with a package being re-installed to ensure
+ * the enabled state of the accounts is retained.
+ */
+public class PhoneAccountBroadcastReceiver extends BroadcastReceiver {
+    /**
+     * Receives the intents the class is configured to received.
+     *
+     * @param context The Context in which the receiver is running.
+     * @param intent The Intent being received.
+     */
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(intent.getAction())) {
+            Uri uri = intent.getData();
+            if (uri == null) {
+                return;
+            }
+
+            String packageName = uri.getSchemeSpecificPart();
+            handlePackageRemoved(context, packageName);
+        }
+    }
+
+    /**
+     * Handles the removal of a package by calling upon the {@link PhoneAccountRegistrar} to
+     * un-register any {@link android.telecom.PhoneAccount}s associated with the package.
+     *
+     * @param packageName The name of the removed package.
+     */
+    private void handlePackageRemoved(Context context, String packageName) {
+        TelecomApp telecomApp = TelecomApp.getInstance();
+        if (telecomApp == null) {
+            return;
+        }
+
+        PhoneAccountRegistrar registrar = telecomApp.getPhoneAccountRegistrar();
+        if (registrar == null) {
+            return;
+        }
+
+        registrar.clearAccounts(packageName);
+    }
+}
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
new file mode 100644
index 0000000..31dd727
--- /dev/null
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -0,0 +1,1041 @@
+/*
+ * 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.server.telecom;
+
+import android.Manifest;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.provider.Settings;
+import android.telecom.ConnectionService;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.AtomicFile;
+import android.util.Xml;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.Integer;
+import java.lang.SecurityException;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Handles writing and reading PhoneAccountHandle registration entries. This is a simple verbatim
+ * delegate for all the account handling methods on {@link android.telecom.TelecomManager} as implemented in
+ * {@link TelecomServiceImpl}, with the notable exception that {@link TelecomServiceImpl} is
+ * responsible for security checking to make sure that the caller has proper authority over
+ * the {@code ComponentName}s they are declaring in their {@code PhoneAccountHandle}s.
+ */
+public final class PhoneAccountRegistrar {
+
+    public static final PhoneAccountHandle NO_ACCOUNT_SELECTED =
+            new PhoneAccountHandle(new ComponentName("null", "null"), "NO_ACCOUNT_SELECTED");
+
+    public abstract static class Listener {
+        public void onAccountsChanged(PhoneAccountRegistrar registrar) {}
+        public void onDefaultOutgoingChanged(PhoneAccountRegistrar registrar) {}
+        public void onSimCallManagerChanged(PhoneAccountRegistrar registrar) {}
+    }
+
+    private static final String FILE_NAME = "phone-account-registrar-state.xml";
+    @VisibleForTesting
+    public static final int EXPECTED_STATE_VERSION = 3;
+
+    /** Keep in sync with the same in SipSettings.java */
+    private static final String SIP_SHARED_PREFERENCES = "SIP_PREFERENCES";
+
+    private final List<Listener> mListeners = new CopyOnWriteArrayList<>();
+    private final AtomicFile mAtomicFile;
+    private final Context mContext;
+    private State mState;
+
+    public PhoneAccountRegistrar(Context context) {
+        this(context, FILE_NAME);
+    }
+
+    @VisibleForTesting
+    public PhoneAccountRegistrar(Context context, String fileName) {
+        // TODO: Change file location when Telecom is part of system
+        mAtomicFile = new AtomicFile(new File(context.getFilesDir(), fileName));
+        mState = new State();
+        mContext = context;
+        read();
+    }
+
+    /**
+     * Retrieves the default outgoing phone account supporting the specified uriScheme.
+     * @param uriScheme The URI scheme for the outgoing call.
+     * @return The {@link PhoneAccountHandle} to use.
+     */
+    public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
+        final PhoneAccountHandle userSelected = getUserSelectedOutgoingPhoneAccount();
+
+        if (userSelected != null) {
+            // If there is a default PhoneAccount, ensure it supports calls to handles with the
+            // specified uriScheme.
+            final PhoneAccount userSelectedAccount = getPhoneAccount(userSelected);
+            if (userSelectedAccount.supportsUriScheme(uriScheme)) {
+                return userSelected;
+            }
+        }
+
+        List<PhoneAccountHandle> outgoing = getEnabledPhoneAccounts(uriScheme);
+        switch (outgoing.size()) {
+            case 0:
+                // There are no accounts, so there can be no default
+                return null;
+            case 1:
+                // There is only one account, which is by definition the default
+                return outgoing.get(0);
+            default:
+                // There are multiple accounts with no selected default
+                return null;
+        }
+    }
+
+    PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
+        if (mState.defaultOutgoing != null) {
+            // Return the registered outgoing default iff it still exists (we keep a sticky
+            // default to survive account deletion and re-addition)
+            for (int i = 0; i < mState.accounts.size(); i++) {
+                if (mState.accounts.get(i).getAccountHandle().equals(mState.defaultOutgoing)) {
+                    return mState.defaultOutgoing;
+                }
+            }
+            // At this point, there was a registered default but it has been deleted; proceed
+            // as though there were no default
+        }
+        return null;
+    }
+
+    public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
+        if (accountHandle == null) {
+            // Asking to clear the default outgoing is a valid request
+            mState.defaultOutgoing = null;
+        } else {
+            boolean found = false;
+            for (PhoneAccount m : mState.accounts) {
+                if (Objects.equals(accountHandle, m.getAccountHandle())) {
+                    found = true;
+                    break;
+                }
+            }
+
+            if (!found) {
+                Log.w(this, "Trying to set nonexistent default outgoing %s",
+                        accountHandle);
+                return;
+            }
+
+            if (!getPhoneAccount(accountHandle).hasCapabilities(
+                    PhoneAccount.CAPABILITY_CALL_PROVIDER)) {
+                Log.w(this, "Trying to set non-call-provider default outgoing %s",
+                        accountHandle);
+                return;
+            }
+
+            mState.defaultOutgoing = accountHandle;
+        }
+
+        write();
+        fireDefaultOutgoingChanged();
+    }
+
+    public void setSimCallManager(PhoneAccountHandle callManager) {
+        if (!isEnabledConnectionManager()) {
+            return;
+        }
+
+        if (callManager != null) {
+            PhoneAccount callManagerAccount = getPhoneAccount(callManager);
+            if (callManagerAccount == null) {
+                Log.d(this, "setSimCallManager: Nonexistent call manager: %s", callManager);
+                return;
+            } else if (!callManagerAccount.hasCapabilities(
+                    PhoneAccount.CAPABILITY_CONNECTION_MANAGER)) {
+                Log.d(this, "setSimCallManager: Not a call manager: %s", callManagerAccount);
+                return;
+            }
+        } else {
+            callManager = NO_ACCOUNT_SELECTED;
+        }
+        mState.simCallManager = callManager;
+
+        write();
+        fireSimCallManagerChanged();
+    }
+
+    public PhoneAccountHandle getSimCallManager() {
+        if (!isEnabledConnectionManager()) {
+            return null;
+        }
+
+        if (mState.simCallManager != null) {
+            if (NO_ACCOUNT_SELECTED.equals(mState.simCallManager)) {
+                return null;
+            }
+            // Return the registered sim call manager iff it still exists (we keep a sticky
+            // setting to survive account deletion and re-addition)
+            for (int i = 0; i < mState.accounts.size(); i++) {
+                if (mState.accounts.get(i).getAccountHandle().equals(mState.simCallManager)) {
+                    return mState.simCallManager;
+                }
+            }
+        }
+
+        // See if the OEM has specified a default one.
+        String defaultConnectionMgr =
+                mContext.getResources().getString(R.string.default_connection_manager_component);
+        if (!TextUtils.isEmpty(defaultConnectionMgr)) {
+            PackageManager pm = mContext.getPackageManager();
+
+            ComponentName componentName = ComponentName.unflattenFromString(defaultConnectionMgr);
+            Intent intent = new Intent(ConnectionService.SERVICE_INTERFACE);
+            intent.setComponent(componentName);
+
+            // Make sure that the component can be resolved.
+            List<ResolveInfo> resolveInfos = pm.queryIntentServices(intent, 0);
+            if (!resolveInfos.isEmpty()) {
+                // See if there is registered PhoneAccount by this component.
+                List<PhoneAccountHandle> handles = getAllPhoneAccountHandles();
+                for (PhoneAccountHandle handle : handles) {
+                    if (componentName.equals(handle.getComponentName())) {
+                        return handle;
+                    }
+                }
+                Log.d(this, "%s does not have a PhoneAccount; not using as default", componentName);
+            } else {
+                Log.d(this, "%s could not be resolved; not using as default", componentName);
+            }
+        } else {
+            Log.v(this, "No default connection manager specified");
+        }
+
+        return null;
+    }
+
+    /**
+     * Retrieves a list of all {@link PhoneAccountHandle}s registered.
+     *
+     * @return The list of {@link PhoneAccountHandle}s.
+     */
+    public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
+        List<PhoneAccountHandle> accountHandles = new ArrayList<>();
+        for (PhoneAccount m : mState.accounts) {
+            accountHandles.add(m.getAccountHandle());
+        }
+        return accountHandles;
+    }
+
+    public List<PhoneAccount> getAllPhoneAccounts() {
+        return new ArrayList<>(mState.accounts);
+    }
+
+    /**
+     * Determines the number of enabled and disabled {@link PhoneAccount}s.
+     *
+     * @return The number of enabled and disabled {@link PhoneAccount}s
+     */
+    public int getAllPhoneAccountsCount() {
+        return mState.accounts.size();
+    }
+
+    /**
+     * Retrieves a list of all enabled call provider phone accounts.
+     *
+     * @return The phone account handles.
+     */
+    public List<PhoneAccountHandle> getEnabledPhoneAccounts() {
+        return getPhoneAccountHandles(PhoneAccount.CAPABILITY_CALL_PROVIDER);
+    }
+
+    /**
+     * Retrieves a list of all enabled phone account call provider phone accounts supporting the
+     * specified URI scheme.
+     *
+     * @param uriScheme The URI scheme.
+     * @return The phone account handles.
+     */
+    public List<PhoneAccountHandle> getEnabledPhoneAccounts(String uriScheme) {
+        return getPhoneAccountHandles(PhoneAccount.CAPABILITY_CALL_PROVIDER, uriScheme,
+                false /* includeDisabled */);
+    }
+
+    /**
+     * Retrieves a list of all enabled phone account handles with the connection manager capability.
+     *
+     * @return The phone account handles.
+     */
+    public List<PhoneAccountHandle> getConnectionManagerPhoneAccounts() {
+        if (isEnabledConnectionManager()) {
+            return getPhoneAccountHandles(PhoneAccount.CAPABILITY_CONNECTION_MANAGER,
+                    null /* supportedUriScheme */, false /* includeDisabled */);
+        }
+        return Collections.emptyList();
+    }
+
+    public PhoneAccount getPhoneAccount(PhoneAccountHandle handle) {
+        for (PhoneAccount m : mState.accounts) {
+            if (Objects.equals(handle, m.getAccountHandle())) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Changes the enabled state of the {@link PhoneAccount} identified by a
+     * {@link PhoneAccountHandle}.
+     *
+     * @param handle The {@link PhoneAccountHandle}.
+     * @param isEnabled The new enabled state of the {@link PhoneAccount}.
+     */
+    public void setPhoneAccountEnabled(PhoneAccountHandle handle, boolean isEnabled) {
+        PhoneAccount existing = getPhoneAccount(handle);
+        if (existing.isEnabled() == isEnabled) {
+            return;
+        }
+
+        // Do not permit PhoneAccounts which are marked as always enabled to be disabled.
+        if (existing.hasCapabilities(PhoneAccount.CAPABILITY_ALWAYS_ENABLED)) {
+            return;
+        }
+
+        // If we are disabling the current default outgoing phone account or Sim call manager we
+        // need to null out those preferences.
+        if (!isEnabled) {
+            if (mState.defaultOutgoing != null && mState.defaultOutgoing.equals(handle)) {
+                setUserSelectedOutgoingPhoneAccount(null);
+            }
+
+            if (mState.simCallManager != null && mState.simCallManager.equals(handle)) {
+                setSimCallManager(null);
+            }
+        }
+
+        PhoneAccount.Builder builder = existing.toBuilder().setEnabled(isEnabled);
+        PhoneAccount replacement = builder.build();
+        addOrReplacePhoneAccount(replacement);
+
+        // Notify the package which registered this PhoneAccount of its new enabled state.
+        notifyPhoneAccountEnabledStateChanged(replacement.getAccountHandle(), isEnabled);
+    }
+
+    // TODO: Should we implement an artificial limit for # of accounts associated with a single
+    // ComponentName?
+    public void registerPhoneAccount(PhoneAccount account) {
+        // Enforce the requirement that a connection service for a phone account has the correct
+        // permission.
+        if (!phoneAccountHasPermission(account.getAccountHandle())) {
+            Log.w(this, "Phone account %s does not have BIND_CONNECTION_SERVICE permission.",
+                    account.getAccountHandle());
+            throw new SecurityException(
+                    "PhoneAccount connection service requires BIND_CONNECTION_SERVICE permission.");
+        }
+
+        // If there is an existing PhoneAccount already registered with this handle, copy its
+        // enabled state to the new phone account.
+        PhoneAccount existing = getPhoneAccount(account.getAccountHandle());
+        if (existing != null) {
+            account = account.toBuilder().setEnabled(existing.isEnabled()).build();
+        }
+
+        addOrReplacePhoneAccount(account);
+    }
+
+    /**
+     * Adds a {@code PhoneAccount}, replacing an existing one if found.
+     *
+     * @param account The {@code PhoneAccount} to add or replace.
+     */
+    private void addOrReplacePhoneAccount(PhoneAccount account) {
+        mState.accounts.add(account);
+        // Search for duplicates and remove any that are found.
+        for (int i = 0; i < mState.accounts.size() - 1; i++) {
+            if (Objects.equals(
+                    account.getAccountHandle(), mState.accounts.get(i).getAccountHandle())) {
+                // replace existing entry.
+                mState.accounts.remove(i);
+                break;
+            }
+        }
+
+        write();
+        fireAccountsChanged();
+    }
+
+    public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
+        for (int i = 0; i < mState.accounts.size(); i++) {
+            if (Objects.equals(accountHandle, mState.accounts.get(i).getAccountHandle())) {
+                mState.accounts.remove(i);
+                break;
+            }
+        }
+
+        write();
+        fireAccountsChanged();
+    }
+
+    /**
+     * Un-registers all phone accounts associated with a specified package.
+     *
+     * @param packageName The package for which phone accounts will be removed.
+     */
+    public void clearAccounts(String packageName) {
+        boolean accountsRemoved = false;
+        Iterator<PhoneAccount> it = mState.accounts.iterator();
+        while (it.hasNext()) {
+            PhoneAccount phoneAccount = it.next();
+            if (Objects.equals(
+                    packageName,
+                    phoneAccount.getAccountHandle().getComponentName().getPackageName())) {
+                Log.i(this, "Removing phone account " + phoneAccount.getLabel());
+                it.remove();
+                accountsRemoved = true;
+            }
+        }
+
+        if (accountsRemoved) {
+            write();
+            fireAccountsChanged();
+        }
+    }
+
+    public void addListener(Listener l) {
+        mListeners.add(l);
+    }
+
+    public void removeListener(Listener l) {
+        if (l != null) {
+            mListeners.remove(l);
+        }
+    }
+
+    private void fireAccountsChanged() {
+        for (Listener l : mListeners) {
+            l.onAccountsChanged(this);
+        }
+    }
+
+    private void fireDefaultOutgoingChanged() {
+        for (Listener l : mListeners) {
+            l.onDefaultOutgoingChanged(this);
+        }
+    }
+
+    private void fireSimCallManagerChanged() {
+        for (Listener l : mListeners) {
+            l.onSimCallManagerChanged(this);
+        }
+    }
+
+    private boolean isEnabledConnectionManager() {
+        return mContext.getResources().getBoolean(R.bool.connection_manager_enabled);
+    }
+
+    /**
+     * Determines if the connection service specified by a {@link PhoneAccountHandle} has the
+     * {@link Manifest.permission#BIND_CONNECTION_SERVICE} permission.
+     *
+     * @param phoneAccountHandle The phone account to check.
+     * @return {@code True} if the phone account has permission.
+     */
+    public boolean phoneAccountHasPermission(PhoneAccountHandle phoneAccountHandle) {
+        PackageManager packageManager = TelecomApp.getInstance().getPackageManager();
+        try {
+            ServiceInfo serviceInfo = packageManager.getServiceInfo(
+                    phoneAccountHandle.getComponentName(), 0);
+
+            return serviceInfo.permission != null &&
+                    serviceInfo.permission.equals(Manifest.permission.BIND_CONNECTION_SERVICE);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(this, "Name not found %s", e);
+            return false;
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns a list of phone account handles with the specified flag.
+     *
+     * @param flags Flags which the {@code PhoneAccount} must have.
+     */
+    private List<PhoneAccountHandle> getPhoneAccountHandles(int flags) {
+        return getPhoneAccountHandles(flags, null, false /* includeDisabled */);
+    }
+
+    /**
+     * Returns a list of phone account handles with the specified flag, supporting the specified
+     * URI scheme.  By default, only enabled phone accounts are included, unless the
+     * {@code includeDisabled} parameter is set {@code true}.
+     *
+     * @param flags Flags which the {@code PhoneAccount} must have.
+     * @param uriScheme URI schemes the PhoneAccount must handle.  {@code Null} bypasses the
+     *                  URI scheme check.
+     * @param includeDisabled When {@code true}, the list of phone accounts handles includes those
+     *                        which are marked as disabled.
+     */
+    private List<PhoneAccountHandle> getPhoneAccountHandles(int flags, String uriScheme,
+            boolean includeDisabled) {
+        List<PhoneAccountHandle> accountHandles = new ArrayList<>();
+        for (PhoneAccount m : mState.accounts) {
+            if ((includeDisabled || m.isEnabled()) && m.hasCapabilities(flags) &&
+                    (uriScheme == null || m.supportsUriScheme(uriScheme))) {
+                accountHandles.add(m.getAccountHandle());
+            }
+        }
+        return accountHandles;
+    }
+
+    /**
+     * Notifies the package which registered a {@link PhoneAccount} that it has been enabled.
+     * Only broadcasts the intent if the package has a {@link android.content.BroadcastReceiver}
+     * registered for the intent.
+     *
+     * @param phoneAccountHandle The {@link PhoneAccountHandle} which has been enabled or disabled.
+     * @param isEnabled {@code True} if the {@link PhoneAccount} is enabled, false otherwise.
+     */
+    private void notifyPhoneAccountEnabledStateChanged(PhoneAccountHandle phoneAccountHandle,
+            boolean isEnabled) {
+        Intent intent;
+
+        if (isEnabled) {
+            intent = new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_ENABLED);
+        } else {
+            intent = new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_DISABLED);
+        }
+        intent.setPackage(phoneAccountHandle.getComponentName().getPackageName());
+        intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+
+        if (isReceiverListening(intent)) {
+            Log.i(this, "notifyPhoneAccountEnabledState %s %s", phoneAccountHandle,
+                    (isEnabled ? "enabled" : "disabled"));
+            mContext.sendBroadcast(intent);
+        }
+    }
+
+    /**
+     * Determines there is a {@link android.content.BroadcastReceiver} listening for an
+     * {@link Intent}.
+     *
+     * @param intent The {@link Intent}.
+     * @return {@code True} if there is a listener.
+     */
+    private boolean isReceiverListening(Intent intent) {
+        PackageManager pm = mContext.getPackageManager();
+        final List<ResolveInfo> activities = pm.queryBroadcastReceivers(intent, 0);
+        return !(activities.isEmpty());
+    }
+
+    /**
+     * The state of this {@code PhoneAccountRegistrar}.
+     */
+    @VisibleForTesting
+    public static class State {
+        /**
+         * The account selected by the user to be employed by default for making outgoing calls.
+         * If the user has not made such a selection, then this is null.
+         */
+        public PhoneAccountHandle defaultOutgoing = null;
+
+        /**
+         * A {@code PhoneAccount} having {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} which
+         * manages and optimizes a user's PSTN SIM connections.
+         */
+        public PhoneAccountHandle simCallManager;
+
+        /**
+         * The complete list of {@code PhoneAccount}s known to the Telecom subsystem.
+         */
+        public final List<PhoneAccount> accounts = new ArrayList<>();
+
+        /**
+         * The version number of the State data.
+         */
+        public int versionNumber;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // State management
+    //
+
+    private void write() {
+        final FileOutputStream os;
+        try {
+            os = mAtomicFile.startWrite();
+            boolean success = false;
+            try {
+                XmlSerializer serializer = new FastXmlSerializer();
+                serializer.setOutput(new BufferedOutputStream(os), "utf-8");
+                writeToXml(mState, serializer);
+                serializer.flush();
+                success = true;
+            } finally {
+                if (success) {
+                    mAtomicFile.finishWrite(os);
+                } else {
+                    mAtomicFile.failWrite(os);
+                }
+            }
+        } catch (IOException e) {
+            Log.e(this, e, "Writing state to XML file");
+        }
+    }
+
+    private void read() {
+        final InputStream is;
+        try {
+            is = mAtomicFile.openRead();
+        } catch (FileNotFoundException ex) {
+            return;
+        }
+
+        boolean versionChanged = false;
+
+        XmlPullParser parser;
+        try {
+            parser = Xml.newPullParser();
+            parser.setInput(new BufferedInputStream(is), null);
+            parser.nextTag();
+            mState = readFromXml(parser, mContext);
+            versionChanged = mState.versionNumber < EXPECTED_STATE_VERSION;
+
+        } catch (IOException | XmlPullParserException e) {
+            Log.e(this, e, "Reading state from XML file");
+            mState = new State();
+        } finally {
+            try {
+                is.close();
+            } catch (IOException e) {
+                Log.e(this, e, "Closing InputStream");
+            }
+        }
+
+        // If an upgrade occurred, write out the changed data.
+        if (versionChanged) {
+            write();
+        }
+    }
+
+    private static void writeToXml(State state, XmlSerializer serializer)
+            throws IOException {
+        sStateXml.writeToXml(state, serializer);
+    }
+
+    private static State readFromXml(XmlPullParser parser, Context context)
+            throws IOException, XmlPullParserException {
+        State s = sStateXml.readFromXml(parser, 0, context);
+        return s != null ? s : new State();
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // XML serialization
+    //
+
+    @VisibleForTesting
+    public abstract static class XmlSerialization<T> {
+        private static final String LENGTH_ATTRIBUTE = "length";
+        private static final String VALUE_TAG = "value";
+
+        /**
+         * Write the supplied object to XML
+         */
+        public abstract void writeToXml(T o, XmlSerializer serializer)
+                throws IOException;
+
+        /**
+         * Read from the supplied XML into a new object, returning null in case of an
+         * unrecoverable schema mismatch or other data error. 'parser' must be already
+         * positioned at the first tag that is expected to have been emitted by this
+         * object's writeToXml(). This object tries to fail early without modifying
+         * 'parser' if it does not recognize the data it sees.
+         */
+        public abstract T readFromXml(XmlPullParser parser, int version, Context context)
+                throws IOException, XmlPullParserException;
+
+        protected void writeTextSafely(String tagName, Object value, XmlSerializer serializer)
+                throws IOException {
+            if (value != null) {
+                serializer.startTag(null, tagName);
+                serializer.text(Objects.toString(value));
+                serializer.endTag(null, tagName);
+            }
+        }
+
+        /**
+         * Serializes a string array.
+         *
+         * @param tagName The tag name for the string array.
+         * @param values The string values to serialize.
+         * @param serializer The serializer.
+         * @throws IOException
+         */
+        protected void writeStringList(String tagName, List<String> values,
+                XmlSerializer serializer)
+                throws IOException {
+
+            serializer.startTag(null, tagName);
+            if (values != null) {
+                serializer.attribute(null, LENGTH_ATTRIBUTE, Objects.toString(values.size()));
+                for (String toSerialize : values) {
+                    serializer.startTag(null, VALUE_TAG);
+                    if (toSerialize != null ){
+                        serializer.text(toSerialize);
+                    }
+                    serializer.endTag(null, VALUE_TAG);
+                }
+            } else {
+                serializer.attribute(null, LENGTH_ATTRIBUTE, "0");
+            }
+            serializer.endTag(null, tagName);
+
+        }
+
+        /**
+         * Reads a string array from the XML parser.
+         *
+         * @param parser The XML parser.
+         * @return String array containing the parsed values.
+         * @throws IOException Exception related to IO.
+         * @throws XmlPullParserException Exception related to parsing.
+         */
+        protected List<String> readStringList(XmlPullParser parser)
+                throws IOException, XmlPullParserException {
+
+            int length = Integer.parseInt(parser.getAttributeValue(null, LENGTH_ATTRIBUTE));
+            List<String> arrayEntries = new ArrayList<String>(length);
+            String value = null;
+
+            if (length == 0) {
+                return arrayEntries;
+            }
+
+            int outerDepth = parser.getDepth();
+            while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+                if (parser.getName().equals(VALUE_TAG)) {
+                    parser.next();
+                    value = parser.getText();
+                    arrayEntries.add(value);
+                }
+            }
+
+            return arrayEntries;
+        }
+    }
+
+    @VisibleForTesting
+    public static final XmlSerialization<State> sStateXml =
+            new XmlSerialization<State>() {
+        private static final String CLASS_STATE = "phone_account_registrar_state";
+        private static final String DEFAULT_OUTGOING = "default_outgoing";
+        private static final String SIM_CALL_MANAGER = "sim_call_manager";
+        private static final String ACCOUNTS = "accounts";
+        private static final String VERSION = "version";
+
+        @Override
+        public void writeToXml(State o, XmlSerializer serializer)
+                throws IOException {
+            if (o != null) {
+                serializer.startTag(null, CLASS_STATE);
+                serializer.attribute(null, VERSION, Objects.toString(EXPECTED_STATE_VERSION));
+
+                if (o.defaultOutgoing != null) {
+                    serializer.startTag(null, DEFAULT_OUTGOING);
+                    sPhoneAccountHandleXml.writeToXml(o.defaultOutgoing, serializer);
+                    serializer.endTag(null, DEFAULT_OUTGOING);
+                }
+
+                if (o.simCallManager != null) {
+                    serializer.startTag(null, SIM_CALL_MANAGER);
+                    sPhoneAccountHandleXml.writeToXml(o.simCallManager, serializer);
+                    serializer.endTag(null, SIM_CALL_MANAGER);
+                }
+
+                serializer.startTag(null, ACCOUNTS);
+                for (PhoneAccount m : o.accounts) {
+                    sPhoneAccountXml.writeToXml(m, serializer);
+                }
+                serializer.endTag(null, ACCOUNTS);
+
+                serializer.endTag(null, CLASS_STATE);
+            }
+        }
+
+        @Override
+        public State readFromXml(XmlPullParser parser, int version, Context context)
+                throws IOException, XmlPullParserException {
+            if (parser.getName().equals(CLASS_STATE)) {
+                State s = new State();
+
+                String rawVersion = parser.getAttributeValue(null, VERSION);
+                s.versionNumber = TextUtils.isEmpty(rawVersion) ? 1 :
+                        Integer.parseInt(rawVersion);
+
+                int outerDepth = parser.getDepth();
+                while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+                    if (parser.getName().equals(DEFAULT_OUTGOING)) {
+                        parser.nextTag();
+                        s.defaultOutgoing = sPhoneAccountHandleXml.readFromXml(parser,
+                                s.versionNumber, context);
+                    } else if (parser.getName().equals(SIM_CALL_MANAGER)) {
+                        parser.nextTag();
+                        s.simCallManager = sPhoneAccountHandleXml.readFromXml(parser,
+                                s.versionNumber, context);
+                    } else if (parser.getName().equals(ACCOUNTS)) {
+                        int accountsDepth = parser.getDepth();
+                        while (XmlUtils.nextElementWithin(parser, accountsDepth)) {
+                            PhoneAccount account = sPhoneAccountXml.readFromXml(parser,
+                                    s.versionNumber, context);
+
+                            if (account != null && s.accounts != null) {
+                                s.accounts.add(account);
+                            }
+                        }
+                    }
+                }
+                return s;
+            }
+            return null;
+        }
+    };
+
+    @VisibleForTesting
+    public static final XmlSerialization<PhoneAccount> sPhoneAccountXml =
+            new XmlSerialization<PhoneAccount>() {
+        private static final String CLASS_PHONE_ACCOUNT = "phone_account";
+        private static final String ACCOUNT_HANDLE = "account_handle";
+        private static final String ADDRESS = "handle";
+        private static final String SUBSCRIPTION_ADDRESS = "subscription_number";
+        private static final String CAPABILITIES = "capabilities";
+        private static final String ICON_RES_ID = "icon_res_id";
+        private static final String LABEL = "label";
+        private static final String SHORT_DESCRIPTION = "short_description";
+        private static final String SUPPORTED_URI_SCHEMES = "supported_uri_schemes";
+        private static final String ENABLED = "enabled";
+        private static final String TRUE = "true";
+        private static final String FALSE = "false";
+
+        @Override
+        public void writeToXml(PhoneAccount o, XmlSerializer serializer)
+                throws IOException {
+            if (o != null) {
+                serializer.startTag(null, CLASS_PHONE_ACCOUNT);
+
+                if (o.getAccountHandle() != null) {
+                    serializer.startTag(null, ACCOUNT_HANDLE);
+                    sPhoneAccountHandleXml.writeToXml(o.getAccountHandle(), serializer);
+                    serializer.endTag(null, ACCOUNT_HANDLE);
+                }
+
+                writeTextSafely(ADDRESS, o.getAddress(), serializer);
+                writeTextSafely(SUBSCRIPTION_ADDRESS, o.getSubscriptionAddress(), serializer);
+                writeTextSafely(CAPABILITIES, Integer.toString(o.getCapabilities()), serializer);
+                writeTextSafely(ICON_RES_ID, Integer.toString(o.getIconResId()), serializer);
+                writeTextSafely(LABEL, o.getLabel(), serializer);
+                writeTextSafely(SHORT_DESCRIPTION, o.getShortDescription(), serializer);
+                writeStringList(SUPPORTED_URI_SCHEMES, o.getSupportedUriSchemes(), serializer);
+                writeTextSafely(ENABLED, o.isEnabled() ? TRUE : FALSE, serializer);
+
+                serializer.endTag(null, CLASS_PHONE_ACCOUNT);
+            }
+        }
+
+        public PhoneAccount readFromXml(XmlPullParser parser, int version, Context context)
+                throws IOException, XmlPullParserException {
+            if (parser.getName().equals(CLASS_PHONE_ACCOUNT)) {
+                int outerDepth = parser.getDepth();
+                PhoneAccountHandle accountHandle = null;
+                Uri address = null;
+                Uri subscriptionAddress = null;
+                int capabilities = 0;
+                int iconResId = 0;
+                String label = null;
+                String shortDescription = null;
+                List<String> supportedUriSchemes = null;
+                boolean enabled = false;
+
+                while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+                    if (parser.getName().equals(ACCOUNT_HANDLE)) {
+                        parser.nextTag();
+                        accountHandle = sPhoneAccountHandleXml.readFromXml(parser, version,
+                                context);
+                    } else if (parser.getName().equals(ADDRESS)) {
+                        parser.next();
+                        address = Uri.parse(parser.getText());
+                    } else if (parser.getName().equals(SUBSCRIPTION_ADDRESS)) {
+                        parser.next();
+                        String nextText = parser.getText();
+                        subscriptionAddress = nextText == null ? null : Uri.parse(nextText);
+                    } else if (parser.getName().equals(CAPABILITIES)) {
+                        parser.next();
+                        capabilities = Integer.parseInt(parser.getText());
+                    } else if (parser.getName().equals(ICON_RES_ID)) {
+                        parser.next();
+                        iconResId = Integer.parseInt(parser.getText());
+                    } else if (parser.getName().equals(LABEL)) {
+                        parser.next();
+                        label = parser.getText();
+                    } else if (parser.getName().equals(SHORT_DESCRIPTION)) {
+                        parser.next();
+                        shortDescription = parser.getText();
+                    } else if (parser.getName().equals(SUPPORTED_URI_SCHEMES)) {
+                        supportedUriSchemes = readStringList(parser);
+                    } else if (parser.getName().equals(ENABLED)) {
+                        parser.next();
+                        enabled = parser.getText().equals(TRUE);
+                    }
+                }
+
+                // Upgrade older phone accounts to specify the supported URI schemes.
+                if (version < 2) {
+                    ComponentName sipComponentName = new ComponentName("com.android.phone",
+                            "com.android.services.telephony.sip.SipConnectionService");
+
+                    supportedUriSchemes = new ArrayList<>();
+
+                    // Handle the SIP connection service.
+                    // Check the system settings to see if it also should handle "tel" calls.
+                    if (accountHandle.getComponentName().equals(sipComponentName)) {
+                        boolean useSipForPstn = useSipForPstnCalls(context);
+                        supportedUriSchemes.add(PhoneAccount.SCHEME_SIP);
+                        if (useSipForPstn) {
+                            supportedUriSchemes.add(PhoneAccount.SCHEME_TEL);
+                        }
+                    } else {
+                        supportedUriSchemes.add(PhoneAccount.SCHEME_TEL);
+                        supportedUriSchemes.add(PhoneAccount.SCHEME_VOICEMAIL);
+                    }
+                }
+
+                // Prior to version 3, PhoneAccounts didn't include the enabled option.  Enable
+                // all TelephonyConnectionService phone accounts by default.
+                if (version < 3) {
+                    ComponentName telephonyComponentName = new ComponentName("com.android.phone",
+                            "com.android.services.telephony.TelephonyConnectionService");
+
+                    if (accountHandle.getComponentName().equals(telephonyComponentName)) {
+                        enabled = true;
+                    }
+                }
+
+                return PhoneAccount.builder(accountHandle, label)
+                        .setAddress(address)
+                        .setSubscriptionAddress(subscriptionAddress)
+                        .setCapabilities(capabilities)
+                        .setIconResId(iconResId)
+                        .setShortDescription(shortDescription)
+                        .setSupportedUriSchemes(supportedUriSchemes)
+                        .setEnabled(enabled)
+                        .build();
+            }
+            return null;
+        }
+
+        /**
+         * Determines if the SIP call settings specify to use SIP for all calls, including PSTN calls.
+         *
+         * @param context The context.
+         * @return {@code True} if SIP should be used for all calls.
+         */
+        private boolean useSipForPstnCalls(Context context) {
+            String option = Settings.System.getString(context.getContentResolver(),
+                    Settings.System.SIP_CALL_OPTIONS);
+            option = (option != null) ? option : Settings.System.SIP_ADDRESS_ONLY;
+            return option.equals(Settings.System.SIP_ALWAYS);
+        }
+    };
+
+    @VisibleForTesting
+    public static final XmlSerialization<PhoneAccountHandle> sPhoneAccountHandleXml =
+            new XmlSerialization<PhoneAccountHandle>() {
+        private static final String CLASS_PHONE_ACCOUNT_HANDLE = "phone_account_handle";
+        private static final String COMPONENT_NAME = "component_name";
+        private static final String ID = "id";
+
+        @Override
+        public void writeToXml(PhoneAccountHandle o, XmlSerializer serializer)
+                throws IOException {
+            if (o != null) {
+                serializer.startTag(null, CLASS_PHONE_ACCOUNT_HANDLE);
+
+                if (o.getComponentName() != null) {
+                    writeTextSafely(
+                            COMPONENT_NAME, o.getComponentName().flattenToString(), serializer);
+                }
+
+                writeTextSafely(ID, o.getId(), serializer);
+
+                serializer.endTag(null, CLASS_PHONE_ACCOUNT_HANDLE);
+            }
+        }
+
+        @Override
+        public PhoneAccountHandle readFromXml(XmlPullParser parser, int version, Context context)
+                throws IOException, XmlPullParserException {
+            if (parser.getName().equals(CLASS_PHONE_ACCOUNT_HANDLE)) {
+                String componentNameString = null;
+                String idString = null;
+                int outerDepth = parser.getDepth();
+                while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+                    if (parser.getName().equals(COMPONENT_NAME)) {
+                        parser.next();
+                        componentNameString = parser.getText();
+                    } else if (parser.getName().equals(ID)) {
+                        parser.next();
+                        idString = parser.getText();
+                    }
+                }
+                if (componentNameString != null) {
+                    return new PhoneAccountHandle(
+                            ComponentName.unflattenFromString(componentNameString),
+                            idString);
+                }
+            }
+            return null;
+        }
+    };
+}
diff --git a/src/com/android/server/telecom/PhoneStateBroadcaster.java b/src/com/android/server/telecom/PhoneStateBroadcaster.java
new file mode 100644
index 0000000..d0d0b68
--- /dev/null
+++ b/src/com/android/server/telecom/PhoneStateBroadcaster.java
@@ -0,0 +1,90 @@
+/*
+ * 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.server.telecom;
+
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telecom.CallState;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telephony.ITelephonyRegistry;
+
+/**
+ * Send a {@link TelephonyManager#ACTION_PHONE_STATE_CHANGED} broadcast when the call state
+ * changes.
+ */
+final class PhoneStateBroadcaster extends CallsManagerListenerBase {
+
+    private final ITelephonyRegistry mRegistry;
+    private int mCurrentState = TelephonyManager.CALL_STATE_IDLE;
+
+    public PhoneStateBroadcaster() {
+        mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
+                "telephony.registry"));
+        if (mRegistry == null) {
+            Log.w(this, "TelephonyRegistry is null");
+        }
+    }
+
+    @Override
+    public void onCallStateChanged(Call call, int oldState, int newState) {
+        if ((newState == CallState.DIALING || newState == CallState.ACTIVE
+                || newState == CallState.ON_HOLD) && !CallsManager.getInstance().hasRingingCall()) {
+            /*
+             * EXTRA_STATE_RINGING takes precedence over EXTRA_STATE_OFFHOOK, so if there is
+             * already a ringing call, don't broadcast EXTRA_STATE_OFFHOOK.
+             */
+            sendPhoneStateChangedBroadcast(call, TelephonyManager.CALL_STATE_OFFHOOK);
+        }
+    }
+
+    @Override
+    public void onCallAdded(Call call) {
+        if (call.getState() == CallState.RINGING) {
+            sendPhoneStateChangedBroadcast(call, TelephonyManager.CALL_STATE_RINGING);
+        }
+    };
+
+    @Override
+    public void onCallRemoved(Call call) {
+        if (!CallsManager.getInstance().hasAnyCalls()) {
+            sendPhoneStateChangedBroadcast(call, TelephonyManager.CALL_STATE_IDLE);
+        }
+    }
+
+    private void sendPhoneStateChangedBroadcast(Call call, int phoneState) {
+        if (phoneState == mCurrentState) {
+            return;
+        }
+
+        mCurrentState = phoneState;
+
+        String callHandle = null;
+        if (call.getHandle() != null) {
+            callHandle = call.getHandle().getSchemeSpecificPart();
+        }
+
+        try {
+            if (mRegistry != null) {
+                mRegistry.notifyCallState(phoneState, callHandle);
+                Log.i(this, "Broadcasted state change: %s", mCurrentState);
+            }
+        } catch (RemoteException e) {
+            Log.w(this, "RemoteException when notifying TelephonyRegistry of call state change.");
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/ProximitySensorManager.java b/src/com/android/server/telecom/ProximitySensorManager.java
new file mode 100644
index 0000000..289366f
--- /dev/null
+++ b/src/com/android/server/telecom/ProximitySensorManager.java
@@ -0,0 +1,88 @@
+/*
+ * 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.server.telecom;
+
+import android.content.Context;
+import android.os.PowerManager;
+
+/**
+ * This class manages the proximity sensor and allows callers to turn it on and off.
+ */
+public class ProximitySensorManager extends CallsManagerListenerBase {
+    private static final String TAG = ProximitySensorManager.class.getSimpleName();
+
+    private final PowerManager.WakeLock mProximityWakeLock;
+
+    public ProximitySensorManager(Context context) {
+        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+
+        if (pm.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
+            mProximityWakeLock = pm.newWakeLock(
+                    PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
+        } else {
+            mProximityWakeLock = null;
+        }
+        Log.d(this, "onCreate: mProximityWakeLock: ", mProximityWakeLock);
+    }
+
+    @Override
+    public void onCallRemoved(Call call) {
+        if (CallsManager.getInstance().getCalls().isEmpty()) {
+            Log.v(this, "all calls removed, resetting proximity sensor to default state");
+            turnOff(true);
+        }
+        super.onCallRemoved(call);
+    }
+
+    /**
+     * Turn the proximity sensor on.
+     */
+    void turnOn() {
+        if (CallsManager.getInstance().getCalls().isEmpty()) {
+            Log.w(this, "Asking to turn on prox sensor without a call? I don't think so.");
+            return;
+        }
+
+        if (mProximityWakeLock == null) {
+            return;
+        }
+        if (!mProximityWakeLock.isHeld()) {
+            Log.i(this, "Acquiring proximity wake lock");
+            mProximityWakeLock.acquire();
+        } else {
+            Log.i(this, "Proximity wake lock already acquired");
+        }
+    }
+
+    /**
+     * Turn the proximity sensor off.
+     * @param screenOnImmediately
+     */
+    void turnOff(boolean screenOnImmediately) {
+        if (mProximityWakeLock == null) {
+            return;
+        }
+        if (mProximityWakeLock.isHeld()) {
+            Log.i(this, "Releasing proximity wake lock");
+            int flags =
+                (screenOnImmediately ? 0 : PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
+            mProximityWakeLock.release(flags);
+        } else {
+            Log.i(this, "Proximity wake lock already released");
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/QuickResponseUtils.java b/src/com/android/server/telecom/QuickResponseUtils.java
new file mode 100644
index 0000000..dad2907
--- /dev/null
+++ b/src/com/android/server/telecom/QuickResponseUtils.java
@@ -0,0 +1,116 @@
+/*
+ * 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.server.telecom;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+
+
+/**
+ * Utils class that exposes some helper routines to used to manage the QuickResponses
+ */
+public class QuickResponseUtils {
+    public static final String LOG_TAG = "QuickResponseUtils";
+
+    // SharedPreferences file name for our persistent settings.
+    public static final String SHARED_PREFERENCES_NAME = "respond_via_sms_prefs";
+    private static final String PACKAGE_NAME_TELEPHONY = "com.android.phone";
+
+    // Preference keys for the 4 "canned responses"; see RespondViaSmsManager$Settings.
+    // Since (for now at least) the number of messages is fixed at 4, and since
+    // SharedPreferences can't deal with arrays anyway, just store the messages
+    // as 4 separate strings.
+    public static final int NUM_CANNED_RESPONSES = 4;
+    public static final String KEY_CANNED_RESPONSE_PREF_1 = "canned_response_pref_1";
+    public static final String KEY_CANNED_RESPONSE_PREF_2 = "canned_response_pref_2";
+    public static final String KEY_CANNED_RESPONSE_PREF_3 = "canned_response_pref_3";
+    public static final String KEY_CANNED_RESPONSE_PREF_4 = "canned_response_pref_4";
+
+    /**
+     * As of L, QuickResponses were moved from Telephony to Telecom. Because of
+     * this, we need to make sure that we migrate any old QuickResponses to our
+     * current SharedPreferences.  This is a lazy migration as it happens only when
+     * the QuickResponse settings are viewed or if they are queried via RespondViaSmsManager.
+     */
+    public static void maybeMigrateLegacyQuickResponses() {
+        // The algorithm will go as such:
+        // If Telecom QuickResponses exist, we will skip migration because this implies
+        // that a user has already specified their desired QuickResponses and have abandoned any
+        // older QuickResponses.
+        // Then, if Telephony QuickResponses exist, we will move those to Telecom.
+        // If neither exist, we'll populate Telecom with the default QuickResponses.
+        // This guarantees the caller that QuickResponses exist in SharedPreferences after this
+        // function is called.
+
+        Log.d(LOG_TAG, "maybeMigrateLegacyQuickResponses() - Starting");
+
+        final Context telecomContext = TelecomApp.getInstance();
+        final SharedPreferences prefs = telecomContext.getSharedPreferences(
+                SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
+        final Resources res = telecomContext.getResources();
+
+        final boolean responsesExist = prefs.contains(KEY_CANNED_RESPONSE_PREF_1);
+        if (responsesExist) {
+            // If one QuickResponse exists, they all exist.
+            Log.d(LOG_TAG, "maybeMigrateLegacyQuickResponses() - Telecom QuickResponses exist");
+            return;
+        }
+
+        // Grab the all the default QuickResponses from our resources.
+        String cannedResponse1 = res.getString(R.string.respond_via_sms_canned_response_1);
+        String cannedResponse2 = res.getString(R.string.respond_via_sms_canned_response_2);
+        String cannedResponse3 = res.getString(R.string.respond_via_sms_canned_response_3);
+        String cannedResponse4 = res.getString(R.string.respond_via_sms_canned_response_4);
+
+        Log.d(LOG_TAG, "maybeMigrateLegacyQuickResponses() - No local QuickResponses");
+
+        // We don't have local QuickResponses, let's see if they live in
+        // the Telephony package and we'll fall back on using our default values.
+        Context telephonyContext = null;
+        try {
+            telephonyContext = telecomContext.createPackageContext(PACKAGE_NAME_TELEPHONY, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(LOG_TAG, e, "maybeMigrateLegacyQuickResponses() - Can't find Telephony package.");
+        }
+
+        // Read the old canned responses from the Telephony SharedPreference if possible.
+        if (telephonyContext != null) {
+            // Note that if any one QuickResponse does not exist, we'll use the default
+            // value to populate it.
+            Log.d(LOG_TAG, "maybeMigrateLegacyQuickResponses() - Using Telephony QuickResponses.");
+            final SharedPreferences oldPrefs = telephonyContext.getSharedPreferences(
+                    SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
+            cannedResponse1 = oldPrefs.getString(KEY_CANNED_RESPONSE_PREF_1, cannedResponse1);
+            cannedResponse2 = oldPrefs.getString(KEY_CANNED_RESPONSE_PREF_2, cannedResponse2);
+            cannedResponse3 = oldPrefs.getString(KEY_CANNED_RESPONSE_PREF_3, cannedResponse3);
+            cannedResponse4 = oldPrefs.getString(KEY_CANNED_RESPONSE_PREF_4, cannedResponse4);
+        }
+
+        // Either way, write them back into Telecom SharedPreferences.
+        final SharedPreferences.Editor editor = prefs.edit();
+        editor.putString(KEY_CANNED_RESPONSE_PREF_1, cannedResponse1);
+        editor.putString(KEY_CANNED_RESPONSE_PREF_2, cannedResponse2);
+        editor.putString(KEY_CANNED_RESPONSE_PREF_3, cannedResponse3);
+        editor.putString(KEY_CANNED_RESPONSE_PREF_4, cannedResponse4);
+        editor.commit();
+
+        Log.d(LOG_TAG, "maybeMigrateLegacyQuickResponses() - Done.");
+        return;
+    }
+}
diff --git a/src/com/android/server/telecom/README b/src/com/android/server/telecom/README
new file mode 100644
index 0000000..be202fe
--- /dev/null
+++ b/src/com/android/server/telecom/README
@@ -0,0 +1,2 @@
+Code to manage and handle phone calls etc, approximately migrated from
+/telephony etc.
\ No newline at end of file
diff --git a/src/com/android/server/telecom/RespondViaSmsManager.java b/src/com/android/server/telecom/RespondViaSmsManager.java
new file mode 100644
index 0000000..6c054e6
--- /dev/null
+++ b/src/com/android/server/telecom/RespondViaSmsManager.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2011 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.server.telecom;
+
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telephony.SmsApplication;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.telecom.Response;
+import android.telephony.TelephonyManager;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper class to manage the "Respond via Message" feature for incoming calls.
+ */
+public class RespondViaSmsManager extends CallsManagerListenerBase {
+    private static final int MSG_CANNED_TEXT_MESSAGES_READY = 1;
+    private static final int MSG_SHOW_SENT_TOAST = 2;
+
+    private static final RespondViaSmsManager sInstance = new RespondViaSmsManager();
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_CANNED_TEXT_MESSAGES_READY:
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Response<Void, List<String>> response =
+                                (Response<Void, List<String>>) args.arg1;
+                        List<String> textMessages =
+                                (List<String>) args.arg2;
+                        if (textMessages != null) {
+                            response.onResult(null, textMessages);
+                        } else {
+                            response.onError(null, 0, null);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                case MSG_SHOW_SENT_TOAST:
+                    showMessageSentToast((String) msg.obj);
+                    break;
+            }
+        }
+    };
+
+    public static RespondViaSmsManager getInstance() { return sInstance; }
+
+    private RespondViaSmsManager() {}
+
+    /**
+     * Read the (customizable) canned responses from SharedPreferences,
+     * or from defaults if the user has never actually brought up
+     * the Settings UI.
+     *
+     * The interface of this method is asynchronous since it does disk I/O.
+     *
+     * @param response An object to receive an async reply, which will be called from
+     *                 the main thread.
+     */
+    public void loadCannedTextMessages(final Response<Void, List<String>> response) {
+        new Thread() {
+            @Override
+            public void run() {
+                Log.d(RespondViaSmsManager.this, "loadCannedResponses() starting");
+
+                // This function guarantees that QuickResponses will be in our
+                // SharedPreferences with the proper values considering there may be
+                // old QuickResponses in Telephony pre L.
+                QuickResponseUtils.maybeMigrateLegacyQuickResponses();
+
+                final SharedPreferences prefs = TelecomApp.getInstance().getSharedPreferences(
+                        QuickResponseUtils.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
+                final Resources res = TelecomApp.getInstance().getInstance().getResources();
+
+                final ArrayList<String> textMessages = new ArrayList<>(
+                        QuickResponseUtils.NUM_CANNED_RESPONSES);
+
+                // Note the default values here must agree with the corresponding
+                // android:defaultValue attributes in respond_via_sms_settings.xml.
+                textMessages.add(0, prefs.getString(QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_1,
+                        res.getString(R.string.respond_via_sms_canned_response_1)));
+                textMessages.add(1, prefs.getString(QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_2,
+                        res.getString(R.string.respond_via_sms_canned_response_2)));
+                textMessages.add(2, prefs.getString(QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_3,
+                        res.getString(R.string.respond_via_sms_canned_response_3)));
+                textMessages.add(3, prefs.getString(QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_4,
+                        res.getString(R.string.respond_via_sms_canned_response_4)));
+
+                Log.d(RespondViaSmsManager.this,
+                        "loadCannedResponses() completed, found responses: %s",
+                        textMessages.toString());
+
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = response;
+                args.arg2 = textMessages;
+                mHandler.obtainMessage(MSG_CANNED_TEXT_MESSAGES_READY, args).sendToTarget();
+            }
+        }.start();
+    }
+
+    @Override
+    public void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage) {
+        if (rejectWithMessage) {
+            rejectCallWithMessage(call.getHandle().getSchemeSpecificPart(), textMessage);
+        }
+    }
+
+    private void showMessageSentToast(final String phoneNumber) {
+        // ...and show a brief confirmation to the user (since
+        // otherwise it's hard to be sure that anything actually
+        // happened.)
+        final Resources res = TelecomApp.getInstance().getResources();
+        final String formatString = res.getString(
+                R.string.respond_via_sms_confirmation_format);
+        final String confirmationMsg = String.format(formatString, phoneNumber);
+        Toast.makeText(TelecomApp.getInstance(), confirmationMsg,
+                Toast.LENGTH_LONG).show();
+
+        // TODO: If the device is locked, this toast won't actually ever
+        // be visible!  (That's because we're about to dismiss the call
+        // screen, which means that the device will return to the
+        // keyguard.  But toasts aren't visible on top of the keyguard.)
+        // Possible fixes:
+        // (1) Is it possible to allow a specific Toast to be visible
+        //     on top of the keyguard?
+        // (2) Artificially delay the dismissCallScreen() call by 3
+        //     seconds to allow the toast to be seen?
+        // (3) Don't use a toast at all; instead use a transient state
+        //     of the InCallScreen (perhaps via the InCallUiState
+        //     progressIndication feature), and have that state be
+        //     visible for 3 seconds before calling dismissCallScreen().
+    }
+
+    /**
+     * Reject the call with the specified message. If message is null this call is ignored.
+     */
+    private void rejectCallWithMessage(String phoneNumber, String textMessage) {
+        if (textMessage != null) {
+            final ComponentName component =
+                    SmsApplication.getDefaultRespondViaMessageApplication(
+                            TelecomApp.getInstance(), true /*updateIfNeeded*/);
+            if (component != null) {
+                // Build and send the intent
+                final Uri uri = Uri.fromParts(Constants.SCHEME_SMSTO, phoneNumber, null);
+                final Intent intent = new Intent(TelephonyManager.ACTION_RESPOND_VIA_MESSAGE, uri);
+                intent.putExtra(Intent.EXTRA_TEXT, textMessage);
+                mHandler.obtainMessage(MSG_SHOW_SENT_TOAST, phoneNumber).sendToTarget();
+                intent.setComponent(component);
+                TelecomApp.getInstance().startService(intent);
+            }
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/RespondViaSmsSettings.java b/src/com/android/server/telecom/RespondViaSmsSettings.java
new file mode 100644
index 0000000..23bf7b2
--- /dev/null
+++ b/src/com/android/server/telecom/RespondViaSmsSettings.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2011 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.server.telecom;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * Helper class to manage the "Respond via SMS Message" feature for incoming calls.
+ */
+public class RespondViaSmsSettings {
+    private static final String KEY_PREFERRED_PACKAGE = "preferred_package_pref";
+    private static final String KEY_INSTANT_TEXT_DEFAULT_COMPONENT = "instant_text_def_component";
+
+    // TODO: This class is newly copied into Telecom (com.android.server.telecom) from it previous
+    // location in Telephony (com.android.phone). User's preferences stored in the old location
+    // will be lost. We need code here to migrate KLP -> LMP settings values.
+
+    /**
+     * Settings activity under "Call settings" to let you manage the
+     * canned responses; see respond_via_sms_settings.xml
+     */
+    public static class Settings extends PreferenceActivity
+            implements Preference.OnPreferenceChangeListener {
+        @Override
+        protected void onCreate(Bundle icicle) {
+            super.onCreate(icicle);
+            Log.d(this, "Settings: onCreate()...");
+
+            // This function guarantees that QuickResponses will be in our
+            // SharedPreferences with the proper values considering there may be
+            // old QuickResponses in Telephony pre L.
+            QuickResponseUtils.maybeMigrateLegacyQuickResponses();
+
+            getPreferenceManager().setSharedPreferencesName(
+                    QuickResponseUtils.SHARED_PREFERENCES_NAME);
+
+            // This preference screen is ultra-simple; it's just 4 plain
+            // <EditTextPreference>s, one for each of the 4 "canned responses".
+            //
+            // The only nontrivial thing we do here is copy the text value of
+            // each of those EditTextPreferences and use it as the preference's
+            // "title" as well, so that the user will immediately see all 4
+            // strings when they arrive here.
+            //
+            // Also, listen for change events (since we'll need to update the
+            // title any time the user edits one of the strings.)
+
+            addPreferencesFromResource(R.xml.respond_via_sms_settings);
+
+            EditTextPreference pref;
+            pref = (EditTextPreference) findPreference(
+                    QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_1);
+            pref.setTitle(pref.getText());
+            pref.setOnPreferenceChangeListener(this);
+
+            pref = (EditTextPreference) findPreference(
+                    QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_2);
+            pref.setTitle(pref.getText());
+            pref.setOnPreferenceChangeListener(this);
+
+            pref = (EditTextPreference) findPreference(
+                    QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_3);
+            pref.setTitle(pref.getText());
+            pref.setOnPreferenceChangeListener(this);
+
+            pref = (EditTextPreference) findPreference(
+                    QuickResponseUtils.KEY_CANNED_RESPONSE_PREF_4);
+            pref.setTitle(pref.getText());
+            pref.setOnPreferenceChangeListener(this);
+
+            ActionBar actionBar = getActionBar();
+            if (actionBar != null) {
+                // android.R.id.home will be triggered in onOptionsItemSelected()
+                actionBar.setDisplayHomeAsUpEnabled(true);
+            }
+        }
+
+        // Preference.OnPreferenceChangeListener implementation
+        @Override
+        public boolean onPreferenceChange(Preference preference, Object newValue) {
+            Log.d(this, "onPreferenceChange: key = %s", preference.getKey());
+            Log.d(this, "  preference = '%s'", preference);
+            Log.d(this, "  newValue = '%s'", newValue);
+
+            EditTextPreference pref = (EditTextPreference) preference;
+
+            // Copy the new text over to the title, just like in onCreate().
+            // (Watch out: onPreferenceChange() is called *before* the
+            // Preference itself gets updated, so we need to use newValue here
+            // rather than pref.getText().)
+            pref.setTitle((String) newValue);
+
+            return true;  // means it's OK to update the state of the Preference with the new value
+        }
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem item) {
+            final int itemId = item.getItemId();
+            switch (itemId) {
+                case android.R.id.home:
+                    goUpToTopLevelSetting(this);
+                    return true;
+                case R.id.respond_via_message_reset:
+                    // Reset the preferences settings
+                    SharedPreferences prefs = getSharedPreferences(
+                            QuickResponseUtils.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
+                    SharedPreferences.Editor editor = prefs.edit();
+                    editor.remove(KEY_INSTANT_TEXT_DEFAULT_COMPONENT);
+                    editor.apply();
+
+                    return true;
+                default:
+            }
+            return super.onOptionsItemSelected(item);
+        }
+
+        @Override
+        public boolean onCreateOptionsMenu(Menu menu) {
+            getMenuInflater().inflate(R.menu.respond_via_message_settings_menu, menu);
+            return super.onCreateOptionsMenu(menu);
+        }
+    }
+
+    /**
+     * Finish current Activity and go up to the top level Settings.
+     */
+    public static void goUpToTopLevelSetting(Activity activity) {
+        activity.finish();
+     }
+}
diff --git a/src/com/android/server/telecom/RingbackPlayer.java b/src/com/android/server/telecom/RingbackPlayer.java
new file mode 100644
index 0000000..dc06c95
--- /dev/null
+++ b/src/com/android/server/telecom/RingbackPlayer.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.telecom.CallState;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Plays ringback tones. Ringback is different from other tones because it operates as the current
+ * audio for a call, whereas most tones play as simple timed events. This means ringback must be
+ * able to turn off and on as the user switches between calls. This is why it is implemented as its
+ * own class.
+ */
+class RingbackPlayer extends CallsManagerListenerBase {
+
+    private final CallsManager mCallsManager;
+
+    private final InCallTonePlayer.Factory mPlayerFactory;
+
+    /**
+     * The current call for which the ringback tone is being played.
+     */
+    private Call mCall;
+
+    /**
+     * The currently active player.
+     */
+    private InCallTonePlayer mTonePlayer;
+
+    RingbackPlayer(CallsManager callsManager, InCallTonePlayer.Factory playerFactory) {
+        mCallsManager = callsManager;
+        mPlayerFactory = playerFactory;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
+        if (oldForegroundCall != null) {
+            stopRingbackForCall(oldForegroundCall);
+        }
+
+        if (shouldStartRinging(newForegroundCall)) {
+            startRingbackForCall(newForegroundCall);
+        }
+    }
+
+    @Override
+    public void onConnectionServiceChanged(
+            Call call,
+            ConnectionServiceWrapper oldService,
+            ConnectionServiceWrapper newService) {
+
+        // Treat as ending or begining dialing based on the state transition.
+        if (shouldStartRinging(call)) {
+            startRingbackForCall(call);
+        } else if (newService == null) {
+            stopRingbackForCall(call);
+        }
+    }
+
+    @Override
+    public void onRingbackRequested(Call call, boolean ignored) {
+        if (shouldStartRinging(call)) {
+            startRingbackForCall(call);
+        } else {
+            stopRingbackForCall(call);
+        }
+    }
+
+    /**
+     * Starts ringback for the specified dialing call as needed.
+     *
+     * @param call The call for which to ringback.
+     */
+    private void startRingbackForCall(Call call) {
+        Preconditions.checkState(call.getState() == CallState.DIALING);
+        ThreadUtil.checkOnMainThread();
+
+        if (mCall == call) {
+            Log.w(this, "Ignoring duplicate requests to ring for %s.", call);
+            return;
+        }
+
+        if (mCall != null) {
+            // We only get here for the foreground call so, there's no reason why there should
+            // exist a current dialing call.
+            Log.wtf(this, "Ringback player thinks there are two foreground-dialing calls.");
+        }
+
+        mCall = call;
+        if (mTonePlayer == null) {
+            Log.d(this, "Playing the ringback tone for %s.", call);
+            mTonePlayer = mPlayerFactory.createPlayer(InCallTonePlayer.TONE_RING_BACK);
+            mTonePlayer.startTone();
+        }
+    }
+
+    /**
+     * Stops the ringback for the specified dialing call as needed.
+     *
+     * @param call The call for which to stop ringback.
+     */
+    private void stopRingbackForCall(Call call) {
+        ThreadUtil.checkOnMainThread();
+
+        if (mCall == call) {
+            // The foreground call is no longer dialing or is no longer the foreground call. In
+            // either case, stop the ringback tone.
+            mCall = null;
+
+            if (mTonePlayer == null) {
+                Log.w(this, "No player found to stop.");
+            } else {
+                Log.i(this, "Stopping the ringback tone for %s.", call);
+                mTonePlayer.stopTone();
+                mTonePlayer = null;
+            }
+        }
+    }
+
+    private boolean shouldStartRinging(Call call) {
+        return call != null
+                && mCallsManager.getForegroundCall() == call
+                && call.getState() == CallState.DIALING
+                && call.isRingbackRequested();
+    }
+}
diff --git a/src/com/android/server/telecom/Ringer.java b/src/com/android/server/telecom/Ringer.java
new file mode 100644
index 0000000..34f6829
--- /dev/null
+++ b/src/com/android/server/telecom/Ringer.java
@@ -0,0 +1,269 @@
+/*
+ * 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.server.telecom;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.SystemVibrator;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.telecom.CallState;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Controls the ringtone player.
+ */
+final class Ringer extends CallsManagerListenerBase {
+    private static final long[] VIBRATION_PATTERN = new long[] {
+        0, // No delay before starting
+        1000, // How long to vibrate
+        1000, // How long to wait before vibrating again
+    };
+
+    private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
+            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+            .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
+            .build();
+
+    /** Indicate that we want the pattern to repeat at the step which turns on vibration. */
+    private static final int VIBRATION_PATTERN_REPEAT = 1;
+
+    private final AsyncRingtonePlayer mRingtonePlayer = new AsyncRingtonePlayer();
+
+    /**
+     * Used to keep ordering of unanswered incoming calls. There can easily exist multiple incoming
+     * calls and explicit ordering is useful for maintaining the proper state of the ringer.
+     */
+    private final List<Call> mRingingCalls = new LinkedList<>();
+
+    private final CallAudioManager mCallAudioManager;
+    private final CallsManager mCallsManager;
+    private final InCallTonePlayer.Factory mPlayerFactory;
+    private final Context mContext;
+    private final Vibrator mVibrator;
+
+    private InCallTonePlayer mCallWaitingPlayer;
+
+    /**
+     * Used to track the status of {@link #mVibrator} in the case of simultaneous incoming calls.
+     */
+    private boolean mIsVibrating = false;
+
+    /** Initializes the Ringer. */
+    Ringer(
+            CallAudioManager callAudioManager,
+            CallsManager callsManager,
+            InCallTonePlayer.Factory playerFactory,
+            Context context) {
+
+        mCallAudioManager = callAudioManager;
+        mCallsManager = callsManager;
+        mPlayerFactory = playerFactory;
+        mContext = context;
+        // We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure this
+        // vibrator object will be isolated from others.
+        mVibrator = new SystemVibrator(TelecomApp.getInstance());
+    }
+
+    @Override
+    public void onCallAdded(final Call call) {
+        if (call.isIncoming() && call.getState() == CallState.RINGING) {
+            if (mRingingCalls.contains(call)) {
+                Log.wtf(this, "New ringing call is already in list of unanswered calls");
+            }
+            mRingingCalls.add(call);
+            updateRinging();
+        }
+    }
+
+    @Override
+    public void onCallRemoved(Call call) {
+        removeFromUnansweredCall(call);
+    }
+
+    @Override
+    public void onCallStateChanged(Call call, int oldState, int newState) {
+        if (newState != CallState.RINGING) {
+            removeFromUnansweredCall(call);
+        }
+    }
+
+    @Override
+    public void onIncomingCallAnswered(Call call) {
+        onRespondedToIncomingCall(call);
+    }
+
+    @Override
+    public void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage) {
+        onRespondedToIncomingCall(call);
+    }
+
+    @Override
+    public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
+        if (mRingingCalls.contains(oldForegroundCall) ||
+                mRingingCalls.contains(newForegroundCall)) {
+            updateRinging();
+        }
+    }
+
+    /**
+     * Silences the ringer for any actively ringing calls.
+     */
+    void silence() {
+        // Remove all calls from the "ringing" set and then update the ringer.
+        mRingingCalls.clear();
+        updateRinging();
+    }
+
+    private void onRespondedToIncomingCall(Call call) {
+        // Only stop the ringer if this call is the top-most incoming call.
+        if (getTopMostUnansweredCall() == call) {
+            stopRinging();
+            stopCallWaiting();
+        }
+
+        // We do not remove the call from mRingingCalls until the call state changes from
+        // STATE_RINGING or the call is removed. see onCallStateChanged or onCallRemoved.
+    }
+
+    private Call getTopMostUnansweredCall() {
+        return mRingingCalls.isEmpty() ? null : mRingingCalls.get(0);
+    }
+
+    /**
+     * Removes the specified call from the list of unanswered incoming calls and updates the ringer
+     * based on the new state of {@link #mRingingCalls}. Safe to call with a call that is not
+     * present in the list of incoming calls.
+     */
+    private void removeFromUnansweredCall(Call call) {
+        mRingingCalls.remove(call);
+        updateRinging();
+    }
+
+    private void updateRinging() {
+        if (mRingingCalls.isEmpty()) {
+            stopRinging();
+            stopCallWaiting();
+        } else {
+            startRingingOrCallWaiting();
+        }
+    }
+
+    private void startRingingOrCallWaiting() {
+        Call foregroundCall = mCallsManager.getForegroundCall();
+        Log.v(this, "startRingingOrCallWaiting, foregroundCall: %s.", foregroundCall);
+
+        if (mRingingCalls.contains(foregroundCall)) {
+            // The foreground call is one of incoming calls so play the ringer out loud.
+            stopCallWaiting();
+
+            if (!shouldRingForContact(foregroundCall.getContactUri())) {
+                return;
+            }
+
+            AudioManager audioManager =
+                    (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+            if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
+                Log.v(this, "startRingingOrCallWaiting");
+                mCallAudioManager.setIsRinging(true);
+
+                // Because we wait until a contact info query to complete before processing a
+                // call (for the purposes of direct-to-voicemail), the information about custom
+                // ringtones should be available by the time this code executes. We can safely
+                // request the custom ringtone from the call and expect it to be current.
+                mRingtonePlayer.play(foregroundCall.getRingtone());
+            } else {
+                Log.v(this, "startRingingOrCallWaiting, skipping because volume is 0");
+            }
+
+            if (shouldVibrate(TelecomApp.getInstance()) && !mIsVibrating) {
+                mVibrator.vibrate(VIBRATION_PATTERN, VIBRATION_PATTERN_REPEAT,
+                        VIBRATION_ATTRIBUTES);
+                mIsVibrating = true;
+            }
+        } else {
+            Log.v(this, "Playing call-waiting tone.");
+
+            // All incoming calls are in background so play call waiting.
+            stopRinging();
+
+            if (mCallWaitingPlayer == null) {
+                mCallWaitingPlayer =
+                        mPlayerFactory.createPlayer(InCallTonePlayer.TONE_CALL_WAITING);
+                mCallWaitingPlayer.startTone();
+            }
+        }
+    }
+
+    private boolean shouldRingForContact(Uri contactUri) {
+        final NotificationManager manager =
+                (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        final Bundle extras = new Bundle();
+        if (contactUri != null) {
+            extras.putStringArray(Notification.EXTRA_PEOPLE, new String[] {contactUri.toString()});
+        }
+        return manager.matchesCallFilter(extras);
+    }
+
+    private void stopRinging() {
+        Log.v(this, "stopRinging");
+
+        mRingtonePlayer.stop();
+
+        if (mIsVibrating) {
+            mVibrator.cancel();
+            mIsVibrating = false;
+        }
+
+        // Even though stop is asynchronous it's ok to update the audio manager. Things like audio
+        // focus are voluntary so releasing focus too early is not detrimental.
+        mCallAudioManager.setIsRinging(false);
+    }
+
+    private void stopCallWaiting() {
+        Log.v(this, "stop call waiting.");
+        if (mCallWaitingPlayer != null) {
+            mCallWaitingPlayer.stopTone();
+            mCallWaitingPlayer = null;
+        }
+    }
+
+    private boolean shouldVibrate(Context context) {
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        int ringerMode = audioManager.getRingerMode();
+        if (getVibrateWhenRinging(context)) {
+            return ringerMode != AudioManager.RINGER_MODE_SILENT;
+        } else {
+            return ringerMode == AudioManager.RINGER_MODE_VIBRATE;
+        }
+    }
+
+    private boolean getVibrateWhenRinging(Context context) {
+        if (!mVibrator.hasVibrator()) {
+            return false;
+        }
+        return Settings.System.getInt(context.getContentResolver(),
+                Settings.System.VIBRATE_WHEN_RINGING, 0) != 0;
+    }
+}
diff --git a/src/com/android/server/telecom/ServiceBinder.java b/src/com/android/server/telecom/ServiceBinder.java
new file mode 100644
index 0000000..98e7bd0
--- /dev/null
+++ b/src/com/android/server/telecom/ServiceBinder.java
@@ -0,0 +1,314 @@
+/*
+ * 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.server.telecom;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.IInterface;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+import com.google.common.collect.Sets;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Abstract class to perform the work of binding and unbinding to the specified service interface.
+ * Subclasses supply the service intent and component name and this class will invoke protected
+ * methods when the class is bound, unbound, or upon failure.
+ */
+abstract class ServiceBinder<ServiceInterface extends IInterface> {
+
+    /**
+     * Callback to notify after a binding succeeds or fails.
+     */
+    interface BindCallback {
+        void onSuccess();
+        void onFailure();
+    }
+
+    /**
+     * Listener for bind events on ServiceBinder.
+     */
+    interface Listener<ServiceBinderClass extends ServiceBinder<?>> {
+        void onUnbind(ServiceBinderClass serviceBinder);
+    }
+
+    /**
+     * Helper class to perform on-demand binding.
+     */
+    final class Binder {
+        /**
+         * Performs an asynchronous bind to the service (only if not already bound) and executes the
+         * specified callback.
+         *
+         * @param callback The callback to notify of the binding's success or failure.
+         */
+        void bind(BindCallback callback) {
+            ThreadUtil.checkOnMainThread();
+            Log.d(ServiceBinder.this, "bind()");
+
+            // Reset any abort request if we're asked to bind again.
+            clearAbort();
+
+            if (!mCallbacks.isEmpty()) {
+                // Binding already in progress, append to the list of callbacks and bail out.
+                mCallbacks.add(callback);
+                return;
+            }
+
+            mCallbacks.add(callback);
+            if (mServiceConnection == null) {
+                Intent serviceIntent = new Intent(mServiceAction).setComponent(mComponentName);
+                ServiceConnection connection = new ServiceBinderConnection();
+
+                Log.d(ServiceBinder.this, "Binding to service with intent: %s", serviceIntent);
+                if (!mContext.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE)) {
+                    handleFailedConnection();
+                    return;
+                }
+            } else {
+                Log.d(ServiceBinder.this, "Service is already bound.");
+                Preconditions.checkNotNull(mBinder);
+                handleSuccessfulConnection();
+            }
+        }
+    }
+
+    private final class ServiceBinderConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName componentName, IBinder binder) {
+            ThreadUtil.checkOnMainThread();
+            Log.i(this, "Service bound %s", componentName);
+
+            // Unbind request was queued so unbind immediately.
+            if (mIsBindingAborted) {
+                clearAbort();
+                logServiceDisconnected("onServiceConnected");
+                mContext.unbindService(this);
+                handleFailedConnection();
+                return;
+            }
+
+            mServiceConnection = this;
+            setBinder(binder);
+            handleSuccessfulConnection();
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName componentName) {
+            logServiceDisconnected("onServiceDisconnected");
+
+            mServiceConnection = null;
+            clearAbort();
+
+            handleServiceDisconnected();
+        }
+    }
+
+    /** The application context. */
+    private final Context mContext;
+
+    /** The intent action to use when binding through {@link Context#bindService}. */
+    private final String mServiceAction;
+
+    /** The component name of the service to bind to. */
+    private final ComponentName mComponentName;
+
+    /** The set of callbacks waiting for notification of the binding's success or failure. */
+    private final Set<BindCallback> mCallbacks = Sets.newHashSet();
+
+    /** Used to bind and unbind from the service. */
+    private ServiceConnection mServiceConnection;
+
+    /** The binder provided by {@link ServiceConnection#onServiceConnected} */
+    private IBinder mBinder;
+
+    private int mAssociatedCallCount = 0;
+
+    /**
+     * Indicates that an unbind request was made when the service was not yet bound. If the service
+     * successfully connects when this is true, it should be unbound immediately.
+     */
+    private boolean mIsBindingAborted;
+
+    /**
+     * Set of currently registered listeners.
+     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
+     * load factor before resizing, 1 means we only expect a single thread to
+     * access the map so make only a single shard
+     */
+    private final Set<Listener> mListeners = Collections.newSetFromMap(
+            new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
+
+    /**
+     * Persists the specified parameters and initializes the new instance.
+     *
+     * @param serviceAction The intent-action used with {@link Context#bindService}.
+     * @param componentName The component name of the service with which to bind.
+     */
+    protected ServiceBinder(String serviceAction, ComponentName componentName) {
+        Preconditions.checkState(!Strings.isNullOrEmpty(serviceAction));
+        Preconditions.checkNotNull(componentName);
+
+        mContext = TelecomApp.getInstance();
+        mServiceAction = serviceAction;
+        mComponentName = componentName;
+    }
+
+    final void incrementAssociatedCallCount() {
+        mAssociatedCallCount++;
+        Log.v(this, "Call count increment %d, %s", mAssociatedCallCount,
+                mComponentName.flattenToShortString());
+    }
+
+    final void decrementAssociatedCallCount() {
+        if (mAssociatedCallCount > 0) {
+            mAssociatedCallCount--;
+            Log.v(this, "Call count decrement %d, %s", mAssociatedCallCount,
+                    mComponentName.flattenToShortString());
+
+            if (mAssociatedCallCount == 0) {
+                unbind();
+            }
+        } else {
+            Log.wtf(this, "%s: ignoring a request to decrement mAssociatedCallCount below zero",
+                    mComponentName.getClassName());
+        }
+    }
+
+    final int getAssociatedCallCount() {
+        return mAssociatedCallCount;
+    }
+
+    /**
+     * Unbinds from the service if already bound, no-op otherwise.
+     */
+    final void unbind() {
+        ThreadUtil.checkOnMainThread();
+
+        if (mServiceConnection == null) {
+            // We're not yet bound, so queue up an abort request.
+            mIsBindingAborted = true;
+        } else {
+            logServiceDisconnected("unbind");
+            mContext.unbindService(mServiceConnection);
+            mServiceConnection = null;
+            setBinder(null);
+        }
+    }
+
+    final ComponentName getComponentName() {
+        return mComponentName;
+    }
+
+    final boolean isServiceValid(String actionName) {
+        if (mBinder == null) {
+            Log.w(this, "%s invoked while service is unbound", actionName);
+            return false;
+        }
+
+        return true;
+    }
+
+    final void addListener(Listener listener) {
+        mListeners.add(listener);
+    }
+
+    final void removeListener(Listener listener) {
+        if (listener != null) {
+            mListeners.remove(listener);
+        }
+    }
+
+    /**
+     * Logs a standard message upon service disconnection. This method exists because there is no
+     * single method called whenever the service unbinds and we want to log the same string in all
+     * instances where that occurs.  (Context.unbindService() does not cause onServiceDisconnected
+     * to execute).
+     *
+     * @param sourceTag Tag to disambiguate
+     */
+    private void logServiceDisconnected(String sourceTag) {
+        Log.i(this, "Service unbound %s, from %s.", mComponentName, sourceTag);
+    }
+
+    /**
+     * Notifies all the outstanding callbacks that the service is successfully bound. The list of
+     * outstanding callbacks is cleared afterwards.
+     */
+    private void handleSuccessfulConnection() {
+        for (BindCallback callback : mCallbacks) {
+            callback.onSuccess();
+        }
+        mCallbacks.clear();
+    }
+
+    /**
+     * Notifies all the outstanding callbacks that the service failed to bind. The list of
+     * outstanding callbacks is cleared afterwards.
+     */
+    private void handleFailedConnection() {
+        for (BindCallback callback : mCallbacks) {
+            callback.onFailure();
+        }
+        mCallbacks.clear();
+    }
+
+    /**
+     * Handles a service disconnection.
+     */
+    private void handleServiceDisconnected() {
+        setBinder(null);
+    }
+
+    private void clearAbort() {
+        mIsBindingAborted = false;
+    }
+
+    /**
+     * Sets the (private) binder and updates the child class.
+     *
+     * @param binder The new binder value.
+     */
+    private void setBinder(IBinder binder) {
+        if (mBinder != binder) {
+            mBinder = binder;
+
+            setServiceInterface(binder);
+
+            if (binder == null) {
+                for (Listener l : mListeners) {
+                    l.onUnbind(this);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the service interface after the service is bound or unbound.
+     *
+     * @param binder The actual bound service implementation.
+     */
+    protected abstract void setServiceInterface(IBinder binder);
+}
diff --git a/src/com/android/server/telecom/StatusBarNotifier.java b/src/com/android/server/telecom/StatusBarNotifier.java
new file mode 100644
index 0000000..14253a0
--- /dev/null
+++ b/src/com/android/server/telecom/StatusBarNotifier.java
@@ -0,0 +1,98 @@
+/*
+ * 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.server.telecom;
+
+import android.app.StatusBarManager;
+import android.content.Context;
+
+/**
+ * Manages the special status bar notifications used by the phone app.
+ */
+final class StatusBarNotifier extends CallsManagerListenerBase {
+    private static final String SLOT_MUTE = "mute";
+    private static final String SLOT_SPEAKERPHONE = "speakerphone";
+
+    private final Context mContext;
+    private final CallsManager mCallsManager;
+    private final StatusBarManager mStatusBarManager;
+
+    private boolean mIsShowingMute;
+    private boolean mIsShowingSpeakerphone;
+
+    StatusBarNotifier(Context context, CallsManager callsManager) {
+        mContext = context;
+        mCallsManager = callsManager;
+        mStatusBarManager = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
+    }
+
+    /** ${inheritDoc} */
+    @Override
+    public void onCallRemoved(Call call) {
+        if (!mCallsManager.hasAnyCalls()) {
+            notifyMute(false);
+            notifySpeakerphone(false);
+        }
+    }
+
+    void notifyMute(boolean isMuted) {
+        // Never display anything if there are no calls.
+        if (!mCallsManager.hasAnyCalls()) {
+            isMuted = false;
+        }
+
+        if (mIsShowingMute == isMuted) {
+            return;
+        }
+
+        Log.d(this, "Mute status bar icon being set to %b", isMuted);
+
+        if (isMuted) {
+            mStatusBarManager.setIcon(
+                    SLOT_MUTE,
+                    android.R.drawable.stat_notify_call_mute,
+                    0,  /* iconLevel */
+                    mContext.getString(R.string.accessibility_call_muted));
+        } else {
+            mStatusBarManager.removeIcon(SLOT_MUTE);
+        }
+        mIsShowingMute = isMuted;
+    }
+
+    void notifySpeakerphone(boolean isSpeakerphone) {
+        // Never display anything if there are no calls.
+        if (!mCallsManager.hasAnyCalls()) {
+            isSpeakerphone = false;
+        }
+
+        if (mIsShowingSpeakerphone == isSpeakerphone) {
+            return;
+        }
+
+        Log.d(this, "Speakerphone status bar icon being set to %b", isSpeakerphone);
+
+        if (isSpeakerphone) {
+            mStatusBarManager.setIcon(
+                    SLOT_SPEAKERPHONE,
+                    android.R.drawable.stat_sys_speakerphone,
+                    0,  /* iconLevel */
+                    mContext.getString(R.string.accessibility_speakerphone_enabled));
+        } else {
+            mStatusBarManager.removeIcon(SLOT_SPEAKERPHONE);
+        }
+        mIsShowingSpeakerphone = isSpeakerphone;
+    }
+}
diff --git a/src/com/android/server/telecom/TelecomApp.java b/src/com/android/server/telecom/TelecomApp.java
new file mode 100644
index 0000000..c2e79eb
--- /dev/null
+++ b/src/com/android/server/telecom/TelecomApp.java
@@ -0,0 +1,68 @@
+/*
+ * 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.server.telecom;
+
+import android.app.Application;
+import android.os.UserHandle;
+
+/**
+ * Top-level Application class for Telecom.
+ */
+public final class TelecomApp extends Application {
+
+    /** Singleton instance of TelecomApp. */
+    private static TelecomApp sInstance;
+
+    /**
+     * Missed call notifier. Exists here so that the instance can be shared with
+     * {@link TelecomBroadcastReceiver}.
+     */
+    private MissedCallNotifier mMissedCallNotifier;
+
+    /**
+     * Maintains the list of registered {@link android.telecom.PhoneAccountHandle}s.
+     */
+    private PhoneAccountRegistrar mPhoneAccountRegistrar;
+
+    /** {@inheritDoc} */
+    @Override public void onCreate() {
+        super.onCreate();
+        sInstance = this;
+
+        mMissedCallNotifier = new MissedCallNotifier(this);
+        mPhoneAccountRegistrar = new PhoneAccountRegistrar(this);
+
+        if (UserHandle.myUserId() == UserHandle.USER_OWNER) {
+            TelecomServiceImpl.init(mMissedCallNotifier, mPhoneAccountRegistrar);
+        }
+    }
+
+    public static TelecomApp getInstance() {
+        if (null == sInstance) {
+            throw new IllegalStateException("No TelecomApp running.");
+        }
+        return sInstance;
+    }
+
+    MissedCallNotifier getMissedCallNotifier() {
+        return mMissedCallNotifier;
+    }
+
+    PhoneAccountRegistrar getPhoneAccountRegistrar() {
+        return mPhoneAccountRegistrar;
+    }
+}
diff --git a/src/com/android/server/telecom/TelecomBroadcastReceiver.java b/src/com/android/server/telecom/TelecomBroadcastReceiver.java
new file mode 100644
index 0000000..36c23fc
--- /dev/null
+++ b/src/com/android/server/telecom/TelecomBroadcastReceiver.java
@@ -0,0 +1,85 @@
+/*
+ * 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.server.telecom;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.UserHandle;
+
+/**
+ * Handles miscellaneous Telecom broadcast intents. This should be visible from outside, but
+ * should not be in the "exported" state.
+ */
+public final class TelecomBroadcastReceiver extends BroadcastReceiver {
+    /** The action used to send SMS response for the missed call notification. */
+    static final String ACTION_SEND_SMS_FROM_NOTIFICATION =
+            "com.android.server.telecom.ACTION_SEND_SMS_FROM_NOTIFICATION";
+
+    /** The action used to call a handle back for the missed call notification. */
+    static final String ACTION_CALL_BACK_FROM_NOTIFICATION =
+            "com.android.server.telecom.ACTION_CALL_BACK_FROM_NOTIFICATION";
+
+    /** The action used to clear missed calls. */
+    static final String ACTION_CLEAR_MISSED_CALLS =
+            "com.android.server.telecom.ACTION_CLEAR_MISSED_CALLS";
+
+
+    /** {@inheritDoc} */
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+
+        Log.v(this, "Action received: %s.", action);
+
+        MissedCallNotifier missedCallNotifier = TelecomApp.getInstance().getMissedCallNotifier();
+
+        // Send an SMS from the missed call notification.
+        if (ACTION_SEND_SMS_FROM_NOTIFICATION.equals(action)) {
+            // Close the notification shade and the notification itself.
+            closeSystemDialogs(context);
+            missedCallNotifier.clearMissedCalls();
+
+            Intent callIntent = new Intent(Intent.ACTION_SENDTO, intent.getData());
+            callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivity(callIntent);
+
+        // Call back recent caller from the missed call notification.
+        } else if (ACTION_CALL_BACK_FROM_NOTIFICATION.equals(action)) {
+            // Close the notification shade and the notification itself.
+            closeSystemDialogs(context);
+            missedCallNotifier.clearMissedCalls();
+
+            Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData());
+            callIntent.setFlags(
+                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+            context.startActivity(callIntent);
+
+        // Clear the missed call notification and call log entries.
+        } else if (ACTION_CLEAR_MISSED_CALLS.equals(action)) {
+            missedCallNotifier.clearMissedCalls();
+        }
+    }
+
+    /**
+     * Closes open system dialogs and the notification shade.
+     */
+    private void closeSystemDialogs(Context context) {
+        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        context.sendBroadcastAsUser(intent, UserHandle.ALL);
+    }
+}
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
new file mode 100644
index 0000000..5bce513
--- /dev/null
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -0,0 +1,624 @@
+/*
+ * 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.server.telecom;
+
+import android.app.AppOpsManager;
+import android.content.ComponentName;
+import android.content.Context;
+
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.telecom.CallState;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telecom.ITelecomService;
+
+import java.util.List;
+
+/**
+ * Implementation of the ITelecom interface.
+ */
+public class TelecomServiceImpl extends ITelecomService.Stub {
+    private static final String REGISTER_PROVIDER_OR_SUBSCRIPTION =
+            "com.android.server.telecom.permission.REGISTER_PROVIDER_OR_SUBSCRIPTION";
+
+    /** ${inheritDoc} */
+    @Override
+    public IBinder asBinder() {
+        return super.asBinder();
+    }
+
+ /**
+     * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
+     * request after sending. The main thread will notify the request when it is complete.
+     */
+    private static final class MainThreadRequest {
+        /** The result of the request that is run on the main thread */
+        public Object result;
+    }
+
+    /**
+     * A handler that processes messages on the main thread in the phone process. Since many
+     * of the Phone calls are not thread safe this is needed to shuttle the requests from the
+     * inbound binder threads to the main thread in the phone process.
+     */
+    private final class MainThreadHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.obj instanceof MainThreadRequest) {
+                MainThreadRequest request = (MainThreadRequest) msg.obj;
+                Object result = null;
+                switch (msg.what) {
+                    case MSG_SILENCE_RINGER:
+                        mCallsManager.getRinger().silence();
+                        break;
+                    case MSG_SHOW_CALL_SCREEN:
+                        mCallsManager.getInCallController().bringToForeground(msg.arg1 == 1);
+                        break;
+                    case MSG_END_CALL:
+                        result = endCallInternal();
+                        break;
+                    case MSG_ACCEPT_RINGING_CALL:
+                        acceptRingingCallInternal();
+                        break;
+                    case MSG_CANCEL_MISSED_CALLS_NOTIFICATION:
+                        mMissedCallNotifier.clearMissedCalls();
+                        break;
+                    case MSG_IS_TTY_SUPPORTED:
+                        result = mCallsManager.isTtySupported();
+                        break;
+                    case MSG_GET_CURRENT_TTY_MODE:
+                        result = mCallsManager.getCurrentTtyMode();
+                        break;
+                }
+
+                if (result != null) {
+                    request.result = result;
+                    synchronized(request) {
+                        request.notifyAll();
+                    }
+                }
+            }
+        }
+    }
+
+    /** Private constructor; @see init() */
+    private static final String TAG = TelecomServiceImpl.class.getSimpleName();
+
+    private static final String SERVICE_NAME = "telecom";
+
+    private static final int MSG_SILENCE_RINGER = 1;
+    private static final int MSG_SHOW_CALL_SCREEN = 2;
+    private static final int MSG_END_CALL = 3;
+    private static final int MSG_ACCEPT_RINGING_CALL = 4;
+    private static final int MSG_CANCEL_MISSED_CALLS_NOTIFICATION = 5;
+    private static final int MSG_IS_TTY_SUPPORTED = 6;
+    private static final int MSG_GET_CURRENT_TTY_MODE = 7;
+
+    /** The singleton instance. */
+    private static TelecomServiceImpl sInstance;
+
+    private final MainThreadHandler mMainThreadHandler = new MainThreadHandler();
+    private final CallsManager mCallsManager = CallsManager.getInstance();
+    private final MissedCallNotifier mMissedCallNotifier;
+    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
+    private final AppOpsManager mAppOpsManager;
+
+    private TelecomServiceImpl(
+            MissedCallNotifier missedCallNotifier, PhoneAccountRegistrar phoneAccountRegistrar) {
+        mMissedCallNotifier = missedCallNotifier;
+        mPhoneAccountRegistrar = phoneAccountRegistrar;
+        mAppOpsManager =
+                (AppOpsManager) TelecomApp.getInstance().getSystemService(Context.APP_OPS_SERVICE);
+
+        publish();
+    }
+
+    /**
+     * Initialize the singleton TelecommServiceImpl instance.
+     * This is only done once, at startup, from TelecommApp.onCreate().
+     */
+    static TelecomServiceImpl init(
+            MissedCallNotifier missedCallNotifier, PhoneAccountRegistrar phoneAccountRegistrar) {
+        synchronized (TelecomServiceImpl.class) {
+            if (sInstance == null) {
+                sInstance = new TelecomServiceImpl(missedCallNotifier, phoneAccountRegistrar);
+            } else {
+                Log.wtf(TAG, "init() called multiple times!  sInstance %s", sInstance);
+            }
+            return sInstance;
+        }
+    }
+
+    //
+    // Implementation of the ITelecomService interface.
+    //
+
+    @Override
+    public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
+        try {
+            return mPhoneAccountRegistrar.getDefaultOutgoingPhoneAccount(uriScheme);
+        } catch (Exception e) {
+            Log.e(this, e, "getDefaultOutgoingPhoneAccount");
+            throw e;
+        }
+    }
+
+    @Override
+    public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
+        try {
+            return mPhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount();
+        } catch (Exception e) {
+            Log.e(this, e, "getUserSelectedOutgoingPhoneAccount");
+            throw e;
+        }
+    }
+
+    @Override
+    public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
+        enforceModifyPermission();
+
+        try {
+            mPhoneAccountRegistrar.setUserSelectedOutgoingPhoneAccount(accountHandle);
+        } catch (Exception e) {
+            Log.e(this, e, "setUserSelectedOutgoingPhoneAccount");
+            throw e;
+        }
+    }
+
+    @Override
+    public List<PhoneAccountHandle> getEnabledPhoneAccounts() {
+        try {
+            return mPhoneAccountRegistrar.getEnabledPhoneAccounts();
+        } catch (Exception e) {
+            Log.e(this, e, "getEnabledPhoneAccounts");
+            throw e;
+        }
+    }
+
+    @Override
+    public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) {
+        try {
+            return mPhoneAccountRegistrar.getEnabledPhoneAccounts(uriScheme);
+        } catch (Exception e) {
+            Log.e(this, e, "getPhoneAccountsSupportingScheme");
+            throw e;
+        }
+    }
+
+    @Override
+    public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) {
+        try {
+            return mPhoneAccountRegistrar.getPhoneAccount(accountHandle);
+        } catch (Exception e) {
+            Log.e(this, e, "getPhoneAccount %s", accountHandle);
+            throw e;
+        }
+    }
+
+    @Override
+    public int getAllPhoneAccountsCount() {
+        try {
+            return mPhoneAccountRegistrar.getAllPhoneAccountsCount();
+        } catch (Exception e) {
+            Log.e(this, e, "getAllPhoneAccountsCount");
+            throw e;
+        }
+    }
+
+    @Override
+    public List<PhoneAccount> getAllPhoneAccounts() {
+        try {
+            return mPhoneAccountRegistrar.getAllPhoneAccounts();
+        } catch (Exception e) {
+            Log.e(this, e, "getAllPhoneAccounts");
+            throw e;
+        }
+    }
+
+    @Override
+    public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
+        try {
+            return mPhoneAccountRegistrar.getAllPhoneAccountHandles();
+        } catch (Exception e) {
+            Log.e(this, e, "getAllPhoneAccounts");
+            throw e;
+        }
+    }
+
+    @Override
+    public PhoneAccountHandle getSimCallManager() {
+        try {
+            return mPhoneAccountRegistrar.getSimCallManager();
+        } catch (Exception e) {
+            Log.e(this, e, "getSimCallManager");
+            throw e;
+        }
+    }
+
+    @Override
+    public void setSimCallManager(PhoneAccountHandle accountHandle) {
+        enforceModifyPermission();
+
+        try {
+            mPhoneAccountRegistrar.setSimCallManager(accountHandle);
+        } catch (Exception e) {
+            Log.e(this, e, "setSimCallManager");
+            throw e;
+        }
+    }
+
+    @Override
+    public List<PhoneAccountHandle> getSimCallManagers() {
+        try {
+            return mPhoneAccountRegistrar.getConnectionManagerPhoneAccounts();
+        } catch (Exception e) {
+            Log.e(this, e, "getSimCallManagers");
+            throw e;
+        }
+    }
+
+    @Override
+    public void registerPhoneAccount(PhoneAccount account) {
+        try {
+            enforceModifyPermissionOrCallingPackage(
+                    account.getAccountHandle().getComponentName().getPackageName());
+            if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) ||
+                account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
+                enforceRegisterProviderOrSubscriptionPermission();
+            }
+
+            // If the account is marked as enabled or has CAPABILITY_ALWAYS_ENABLED set, check to
+            // ensure the caller has modify permission.  If they do not, set the account to be
+            // disabled and remove CAPABILITY_ALWAYS_ENABLED.
+            if (account.isEnabled() ||
+                    account.hasCapabilities(PhoneAccount.CAPABILITY_ALWAYS_ENABLED)) {
+                try {
+                    enforceModifyPermission();
+                } catch (SecurityException e) {
+                    // Caller does not have modify permission, so change account to disabled by
+                    // default and remove the CAPABILITY_ALWAYS_ENABLED capability.
+                    int capabilities = account.getCapabilities() &
+                            ~PhoneAccount.CAPABILITY_ALWAYS_ENABLED;
+                    account = account.toBuilder()
+                            .setEnabled(false)
+                            .setCapabilities(capabilities)
+                            .build();
+                }
+            }
+
+            mPhoneAccountRegistrar.registerPhoneAccount(account);
+        } catch (Exception e) {
+            Log.e(this, e, "registerPhoneAccount %s", account);
+            throw e;
+        }
+    }
+
+    @Override
+    public void setPhoneAccountEnabled(PhoneAccountHandle account, boolean isEnabled) {
+        try {
+            enforceModifyPermission();
+            mPhoneAccountRegistrar.setPhoneAccountEnabled(account, isEnabled);
+        } catch (Exception e) {
+            Log.e(this, e, "setPhoneAccountEnabled %s %d", account, isEnabled ? 1 : 0);
+            throw e;
+        }
+    }
+
+    @Override
+    public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
+        try {
+            enforceModifyPermissionOrCallingPackage(
+                    accountHandle.getComponentName().getPackageName());
+            mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
+        } catch (Exception e) {
+            Log.e(this, e, "unregisterPhoneAccount %s", accountHandle);
+            throw e;
+        }
+    }
+
+    @Override
+    public void clearAccounts(String packageName) {
+        try {
+            enforceModifyPermissionOrCallingPackage(packageName);
+            mPhoneAccountRegistrar.clearAccounts(packageName);
+        } catch (Exception e) {
+            Log.e(this, e, "clearAccounts %s", packageName);
+            throw e;
+        }
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#silenceRinger
+     */
+    @Override
+    public void silenceRinger() {
+        Log.d(this, "silenceRinger");
+        enforceModifyPermission();
+        sendRequestAsync(MSG_SILENCE_RINGER, 0);
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#getDefaultPhoneApp
+     */
+    @Override
+    public ComponentName getDefaultPhoneApp() {
+        Resources resources = TelecomApp.getInstance().getResources();
+        return new ComponentName(
+                resources.getString(R.string.ui_default_package),
+                resources.getString(R.string.dialer_default_class));
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#isInCall
+     */
+    @Override
+    public boolean isInCall() {
+        enforceReadPermission();
+        // Do not use sendRequest() with this method since it could cause a deadlock with
+        // audio service, which we call into from the main thread: AudioManager.setMode().
+        return mCallsManager.hasAnyCalls();
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#isRinging
+     */
+    @Override
+    public boolean isRinging() {
+        enforceReadPermission();
+        return mCallsManager.hasRingingCall();
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#endCall
+     */
+    @Override
+    public boolean endCall() {
+        enforceModifyPermission();
+        return (boolean) sendRequest(MSG_END_CALL);
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#acceptRingingCall
+     */
+    @Override
+    public void acceptRingingCall() {
+        enforceModifyPermission();
+        sendRequestAsync(MSG_ACCEPT_RINGING_CALL, 0);
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#showInCallScreen
+     */
+    @Override
+    public void showInCallScreen(boolean showDialpad) {
+        enforceReadPermissionOrDefaultDialer();
+        sendRequestAsync(MSG_SHOW_CALL_SCREEN, showDialpad ? 1 : 0);
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#cancelMissedCallsNotification
+     */
+    @Override
+    public void cancelMissedCallsNotification() {
+        enforceModifyPermissionOrDefaultDialer();
+        sendRequestAsync(MSG_CANCEL_MISSED_CALLS_NOTIFICATION, 0);
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#handleMmi
+     */
+    @Override
+    public boolean handlePinMmi(String dialString) {
+        enforceModifyPermissionOrDefaultDialer();
+
+        // Switch identity so that TelephonyManager checks Telecom's permissions instead.
+        long token = Binder.clearCallingIdentity();
+        boolean retval = getTelephonyManager().handlePinMmi(dialString);
+        Binder.restoreCallingIdentity(token);
+
+        return retval;
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#isTtySupported
+     */
+    @Override
+    public boolean isTtySupported() {
+        enforceReadPermission();
+        return (boolean) sendRequest(MSG_IS_TTY_SUPPORTED);
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#getCurrentTtyMode
+     */
+    @Override
+    public int getCurrentTtyMode() {
+        enforceReadPermission();
+        return (int) sendRequest(MSG_GET_CURRENT_TTY_MODE);
+    }
+
+    /**
+     * @see android.telecom.TelecomManager#addNewIncomingCall
+     */
+    @Override
+    public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
+        if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) {
+            mAppOpsManager.checkPackage(
+                    Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName());
+
+            Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);
+            intent.setPackage(TelecomApp.getInstance().getPackageName());
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+            if (extras != null) {
+                intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
+            }
+
+            long token = Binder.clearCallingIdentity();
+            TelecomApp.getInstance().startActivityAsUser(intent, UserHandle.CURRENT);
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    //
+    // Supporting methods for the ITelecomService interface implementation.
+    //
+
+    private void acceptRingingCallInternal() {
+        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
+        if (call != null) {
+            call.answer(call.getVideoState());
+        }
+    }
+
+    private boolean endCallInternal() {
+        // Always operate on the foreground call if one exists, otherwise get the first call in
+        // priority order by call-state.
+        Call call = mCallsManager.getForegroundCall();
+        if (call == null) {
+            call = mCallsManager.getFirstCallWithState(
+                    CallState.ACTIVE,
+                    CallState.DIALING,
+                    CallState.RINGING,
+                    CallState.ON_HOLD);
+        }
+
+        if (call != null) {
+            if (call.getState() == CallState.RINGING) {
+                call.reject(false /* rejectWithMessage */, null);
+            } else {
+                call.disconnect();
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Make sure the caller has the MODIFY_PHONE_STATE permission.
+     *
+     * @throws SecurityException if the caller does not have the required permission
+     */
+    private void enforceModifyPermission() {
+        TelecomApp.getInstance().enforceCallingOrSelfPermission(
+                android.Manifest.permission.MODIFY_PHONE_STATE, null);
+    }
+
+    private void enforceModifyPermissionOrDefaultDialer() {
+        if (!isDefaultDialerCalling()) {
+            enforceModifyPermission();
+        }
+    }
+
+    private void enforceRegisterProviderOrSubscriptionPermission() {
+        TelecomApp.getInstance().enforceCallingOrSelfPermission(
+                REGISTER_PROVIDER_OR_SUBSCRIPTION, null);
+    }
+
+    private void enforceModifyPermissionOrCallingPackage(String packageName) {
+        // TODO: Use a new telecom permission for this instead of reusing modify.
+        try {
+            enforceModifyPermission();
+        } catch (SecurityException e) {
+            enforceCallingPackage(packageName);
+        }
+    }
+
+    private void enforceReadPermission() {
+        TelecomApp.getInstance().enforceCallingOrSelfPermission(
+                android.Manifest.permission.READ_PHONE_STATE, null);
+    }
+
+    private void enforceReadPermissionOrDefaultDialer() {
+        if (!isDefaultDialerCalling()) {
+            enforceReadPermission();
+        }
+    }
+
+    private void enforceCallingPackage(String packageName) {
+        mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
+    }
+
+    private boolean isDefaultDialerCalling() {
+        ComponentName defaultDialerComponent = getDefaultPhoneApp();
+        if (defaultDialerComponent != null) {
+            try {
+                mAppOpsManager.checkPackage(
+                        Binder.getCallingUid(), defaultDialerComponent.getPackageName());
+                return true;
+            } catch (SecurityException e) {
+                Log.e(TAG, e, "Could not get default dialer.");
+            }
+        }
+        return false;
+    }
+
+    private TelephonyManager getTelephonyManager() {
+        return (TelephonyManager)
+                TelecomApp.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
+    }
+
+    private void publish() {
+        Log.d(this, "publish: %s", this);
+        ServiceManager.addService(SERVICE_NAME, this);
+    }
+
+    private MainThreadRequest sendRequestAsync(int command, int arg1) {
+        MainThreadRequest request = new MainThreadRequest();
+        mMainThreadHandler.obtainMessage(command, arg1, 0, request).sendToTarget();
+        return request;
+    }
+
+    /**
+     * Posts the specified command to be executed on the main thread, waits for the request to
+     * complete, and returns the result.
+     */
+    private Object sendRequest(int command) {
+        if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
+            MainThreadRequest request = new MainThreadRequest();
+            mMainThreadHandler.handleMessage(mMainThreadHandler.obtainMessage(command, request));
+            return request.result;
+        } else {
+            MainThreadRequest request = sendRequestAsync(command, 0);
+
+            // Wait for the request to complete
+            synchronized (request) {
+                while (request.result == null) {
+                    try {
+                        request.wait();
+                    } catch (InterruptedException e) {
+                        // Do nothing, go back and wait until the request is complete
+                    }
+                }
+            }
+            return request.result;
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/TelephonyUtil.java b/src/com/android/server/telecom/TelephonyUtil.java
new file mode 100644
index 0000000..29b6f89
--- /dev/null
+++ b/src/com/android/server/telecom/TelephonyUtil.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.Uri;
+import android.telephony.PhoneNumberUtils;
+
+/**
+ * Utilities to deal with the system telephony services. The system telephony services are treated
+ * differently from 3rd party services in some situations (emergency calls, audio focus, etc...).
+ */
+public final class TelephonyUtil {
+    private static final String TAG = TelephonyUtil.class.getSimpleName();
+
+    private static final String TELEPHONY_PACKAGE_NAME = "com.android.phone";
+
+    private static final String PSTN_CALL_SERVICE_CLASS_NAME =
+            "com.android.services.telephony.TelephonyConnectionService";
+
+    private TelephonyUtil() {}
+
+    static boolean isPstnComponentName(ComponentName componentName) {
+        final ComponentName pstnComponentName = new ComponentName(
+                TELEPHONY_PACKAGE_NAME, PSTN_CALL_SERVICE_CLASS_NAME);
+        return pstnComponentName.equals(componentName);
+    }
+
+    static boolean shouldProcessAsEmergency(Context context, Uri handle) {
+        return handle != null && PhoneNumberUtils.isPotentialLocalEmergencyNumber(
+                context, handle.getSchemeSpecificPart());
+    }
+}
diff --git a/src/com/android/server/telecom/ThreadUtil.java b/src/com/android/server/telecom/ThreadUtil.java
new file mode 100644
index 0000000..650e73f
--- /dev/null
+++ b/src/com/android/server/telecom/ThreadUtil.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 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.server.telecom;
+
+import android.os.Looper;
+
+/**
+ * Helper methods to deal with threading related tasks.
+ */
+public final class ThreadUtil {
+    private static final String TAG = ThreadUtil.class.getSimpleName();
+
+    private ThreadUtil() {}
+
+    /** @return whether this method is being called from the main (UI) thread. */
+    public static boolean isOnMainThread() {
+        return Looper.getMainLooper() == Looper.myLooper();
+    }
+
+    /**
+     * Checks that this is being executed on the main thread. If not, a message is logged at
+     * WTF-level priority.
+     */
+    public static void checkOnMainThread() {
+        if (!isOnMainThread()) {
+            Log.wtf(TAG, new IllegalStateException(), "Must be on the main thread!");
+        }
+    }
+
+    /**
+     * Checks that this is not being executed on the main thread. If so, a message is logged at
+     * WTF-level priority.
+     */
+    public static void checkNotOnMainThread() {
+        if (isOnMainThread()) {
+            Log.wtf(TAG, new IllegalStateException(), "Must not be on the main thread!");
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/Timeouts.java b/src/com/android/server/telecom/Timeouts.java
new file mode 100644
index 0000000..4434db4
--- /dev/null
+++ b/src/com/android/server/telecom/Timeouts.java
@@ -0,0 +1,54 @@
+/*
+ * 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.server.telecom;
+
+import android.provider.Settings;
+
+/**
+ * A helper class which serves only to make it easier to lookup timeout values. This class should
+ * never be instantiated, and only accessed through the {@link #get(String, long)} method.
+ *
+ * These methods are safe to call from any thread, including the UI thread.
+ */
+public final class Timeouts {
+    /** A prefix to use for all keys so to not clobber the global namespace. */
+    private static final String PREFIX = "telecom.";
+
+    private Timeouts() {}
+
+    /**
+     * Returns the timeout value from Settings or the default value if it hasn't been changed. This
+     * method is safe to call from any thread, including the UI thread.
+     *
+     * @param key Settings key to retrieve.
+     * @param defaultValue Default value, in milliseconds.
+     * @return The timeout value from Settings or the default value if it hasn't been changed.
+     */
+    private static long get(String key, long defaultValue) {
+        return Settings.Secure.getLong(
+                TelecomApp.getInstance().getContentResolver(), PREFIX + key, defaultValue);
+    }
+
+    /**
+     * Returns the longest period, in milliseconds, to wait for the query for direct-to-voicemail
+     * to complete. If the query goes beyond this timeout, the incoming call screen is shown to the
+     * user.
+     */
+    public static long getDirectToVoicemailMillis() {
+        return get("direct_to_voicemail_ms", 500L);
+    }
+}
diff --git a/src/com/android/server/telecom/TtyManager.java b/src/com/android/server/telecom/TtyManager.java
new file mode 100644
index 0000000..945da5e
--- /dev/null
+++ b/src/com/android/server/telecom/TtyManager.java
@@ -0,0 +1,123 @@
+/*
+ * 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.server.telecom;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.telecom.TelecomManager;
+
+final class TtyManager implements WiredHeadsetManager.Listener {
+    private final TtyBroadcastReceiver mReceiver = new TtyBroadcastReceiver();
+    private final Context mContext;
+    private final WiredHeadsetManager mWiredHeadsetManager;
+    private int mPreferredTtyMode = TelecomManager.TTY_MODE_OFF;
+    private int mCurrentTtyMode = TelecomManager.TTY_MODE_OFF;
+
+    TtyManager(Context context, WiredHeadsetManager wiredHeadsetManager) {
+        mContext = context;
+        mWiredHeadsetManager = wiredHeadsetManager;
+        mWiredHeadsetManager.addListener(this);
+
+        mPreferredTtyMode = Settings.Secure.getInt(
+                mContext.getContentResolver(),
+                Settings.Secure.PREFERRED_TTY_MODE,
+                TelecomManager.TTY_MODE_OFF);
+
+        IntentFilter intentFilter = new IntentFilter(
+                TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
+        mContext.registerReceiver(mReceiver, intentFilter);
+
+        updateCurrentTtyMode();
+    }
+
+    boolean isTtySupported() {
+        boolean isEnabled = mContext.getResources().getBoolean(R.bool.tty_enabled);
+        Log.v(this, "isTtySupported: %b", isEnabled);
+        return isEnabled;
+    }
+
+    int getCurrentTtyMode() {
+        return mCurrentTtyMode;
+    }
+
+    @Override
+    public void onWiredHeadsetPluggedInChanged(boolean oldIsPluggedIn, boolean newIsPluggedIn) {
+        Log.v(this, "onWiredHeadsetPluggedInChanged");
+        updateCurrentTtyMode();
+    }
+
+    private void updateCurrentTtyMode() {
+        int newTtyMode = TelecomManager.TTY_MODE_OFF;
+        if (isTtySupported() && mWiredHeadsetManager.isPluggedIn()) {
+            newTtyMode = mPreferredTtyMode;
+        }
+        Log.v(this, "updateCurrentTtyMode, %d -> %d", mCurrentTtyMode, newTtyMode);
+
+        if (mCurrentTtyMode != newTtyMode) {
+            mCurrentTtyMode = newTtyMode;
+            Intent ttyModeChanged = new Intent(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
+            ttyModeChanged.putExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE, mCurrentTtyMode);
+            mContext.sendBroadcastAsUser(ttyModeChanged, UserHandle.ALL);
+
+            updateAudioTtyMode();
+        }
+    }
+
+    private void updateAudioTtyMode() {
+        String audioTtyMode;
+        switch (mCurrentTtyMode) {
+            case TelecomManager.TTY_MODE_FULL:
+                audioTtyMode = "tty_full";
+                break;
+            case TelecomManager.TTY_MODE_VCO:
+                audioTtyMode = "tty_vco";
+                break;
+            case TelecomManager.TTY_MODE_HCO:
+                audioTtyMode = "tty_hco";
+                break;
+            case TelecomManager.TTY_MODE_OFF:
+            default:
+                audioTtyMode = "tty_off";
+                break;
+        }
+        Log.v(this, "updateAudioTtyMode, %s", audioTtyMode);
+
+        AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setParameters("tty_mode=" + audioTtyMode);
+    }
+
+    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_TTY_PREFERRED_MODE_CHANGED)) {
+                int newPreferredTtyMode = intent.getIntExtra(
+                        TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
+                if (mPreferredTtyMode != newPreferredTtyMode) {
+                    mPreferredTtyMode = newPreferredTtyMode;
+                    updateCurrentTtyMode();
+                }
+            }
+        }
+    }
+}
diff --git a/src/com/android/server/telecom/WiredHeadsetManager.java b/src/com/android/server/telecom/WiredHeadsetManager.java
new file mode 100644
index 0000000..8ce7b61
--- /dev/null
+++ b/src/com/android/server/telecom/WiredHeadsetManager.java
@@ -0,0 +1,94 @@
+/*
+ * 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.server.telecom;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/** Listens for and caches headset state. */
+class WiredHeadsetManager {
+    interface Listener {
+        void onWiredHeadsetPluggedInChanged(boolean oldIsPluggedIn, boolean newIsPluggedIn);
+    }
+
+    /** Receiver for wired headset plugged and unplugged events. */
+    private class WiredHeadsetBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
+                boolean isPluggedIn = intent.getIntExtra("state", 0) == 1;
+                Log.v(WiredHeadsetManager.this, "ACTION_HEADSET_PLUG event, plugged in: %b",
+                        isPluggedIn);
+                onHeadsetPluggedInChanged(isPluggedIn);
+            }
+        }
+    }
+
+    private final WiredHeadsetBroadcastReceiver mReceiver;
+    private boolean mIsPluggedIn;
+    /**
+     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
+     * load factor before resizing, 1 means we only expect a single thread to
+     * access the map so make only a single shard
+     */
+    private final Set<Listener> mListeners = Collections.newSetFromMap(
+            new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
+
+    WiredHeadsetManager(Context context) {
+        mReceiver = new WiredHeadsetBroadcastReceiver();
+
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        mIsPluggedIn = audioManager.isWiredHeadsetOn();
+
+        // Register for misc other intent broadcasts.
+        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
+        context.registerReceiver(mReceiver, intentFilter);
+    }
+
+    void addListener(Listener listener) {
+        mListeners.add(listener);
+    }
+
+    void removeListener(Listener listener) {
+        if (listener != null) {
+            mListeners.remove(listener);
+        }
+    }
+
+    boolean isPluggedIn() {
+        return mIsPluggedIn;
+    }
+
+    private void onHeadsetPluggedInChanged(boolean isPluggedIn) {
+        if (mIsPluggedIn != isPluggedIn) {
+            Log.v(this, "onHeadsetPluggedInChanged, mIsPluggedIn: %b -> %b", mIsPluggedIn,
+                    isPluggedIn);
+            boolean oldIsPluggedIn = mIsPluggedIn;
+            mIsPluggedIn = isPluggedIn;
+            for (Listener listener : mListeners) {
+                listener.onWiredHeadsetPluggedInChanged(oldIsPluggedIn, mIsPluggedIn);
+            }
+        }
+    }
+}
