Misc Telecomm API changes - impl

This CL contains plumbing for Telecomm API changes made in
ag/501321.

As a cleanup I also made InCallController listen to changes
to calls directly instead of using CallsManager.

Change-Id: Iaffe0b84cea6003f2a9b9d8b30676743d2b236d4
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index f5229cc..d91ee11 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -23,6 +23,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.ContactsContract.Contacts;
+import android.telecomm.CallPropertyPresentation;
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
 import android.telecomm.ConnectionRequest;
@@ -48,6 +49,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -74,10 +76,11 @@
         void onChildrenChanged(Call call);
         void onCannedSmsResponsesLoaded(Call call);
         void onCallVideoProviderChanged(Call call);
-        void onFeaturesChanged(Call call);
         void onCallerInfoChanged(Call call);
         void onAudioModeIsVoipChanged(Call call);
         void onStatusHintsChanged(Call call);
+        void onHandleChanged(Call call);
+        void onCallerDisplayNameChanged(Call call);
     }
 
     abstract static class ListenerBase implements Listener {
@@ -110,13 +113,15 @@
         @Override
         public void onCallVideoProviderChanged(Call call) {}
         @Override
-        public void onFeaturesChanged(Call call) {}
-        @Override
         public void onCallerInfoChanged(Call call) {}
         @Override
         public void onAudioModeIsVoipChanged(Call call) {}
         @Override
         public void onStatusHintsChanged(Call call) {}
+        @Override
+        public void onHandleChanged(Call call) {}
+        @Override
+        public void onCallerDisplayNameChanged(Call call) {}
     }
 
     private static final OnQueryCompleteListener sCallerInfoQueryListener =
@@ -171,6 +176,15 @@
     /** The handle with which to establish this call. */
     private Uri mHandle;
 
+    /** The {@link CallPropertyPresentation} that controls how the handle is shown. */
+    private int mHandlePresentation;
+
+    /** The caller display name (CNAP) set by the connection service. */
+    private String mCallerDisplayName;
+
+    /** The {@link CallPropertyPresentation} that controls how the caller display name is shown. */
+    private int mCallerDisplayNamePresentation;
+
     /**
      * The connection service which is attempted or already connecting this call.
      */
@@ -232,9 +246,6 @@
 
     private ICallVideoProvider mCallVideoProvider;
 
-    /** Features associated with the call which the InCall UI may wish to show icons for. */
-    private int mFeatures;
-
     private boolean mAudioModeIsVoip;
     private StatusHints mStatusHints;
 
@@ -258,7 +269,7 @@
     Call(Uri handle, GatewayInfo gatewayInfo, PhoneAccount account,
             boolean isIncoming, boolean isConference) {
         mState = isConference ? CallState.ACTIVE : CallState.NEW;
-        setHandle(handle);
+        setHandle(handle, CallPropertyPresentation.ALLOWED);
         mGatewayInfo = gatewayInfo;
         mPhoneAccount = account;
         mIsIncoming = isIncoming;
@@ -326,12 +337,39 @@
         return mHandle;
     }
 
-    void setHandle(Uri handle) {
-        if ((mHandle == null && handle != null) || (mHandle != null && !mHandle.equals(handle))) {
+    int getHandlePresentation() {
+        return mHandlePresentation;
+    }
+
+    void setHandle(Uri handle, int presentation) {
+        if (!Objects.equals(handle, mHandle) || presentation != mHandlePresentation) {
             mHandle = handle;
+            mHandlePresentation = presentation;
             mIsEmergencyCall = mHandle != null && PhoneNumberUtils.isLocalEmergencyNumber(
                     TelecommApp.getInstance(), mHandle.getSchemeSpecificPart());
             startCallerInfoLookup();
+            for (Listener l : mListeners) {
+                l.onHandleChanged(this);
+            }
+        }
+    }
+
+    String getCallerDisplayName() {
+        return mCallerDisplayName;
+    }
+
+    int getCallerDisplayNamePresentation() {
+        return mCallerDisplayNamePresentation;
+    }
+
+    void setCallerDisplayName(String callerDisplayName, int presentation) {
+        if (!TextUtils.equals(callerDisplayName, mCallerDisplayName) ||
+                presentation != mCallerDisplayNamePresentation) {
+            mCallerDisplayName = callerDisplayName;
+            mCallerDisplayNamePresentation = presentation;
+            for (Listener l : mListeners) {
+                l.onCallerDisplayNameChanged(this);
+            }
         }
     }
 
@@ -501,7 +539,7 @@
         mDirectToVoicemailQueryPending = true;
 
         // Setting the handle triggers the caller info lookup code.
-        setHandle(request.getHandle());
+        setHandle(request.getHandle(), CallPropertyPresentation.ALLOWED);
 
         // Timeout the direct-to-voicemail lookup execution so that we dont wait too long before
         // showing the user the incoming call screen.
@@ -772,6 +810,10 @@
         // TODO(santoscordon): todo
     }
 
+    void swapWithBackgroundCall() {
+        mConnectionService.swapWithBackgroundCall(this);
+    }
+
     void setParentCall(Call parentCall) {
         if (parentCall == this) {
             Log.e(this, new Exception(), "setting the parent to self");
@@ -1024,28 +1066,6 @@
     }
 
     /**
-     * Returns the features of this call.
-     *
-     * @return The features of this call.
-     */
-    public int getFeatures() {
-        return mFeatures;
-    }
-
-    /**
-     * Set the features associated with the call and notify any listeners of the change.
-     *
-     * @param features The features.
-     */
-    public void setFeatures(int features) {
-        Log.d(this, "setFeatures: %d", features);
-        mFeatures = features;
-        for (Listener l : mListeners) {
-            l.onFeaturesChanged(Call.this);
-        }
-    }
-
-    /**
      * The current video state for the call.
      * Valid values: {@link android.telecomm.VideoCallProfile#VIDEO_STATE_AUDIO_ONLY},
      * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_BIDIRECTIONAL},
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 3811de1..c983ff1 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -23,7 +23,6 @@
 import android.telecomm.CallState;
 import android.telecomm.GatewayInfo;
 import android.telecomm.PhoneAccount;
-import android.telecomm.StatusHints;
 import android.telephony.DisconnectCause;
 
 import com.google.common.base.Preconditions;
@@ -57,13 +56,8 @@
         void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall);
         void onAudioStateChanged(CallAudioState oldAudioState, CallAudioState newAudioState);
         void onRequestingRingback(Call call, boolean ringback);
-        void onCallCapabilitiesChanged(Call call);
         void onIsConferencedChanged(Call call);
-        void onCannedSmsResponsesLoaded(Call call);
-        void onCallVideoProviderChanged(Call call);
-        void onFeaturesChanged(Call call);
         void onAudioModeIsVoipChanged(Call call);
-        void onStatusHintsChanged(Call call);
     }
 
     private static final CallsManager INSTANCE = new CallsManager();
@@ -161,13 +155,6 @@
     }
 
     @Override
-    public void onCallCapabilitiesChanged(Call call) {
-        for (CallsManagerListener listener : mListeners) {
-            listener.onCallCapabilitiesChanged(call);
-        }
-    }
-
-    @Override
     public void onRequestingRingback(Call call, boolean ringback) {
         for (CallsManagerListener listener : mListeners) {
             listener.onRequestingRingback(call, ringback);
@@ -208,41 +195,12 @@
     }
 
     @Override
-    public void onCannedSmsResponsesLoaded(Call call) {
-        for (CallsManagerListener listener : mListeners) {
-            listener.onCannedSmsResponsesLoaded(call);
-        }
-    }
-
-    @Override
-    public void onCallVideoProviderChanged(Call call) {
-        for (CallsManagerListener listener : mListeners) {
-            listener.onCallVideoProviderChanged(call);
-        }
-    }
-
-    @Override
-    public void onFeaturesChanged(Call call) {
-        Log.v(this, "onFeaturesChanged: %d", call.getFeatures());
-        for (CallsManagerListener listener : mListeners) {
-            listener.onFeaturesChanged(call);
-        }
-    }
-
-    @Override
     public void onAudioModeIsVoipChanged(Call call) {
         for (CallsManagerListener listener : mListeners) {
             listener.onAudioModeIsVoipChanged(call);
         }
     }
 
-    @Override
-    public void onStatusHintsChanged(Call call) {
-        for (CallsManagerListener listener : mListeners) {
-            listener.onStatusHintsChanged(call);
-        }
-    }
-
     ImmutableCollection<Call> getCalls() {
         return ImmutableList.copyOf(mCalls);
     }
@@ -726,20 +684,4 @@
             }
         }
     }
-
-    private static boolean areDescriptorsEqual(
-            CallServiceDescriptor descriptor1,
-            CallServiceDescriptor descriptor2) {
-        if (descriptor1 == null) {
-            return descriptor2 == null;
-        }
-        return descriptor1.equals(descriptor2);
-    }
-
-    private static boolean areUriEqual(Uri handle1, Uri handle2) {
-        if (handle1 == null) {
-            return handle2 == null;
-        }
-        return handle1.equals(handle2);
-    }
 }
diff --git a/src/com/android/telecomm/CallsManagerListenerBase.java b/src/com/android/telecomm/CallsManagerListenerBase.java
index 8073042..70dac25 100644
--- a/src/com/android/telecomm/CallsManagerListenerBase.java
+++ b/src/com/android/telecomm/CallsManagerListenerBase.java
@@ -20,7 +20,6 @@
 import android.telecomm.CallAudioState;
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
-import android.telecomm.StatusHints;
 
 /**
  * Provides a default implementation for listeners of CallsManager.
@@ -66,30 +65,10 @@
     }
 
     @Override
-    public void onCallCapabilitiesChanged(Call call) {
-    }
-
-    @Override
     public void onIsConferencedChanged(Call call) {
     }
 
     @Override
-    public void onCannedSmsResponsesLoaded(Call call) {
-    }
-
-    @Override
-    public void onCallVideoProviderChanged(Call call) {
-    }
-
-    @Override
-    public void onFeaturesChanged(Call call) {
-    }
-
-    @Override
     public void onAudioModeIsVoipChanged(Call call) {
     }
-
-    @Override
-    public void onStatusHintsChanged(Call call) {
-    }
 }
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
index 9d59aed..e131e07 100644
--- a/src/com/android/telecomm/ConnectionServiceWrapper.java
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -17,6 +17,7 @@
 package com.android.telecomm;
 
 import android.content.ComponentName;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -75,9 +76,10 @@
     private static final int MSG_ON_POST_DIAL_WAIT = 15;
     private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 16;
     private static final int MSG_SET_CALL_VIDEO_PROVIDER = 17;
-    private static final int MSG_SET_FEATURES = 18;
-    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 19;
-    private static final int MSG_SET_STATUS_HINTS = 20;
+    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 18;
+    private static final int MSG_SET_STATUS_HINTS = 19;
+    private static final int MSG_SET_HANDLE = 20;
+    private static final int MSG_SET_CALLER_DISPLAY_NAME = 21;
 
     private final Handler mHandler = new Handler() {
         @Override
@@ -286,13 +288,6 @@
                     }
                     break;
                 }
-                case MSG_SET_FEATURES: {
-                    call = mCallIdMapper.getCall(msg.obj);
-                    if (call != null) {
-                        call.setFeatures(msg.arg1);
-                    }
-                    break;
-                }
                 case MSG_SET_AUDIO_MODE_IS_VOIP: {
                     call = mCallIdMapper.getCall(msg.obj);
                     if (call != null) {
@@ -313,12 +308,35 @@
                     }
                     break;
                 }
+                case MSG_SET_HANDLE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null) {
+                            call.setHandle((Uri) args.arg2, args.argi1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_SET_CALLER_DISPLAY_NAME: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null) {
+                            call.setCallerDisplayName((String) args.arg2, args.argi1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
             }
         }
     };
 
     private final class Adapter extends IConnectionServiceAdapter.Stub {
-        /** {@inheritDoc} */
         @Override
         public void notifyIncomingCall(ConnectionRequest request) {
             logIncoming("notifyIncomingCall %s", request);
@@ -326,7 +344,6 @@
             mHandler.obtainMessage(MSG_NOTIFY_INCOMING_CALL, request).sendToTarget();
         }
 
-        /** {@inheritDoc} */
         @Override
         public void handleSuccessfulOutgoingCall(ConnectionRequest request) {
             logIncoming("handleSuccessfulOutgoingCall %s", request);
@@ -334,7 +351,6 @@
             mHandler.obtainMessage(MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL, request).sendToTarget();
         }
 
-        /** {@inheritDoc} */
         @Override
         public void handleFailedOutgoingCall(
                 ConnectionRequest request,
@@ -349,7 +365,6 @@
             mHandler.obtainMessage(MSG_HANDLE_FAILED_OUTGOING_CALL, args).sendToTarget();
         }
 
-        /** {@inheritDoc} */
         @Override
         public void cancelOutgoingCall(ConnectionRequest request) {
             logIncoming("cancelOutgoingCall %s", request);
@@ -357,7 +372,6 @@
             mHandler.obtainMessage(MSG_CANCEL_OUTGOING_CALL, request).sendToTarget();
         }
 
-        /** {@inheritDoc} */
         @Override
         public void setActive(String callId) {
             logIncoming("setActive %s", callId);
@@ -365,7 +379,6 @@
             mHandler.obtainMessage(MSG_SET_ACTIVE, callId).sendToTarget();
         }
 
-        /** {@inheritDoc} */
         @Override
         public void setRinging(String callId) {
             logIncoming("setRinging %s", callId);
@@ -373,7 +386,6 @@
             mHandler.obtainMessage(MSG_SET_RINGING, callId).sendToTarget();
         }
 
-        /** {@inheritDoc} */
         @Override
         public void setCallVideoProvider(String callId, ICallVideoProvider callVideoProvider) {
             logIncoming("setCallVideoProvider %s", callId);
@@ -384,7 +396,6 @@
             mHandler.obtainMessage(MSG_SET_CALL_VIDEO_PROVIDER, args).sendToTarget();
         }
 
-        /** {@inheritDoc} */
         @Override
         public void setDialing(String callId) {
             logIncoming("setDialing %s", callId);
@@ -392,7 +403,6 @@
             mHandler.obtainMessage(MSG_SET_DIALING, callId).sendToTarget();
         }
 
-        /** {@inheritDoc} */
         @Override
         public void setDisconnected(
                 String callId, int disconnectCause, String disconnectMessage) {
@@ -405,7 +415,6 @@
             mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
         }
 
-        /** {@inheritDoc} */
         @Override
         public void setOnHold(String callId) {
             logIncoming("setOnHold %s", callId);
@@ -413,7 +422,6 @@
             mHandler.obtainMessage(MSG_SET_ON_HOLD, callId).sendToTarget();
         }
 
-        /** {@inheritDoc} */
         @Override
         public void setRequestingRingback(String callId, boolean ringback) {
             logIncoming("setRequestingRingback %s %b", callId, ringback);
@@ -424,13 +432,11 @@
             mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, args).sendToTarget();
         }
 
-        /** ${inheritDoc} */
         @Override
         public void removeCall(String callId) {
             logIncoming("removeCall %s", callId);
         }
 
-        /** ${inheritDoc} */
         @Override
         public void setCallCapabilities(String callId, int callCapabilities) {
             logIncoming("setCallCapabilities %s %d", callId, callCapabilities);
@@ -438,7 +444,6 @@
                     .sendToTarget();
         }
 
-        /** ${inheritDoc} */
         @Override
         public void setIsConferenced(String callId, String conferenceCallId) {
             logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
@@ -448,7 +453,6 @@
             mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
         }
 
-        /** ${InheritDoc} */
         @Override
         public void addConferenceCall(String callId) {
             logIncoming("addConferenceCall %s", callId);
@@ -466,7 +470,6 @@
             mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
         }
 
-        /** ${inheritDoc} */
         @Override
         public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
             logIncoming("queryRemoteCSs");
@@ -474,13 +477,6 @@
         }
 
         @Override
-        public void setFeatures(String callId, int features) {
-            logIncoming("setFeatures %s %d", callId, features);
-            mCallIdMapper.checkValidCallId(callId);
-            mHandler.obtainMessage(MSG_SET_FEATURES, features, 0, callId).sendToTarget();
-        }
-
-        @Override
         public void setAudioModeIsVoip(String callId, boolean isVoip) {
             logIncoming("setAudioModeIsVoip %s %b", callId, isVoip);
             mCallIdMapper.checkValidCallId(callId);
@@ -497,6 +493,29 @@
             args.arg2 = statusHints;
             mHandler.obtainMessage(MSG_SET_STATUS_HINTS, args).sendToTarget();
         }
+
+        @Override
+        public void setHandle(String callId, Uri handle, int presentation) {
+            logIncoming("setHandle %s %s %d", callId, handle, presentation);
+            mCallIdMapper.checkValidCallId(callId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = handle;
+            args.argi1 = presentation;
+            mHandler.obtainMessage(MSG_SET_HANDLE, args).sendToTarget();
+        }
+
+        @Override
+        public void setCallerDisplayName(
+                String callId, String callerDisplayName, int presentation) {
+            logIncoming("setCallerDisplayName %s %s %d", callId, callerDisplayName, presentation);
+            mCallIdMapper.checkValidCallId(callId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = callerDisplayName;
+            args.argi1 = presentation;
+            mHandler.obtainMessage(MSG_SET_CALLER_DISPLAY_NAME, args).sendToTarget();
+        }
     }
 
     private final Adapter mAdapter = new Adapter();
@@ -569,7 +588,12 @@
                             NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_ORIGINAL_URI,
                             gatewayInfo.getOriginalHandle());
                 }
-                ConnectionRequest request = new ConnectionRequest(callId, call.getHandle(), extras,
+                ConnectionRequest request = new ConnectionRequest(
+                        call.getPhoneAccount(),
+                        callId,
+                        call.getHandle(),
+                        call.getHandlePresentation(),
+                        extras,
                         call.getVideoState());
 
                 try {
@@ -663,7 +687,12 @@
                     String callId = mCallIdMapper.getCallId(call);
                     logOutgoing("createIncomingCall %s %s", callId, extras);
                     ConnectionRequest request = new ConnectionRequest(
-                            callId, call.getHandle(), extras, call.getVideoState());
+                            call.getPhoneAccount(),
+                            callId,
+                            call.getHandle(),
+                            call.getHandlePresentation(),
+                            extras,
+                            call.getVideoState());
                     try {
                         mServiceInterface.createIncomingCall(request);
                     } catch (RemoteException e) {
@@ -816,6 +845,16 @@
         }
     }
 
+    void swapWithBackgroundCall(Call call) {
+        if (isServiceValid("swapWithBackgroundCall")) {
+            try {
+                logOutgoing("swapWithBackgroundCall %s", mCallIdMapper.getCallId(call));
+                mServiceInterface.swapWithBackgroundCall(mCallIdMapper.getCallId(call));
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
     /** {@inheritDoc} */
     @Override
     protected void setServiceInterface(IBinder binder) {
diff --git a/src/com/android/telecomm/InCallAdapter.java b/src/com/android/telecomm/InCallAdapter.java
index 40bb61d..7db9325 100644
--- a/src/com/android/telecomm/InCallAdapter.java
+++ b/src/com/android/telecomm/InCallAdapter.java
@@ -41,6 +41,7 @@
     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 static final int MSG_SWAP_WITH_BACKGROUND_CALL = 13;
 
     private final class InCallAdapterHandler extends Handler {
         @Override
@@ -151,6 +152,14 @@
                         Log.w(this, "splitFromConference, unknown call id: %s", msg.obj);
                     }
                     break;
+                case MSG_SWAP_WITH_BACKGROUND_CALL:
+                    call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        call.swapWithBackgroundCall();
+                    } else {
+                        Log.w(this, "swapWithBackgroundCall, unknown call id: %s", msg.obj);
+                    }
+                    break;
             }
         }
     }
@@ -166,7 +175,6 @@
         mCallIdMapper = callIdMapper;
     }
 
-    /** {@inheritDoc} */
     @Override
     public void answerCall(String callId) {
         Log.d(this, "answerCall(%s)", callId);
@@ -174,7 +182,6 @@
         mHandler.obtainMessage(MSG_ANSWER_CALL, callId).sendToTarget();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
         Log.d(this, "rejectCall(%s,%b,%s)", callId, rejectWithMessage, textMessage);
@@ -186,7 +193,6 @@
         mHandler.obtainMessage(MSG_REJECT_CALL, args).sendToTarget();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void playDtmfTone(String callId, char digit) {
         Log.d(this, "playDtmfTone(%s,%c)", callId, digit);
@@ -194,7 +200,6 @@
         mHandler.obtainMessage(MSG_PLAY_DTMF_TONE, (int) digit, 0, callId).sendToTarget();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void stopDtmfTone(String callId) {
         Log.d(this, "stopDtmfTone(%s)", callId);
@@ -202,7 +207,6 @@
         mHandler.obtainMessage(MSG_STOP_DTMF_TONE, callId).sendToTarget();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void postDialContinue(String callId, boolean proceed) {
         Log.d(this, "postDialContinue(%s)", callId);
@@ -210,7 +214,6 @@
         mHandler.obtainMessage(MSG_POST_DIAL_CONTINUE, proceed ? 1 : 0, 0, callId).sendToTarget();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void disconnectCall(String callId) {
         Log.v(this, "disconnectCall: %s", callId);
@@ -218,48 +221,46 @@
         mHandler.obtainMessage(MSG_DISCONNECT_CALL, callId).sendToTarget();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void holdCall(String callId) {
         mCallIdMapper.checkValidCallId(callId);
         mHandler.obtainMessage(MSG_HOLD_CALL, callId).sendToTarget();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void unholdCall(String callId) {
         mCallIdMapper.checkValidCallId(callId);
         mHandler.obtainMessage(MSG_UNHOLD_CALL, callId).sendToTarget();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void phoneAccountClicked(String callId) {
         mCallIdMapper.checkValidCallId(callId);
         mHandler.obtainMessage(MSG_PHONE_ACCOUNT_CLICKED, callId).sendToTarget();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void mute(boolean shouldMute) {
         mHandler.obtainMessage(MSG_MUTE, shouldMute ? 1 : 0, 0).sendToTarget();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void setAudioRoute(int route) {
         mHandler.obtainMessage(MSG_SET_AUDIO_ROUTE, route, 0).sendToTarget();
     }
 
-    /** ${inheritDoc} */
     @Override
     public void conference(String callId) {
         mHandler.obtainMessage(MSG_CONFERENCE, callId).sendToTarget();
     }
 
-    /** ${inheritDoc} */
     @Override
     public void splitFromConference(String callId) {
         mHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, callId).sendToTarget();
     }
+
+    @Override
+    public void swapWithBackgroundCall(String callId) {
+        mHandler.obtainMessage(MSG_SWAP_WITH_BACKGROUND_CALL, callId).sendToTarget();
+    }
 }
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index 94f5b6e..d8e4030 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -28,6 +28,7 @@
 import android.os.UserHandle;
 import android.telecomm.CallAudioState;
 import android.telecomm.CallCapabilities;
+import android.telecomm.CallPropertyPresentation;
 import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
 import android.telecomm.InCallCall;
@@ -60,6 +61,38 @@
         }
     }
 
+    private final Call.Listener mCallListener = new Call.ListenerBase() {
+        @Override
+        public void onCallCapabilitiesChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onCannedSmsResponsesLoaded(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onCallVideoProviderChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onStatusHintsChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onHandleChanged(Call call) {
+            updateCall(call);
+        }
+
+        @Override
+        public void onCallerDisplayNameChanged(Call call) {
+            updateCall(call);
+        }
+    };
+
     /** Maintains a binding connection to the in-call app. */
     private final InCallServiceConnection mConnection = new InCallServiceConnection();
 
@@ -80,6 +113,7 @@
             Log.i(this, "Adding call: %s", call);
             if (mCallIdMapper.getCallId(call) == null) {
                 mCallIdMapper.addCall(call);
+                call.addListener(mCallListener);
                 try {
                     mInCallService.addCall(toInCallCall(call));
                 } catch (RemoteException ignored) {
@@ -94,6 +128,7 @@
             // TODO(sail): Wait for all messages to be delivered to the service before unbinding.
             unbind();
         }
+        call.removeListener(mCallListener);
         mCallIdMapper.removeCall(call);
     }
 
@@ -133,37 +168,11 @@
     }
 
     @Override
-    public void onCallCapabilitiesChanged(Call call) {
-        updateCall(call);
-    }
-
-    @Override
     public void onIsConferencedChanged(Call call) {
         Log.v(this, "onIsConferencedChanged %s", call);
         updateCall(call);
     }
 
-    @Override
-    public void onCannedSmsResponsesLoaded(Call call) {
-        updateCall(call);
-    }
-
-    @Override
-    public void onCallVideoProviderChanged(Call call) {
-        updateCall(call);
-    }
-
-    @Override
-    public void onFeaturesChanged(Call call) {
-        Log.v(this,"onFeaturesChanged: %d", call.getFeatures());
-        updateCall(call);
-    }
-
-    @Override
-    public void onStatusHintsChanged(Call call) {
-        updateCall(call);
-    }
-
     void bringToForeground(boolean showDialpad) {
         if (mInCallService != null) {
             try {
@@ -303,10 +312,16 @@
             capabilities |= CallCapabilities.RESPOND_VIA_TEXT;
         }
 
+        Uri handle = call.getHandlePresentation() == CallPropertyPresentation.ALLOWED ?
+                call.getHandle() : null;
+        String callerDisplayName = call.getCallerDisplayNamePresentation() ==
+                CallPropertyPresentation.ALLOWED ?  call.getCallerDisplayName() : null;
+
         return new InCallCall(callId, state, call.getDisconnectCause(), call.getDisconnectMessage(),
-                call.getCannedSmsResponses(), capabilities, connectTimeMillis, call.getHandle(),
-                call.getGatewayInfo(), call.getPhoneAccount(), descriptor,
-                call.getCallVideoProvider(), parentCallId, childCallIds, call.getFeatures(),
-                call.getStatusHints());
+                call.getCannedSmsResponses(), capabilities, connectTimeMillis, handle,
+                call.getHandlePresentation(), callerDisplayName,
+                call.getCallerDisplayNamePresentation(), call.getGatewayInfo(),
+                call.getPhoneAccount(), descriptor, call.getCallVideoProvider(), parentCallId,
+                childCallIds, call.getStatusHints());
     }
 }
diff --git a/src/com/android/telecomm/MissedCallNotifier.java b/src/com/android/telecomm/MissedCallNotifier.java
index f0f5217..bb2f092 100644
--- a/src/com/android/telecomm/MissedCallNotifier.java
+++ b/src/com/android/telecomm/MissedCallNotifier.java
@@ -271,6 +271,12 @@
                         // Get data about the missed call from the cursor
                         Uri handle = Uri.parse(cursor.getString(
                                 cursor.getColumnIndexOrThrow(Calls.NUMBER)));
+                        int presentation = cursor.getInt(cursor.getColumnIndexOrThrow(
+                                Calls.NUMBER_PRESENTATION));
+
+                        if (presentation != Calls.PRESENTATION_ALLOWED) {
+                            handle = null;
+                        }
 
                         // Convert the data to a call object
                         Call call = new Call(null, null, null, true, false);
@@ -289,7 +295,7 @@
                             }
                         });
                         // Set the handle here because that is what triggers the contact info query.
-                        call.setHandle(handle);
+                        call.setHandle(handle, presentation);
                     }
                 }
             }