resolved conflicts for merge of 10838c23 to master

Change-Id: I2c860eece81258c868ed8429aca5a4ebe2d62ba9
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 607aeb1..66f9366 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -40,9 +40,6 @@
 import com.google.android.collect.Sets;
 import com.google.common.base.Preconditions;
 
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 
@@ -63,11 +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);
     }
 
     private static final OnQueryCompleteListener sCallerInfoQueryListener =
@@ -188,21 +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<>();
-
     /**
      * 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);
     }
 
     /**
@@ -212,12 +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;
     }
 
     void addListener(Listener listener) {
@@ -238,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;
     }
 
     /**
@@ -368,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;
     }
@@ -496,7 +450,7 @@
             public void run() {
                 processDirectToVoicemail();
             }
-        }, Timeouts.getDirectToVoicemailMillis());
+        }, Timeouts.getDirectToVoicemail());
     }
 
     void processDirectToVoicemail() {
@@ -786,73 +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 True if the call is ringing, else logs the action name.
      */
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 49eff44..9a9e235 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -61,8 +61,6 @@
         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);
     }
 
     private static final CallsManager INSTANCE = new CallsManager();
@@ -167,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);
@@ -185,34 +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);
-        }
-    }
-
     ImmutableCollection<Call> getCalls() {
         return ImmutableList.copyOf(mCalls);
     }
@@ -255,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);
 
@@ -280,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);
@@ -291,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.
@@ -459,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());
@@ -760,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 60fdbf6..d3ea758 100644
--- a/src/com/android/telecomm/CallsManagerListenerBase.java
+++ b/src/com/android/telecomm/CallsManagerListenerBase.java
@@ -74,12 +74,4 @@
     @Override
     public void onRequestingRingback(Call call, boolean ringback) {
     }
-
-    @Override
-    public void onIsConferenceCapableChanged(Call call, boolean isConferenceCapable) {
-    }
-
-    @Override
-    public void onIsConferencedChanged(Call call) {
-    }
 }
diff --git a/src/com/android/telecomm/InCallAdapter.java b/src/com/android/telecomm/InCallAdapter.java
index 7ae12ab..0dfcae8 100644
--- a/src/com/android/telecomm/InCallAdapter.java
+++ b/src/com/android/telecomm/InCallAdapter.java
@@ -39,8 +39,6 @@
     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
@@ -88,12 +86,6 @@
                 case MSG_SET_AUDIO_ROUTE:
                     mCallsManager.setAudioRoute(msg.arg1);
                     break;
-                case MSG_CONFERENCE:
-                    mCallsManager.conference(call);
-                    break;
-                case MSG_SPLIT_FROM_CONFERENCE:
-                    call.splitFromConference();
-                    break;
             }
         }
     }
@@ -192,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 6dac2ce..637e03e 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -23,6 +23,7 @@
 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;
@@ -33,10 +34,6 @@
 import com.android.internal.telecomm.IInCallService;
 import com.google.common.collect.ImmutableCollection;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
 /**
  * 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
@@ -156,17 +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);
-    }
-
     void bringToForeground(boolean showDialpad) {
         if (mInCallService != null) {
             try {
@@ -205,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.
@@ -256,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) {
             }
         }
@@ -274,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;
         }
@@ -288,27 +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));
-            }
-        }
-
         return new InCallCall(callId, state, call.getDisconnectCause(), call.getDisconnectMessage(),
-                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/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
+    }
+}