Merge "Fix problem with AsyncQueryHandler"
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.