Merge "Fix problem with AsyncQueryHandler"
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 549fa60..149ffe9 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -22,6 +22,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Trace;
 import android.provider.ContactsContract.Contacts;
 import android.telecom.CallState;
@@ -175,7 +176,9 @@
     private final Runnable mDirectToVoicemailRunnable = new Runnable() {
         @Override
         public void run() {
-            processDirectToVoicemail();
+            synchronized (mLock) {
+                processDirectToVoicemail();
+            }
         }
     };
 
@@ -209,7 +212,7 @@
 
     private PhoneAccountHandle mTargetPhoneAccountHandle;
 
-    private final Handler mHandler = new Handler();
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
 
     private final List<Call> mConferenceableCalls = new ArrayList<>();
 
@@ -303,6 +306,7 @@
     private final ContactsAsyncHelper mContactsAsyncHelper;
     private final Context mContext;
     private final CallsManager mCallsManager;
+    private final TelecomSystem.SyncRoot mLock;
 
     private boolean mWasConferencePreviouslyMerged = false;
 
@@ -331,6 +335,7 @@
     public Call(
             Context context,
             CallsManager callsManager,
+            TelecomSystem.SyncRoot lock,
             ConnectionServiceRepository repository,
             ContactsAsyncHelper contactsAsyncHelper,
             Uri handle,
@@ -342,6 +347,7 @@
         mState = isConference ? CallState.ACTIVE : CallState.NEW;
         mContext = context;
         mCallsManager = callsManager;
+        mLock = lock;
         mRepository = repository;
         mContactsAsyncHelper = contactsAsyncHelper;
         setHandle(handle);
@@ -372,6 +378,7 @@
     Call(
             Context context,
             CallsManager callsManager,
+            TelecomSystem.SyncRoot lock,
             ConnectionServiceRepository repository,
             ContactsAsyncHelper contactsAsyncHelper,
             Uri handle,
@@ -381,7 +388,7 @@
             boolean isIncoming,
             boolean isConference,
             long connectTimeMillis) {
-        this(context, callsManager, repository, contactsAsyncHelper, handle, gatewayInfo,
+        this(context, callsManager, lock, repository, contactsAsyncHelper, handle, gatewayInfo,
                 connectionManagerPhoneAccountHandle, targetPhoneAccountHandle, isIncoming,
                 isConference);
 
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 5b5e96e..aed592d 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.media.AudioManager;
+import android.os.Binder;
 import android.telecom.AudioState;
 import android.telecom.CallState;
 
@@ -443,8 +444,13 @@
         // it a hint about the purpose of our focus.
         if (mAudioFocusStreamType != stream) {
             Log.v(this, "requesting audio focus for stream: %d", stream);
-            mAudioManager.requestAudioFocusForCall(stream,
-                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+            long token = Binder.clearCallingIdentity();
+            try {
+                mAudioManager.requestAudioFocusForCall(stream,
+                        AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
         mAudioFocusStreamType = stream;
 
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index ffaf948..bd60116 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -20,6 +20,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Trace;
 import android.provider.CallLog.Calls;
 import android.telecom.AudioState;
@@ -128,7 +129,7 @@
     private final Set<Call> mLocallyDisconnectingCalls = new HashSet<>();
     private final Set<Call> mPendingCallsToDisconnect = new HashSet<>();
     /* Handler tied to thread in which CallManager was initialized. */
-    private final Handler mHandler = new Handler();
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
 
     private boolean mCanAddCall = true;
 
@@ -431,6 +432,7 @@
         Call call = new Call(
                 mContext,
                 this,
+                mLock,
                 mConnectionServiceRepository,
                 mContactsAsyncHelper,
                 handle,
@@ -452,6 +454,7 @@
         Call call = new Call(
                 mContext,
                 this,
+                mLock,
                 mConnectionServiceRepository,
                 mContactsAsyncHelper,
                 handle,
@@ -490,6 +493,7 @@
         return new Call(
                 mContext,
                 this,
+                mLock,
                 mConnectionServiceRepository,
                 mContactsAsyncHelper,
                 handle,
@@ -1079,6 +1083,7 @@
         Call call = new Call(
                 mContext,
                 this,
+                mLock,
                 mConnectionServiceRepository,
                 mContactsAsyncHelper,
                 null /* handle */,
@@ -1427,6 +1432,7 @@
         Call call = new Call(
                 mContext,
                 this,
+                mLock,
                 mConnectionServiceRepository,
                 mContactsAsyncHelper,
                 connection.getHandle() /* handle */,
diff --git a/src/com/android/server/telecom/CreateConnectionTimeout.java b/src/com/android/server/telecom/CreateConnectionTimeout.java
index 78edfe9..553552b 100644
--- a/src/com/android/server/telecom/CreateConnectionTimeout.java
+++ b/src/com/android/server/telecom/CreateConnectionTimeout.java
@@ -20,6 +20,7 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.os.Handler;
+import android.os.Looper;
 import android.telecom.CallState;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.TelephonyManager;
@@ -37,7 +38,7 @@
     private final PhoneAccountRegistrar mPhoneAccountRegistrar;
     private final ConnectionServiceWrapper mConnectionService;
     private final Call mCall;
-    private final Handler mHandler = new Handler();
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
     private boolean mIsRegistered;
     private boolean mIsCallTimedOut;
 
diff --git a/src/com/android/server/telecom/RespondViaSmsManager.java b/src/com/android/server/telecom/RespondViaSmsManager.java
index 98ba3b4..e5a2042 100644
--- a/src/com/android/server/telecom/RespondViaSmsManager.java
+++ b/src/com/android/server/telecom/RespondViaSmsManager.java
@@ -28,6 +28,7 @@
 import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
 import android.telecom.Response;
 import android.telephony.SubscriptionManager;
@@ -46,7 +47,7 @@
     private final CallsManager mCallsManager;
     private final TelecomSystem.SyncRoot mLock;
 
-    private final Handler mHandler = new Handler() {
+    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
diff --git a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
index 9022d27..bb1faed 100644
--- a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
+++ b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
@@ -41,6 +41,7 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.Binder;
 import android.os.UserHandle;
 import android.provider.CallLog.Calls;
 import android.telecom.CallState;
@@ -195,15 +196,25 @@
         configureLedOnNotification(notification);
 
         Log.i(this, "Adding missed call notification for %s.", call);
-        mNotificationManager.notifyAsUser(
-                null /* tag */ , MISSED_CALL_NOTIFICATION_ID, notification, UserHandle.CURRENT);
+        long token = Binder.clearCallingIdentity();
+        try {
+            mNotificationManager.notifyAsUser(
+                    null /* tag */, MISSED_CALL_NOTIFICATION_ID, notification, UserHandle.CURRENT);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     /** Cancels the "missed call" notification. */
     private void cancelMissedCallNotification() {
         // Reset the number of missed calls to 0.
         mMissedCallCount = 0;
-        mNotificationManager.cancel(MISSED_CALL_NOTIFICATION_ID);
+        long token = Binder.clearCallingIdentity();
+        try {
+            mNotificationManager.cancel(MISSED_CALL_NOTIFICATION_ID);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     /**
@@ -328,7 +339,7 @@
                             synchronized (lock) {
 
                                 // Convert the data to a call object
-                                Call call = new Call(mContext, callsManager,
+                                Call call = new Call(mContext, callsManager, lock,
                                         null, contactsAsyncHelper, null, null, null, null, true,
                                         false);
                                 call.setDisconnectCause(