diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index f5f9606..149ffe9 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -1255,18 +1255,23 @@
      * Looks up contact information based on the current handle.
      */
     private void startCallerInfoLookup() {
-        String number = mHandle == null ? null : mHandle.getSchemeSpecificPart();
+        final String number = mHandle == null ? null : mHandle.getSchemeSpecificPart();
 
         mQueryToken++;  // Updated so that previous queries can no longer set the information.
         mCallerInfo = null;
         if (!TextUtils.isEmpty(number)) {
             Log.v(this, "Looking up information for: %s.", Log.piiHandle(number));
-            CallerInfoAsyncQuery.startQuery(
-                    mQueryToken,
-                    mContext,
-                    number,
-                    sCallerInfoQueryListener,
-                    this);
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    CallerInfoAsyncQuery.startQuery(
+                            mQueryToken,
+                            mContext,
+                            number,
+                            sCallerInfoQueryListener,
+                            Call.this);
+                }
+            });
         }
     }
 
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 1aea31d..2d94a24 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -19,6 +19,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -66,360 +67,472 @@
                 String callId,
                 ConnectionRequest request,
                 ParcelableConnection connection) {
-            synchronized (mLock) {
-                logIncoming("handleCreateConnectionComplete %s", callId);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    ConnectionServiceWrapper.this
-                            .handleCreateConnectionComplete(callId, request, connection);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("handleCreateConnectionComplete %s", callId);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        ConnectionServiceWrapper.this
+                                .handleCreateConnectionComplete(callId, request, connection);
+                    }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setActive(String callId) {
-            synchronized (mLock) {
-                logIncoming("setActive %s", callId);
-                if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
-                        .isValidConferenceId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.markCallAsActive(call);
-                    } else {
-                        //Log.w(this, "setActive, unknown call id: %s", msg.obj);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setActive %s", callId);
+                    if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
+                            .isValidConferenceId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            mCallsManager.markCallAsActive(call);
+                        } else {
+                            // Log.w(this, "setActive, unknown call id: %s", msg.obj);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setRinging(String callId) {
-            synchronized (mLock) {
-                logIncoming("setRinging %s", callId);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.markCallAsRinging(call);
-                    } else {
-                        //Log.w(this, "setRinging, unknown call id: %s", msg.obj);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setRinging %s", callId);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            mCallsManager.markCallAsRinging(call);
+                        } else {
+                            // Log.w(this, "setRinging, unknown call id: %s", msg.obj);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setVideoProvider(String callId, IVideoProvider videoProvider) {
-            synchronized (mLock) {
-                logIncoming("setVideoProvider %s", callId);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.setVideoProvider(videoProvider);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setVideoProvider %s", callId);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            call.setVideoProvider(videoProvider);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setDialing(String callId) {
-            synchronized (mLock) {
-                logIncoming("setDialing %s", callId);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.markCallAsDialing(call);
-                    } else {
-                        //Log.w(this, "setDialing, unknown call id: %s", msg.obj);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setDialing %s", callId);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            mCallsManager.markCallAsDialing(call);
+                        } else {
+                            // Log.w(this, "setDialing, unknown call id: %s", msg.obj);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setDisconnected(String callId, DisconnectCause disconnectCause) {
-            synchronized (mLock) {
-                logIncoming("setDisconnected %s %s", callId, disconnectCause);
-                if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
-                        .isValidConferenceId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    Log.d(this, "disconnect call %s %s", disconnectCause, call);
-                    if (call != null) {
-                        mCallsManager.markCallAsDisconnected(call, disconnectCause);
-                    } else {
-                        //Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setDisconnected %s %s", callId, disconnectCause);
+                    if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
+                            .isValidConferenceId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        Log.d(this, "disconnect call %s %s", disconnectCause, call);
+                        if (call != null) {
+                            mCallsManager.markCallAsDisconnected(call, disconnectCause);
+                        } else {
+                            // Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setOnHold(String callId) {
-            synchronized (mLock) {
-                logIncoming("setOnHold %s", callId);
-                if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
-                        .isValidConferenceId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        mCallsManager.markCallAsOnHold(call);
-                    } else {
-                        //Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setOnHold %s", callId);
+                    if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
+                            .isValidConferenceId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            mCallsManager.markCallAsOnHold(call);
+                        } else {
+                            // Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setRingbackRequested(String callId, boolean ringback) {
-            synchronized (mLock) {
-                logIncoming("setRingbackRequested %s %b", callId, ringback);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.setRingbackRequested(ringback);
-                    } else {
-                        //Log.w(this, "setRingback, unknown call id: %s", args.arg1);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setRingbackRequested %s %b", callId, ringback);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            call.setRingbackRequested(ringback);
+                        } else {
+                            // Log.w(this, "setRingback, unknown call id: %s", args.arg1);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void removeCall(String callId) {
-            synchronized (mLock) {
-                logIncoming("removeCall %s", callId);
-                if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
-                        .isValidConferenceId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        if (call.isAlive()) {
-                            mCallsManager.markCallAsDisconnected(
-                                    call, new DisconnectCause(DisconnectCause.REMOTE));
-                        } else {
-                            mCallsManager.markCallAsRemoved(call);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("removeCall %s", callId);
+                    if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
+                            .isValidConferenceId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            if (call.isAlive()) {
+                                mCallsManager.markCallAsDisconnected(
+                                        call, new DisconnectCause(DisconnectCause.REMOTE));
+                            } else {
+                                mCallsManager.markCallAsRemoved(call);
+                            }
                         }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setConnectionCapabilities(String callId, int connectionCapabilities) {
-            synchronized (mLock) {
-                logIncoming("setConnectionCapabilities %s %d", callId, connectionCapabilities);
-                if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
-                        .isValidConferenceId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.setConnectionCapabilities(connectionCapabilities);
-                    } else {
-                        //Log.w(ConnectionServiceWrapper.this,
-                        //      "setConnectionCapabilities, unknown call id: %s", msg.obj);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setConnectionCapabilities %s %d", callId, connectionCapabilities);
+                    if (mCallIdMapper.isValidCallId(callId) || mCallIdMapper
+                            .isValidConferenceId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            call.setConnectionCapabilities(connectionCapabilities);
+                        } else {
+                            // Log.w(ConnectionServiceWrapper.this,
+                            // "setConnectionCapabilities, unknown call id: %s", msg.obj);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setIsConferenced(String callId, String conferenceCallId) {
-            synchronized (mLock) {
-                logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
-                Call childCall = mCallIdMapper.getCall(callId);
-                if (childCall != null) {
-                    if (conferenceCallId == null) {
-                        Log.d(this, "unsetting parent: %s", conferenceCallId);
-                        childCall.setParentCall(null);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
+                    Call childCall = mCallIdMapper.getCall(callId);
+                    if (childCall != null) {
+                        if (conferenceCallId == null) {
+                            Log.d(this, "unsetting parent: %s", conferenceCallId);
+                            childCall.setParentCall(null);
+                        } else {
+                            Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
+                            childCall.setParentCall(conferenceCall);
+                        }
                     } else {
-                        Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
-                        childCall.setParentCall(conferenceCall);
+                        // Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
                     }
-                } else {
-                    //Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void addConferenceCall(String callId, ParcelableConference parcelableConference) {
-            synchronized (mLock) {
-                if (mCallIdMapper.getCall(callId) != null) {
-                    Log.w(this, "Attempting to add a conference call using an existing " +
-                            "call id %s", callId);
-                    return;
-                }
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    if (mCallIdMapper.getCall(callId) != null) {
+                        Log.w(this, "Attempting to add a conference call using an existing " +
+                                "call id %s", callId);
+                        return;
+                    }
 
-                // Make sure that there's at least one valid call. For remote connections
-                // we'll get a add conference msg from both the remote connection service
-                // and from the real connection service.
-                boolean hasValidCalls = false;
-                for (String connId : parcelableConference.getConnectionIds()) {
-                    if (mCallIdMapper.getCall(connId) != null) {
-                        hasValidCalls = true;
+                    // Make sure that there's at least one valid call. For remote connections
+                    // we'll get a add conference msg from both the remote connection service
+                    // and from the real connection service.
+                    boolean hasValidCalls = false;
+                    for (String connId : parcelableConference.getConnectionIds()) {
+                        if (mCallIdMapper.getCall(connId) != null) {
+                            hasValidCalls = true;
+                        }
+                    }
+                    // But don't bail out if the connection count is 0, because that is a valid
+                    // IMS conference state.
+                    if (!hasValidCalls && parcelableConference.getConnectionIds().size() > 0) {
+                        Log.d(this, "Attempting to add a conference with no valid calls");
+                        return;
+                    }
+
+                    // need to create a new Call
+                    PhoneAccountHandle phAcc = null;
+                    if (parcelableConference != null &&
+                            parcelableConference.getPhoneAccount() != null) {
+                        phAcc = parcelableConference.getPhoneAccount();
+                    }
+                    Call conferenceCall = mCallsManager.createConferenceCall(
+                            phAcc, parcelableConference);
+                    mCallIdMapper.addCall(conferenceCall, callId);
+                    conferenceCall.setConnectionService(ConnectionServiceWrapper.this);
+
+                    Log.d(this, "adding children to conference %s phAcc %s",
+                            parcelableConference.getConnectionIds(), phAcc);
+                    for (String connId : parcelableConference.getConnectionIds()) {
+                        Call childCall = mCallIdMapper.getCall(connId);
+                        Log.d(this, "found child: %s", connId);
+                        if (childCall != null) {
+                            childCall.setParentCall(conferenceCall);
+                        }
                     }
                 }
-                // But don't bail out if the connection count is 0, because that is a valid
-                // IMS conference state.
-                if (!hasValidCalls && parcelableConference.getConnectionIds().size() > 0) {
-                    Log.d(this, "Attempting to add a conference with no valid calls");
-                    return;
-                }
-
-                // need to create a new Call
-                PhoneAccountHandle phAcc = null;
-                if (parcelableConference != null &&
-                        parcelableConference.getPhoneAccount() != null) {
-                    phAcc = parcelableConference.getPhoneAccount();
-                }
-                Call conferenceCall = mCallsManager.createConferenceCall(
-                        phAcc, parcelableConference);
-                mCallIdMapper.addCall(conferenceCall, callId);
-                conferenceCall.setConnectionService(ConnectionServiceWrapper.this);
-
-                Log.d(this, "adding children to conference %s phAcc %s",
-                        parcelableConference.getConnectionIds(), phAcc);
-                for (String connId : parcelableConference.getConnectionIds()) {
-                    Call childCall = mCallIdMapper.getCall(connId);
-                    Log.d(this, "found child: %s", connId);
-                    if (childCall != null) {
-                        childCall.setParentCall(conferenceCall);
-                    }
-                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void onPostDialWait(String callId, String remaining) throws RemoteException {
-            synchronized (mLock) {
-                logIncoming("onPostDialWait %s %s", callId, remaining);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.onPostDialWait(remaining);
-                    } else {
-                        //Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("onPostDialWait %s %s", callId, remaining);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            call.onPostDialWait(remaining);
+                        } else {
+                            // Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void onPostDialChar(String callId, char nextChar) throws RemoteException {
-            synchronized (mLock) {
-                logIncoming("onPostDialChar %s %s", callId, nextChar);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.onPostDialChar(nextChar);
-                    } else {
-                        //Log.w(this, "onPostDialChar, unknown call id: %s", args.arg1);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("onPostDialChar %s %s", callId, nextChar);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            call.onPostDialChar(nextChar);
+                        } else {
+                            // Log.w(this, "onPostDialChar, unknown call id: %s", args.arg1);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
-            synchronized (mLock) {
-                logIncoming("queryRemoteConnectionServices %s", callback);
-                ConnectionServiceWrapper.this.queryRemoteConnectionServices(callback);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("queryRemoteConnectionServices %s", callback);
+                    ConnectionServiceWrapper.this.queryRemoteConnectionServices(callback);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setVideoState(String callId, int videoState) {
-            synchronized (mLock) {
-                logIncoming("setVideoState %s %d", callId, videoState);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.setVideoState(videoState);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setVideoState %s %d", callId, videoState);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            call.setVideoState(videoState);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setIsVoipAudioMode(String callId, boolean isVoip) {
-            synchronized (mLock) {
-                logIncoming("setIsVoipAudioMode %s %b", callId, isVoip);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.setIsVoipAudioMode(isVoip);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setIsVoipAudioMode %s %b", callId, isVoip);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            call.setIsVoipAudioMode(isVoip);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setStatusHints(String callId, StatusHints statusHints) {
-            synchronized (mLock) {
-                logIncoming("setStatusHints %s %s", callId, statusHints);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.setStatusHints(statusHints);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setStatusHints %s %s", callId, statusHints);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            call.setStatusHints(statusHints);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setAddress(String callId, Uri address, int presentation) {
-            synchronized (mLock) {
-                logIncoming("setAddress %s %s %d", callId, address, presentation);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.setHandle(address, presentation);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setAddress %s %s %d", callId, address, presentation);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            call.setHandle(address, presentation);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setCallerDisplayName(
                 String callId, String callerDisplayName, int presentation) {
-            synchronized (mLock) {
-                logIncoming("setCallerDisplayName %s %s %d", callId, callerDisplayName, presentation);
-                if (mCallIdMapper.isValidCallId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null) {
-                        call.setCallerDisplayName(callerDisplayName, presentation);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setCallerDisplayName %s %s %d", callId, callerDisplayName,
+                            presentation);
+                    if (mCallIdMapper.isValidCallId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            call.setCallerDisplayName(callerDisplayName, presentation);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void setConferenceableConnections(
                 String callId, List<String> conferenceableCallIds) {
-            synchronized (mLock) {
-                logIncoming("setConferenceableConnections %s %s", callId, conferenceableCallIds);
-                if (mCallIdMapper.isValidCallId(callId) ||
-                        mCallIdMapper.isValidConferenceId(callId)) {
-                    Call call = mCallIdMapper.getCall(callId);
-                    if (call != null ){
-                        List<Call> conferenceableCalls =
-                                new ArrayList<>(conferenceableCallIds.size());
-                        for (String otherId : conferenceableCallIds) {
-                            Call otherCall = mCallIdMapper.getCall(otherId);
-                            if (otherCall != null && otherCall != call) {
-                                conferenceableCalls.add(otherCall);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("setConferenceableConnections %s %s", callId,
+                            conferenceableCallIds);
+                    if (mCallIdMapper.isValidCallId(callId) ||
+                            mCallIdMapper.isValidConferenceId(callId)) {
+                        Call call = mCallIdMapper.getCall(callId);
+                        if (call != null) {
+                            List<Call> conferenceableCalls =
+                                    new ArrayList<>(conferenceableCallIds.size());
+                            for (String otherId : conferenceableCallIds) {
+                                Call otherCall = mCallIdMapper.getCall(otherId);
+                                if (otherCall != null && otherCall != call) {
+                                    conferenceableCalls.add(otherCall);
+                                }
                             }
+                            call.setConferenceableCalls(conferenceableCalls);
                         }
-                        call.setConferenceableCalls(conferenceableCalls);
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
         public void addExistingConnection(String callId, ParcelableConnection connection) {
-            synchronized (mLock) {
-                logIncoming("addExistingConnection  %s %s", callId, connection);
-                Call existingCall = mCallsManager
-                        .createCallForExistingConnection(callId, connection);
-                mCallIdMapper.addCall(existingCall, callId);
-                existingCall.setConnectionService(ConnectionServiceWrapper.this);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    logIncoming("addExistingConnection  %s %s", callId, connection);
+                    Call existingCall = mCallsManager
+                            .createCallForExistingConnection(callId, connection);
+                    mCallIdMapper.addCall(existingCall, callId);
+                    existingCall.setConnectionService(ConnectionServiceWrapper.this);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
     }
@@ -428,7 +541,7 @@
     private final CallIdMapper mCallIdMapper = new CallIdMapper("ConnectionService");
     private final Map<String, CreateConnectionResponse> mPendingResponses = new HashMap<>();
 
-    private Binder mBinder = new Binder();
+    private Binder2 mBinder = new Binder2();
     private IConnectionService mServiceInterface;
     private final ConnectionServiceRepository mConnectionServiceRepository;
     private final PhoneAccountRegistrar mPhoneAccountRegistrar;
diff --git a/src/com/android/server/telecom/CreateConnectionTimeout.java b/src/com/android/server/telecom/CreateConnectionTimeout.java
index 1878177..553552b 100644
--- a/src/com/android/server/telecom/CreateConnectionTimeout.java
+++ b/src/com/android/server/telecom/CreateConnectionTimeout.java
@@ -44,6 +44,7 @@
 
     CreateConnectionTimeout(Context context, PhoneAccountRegistrar phoneAccountRegistrar,
             ConnectionServiceWrapper service, Call call) {
+        super(Looper.getMainLooper());
         mContext = context;
         mPhoneAccountRegistrar = phoneAccountRegistrar;
         mConnectionService = service;
diff --git a/src/com/android/server/telecom/InCallAdapter.java b/src/com/android/server/telecom/InCallAdapter.java
index d84c87e..9239288 100644
--- a/src/com/android/server/telecom/InCallAdapter.java
+++ b/src/com/android/server/telecom/InCallAdapter.java
@@ -16,11 +16,9 @@
 
 package com.android.server.telecom;
 
-import android.os.Handler;
-import android.os.Message;
+import android.os.Binder;
 import android.telecom.PhoneAccountHandle;
 
-import com.android.internal.os.SomeArgs;
 import com.android.internal.telecom.IInCallAdapter;
 
 /**
@@ -34,7 +32,8 @@
     private final TelecomSystem.SyncRoot mLock;
 
     /** Persists the specified parameters. */
-    public InCallAdapter(CallsManager callsManager, CallIdMapper callIdMapper, TelecomSystem.SyncRoot lock) {
+    public InCallAdapter(CallsManager callsManager, CallIdMapper callIdMapper,
+            TelecomSystem.SyncRoot lock) {
         mCallsManager = callsManager;
         mCallIdMapper = callIdMapper;
         mLock = lock;
@@ -42,221 +41,306 @@
 
     @Override
     public void answerCall(String callId, int videoState) {
-        synchronized (mLock) {
-            Log.d(this, "answerCall(%s,%d)", callId, videoState);
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    mCallsManager.answerCall(call, videoState);
-                } else {
-                    Log.w(this, "answerCall, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                Log.d(this, "answerCall(%s,%d)", callId, videoState);
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.answerCall(call, videoState);
+                    } else {
+                        Log.w(this, "answerCall, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
-        synchronized (this) {
-            Log.d(this, "rejectCall(%s,%b,%s)", callId, rejectWithMessage, textMessage);
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    mCallsManager.rejectCall(call, rejectWithMessage, textMessage);
-                } else {
-                    Log.w(this, "setRingback, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                Log.d(this, "rejectCall(%s,%b,%s)", callId, rejectWithMessage, textMessage);
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.rejectCall(call, rejectWithMessage, textMessage);
+                    } else {
+                        Log.w(this, "setRingback, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void playDtmfTone(String callId, char digit) {
-        synchronized (mLock) {
-            Log.d(this, "playDtmfTone(%s,%c)", callId, digit);
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    mCallsManager.playDtmfTone(call, digit);
-                } else {
-                    Log.w(this, "playDtmfTone, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                Log.d(this, "playDtmfTone(%s,%c)", callId, digit);
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.playDtmfTone(call, digit);
+                    } else {
+                        Log.w(this, "playDtmfTone, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void stopDtmfTone(String callId) {
-        synchronized (mLock) {
-            Log.d(this, "stopDtmfTone(%s)", callId);
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    mCallsManager.stopDtmfTone(call);
-                } else {
-                    Log.w(this, "stopDtmfTone, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                Log.d(this, "stopDtmfTone(%s)", callId);
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.stopDtmfTone(call);
+                    } else {
+                        Log.w(this, "stopDtmfTone, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void postDialContinue(String callId, boolean proceed) {
-        synchronized (mLock) {
-            Log.d(this, "postDialContinue(%s)", callId);
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    mCallsManager.postDialContinue(call, proceed);
-                } else {
-                    Log.w(this, "postDialContinue, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                Log.d(this, "postDialContinue(%s)", callId);
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.postDialContinue(call, proceed);
+                    } else {
+                        Log.w(this, "postDialContinue, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void disconnectCall(String callId) {
-        synchronized (mLock) {
-            Log.v(this, "disconnectCall: %s", callId);
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    mCallsManager.disconnectCall(call);
-                } else {
-                    Log.w(this, "disconnectCall, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                Log.v(this, "disconnectCall: %s", callId);
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.disconnectCall(call);
+                    } else {
+                        Log.w(this, "disconnectCall, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void holdCall(String callId) {
-        synchronized (mLock) {
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    mCallsManager.holdCall(call);
-                } else {
-                    Log.w(this, "holdCall, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.holdCall(call);
+                    } else {
+                        Log.w(this, "holdCall, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void unholdCall(String callId) {
-        synchronized (mLock) {
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    mCallsManager.unholdCall(call);
-                } else {
-                    Log.w(this, "unholdCall, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.unholdCall(call);
+                    } else {
+                        Log.w(this, "unholdCall, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle,
             boolean setDefault) {
-        synchronized (mLock) {
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    mCallsManager.phoneAccountSelected(call, accountHandle, setDefault);
-                } else {
-                    Log.w(this, "phoneAccountSelected, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        mCallsManager.phoneAccountSelected(call, accountHandle, setDefault);
+                    } else {
+                        Log.w(this, "phoneAccountSelected, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void mute(boolean shouldMute) {
-        synchronized (mLock) {
-            mCallsManager.mute(shouldMute);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                mCallsManager.mute(shouldMute);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void setAudioRoute(int route) {
-        synchronized (mLock) {
-            mCallsManager.setAudioRoute(route);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                mCallsManager.setAudioRoute(route);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void conference(String callId, String otherCallId) {
-        synchronized (mLock) {
-            if (mCallIdMapper.isValidCallId(callId) &&
-                    mCallIdMapper.isValidCallId(otherCallId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                Call otherCall = mCallIdMapper.getCall(otherCallId);
-                if (call != null && otherCall != null) {
-                    mCallsManager.conference(call, otherCall);
-                } else {
-                    Log.w(this, "conference, unknown call id: %s or %s", callId, otherCallId);
-                }
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                if (mCallIdMapper.isValidCallId(callId) &&
+                        mCallIdMapper.isValidCallId(otherCallId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    Call otherCall = mCallIdMapper.getCall(otherCallId);
+                    if (call != null && otherCall != null) {
+                        mCallsManager.conference(call, otherCall);
+                    } else {
+                        Log.w(this, "conference, unknown call id: %s or %s", callId, otherCallId);
+                    }
 
+                }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void splitFromConference(String callId) {
-        synchronized (mLock) {
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    call.splitFromConference();
-                } else {
-                    Log.w(this, "splitFromConference, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.splitFromConference();
+                    } else {
+                        Log.w(this, "splitFromConference, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void mergeConference(String callId) {
-        synchronized (mLock) {
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    call.mergeConference();
-                } else {
-                    Log.w(this, "mergeConference, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.mergeConference();
+                    } else {
+                        Log.w(this, "mergeConference, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void swapConference(String callId) {
-        synchronized (mLock) {
-            if (mCallIdMapper.isValidCallId(callId)) {
-                Call call = mCallIdMapper.getCall(callId);
-                if (call != null) {
-                    call.swapConference();
-                } else {
-                    Log.w(this, "swapConference, unknown call id: %s", callId);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                if (mCallIdMapper.isValidCallId(callId)) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.swapConference();
+                    } else {
+                        Log.w(this, "swapConference, unknown call id: %s", callId);
+                    }
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void turnOnProximitySensor() {
-        synchronized (mLock) {
-            mCallsManager.turnOnProximitySensor();
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                mCallsManager.turnOnProximitySensor();
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
     public void turnOffProximitySensor(boolean screenOnImmediately) {
-        synchronized (mLock) {
-            mCallsManager.turnOffProximitySensor(screenOnImmediately);
+        long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                mCallsManager.turnOffProximitySensor(screenOnImmediately);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 }
diff --git a/src/com/android/server/telecom/ServiceBinder.java b/src/com/android/server/telecom/ServiceBinder.java
index 05882ab..f737f7f 100644
--- a/src/com/android/server/telecom/ServiceBinder.java
+++ b/src/com/android/server/telecom/ServiceBinder.java
@@ -56,7 +56,7 @@
     /**
      * Helper class to perform on-demand binding.
      */
-    final class Binder {
+    final class Binder2 {
         /**
          * Performs an asynchronous bind to the service (only if not already bound) and executes the
          * specified callback.
