am 2230ef3c: (-s ours) Merge "DO NOT MERGE. Port "respond via SMS message" feature to new Telecomm. (2/4)" into lmp-preview-dev

* commit '2230ef3c871fb28a6c291bf8ccb9e40cca2ca3b4':
  DO NOT MERGE. Port "respond via SMS message" feature to new Telecomm. (2/4)
diff --git a/Android.mk b/Android.mk
index 852d0a4..48eece0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -3,7 +3,6 @@
 # Build the Telecomm service.
 include $(CLEAR_VARS)
 
-LOCAL_JAVA_LIBRARIES := telephony-common
 LOCAL_STATIC_JAVA_LIBRARIES := \
         guava \
 
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c49dca9..2a90f86 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -177,12 +177,5 @@
             </intent-filter>
         </receiver>
 
-        <activity android:name=".RespondViaSmsSettings$Settings"
-                  android:label="@string/respond_via_sms_setting_title"
-                  android:configChanges="orientation|screenSize|keyboardHidden">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-            </intent-filter>
-        </activity>
     </application>
 </manifest>
diff --git a/res/menu/respond_via_message_settings_menu.xml b/res/menu/respond_via_message_settings_menu.xml
deleted file mode 100644
index 6f5e246..0000000
--- a/res/menu/respond_via_message_settings_menu.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 Google Inc.
-
-     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.
--->
-
-<!-- Menu for Respond-via-Message settings screen. -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/respond_via_message_reset"
-          android:title="@string/respond_via_sms_menu_reset_default_activity" />
-</menu>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 747eca7..0c46053 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -49,30 +49,4 @@
     <!-- Content description of the speakerphone enabled notification icon for
          accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_speakerphone_enabled">Speakerphone enabled.</string>
-
-    <!-- Canned response for the "Respond via SMS" feature for incoming calls. [CHAR LIMIT=35] -->
-    <string name="respond_via_sms_canned_response_1">Can\'t talk now. What\'s up?</string>
-    <!-- Canned response for the "Respond via SMS" feature for incoming calls. [CHAR LIMIT=35] -->
-    <string name="respond_via_sms_canned_response_2">I\'ll call you right back.</string>
-    <!-- Canned response for the "Respond via SMS" feature for incoming calls. [CHAR LIMIT=35] -->
-    <string name="respond_via_sms_canned_response_3">I\'ll call you later.</string>
-    <!-- Canned response for the "Respond via SMS" feature for incoming calls. [CHAR LIMIT=35] -->
-    <string name="respond_via_sms_canned_response_4">Can\'t talk now. Call me later?</string>
-
-    <!-- Title of settings screen for managing the "Respond via SMS" feature. [CHAR LIMIT=30] -->
-    <string name="respond_via_sms_setting_title">Quick responses</string>
-    <!-- Slightly more verbose title of settings screen for managing the
-         "Respond via SMS" feature. [CHAR LIMIT=30] -->
-    <string name="respond_via_sms_setting_title_2">Edit quick responses</string>
-    <!-- Settings summary string for the "Respond via SMS" feature. [CHAR LIMIT=40] -->
-    <string name="respond_via_sms_setting_summary"></string>
-    <!-- Dialog title when changing a string for the "Respond via SMS" feature. [CHAR LIMIT=30] -->
-    <string name="respond_via_sms_edittext_dialog_title">Quick response</string>
-    <!-- Menu option in  "Respond via SMS" that allows user to reset the default
-         activity used to handle "Respond via SMS" [CHAR LIMIT=30] -->
-    <string name="respond_via_sms_menu_reset_default_activity">Reset default app</string>
-
-    <!-- "Respond via SMS": Confirmation message shown after sending
-        a text response. [CHAR LIMIT=40] -->
-    <string name="respond_via_sms_confirmation_format">Message sent to <xliff:g id="phone_number">%s</xliff:g>.</string>
 </resources>
diff --git a/res/xml/respond_via_sms_settings.xml b/res/xml/respond_via_sms_settings.xml
deleted file mode 100644
index a8eb46c..0000000
--- a/res/xml/respond_via_sms_settings.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<!-- Settings screen that lets the user manage the canned responses
-     for the "Respond via SMS" feature; see RespondViaSmsManager.java -->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-     android:title="@string/respond_via_sms_setting_title_2">
-
-    <!-- Ultra-simple implementation for now: just provide 4 fixed slots
-         with customizable strings. -->
-
-    <!-- TODO: Potential UI improvements:
-         (1) Allow editing the strings in place, rather than having to tap
-             each one and edit it via the popup dialog.
-         (2) Allow reordering the strings by drag-and-drop.
-         (3) Provide an "Add new string..." option? -->
-
-    <!-- The defaultValues here must agree with the values used with
-         prefs.getString() in RespondViaSmsManager.loadCannedResponses(). -->
-
-    <!-- Use MultiLineTitleEditTextPreference instead of the standard
-         EditTextPreference here, to allow the preference "title" to wrap
-         onto multiple lines if the customized messages are long enough. -->
-
-    <com.android.telecomm.MultiLineTitleEditTextPreference
-        android:key="canned_response_pref_1"
-        android:defaultValue="@string/respond_via_sms_canned_response_1"
-        android:dialogTitle="@string/respond_via_sms_edittext_dialog_title" />
-
-    <com.android.telecomm.MultiLineTitleEditTextPreference
-        android:key="canned_response_pref_2"
-        android:defaultValue="@string/respond_via_sms_canned_response_2"
-        android:dialogTitle="@string/respond_via_sms_edittext_dialog_title" />
-
-    <com.android.telecomm.MultiLineTitleEditTextPreference
-        android:key="canned_response_pref_3"
-        android:defaultValue="@string/respond_via_sms_canned_response_3"
-        android:dialogTitle="@string/respond_via_sms_edittext_dialog_title" />
-
-    <com.android.telecomm.MultiLineTitleEditTextPreference
-        android:key="canned_response_pref_4"
-        android:defaultValue="@string/respond_via_sms_canned_response_4"
-        android:dialogTitle="@string/respond_via_sms_edittext_dialog_title" />
-
-</PreferenceScreen>
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 104ff4e..66f9366 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -27,7 +27,6 @@
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
 import android.telecomm.GatewayInfo;
-import android.telecomm.Response;
 import android.telecomm.TelecommConstants;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
@@ -37,14 +36,10 @@
 import com.android.internal.telephony.CallerInfoAsyncQuery;
 import com.android.internal.telephony.CallerInfoAsyncQuery.OnQueryCompleteListener;
 
-import com.android.internal.telephony.SmsApplication;
 import com.android.telecomm.ContactsAsyncHelper.OnImageLoadCompleteListener;
+import com.google.android.collect.Sets;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
 
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 
@@ -65,12 +60,6 @@
         void onFailedIncomingCall(Call call);
         void onRequestingRingback(Call call, boolean requestingRingback);
         void onPostDialWait(Call call, String remaining);
-        void onIsConferenceCapableChanged(Call call, boolean isConferenceCapable);
-        void onExpiredConferenceCall(Call call);
-        void onConfirmedConferenceCall(Call call);
-        void onParentChanged(Call call);
-        void onChildrenChanged(Call call);
-        void onCannedSmsResponsesLoaded(Call call);
     }
 
     private static final OnQueryCompleteListener sCallerInfoQueryListener =
@@ -191,27 +180,13 @@
     /** Incoming call-info to use when direct-to-voicemail query finishes. */
     private CallInfo mPendingDirectToVoicemailCallInfo;
 
-    private boolean mIsConferenceCapable = false;
-
-    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;
-
     /**
      * Creates an empty call object.
      *
      * @param isIncoming True if this is an incoming call.
      */
-    Call(boolean isIncoming, boolean isConference) {
-        this(null, null, isIncoming, isConference);
+    Call(boolean isIncoming) {
+        this(null, null, isIncoming);
     }
 
     /**
@@ -221,13 +196,11 @@
      * @param gatewayInfo Gateway information to use for the call.
      * @param isIncoming True if this is an incoming call.
      */
-    Call(Uri handle, GatewayInfo gatewayInfo, boolean isIncoming, boolean isConference) {
-        mState = isConference ? CallState.ACTIVE : CallState.NEW;
+    Call(Uri handle, GatewayInfo gatewayInfo, boolean isIncoming) {
+        mState = CallState.NEW;
         setHandle(handle);
         mGatewayInfo = gatewayInfo;
         mIsIncoming = isIncoming;
-        mIsConference = isConference;
-        maybeLoadCannedSmsResponses();
     }
 
     void addListener(Listener listener) {
@@ -248,15 +221,7 @@
     }
 
     CallState getState() {
-        if (mIsConference) {
-            if (!mChildCalls.isEmpty()) {
-                // If we have child calls, just return the child call.
-                return mChildCalls.get(0).getState();
-            }
-            return CallState.ACTIVE;
-        } else {
-            return mState;
-        }
+        return mState;
     }
 
     /**
@@ -271,7 +236,6 @@
         if (mState != newState) {
             Log.v(this, "setState %s -> %s", mState, newState);
             mState = newState;
-            maybeLoadCannedSmsResponses();
         }
     }
 
@@ -379,27 +343,6 @@
         mConnectTimeMillis = connectTimeMillis;
     }
 
-    boolean isConferenceCapable() {
-        return mIsConferenceCapable;
-    }
-
-    void setIsConferenceCapable(boolean isConferenceCapable) {
-        if (mIsConferenceCapable != isConferenceCapable) {
-            mIsConferenceCapable = isConferenceCapable;
-            for (Listener l : mListeners) {
-                l.onIsConferenceCapableChanged(this, mIsConferenceCapable);
-            }
-        }
-    }
-
-    Call getParentCall() {
-        return mParentCall;
-    }
-
-    List<Call> getChildCalls() {
-        return mChildCalls;
-    }
-
     CallServiceWrapper getCallService() {
         return mCallService;
     }
@@ -507,7 +450,7 @@
             public void run() {
                 processDirectToVoicemail();
             }
-        }, Timeouts.getDirectToVoicemailMillis());
+        }, Timeouts.getDirectToVoicemail());
     }
 
     void processDirectToVoicemail() {
@@ -517,7 +460,7 @@
                 // TODO(santoscordon): Once we move State handling from CallsManager to Call, we
                 // will not need to set RINGING state prior to calling reject.
                 setState(CallState.RINGING);
-                reject(false, null);
+                reject();
             } else {
                 // TODO(santoscordon): Make this class (not CallsManager) responsible for changing
                 // the call state to RINGING.
@@ -681,11 +624,8 @@
 
     /**
      * 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) {
+    void reject() {
         Preconditions.checkNotNull(mCallService);
 
         // Check to verify that the call is still in the ringing state. A call can change states
@@ -800,133 +740,6 @@
         getCallService().onPostDialContinue(this, proceed);
     }
 
-    void conferenceInto(Call conferenceCall) {
-        if (mCallService == null) {
-            Log.w(this, "conference requested on a call without a call service.");
-        } else {
-            mCallService.conference(conferenceCall, this);
-        }
-    }
-
-    void expireConference() {
-        // The conference call expired before we got a confirmation of the conference from the
-        // call service...so start shutting down.
-        clearCallService();
-        for (Listener l : mListeners) {
-            l.onExpiredConferenceCall(this);
-        }
-    }
-
-    void confirmConference() {
-        Log.v(this, "confirming Conf call %s", mListeners);
-        for (Listener l : mListeners) {
-            l.onConfirmedConferenceCall(this);
-        }
-    }
-
-    void splitFromConference() {
-        // TODO(santoscordon): todo
-    }
-
-    void setParentCall(Call parentCall) {
-        if (parentCall == this) {
-            Log.e(this, new Exception(), "setting the parent to self");
-            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);
-        }
-    }
-
-    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(TelecommApp.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;
-    }
-
     /**
      * @return True if the call is ringing, else logs the action name.
      */
@@ -1008,33 +821,4 @@
             mCallerInfo.cachedPhotoIcon = photoIcon;
         }
     }
-
-    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");
-        }
-    }
 }
diff --git a/src/com/android/telecomm/CallIdMapper.java b/src/com/android/telecomm/CallIdMapper.java
index e6b5c1f..7f92067 100644
--- a/src/com/android/telecomm/CallIdMapper.java
+++ b/src/com/android/telecomm/CallIdMapper.java
@@ -38,15 +38,12 @@
         mCalls.put(callId, newCall);
     }
 
-    void addCall(Call call, String id) {
-        Preconditions.checkNotNull(call);
-        ThreadUtil.checkOnMainThread();
-        mCalls.put(id, call);
-    }
-
     void addCall(Call call) {
         ThreadUtil.checkOnMainThread();
-        addCall(call, getNewId());
+        Preconditions.checkNotNull(call);
+        sIdCount++;
+        String callId = mCallIdPrefix + sIdCount;
+        mCalls.put(callId, call);
     }
 
     void removeCall(Call call) {
@@ -94,9 +91,4 @@
         // Note, no need for thread check, this method is thread safe.
         return callId != null && callId.startsWith(mCallIdPrefix);
     }
-
-    String getNewId() {
-        sIdCount++;
-        return mCallIdPrefix + sIdCount;
-    }
 }
diff --git a/src/com/android/telecomm/CallServiceSelectorWrapper.java b/src/com/android/telecomm/CallServiceSelectorWrapper.java
index 6ee73d2..05d540a 100644
--- a/src/com/android/telecomm/CallServiceSelectorWrapper.java
+++ b/src/com/android/telecomm/CallServiceSelectorWrapper.java
@@ -60,8 +60,6 @@
                                 @SuppressWarnings("unchecked")
                                 List<CallServiceDescriptor> descriptors =
                                         (List<CallServiceDescriptor>) args.arg2;
-
-                                mCallIdMapper.removeCall(callId);
                                 mPendingSelects.remove(callId).onResult(descriptors, 0, null);
                             } else {
                                 Log.w(this, "setSelectedCallServices: unknown call: %s, id: %s",
diff --git a/src/com/android/telecomm/CallServiceWrapper.java b/src/com/android/telecomm/CallServiceWrapper.java
index b963dc1..6165804 100644
--- a/src/com/android/telecomm/CallServiceWrapper.java
+++ b/src/com/android/telecomm/CallServiceWrapper.java
@@ -35,11 +35,11 @@
 import com.android.internal.telecomm.ICallServiceProvider;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
 
 import org.apache.http.conn.ClientConnectionRequest;
 
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -50,7 +50,6 @@
  * and instead should use this class to invoke methods of {@link ICallService}.
  */
 final class CallServiceWrapper extends ServiceBinder<ICallService> {
-    private static final String TAG = CallServiceWrapper.class.getSimpleName();
 
     private final class Adapter extends ICallServiceAdapter.Stub {
         private static final int MSG_NOTIFY_INCOMING_CALL = 1;
@@ -63,9 +62,7 @@
         private static final int MSG_SET_ON_HOLD = 8;
         private static final int MSG_SET_REQUESTING_RINGBACK = 9;
         private static final int MSG_ON_POST_DIAL_WAIT = 10;
-        private static final int MSG_CAN_CONFERENCE = 11;
-        private static final int MSG_SET_IS_CONFERENCED = 12;
-        private static final int MSG_ADD_CONFERENCE_CALL = 13;
+        private static final int MSG_HANDOFF_CALL = 11;
 
         private final Handler mHandler = new Handler() {
             @Override
@@ -82,7 +79,8 @@
                             mIncomingCallsManager.handleSuccessfulIncomingCall(call, callInfo);
                         } else {
                             Log.w(this, "notifyIncomingCall, unknown incoming call: %s, id: %s",
-                                    call, clientCallInfo.getId());
+                                    call,
+                                    clientCallInfo.getId());
                         }
                         break;
                     case MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL: {
@@ -178,7 +176,7 @@
                         }
                         break;
                     }
-                    case MSG_ON_POST_DIAL_WAIT: {
+                    case MSG_ON_POST_DIAL_WAIT:
                         SomeArgs args = (SomeArgs) msg.obj;
                         try {
                             call = mCallIdMapper.getCall(args.arg1);
@@ -191,65 +189,14 @@
                         } finally {
                             args.recycle();
                         }
-                        break;
-                    }
-                    case MSG_CAN_CONFERENCE: {
+                    case MSG_HANDOFF_CALL:
                         call = mCallIdMapper.getCall(msg.obj);
                         if (call != null) {
-                            call.setIsConferenceCapable(msg.arg1 == 1);
+                            mCallsManager.startHandoffForCall(call);
                         } else {
-                            Log.w(CallServiceWrapper.this, "canConference, unknown call id: %s",
-                                    msg.obj);
+                            Log.w(this, "handoffCall, unknown call id: %s", msg.obj);
                         }
                         break;
-                    }
-                    case MSG_SET_IS_CONFERENCED: {
-                        SomeArgs args = (SomeArgs) msg.obj;
-                        try {
-                            Call childCall = mCallIdMapper.getCall(args.arg1);
-                            if (childCall != null) {
-                                String conferenceCallId = (String) args.arg2;
-                                Log.d(this, "setIsConferenced %s, %s", childCall, conferenceCallId);
-
-                                if (conferenceCallId == null) {
-                                    childCall.setParentCall(null);
-                                } else {
-                                    Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
-                                    if (conferenceCall != null &&
-                                            !mPendingConferenceCalls.contains(conferenceCall)) {
-                                        childCall.setParentCall(conferenceCall);
-                                    } else {
-                                        Log.w(this, "setIsConferenced, unknown conference id %s",
-                                                conferenceCallId);
-                                    }
-                                }
-                            } 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 callId = (String) args.arg1;
-                            Log.d(this, "addConferenceCall attempt %s, %s",
-                                    callId, mPendingConferenceCalls);
-
-                            Call conferenceCall = mCallIdMapper.getCall(callId);
-                            if (mPendingConferenceCalls.remove(conferenceCall)) {
-                                Log.v(this, "confirming conf call %s", conferenceCall);
-                                conferenceCall.confirmConference();
-                            } else {
-                                Log.w(this, "addConference, unknown call id: %s", callId);
-                            }
-                        } finally {
-                            args.recycle();
-                        }
-                        break;
-                    }
                 }
             }
         };
@@ -347,29 +294,12 @@
 
         /** ${inheritDoc} */
         @Override
-        public void setCanConference(String callId, boolean canConference) {
-            Log.d(this, "setCanConference(%s, %b)", callId, canConference);
-            mHandler.obtainMessage(MSG_CAN_CONFERENCE, canConference ? 1 : 0, 0, callId)
-                    .sendToTarget();
+        public void setCanConferenceWith(String callId, List<String> conferenceCapableCallIds) {
         }
 
         /** ${inheritDoc} */
         @Override
-        public void setIsConferenced(String callId, String conferenceCallId) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = conferenceCallId;
-            mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
-        }
-
-        /** ${InheritDoc} */
-        @Override
-        public void addConferenceCall(String callId, CallInfo callInfo) {
-            mCallIdMapper.checkValidCallId(callId);
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = callId;
-            args.arg2 = callInfo;
-            mHandler.obtainMessage(MSG_ADD_CONFERENCE_CALL, args).sendToTarget();
+        public void setIsConferenced(String conferenceCallId, String callId, boolean isConferenced) {
         }
 
         @Override
@@ -380,17 +310,22 @@
             args.arg2 = remaining;
             mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
         }
+
+        /** {@inheritDoc} */
+        @Override
+        public void handoffCall(String callId) {
+            mCallIdMapper.checkValidCallId(callId);
+            mHandler.obtainMessage(MSG_HANDOFF_CALL, callId).sendToTarget();
+        }
     }
 
     private final Adapter mAdapter = new Adapter();
     private final CallsManager mCallsManager = CallsManager.getInstance();
-    private final Set<Call> mPendingIncomingCalls = new HashSet<>();
-    private final Set<Call> mPendingConferenceCalls = new HashSet<>();
+    private final Set<Call> mPendingIncomingCalls = Sets.newHashSet();
     private final CallServiceDescriptor mDescriptor;
     private final CallIdMapper mCallIdMapper = new CallIdMapper("CallService");
     private final IncomingCallsManager mIncomingCallsManager;
     private final Map<String, AsyncResultCallback<Boolean>> mPendingOutgoingCalls = new HashMap<>();
-    private final Handler mHandler = new Handler();
 
     private Binder mBinder = new Binder();
     private ICallService mServiceInterface;
@@ -586,9 +521,7 @@
     }
 
     void addCall(Call call) {
-        if (mCallIdMapper.getCallId(call) == null) {
-            mCallIdMapper.addCall(call);
-        }
+        mCallIdMapper.addCall(call);
     }
 
     /**
@@ -620,37 +553,6 @@
         }
     }
 
-    void conference(final Call conferenceCall, Call call) {
-        if (isServiceValid("conference")) {
-            try {
-                conferenceCall.setCallService(this);
-                mPendingConferenceCalls.add(conferenceCall);
-                mHandler.postDelayed(new Runnable() {
-                    @Override public void run() {
-                        if (mPendingConferenceCalls.remove(conferenceCall)) {
-                            conferenceCall.expireConference();
-                            Log.i(this, "Conference call expired: %s", conferenceCall);
-                        }
-                    }
-                }, Timeouts.getConferenceCallExpireMillis());
-
-                mServiceInterface.conference(
-                        mCallIdMapper.getCallId(conferenceCall),
-                        mCallIdMapper.getCallId(call));
-            } catch (RemoteException ignored) {
-            }
-        }
-    }
-
-    void splitFromConference(Call call) {
-        if (isServiceValid("splitFromConference")) {
-            try {
-                mServiceInterface.splitFromConference(mCallIdMapper.getCallId(call));
-            } catch (RemoteException ignored) {
-            }
-        }
-    }
-
     /** {@inheritDoc} */
     @Override
     protected void setServiceInterface(IBinder binder) {
@@ -687,12 +589,12 @@
                 mIncomingCallsManager.handleFailedIncomingCall(call);
             }
 
-            if (!mPendingIncomingCalls.isEmpty()) {
-                Log.wtf(this, "Pending calls did not get cleared.");
-                mPendingIncomingCalls.clear();
-            }
-        }
-
-        mCallIdMapper.clear();
+      if (!mPendingIncomingCalls.isEmpty()) {
+        Log.wtf(this, "Pending calls did not get cleared.");
+        mPendingIncomingCalls.clear();
+      }
     }
+
+    mCallIdMapper.clear();
+  }
 }
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index cb633ef..9a9e235 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -57,13 +57,10 @@
                 CallServiceDescriptor oldDescriptor,
                 CallServiceDescriptor newDescriptor);
         void onIncomingCallAnswered(Call call);
-        void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage);
+        void onIncomingCallRejected(Call call);
         void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall);
         void onAudioStateChanged(CallAudioState oldAudioState, CallAudioState newAudioState);
         void onRequestingRingback(Call call, boolean ringback);
-        void onIsConferenceCapableChanged(Call call, boolean isConferenceCapable);
-        void onIsConferencedChanged(Call call);
-        void onCannedSmsResponsesLoaded(Call call);
     }
 
     private static final CallsManager INSTANCE = new CallsManager();
@@ -122,7 +119,6 @@
         mListeners.add(app.getMissedCallNotifier());
         mListeners.add(mDtmfLocalTonePlayer);
         mListeners.add(mHeadsetMediaButton);
-        mListeners.add(RespondViaSmsManager.getInstance());
     }
 
     @Override
@@ -169,13 +165,6 @@
     }
 
     @Override
-    public void onIsConferenceCapableChanged(Call call, boolean isConferenceCapable) {
-        for (CallsManagerListener listener : mListeners) {
-            listener.onIsConferenceCapableChanged(call, isConferenceCapable);
-        }
-    }
-
-    @Override
     public void onRequestingRingback(Call call, boolean ringback) {
         for (CallsManagerListener listener : mListeners) {
             listener.onRequestingRingback(call, ringback);
@@ -187,41 +176,6 @@
         mInCallController.onPostDialWait(call, remaining);
     }
 
-    @Override
-    public void onExpiredConferenceCall(Call call) {
-        call.removeListener(this);
-    }
-
-    @Override
-    public void onConfirmedConferenceCall(Call call) {
-        addCall(call);
-        Log.v(this, "confirming Conf call %s", call);
-        for (CallsManagerListener listener : mListeners) {
-            listener.onIsConferencedChanged(call);
-        }
-    }
-
-    @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 onCannedSmsResponsesLoaded(Call call) {
-        for (CallsManagerListener listener : mListeners) {
-            listener.onCannedSmsResponsesLoaded(call);
-        }
-    }
-
     ImmutableCollection<Call> getCalls() {
         return ImmutableList.copyOf(mCalls);
     }
@@ -264,7 +218,7 @@
         // Create a call with no handle. Eventually, switchboard will update the call with
         // additional information from the call service, but for now we just need one to pass
         // around.
-        Call call = new Call(true /* isIncoming */, false /* isConference */);
+        Call call = new Call(true /* isIncoming */);
         // TODO(santoscordon): Move this to be a part of addCall()
         call.addListener(this);
 
@@ -289,8 +243,7 @@
                     Log.pii(uriHandle), Log.pii(handle));
         }
 
-        Call call = new Call(
-                uriHandle, gatewayInfo, false /* isIncoming */, false /* isConference */);
+        Call call = new Call(uriHandle, gatewayInfo, false /* isIncoming */);
 
         // TODO(santoscordon): Move this to be a part of addCall()
         call.addListener(this);
@@ -300,17 +253,6 @@
     }
 
     /**
-     * Attempts to start a conference call for the specified call.
-     *
-     * @param call The call to conference with.
-     */
-    void conference(Call call) {
-        Call conferenceCall = new Call(false, true);
-        conferenceCall.addListener(this);
-        call.conferenceInto(conferenceCall);
-    }
-
-    /**
      * Instructs Telecomm to answer the specified call. Intended to be invoked by the in-call
      * app through {@link InCallAdapter} after Telecomm notifies it of an incoming call followed by
      * the user opting to answer said call.
@@ -347,14 +289,14 @@
      * app through {@link InCallAdapter} after Telecomm notifies it of an incoming call followed by
      * the user opting to reject said call.
      */
-    void rejectCall(Call call, boolean rejectWithMessage, String textMessage) {
+    void rejectCall(Call call) {
         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);
+                listener.onIncomingCallRejected(call);
             }
-            call.reject(rejectWithMessage, textMessage);
+            call.reject();
         }
     }
 
@@ -468,8 +410,8 @@
         // original call will live on but its state will be updated to the new call's state. In
         // particular the original call's call service will be updated to the new call's call
         // service.
-        Call tempCall = new Call(
-                originalCall.getHandoffHandle(), originalCall.getGatewayInfo(), false, false);
+        Call tempCall =
+                new Call(originalCall.getHandoffHandle(), originalCall.getGatewayInfo(), false);
         tempCall.setOriginalCall(originalCall);
         tempCall.setExtras(originalCall.getExtras());
         tempCall.setCallServiceSelector(originalCall.getCallServiceSelector());
@@ -769,8 +711,9 @@
         handoffCall.removeListener(this);
 
         if (wasSuccessful) {
-            // Disconnect.
-            originalCall.disconnect();
+            if (TelephonyUtil.isCurrentlyPSTNCall(originalCall)) {
+                originalCall.disconnect();
+            }
 
             // Synchronize.
             originalCall.setCallService(handoffCall.getCallService(), handoffCall);
diff --git a/src/com/android/telecomm/CallsManagerListenerBase.java b/src/com/android/telecomm/CallsManagerListenerBase.java
index 55fa0a1..d3ea758 100644
--- a/src/com/android/telecomm/CallsManagerListenerBase.java
+++ b/src/com/android/telecomm/CallsManagerListenerBase.java
@@ -60,7 +60,7 @@
     }
 
     @Override
-    public void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage) {
+    public void onIncomingCallRejected(Call call) {
     }
 
     @Override
@@ -74,16 +74,4 @@
     @Override
     public void onRequestingRingback(Call call, boolean ringback) {
     }
-
-    @Override
-    public void onIsConferenceCapableChanged(Call call, boolean isConferenceCapable) {
-    }
-
-    @Override
-    public void onIsConferencedChanged(Call call) {
-    }
-
-    @Override
-    public void onCannedSmsResponsesLoaded(Call call) {
-    }
 }
diff --git a/src/com/android/telecomm/InCallAdapter.java b/src/com/android/telecomm/InCallAdapter.java
index 7937e95..0dfcae8 100644
--- a/src/com/android/telecomm/InCallAdapter.java
+++ b/src/com/android/telecomm/InCallAdapter.java
@@ -39,118 +39,53 @@
     private static final int MSG_HANDOFF_CALL = 8;
     private static final int MSG_MUTE = 9;
     private static final int MSG_SET_AUDIO_ROUTE = 10;
-    private static final int MSG_CONFERENCE = 11;
-    private static final int MSG_SPLIT_FROM_CONFERENCE = 12;
 
     private final class InCallAdapterHandler extends Handler {
         @Override
         public void handleMessage(Message msg) {
-            Call call;
+            Call call = null;
+            if (msg.obj != null) {
+                call = mCallIdMapper.getCall(msg.obj);
+                if (call == null) {
+                    Log.w(this, "Unknown call id: %s, msg: %d", msg.obj, msg.what);
+                    return;
+                }
+            }
+
             switch (msg.what) {
                 case MSG_ANSWER_CALL:
-                    call = mCallIdMapper.getCall(msg.obj);
-                    if (call != null) {
-                        mCallsManager.answerCall(call);
-                    } else {
-                        Log.w(this, "answerCall, unknown call id: %s", msg.obj);
-                    }
+                    mCallsManager.answerCall(call);
                     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();
-                    }
+                    mCallsManager.rejectCall(call);
                     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);
-                    }
+                    mCallsManager.playDtmfTone(call, (char) msg.arg1);
                     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);
-                    }
+                    mCallsManager.stopDtmfTone(call);
                     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);
-                    }
+                    mCallsManager.disconnectCall(call);
                     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);
-                    }
+                    mCallsManager.holdCall(call);
                     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);
-                    }
+                    mCallsManager.unholdCall(call);
                     break;
                 case MSG_HANDOFF_CALL:
-                    call = mCallIdMapper.getCall(msg.obj);
-                    if (call != null) {
-                        mCallsManager.startHandoffForCall(call);
-                    } else {
-                        Log.w(this, "startHandoffForCall, unknown call id: %s", msg.obj);
-                    }
+                    mCallsManager.startHandoffForCall(call);
                     break;
                 case MSG_MUTE:
-                    mCallsManager.mute(msg.arg1 == 1);
+                    mCallsManager.mute(msg.arg1 == 1 ? true : false);
                     break;
                 case MSG_SET_AUDIO_ROUTE:
                     mCallsManager.setAudioRoute(msg.arg1);
                     break;
-                case MSG_CONFERENCE:
-                    call = mCallIdMapper.getCall(msg.obj);
-                    if (call != null) {
-                        mCallsManager.conference(call);
-                    } else {
-                        Log.w(this, "conference, unknown call id: %s", msg.obj);
-                    }
-
-                    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;
             }
         }
     }
@@ -176,14 +111,10 @@
 
     /** {@inheritDoc} */
     @Override
-    public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
-        Log.d(this, "rejectCall(%s,%b,%s)", callId, rejectWithMessage, textMessage);
+    public void rejectCall(String callId) {
+        Log.d(this, "rejectCall(%s)", callId);
         mCallIdMapper.checkValidCallId(callId);
-        SomeArgs args = SomeArgs.obtain();
-        args.arg1 = callId;
-        args.argi1 = rejectWithMessage ? 1 : 0;
-        args.arg2 = textMessage;
-        mHandler.obtainMessage(MSG_REJECT_CALL, args).sendToTarget();
+        mHandler.obtainMessage(MSG_REJECT_CALL, callId).sendToTarget();
     }
 
     /** {@inheritDoc} */
@@ -253,13 +184,11 @@
 
     /** ${inheritDoc} */
     @Override
-    public void conference(String callId) {
-        mHandler.obtainMessage(MSG_CONFERENCE, callId).sendToTarget();
+    public void conferenceWith(String arg0, String arg1) {
     }
 
     /** ${inheritDoc} */
     @Override
-    public void splitFromConference(String callId) {
-        mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, callId).sendToTarget();
+    public void splitFromConference(String arg0) {
     }
 }
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index e519220..637e03e 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -23,19 +23,17 @@
 import android.net.Uri;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.telecomm.CallAudioState;
 import android.telecomm.CallCapabilities;
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
 import android.telecomm.InCallCall;
+import android.telecomm.CallState;
 
 import com.android.internal.telecomm.IInCallService;
 import com.google.common.collect.ImmutableCollection;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * 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
@@ -90,12 +88,10 @@
             bind();
         } else {
             Log.i(this, "Adding call: %s", call);
-            if (mCallIdMapper.getCallId(call) == null) {
-                mCallIdMapper.addCall(call);
-                try {
-                    mInCallService.addCall(toInCallCall(call));
-                } catch (RemoteException ignored) {
-                }
+            mCallIdMapper.addCall(call);
+            try {
+                mInCallService.addCall(toInCallCall(call));
+            } catch (RemoteException ignored) {
             }
         }
     }
@@ -157,22 +153,6 @@
         }
     }
 
-    @Override
-    public void onIsConferenceCapableChanged(Call call, boolean isConferenceCapable) {
-        updateCall(call);
-    }
-
-    @Override
-    public void onIsConferencedChanged(Call call) {
-        Log.v(this, "onIsConferencedChanged %s", call);
-        updateCall(call);
-    }
-
-    @Override
-    public void onCannedSmsResponsesLoaded(Call call) {
-        updateCall(call);
-    }
-
     void bringToForeground(boolean showDialpad) {
         if (mInCallService != null) {
             try {
@@ -211,7 +191,8 @@
             serviceIntent.setComponent(component);
 
             Context context = TelecommApp.getInstance();
-            if (!context.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE)) {
+            if (!context.bindServiceAsUser(serviceIntent, mConnection, Context.BIND_AUTO_CREATE,
+                    UserHandle.CURRENT)) {
                 Log.w(this, "Could not connect to the in-call app (%s)", component);
 
                 // TODO(santoscordon): Implement retry or fall-back-to-default logic.
@@ -262,9 +243,7 @@
     private void updateCall(Call call) {
         if (mInCallService != null) {
             try {
-                InCallCall inCallCall = toInCallCall(call);
-                Log.v(this, "updateCall %s ==> %s", call, inCallCall);
-                mInCallService.updateCall(inCallCall);
+                mInCallService.updateCall(toInCallCall(call));
             } catch (RemoteException ignored) {
             }
         }
@@ -280,9 +259,6 @@
         if (call.getHandoffHandle() != null) {
             capabilities |= CallCapabilities.CONNECTION_HANDOFF;
         }
-        if (call.isConferenceCapable()) {
-            capabilities |= CallCapabilities.MERGE_CALLS;
-        }
         if (CallsManager.getInstance().isAddCallCapable(call)) {
             capabilities |= CallCapabilities.ADD_CALL;
         }
@@ -294,32 +270,9 @@
         if (state == CallState.DISCONNECTED && call.getHandoffCallServiceDescriptor() != null) {
             state = CallState.ACTIVE;
         }
-
-        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 |= CallCapabilities.RESPOND_VIA_TEXT;
-        }
-
         return new InCallCall(callId, state, call.getDisconnectCause(), call.getDisconnectMessage(),
-                call.getCannedSmsResponses(), capabilities, connectTimeMillis, call.getHandle(),
-                call.getGatewayInfo(), descriptor, call.getHandoffCallServiceDescriptor(),
-                parentCallId, childCallIds);
+                capabilities, call.getConnectTimeMillis(), call.getHandle(), call.getGatewayInfo(),
+                descriptor, call.getHandoffCallServiceDescriptor());
     }
 
 }
diff --git a/src/com/android/telecomm/MultiLineTitleEditTextPreference.java b/src/com/android/telecomm/MultiLineTitleEditTextPreference.java
deleted file mode 100644
index d40cb21..0000000
--- a/src/com/android/telecomm/MultiLineTitleEditTextPreference.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.telecomm;
-
-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.telecomm.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.telecomm.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/telecomm/RespondViaSmsManager.java b/src/com/android/telecomm/RespondViaSmsManager.java
deleted file mode 100644
index bf1a2a5..0000000
--- a/src/com/android/telecomm/RespondViaSmsManager.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * 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.telecomm;
-
-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.telecomm.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 String SCHEME_SMSTO = "smsto";
-
-    /** SharedPreferences file name for our persistent settings. */
-    private static final String SHARED_PREFERENCES_NAME = "respond_via_sms_prefs";
-
-    // 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.
-    private static final int NUM_CANNED_RESPONSES = 4;
-    private static final String KEY_CANNED_RESPONSE_PREF_1 = "canned_response_pref_1";
-    private static final String KEY_CANNED_RESPONSE_PREF_2 = "canned_response_pref_2";
-    private static final String KEY_CANNED_RESPONSE_PREF_3 = "canned_response_pref_3";
-    private static final String KEY_CANNED_RESPONSE_PREF_4 = "canned_response_pref_4";
-
-    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");
-                final SharedPreferences prefs = TelecommApp.getInstance().getSharedPreferences(
-                        SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
-                final Resources res = TelecommApp.getInstance().getInstance().getResources();
-
-                final ArrayList<String> textMessages = new ArrayList<String>(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(KEY_CANNED_RESPONSE_PREF_1,
-                        res.getString(R.string.respond_via_sms_canned_response_1)));
-                textMessages.add(1, prefs.getString(KEY_CANNED_RESPONSE_PREF_2,
-                        res.getString(R.string.respond_via_sms_canned_response_2)));
-                textMessages.add(2, prefs.getString(KEY_CANNED_RESPONSE_PREF_3,
-                        res.getString(R.string.respond_via_sms_canned_response_3)));
-                textMessages.add(3, prefs.getString(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 = TelecommApp.getInstance().getResources();
-        final String formatString = res.getString(
-                R.string.respond_via_sms_confirmation_format);
-        final String confirmationMsg = String.format(formatString, phoneNumber);
-        Toast.makeText(TelecommApp.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(
-                            TelecommApp.getInstance(), true /*updateIfNeeded*/);
-            if (component != null) {
-                // Build and send the intent
-                final Uri uri = Uri.fromParts(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);
-                TelecommApp.getInstance().startService(intent);
-            }
-        }
-    }
-}
diff --git a/src/com/android/telecomm/RespondViaSmsSettings.java b/src/com/android/telecomm/RespondViaSmsSettings.java
deleted file mode 100644
index 1adf45c..0000000
--- a/src/com/android/telecomm/RespondViaSmsSettings.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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.telecomm;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-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 {
-    /** SharedPreferences file name for our persistent settings. */
-    private static final String SHARED_PREFERENCES_NAME = "respond_via_sms_prefs";
-
-    // 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.
-    private static final int NUM_CANNED_RESPONSES = 4;
-    private static final String KEY_CANNED_RESPONSE_PREF_1 = "canned_response_pref_1";
-    private static final String KEY_CANNED_RESPONSE_PREF_2 = "canned_response_pref_2";
-    private static final String KEY_CANNED_RESPONSE_PREF_3 = "canned_response_pref_3";
-    private static final String KEY_CANNED_RESPONSE_PREF_4 = "canned_response_pref_4";
-    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 Telecomm (com.android.telecomm) 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()...");
-
-            getPreferenceManager().setSharedPreferencesName(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(KEY_CANNED_RESPONSE_PREF_1);
-            pref.setTitle(pref.getText());
-            pref.setOnPreferenceChangeListener(this);
-
-            pref = (EditTextPreference) findPreference(KEY_CANNED_RESPONSE_PREF_2);
-            pref.setTitle(pref.getText());
-            pref.setOnPreferenceChangeListener(this);
-
-            pref = (EditTextPreference) findPreference(KEY_CANNED_RESPONSE_PREF_3);
-            pref.setTitle(pref.getText());
-            pref.setOnPreferenceChangeListener(this);
-
-            pref = (EditTextPreference) findPreference(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(
-                            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) {
-        Intent intent = new Intent();
-        try {
-            intent.setClassName(
-                    activity.createPackageContext("com.android.phone", 0),
-                    "com.android.phone.CallFeaturesSetting");
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.w(RespondViaSmsSettings.class,
-                    "Exception building package context com.android.phone", e);
-            return;
-        }
-        intent.setAction(Intent.ACTION_MAIN);
-        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        activity.startActivity(intent);
-        activity.finish();
-     }
-}
diff --git a/src/com/android/telecomm/Ringer.java b/src/com/android/telecomm/Ringer.java
index 0b54a2b..5b5beff 100644
--- a/src/com/android/telecomm/Ringer.java
+++ b/src/com/android/telecomm/Ringer.java
@@ -105,7 +105,7 @@
     }
 
     @Override
-    public void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage) {
+    public void onIncomingCallRejected(Call call) {
         onRespondedToIncomingCall(call);
     }
 
diff --git a/src/com/android/telecomm/TelecommApp.java b/src/com/android/telecomm/TelecommApp.java
index 48f6ba5..7f477f9 100644
--- a/src/com/android/telecomm/TelecommApp.java
+++ b/src/com/android/telecomm/TelecommApp.java
@@ -17,6 +17,7 @@
 package com.android.telecomm;
 
 import android.app.Application;
+import android.os.UserHandle;
 
 /**
  * Top-level Application class for Telecomm.
@@ -38,7 +39,9 @@
         sInstance = this;
 
         mMissedCallNotifier = new MissedCallNotifier(this);
-        TelecommServiceImpl.init();
+        if (UserHandle.myUserId() == UserHandle.USER_OWNER) {
+            TelecommServiceImpl.init();
+        }
     }
 
     public static TelecommApp getInstance() {
diff --git a/src/com/android/telecomm/Timeouts.java b/src/com/android/telecomm/Timeouts.java
index 3e5899c..d13091f 100644
--- a/src/com/android/telecomm/Timeouts.java
+++ b/src/com/android/telecomm/Timeouts.java
@@ -65,14 +65,7 @@
      * to complete. If the query goes beyond this timeout, the incoming call screen is shown to the
      * user.
      */
-    public static long getDirectToVoicemailMillis() {
+    public static long getDirectToVoicemail() {
         return get("direct_to_voicemail_ms", 500L);
     }
-
-    /**
-     * Returns the amount of time that a connection service has to respond to a "conference" action.
-     */
-    public static long getConferenceCallExpireMillis() {
-        return get("conference_call_expire_ms", 15 * 1000L);
-    }
 }
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 570b2ae..807e669 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -16,31 +16,32 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.telecomm.tests">
+
     <application android:label="@string/app_name">
         <uses-library android:name="android.test.runner" />
 
         <!-- Miscellaneous telecomm app-related test activities. -->
 
         <!-- TODO(santoscordon): STOPSHIP Services in this manifest need permission protection. -->
-        <service android:name="com.android.telecomm.testcallservice.TestCallServiceProvider">
+        <service android:name="com.android.telecomm.testapps.TestCallServiceProvider">
             <intent-filter>
                 <action android:name="android.telecomm.CallServiceProvider" />
             </intent-filter>
         </service>
 
-        <service android:name="com.android.telecomm.testcallservice.TestCallService">
+        <service android:name="com.android.telecomm.testapps.TestCallService">
             <intent-filter>
                 <action android:name="android.telecomm.CallService" />
             </intent-filter>
         </service>
 
-        <service android:name="com.android.telecomm.testcallservice.DummyCallServiceSelector">
+        <service android:name="com.android.telecomm.testapps.DummyCallServiceSelector">
             <intent-filter>
                 <action android:name="android.telecomm.CallServiceSelector" />
             </intent-filter>
         </service>
 
-        <activity android:name="com.android.telecomm.testcallservice.TestCallActivity"
+        <activity android:name="com.android.telecomm.testapps.TestCallActivity"
                 android:label="@string/testCallActivityLabel">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -49,14 +50,48 @@
             </intent-filter>
         </activity>
 
-        <receiver android:name="com.android.telecomm.testcallservice.CallNotificationReceiver"
+        <receiver android:name="com.android.telecomm.testapps.CallNotificationReceiver"
                 android:exported="false">
             <intent-filter>
-                <action android:name="com.android.telecomm.testcallservice.ACTION_CALL_SERVICE_EXIT"
+                <action android:name="com.android.telecomm.testapps.ACTION_CALL_SERVICE_EXIT"
                 />
             </intent-filter>
         </receiver>
 
+        <activity android:name="com.android.telecomm.testapps.TestDialerActivity"
+                android:label="@string/testDialerActivityLabel" >
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:mimeType="vnd.android.cursor.item/phone" />
+                <data android:mimeType="vnd.android.cursor.item/person" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="voicemail" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="tel" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+
     </application>
 
     <!--
diff --git a/tests/res/layout/testdialer_main.xml b/tests/res/layout/testdialer_main.xml
new file mode 100644
index 0000000..a5453fc
--- /dev/null
+++ b/tests/res/layout/testdialer_main.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+    <EditText
+        android:id="@+id/number"
+        android:inputType="number"
+        android:layout_width="200dp"
+        android:layout_height="wrap_content" />
+    <Button
+        android:id="@+id/place_call_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/placeCallButton" />
+    <Button
+        android:id="@+id/set_default_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/defaultDialerButton" />
+</LinearLayout>
diff --git a/tests/res/values/donottranslate_strings.xml b/tests/res/values/donottranslate_strings.xml
index 6e4788f..76d8777 100644
--- a/tests/res/values/donottranslate_strings.xml
+++ b/tests/res/values/donottranslate_strings.xml
@@ -20,4 +20,13 @@
 
     <!-- String for the TestCallActivity -->
     <string name="testCallActivityLabel">Test CallService App</string>
+
+    <!-- String for the TestDialerActivity -->
+    <string name="testDialerActivityLabel">Test Dialer</string>
+
+    <!-- String for button in TestDialerActivity that reassigns the default Dialer -->
+    <string name="defaultDialerButton">Default dialer request</string>
+
+    <!-- String for button in TestDialerActivity that places a test call -->
+    <string name="placeCallButton">Place call</string>
 </resources>
diff --git a/tests/src/com/android/telecomm/testcallservice/CallNotificationReceiver.java b/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
similarity index 96%
rename from tests/src/com/android/telecomm/testcallservice/CallNotificationReceiver.java
rename to tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
index 5e74069..4ab908f 100644
--- a/tests/src/com/android/telecomm/testcallservice/CallNotificationReceiver.java
+++ b/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.telecomm.testcallservice;
+package com.android.telecomm.testapps;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
diff --git a/tests/src/com/android/telecomm/testcallservice/CallServiceNotifier.java b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
similarity index 98%
rename from tests/src/com/android/telecomm/testcallservice/CallServiceNotifier.java
rename to tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
index e88c293..336ce56 100644
--- a/tests/src/com/android/telecomm/testcallservice/CallServiceNotifier.java
+++ b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.telecomm.testcallservice;
+package com.android.telecomm.testapps;
 
 import android.app.Notification;
 import android.app.NotificationManager;
diff --git a/tests/src/com/android/telecomm/testcallservice/DummyCallServiceSelector.java b/tests/src/com/android/telecomm/testapps/DummyCallServiceSelector.java
similarity index 98%
rename from tests/src/com/android/telecomm/testcallservice/DummyCallServiceSelector.java
rename to tests/src/com/android/telecomm/testapps/DummyCallServiceSelector.java
index 28085ea..5f0db05 100644
--- a/tests/src/com/android/telecomm/testcallservice/DummyCallServiceSelector.java
+++ b/tests/src/com/android/telecomm/testapps/DummyCallServiceSelector.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.telecomm.testcallservice;
+package com.android.telecomm.testapps;
 
 import android.net.Uri;
 import android.os.Bundle;
diff --git a/tests/src/com/android/telecomm/testcallservice/TestCallActivity.java b/tests/src/com/android/telecomm/testapps/TestCallActivity.java
similarity index 96%
rename from tests/src/com/android/telecomm/testcallservice/TestCallActivity.java
rename to tests/src/com/android/telecomm/testapps/TestCallActivity.java
index 5c483ef..9752252 100644
--- a/tests/src/com/android/telecomm/testcallservice/TestCallActivity.java
+++ b/tests/src/com/android/telecomm/testapps/TestCallActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.telecomm.testcallservice;
+package com.android.telecomm.testapps;
 
 import android.app.Activity;
 import android.os.Bundle;
diff --git a/tests/src/com/android/telecomm/testcallservice/TestCallService.java b/tests/src/com/android/telecomm/testapps/TestCallService.java
similarity index 96%
rename from tests/src/com/android/telecomm/testcallservice/TestCallService.java
rename to tests/src/com/android/telecomm/testapps/TestCallService.java
index b179849..d34a2d2 100644
--- a/tests/src/com/android/telecomm/testcallservice/TestCallService.java
+++ b/tests/src/com/android/telecomm/testapps/TestCallService.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.telecomm.testcallservice;
+package com.android.telecomm.testapps;
 
 import android.content.Intent;
 import android.media.MediaPlayer;
@@ -185,12 +185,12 @@
 
     /** ${inheritDoc} */
     @Override
-    public void conference(String conferenceCallId, String callId) {
+    public void addToConference(String conferenceCallId, List<String> callIds) {
     }
 
     /** ${inheritDoc} */
     @Override
-    public void splitFromConference(String callId) {
+    public void splitFromConference(String conferenceCallId, String callId) {
     }
 
     private void activateCall(String callId) {
diff --git a/tests/src/com/android/telecomm/testcallservice/TestCallServiceProvider.java b/tests/src/com/android/telecomm/testapps/TestCallServiceProvider.java
similarity index 96%
rename from tests/src/com/android/telecomm/testcallservice/TestCallServiceProvider.java
rename to tests/src/com/android/telecomm/testapps/TestCallServiceProvider.java
index 3a6646c..a8ccaa1 100644
--- a/tests/src/com/android/telecomm/testcallservice/TestCallServiceProvider.java
+++ b/tests/src/com/android/telecomm/testapps/TestCallServiceProvider.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.telecomm.testcallservice;
+package com.android.telecomm.testapps;
 
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallServiceLookupResponse;
diff --git a/tests/src/com/android/telecomm/testapps/TestDialerActivity.java b/tests/src/com/android/telecomm/testapps/TestDialerActivity.java
new file mode 100644
index 0000000..405bca5
--- /dev/null
+++ b/tests/src/com/android/telecomm/testapps/TestDialerActivity.java
@@ -0,0 +1,56 @@
+package com.android.telecomm.testapps;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.EditText;
+
+import com.android.telecomm.tests.R;
+
+public class TestDialerActivity extends Activity {
+    private EditText mNumberView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.testdialer_main);
+        findViewById(R.id.set_default_button).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                setDefault();
+            }
+        });
+        findViewById(R.id.place_call_button).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                placeCall();
+            }
+        });
+
+        mNumberView = (EditText) findViewById(R.id.number);
+        updateEditTextWithNumber();
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        updateEditTextWithNumber();
+    }
+
+    private void updateEditTextWithNumber() {
+        Intent intent = getIntent();
+        if (intent != null) {
+            mNumberView.setText(intent.getDataString());
+        }
+    }
+
+    private void setDefault() {
+        // TODO: Send a request to become the default dialer application
+    }
+
+    private void placeCall() {
+        // TODO: Place a call with the number entered in the number field
+    }
+}