Use the Telecom lock in Telecom.Runnable

To prevent deadlocks in Telecom when using Session Runnables, we will
now lock on the main Telecom Lock instead of an independent lock inside
of Telecom.

Bug: 31076766
Change-Id: I993d7f2e8b077f89daef72ce1ca7b7fad2ad8823
(cherry picked from commit f5e066609d0acc7ff53752bd6b9e3f2634bd0746)
diff --git a/src/com/android/server/telecom/BluetoothManager.java b/src/com/android/server/telecom/BluetoothManager.java
index 3819879..d31c69d 100644
--- a/src/com/android/server/telecom/BluetoothManager.java
+++ b/src/com/android/server/telecom/BluetoothManager.java
@@ -121,7 +121,7 @@
 
     private BluetoothHeadsetProxy mBluetoothHeadset;
     private long mBluetoothConnectionRequestTime;
-    private final Runnable mBluetoothConnectionTimeout = new Runnable("BM.cBA") {
+    private final Runnable mBluetoothConnectionTimeout = new Runnable("BM.cBA", null /*lock*/) {
         @Override
         public void loggedRun() {
             if (!isBluetoothAudioConnected()) {
@@ -132,7 +132,7 @@
         }
     };
 
-    private final Runnable mRetryConnectAudio = new Runnable("BM.rCA") {
+    private final Runnable mRetryConnectAudio = new Runnable("BM.rCA", null /*lock*/) {
         @Override
         public void loggedRun() {
             Log.i(this, "Retrying connecting to bluetooth audio.");
diff --git a/src/com/android/server/telecom/CallerInfoLookupHelper.java b/src/com/android/server/telecom/CallerInfoLookupHelper.java
index 4561c1c..0dec317 100644
--- a/src/com/android/server/telecom/CallerInfoLookupHelper.java
+++ b/src/com/android/server/telecom/CallerInfoLookupHelper.java
@@ -110,7 +110,7 @@
             }
         }
 
-        mHandler.post(new Runnable("CILH.sL") {
+        mHandler.post(new Runnable("CILH.sL", mLock) {
             @Override
             public void loggedRun() {
                 Session continuedSession = Log.createSubsession();
@@ -160,7 +160,7 @@
     }
 
     private void startPhotoLookup(final Uri handle, final Uri contactPhotoUri) {
-        mHandler.post(new Runnable("CILH.sPL") {
+        mHandler.post(new Runnable("CILH.sPL", mLock) {
             @Override
             public void loggedRun() {
                 Session continuedSession = Log.createSubsession();
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index d7961b8..8df77cf 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -446,15 +446,12 @@
 
             mDtmfLocalTonePlayer.playTone(call, nextChar);
 
-            // TODO: Create a LockedRunnable class that does the synchronization automatically.
-            mStopTone = new Runnable("CM.oPDC") {
+            mStopTone = new Runnable("CM.oPDC", mLock) {
                 @Override
                 public void loggedRun() {
-                    synchronized (mLock) {
-                        // Set a timeout to stop the tone in case there isn't another tone to
-                        // follow.
-                        mDtmfLocalTonePlayer.stopTone(call);
-                    }
+                    // Set a timeout to stop the tone in case there isn't another tone to
+                    // follow.
+                    mDtmfLocalTonePlayer.stopTone(call);
                 }
             };
             mHandler.postDelayed(mStopTone.prepare(),
@@ -508,14 +505,12 @@
     @Override
     public boolean onCanceledViaNewOutgoingCallBroadcast(final Call call) {
         mPendingCallsToDisconnect.add(call);
-        mHandler.postDelayed(new Runnable("CM.oCVNOCB") {
+        mHandler.postDelayed(new Runnable("CM.oCVNOCB", mLock) {
             @Override
             public void loggedRun() {
-                synchronized (mLock) {
-                    if (mPendingCallsToDisconnect.remove(call)) {
-                        Log.i(this, "Delayed disconnection of call: %s", call);
-                        call.disconnect();
-                    }
+                if (mPendingCallsToDisconnect.remove(call)) {
+                    Log.i(this, "Delayed disconnection of call: %s", call);
+                    call.disconnect();
                 }
             }
         }.prepare(), Timeouts.getNewOutgoingCallCancelMillis(mContext.getContentResolver()));
diff --git a/src/com/android/server/telecom/CreateConnectionTimeout.java b/src/com/android/server/telecom/CreateConnectionTimeout.java
index 9bfeb7f..8bc3373 100644
--- a/src/com/android/server/telecom/CreateConnectionTimeout.java
+++ b/src/com/android/server/telecom/CreateConnectionTimeout.java
@@ -40,7 +40,7 @@
 
     CreateConnectionTimeout(Context context, PhoneAccountRegistrar phoneAccountRegistrar,
             ConnectionServiceWrapper service, Call call) {
-        super("CCT");
+        super("CCT", null /*lock*/);
         mContext = context;
         mPhoneAccountRegistrar = phoneAccountRegistrar;
         mConnectionService = service;
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 5e1b887..8b69245 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -661,14 +661,12 @@
              *  give them enough time to process all the pending messages.
              */
             Handler handler = new Handler(Looper.getMainLooper());
-            handler.postDelayed(new Runnable("ICC.oCR") {
+            handler.postDelayed(new Runnable("ICC.oCR", mLock) {
                 @Override
                 public void loggedRun() {
-                    synchronized (mLock) {
-                        // Check again to make sure there are no active calls.
-                        if (mCallsManager.getCalls().isEmpty()) {
-                            unbindFromServices();
-                        }
+                    // Check again to make sure there are no active calls.
+                    if (mCallsManager.getCalls().isEmpty()) {
+                        unbindFromServices();
                     }
                 }
             }.prepare(), Timeouts.getCallRemoveUnbindInCallServicesDelay(
diff --git a/src/com/android/server/telecom/InCallTonePlayer.java b/src/com/android/server/telecom/InCallTonePlayer.java
index 9b97087..e0b0dc0 100644
--- a/src/com/android/server/telecom/InCallTonePlayer.java
+++ b/src/com/android/server/telecom/InCallTonePlayer.java
@@ -297,15 +297,13 @@
 
     private void cleanUpTonePlayer() {
         // Release focus on the main thread.
-        mMainThreadHandler.post(new Runnable("ICTP.cUTP") {
+        mMainThreadHandler.post(new Runnable("ICTP.cUTP", mLock) {
             @Override
             public void loggedRun() {
-                synchronized (mLock) {
-                    if (sTonesPlaying == 0) {
-                        Log.wtf(this, "Over-releasing focus for tone player.");
-                    } else if (--sTonesPlaying == 0) {
-                        mCallAudioManager.setIsTonePlaying(false);
-                    }
+                if (sTonesPlaying == 0) {
+                    Log.wtf(this, "Over-releasing focus for tone player.");
+                } else if (--sTonesPlaying == 0) {
+                    mCallAudioManager.setIsTonePlaying(false);
                 }
             }
         }.prepare());
diff --git a/src/com/android/server/telecom/Runnable.java b/src/com/android/server/telecom/Runnable.java
index 41415fd..c7ace72 100644
--- a/src/com/android/server/telecom/Runnable.java
+++ b/src/com/android/server/telecom/Runnable.java
@@ -24,7 +24,7 @@
 
     private Session mSubsession;
     private final String mSubsessionName;
-    private final Object mLock = new Object();
+    private final Object mLock;
     private final java.lang.Runnable mRunnable = new java.lang.Runnable() {
             @Override
             public void run() {
@@ -42,7 +42,18 @@
             }
         };
 
-    public Runnable(String subsessionName) {
+    /**
+     * Creates a new Telecom Runnable that incorporates Session Logging into it. Useful for carrying
+     * Logging Sessions through different threads as well as through handlers.
+     * @param subsessionName The name that will be used in the Logs to mark this Session
+     * @param lock The synchronization lock that will be used to lock loggedRun().
+     */
+    public Runnable(String subsessionName, Object lock) {
+        if (lock == null) {
+            mLock = new Object();
+        } else {
+            mLock = lock;
+        }
         mSubsessionName = subsessionName;
     }
 
@@ -78,7 +89,8 @@
     }
 
     /**
-     * The method that will be run in the handler/thread.
+     * The method that will be run in the handler/thread. This method will be called with mLock
+     * held.
      */
     abstract public void loggedRun();
 
diff --git a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
index 4685ec0..6e0c684 100644
--- a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
+++ b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
@@ -70,17 +70,15 @@
         for (CallFilter filter : mFilters) {
             filter.startFilterLookup(mCall, this);
         }
-        mHandler.postDelayed(new Runnable("ICF.pFTO") { // performFiltering time-out
+        // synchronized to prevent a race on mResult and to enter into Telecom.
+        mHandler.postDelayed(new Runnable("ICF.pFTO", mTelecomLock) { // performFiltering time-out
             @Override
             public void loggedRun() {
-                // synchronized to prevent a race on mResult and to enter into Telecom.
-                synchronized (mTelecomLock) {
-                    if (mIsPending) {
-                        Log.i(IncomingCallFilter.this, "Call filtering has timed out.");
-                        Log.event(mCall, Log.Events.FILTERING_TIMED_OUT);
-                        mListener.onCallFilteringComplete(mCall, mResult);
-                        mIsPending = false;
-                    }
+                if (mIsPending) {
+                    Log.i(IncomingCallFilter.this, "Call filtering has timed out.");
+                    Log.event(mCall, Log.Events.FILTERING_TIMED_OUT);
+                    mListener.onCallFilteringComplete(mCall, mResult);
+                    mIsPending = false;
                 }
             }
         }.prepare(), mTimeoutsAdapter.getCallScreeningTimeoutMillis(mContext.getContentResolver()));
@@ -91,16 +89,14 @@
             mNumPendingFilters--;
             mResult = result.combine(mResult);
             if (mNumPendingFilters == 0) {
-                mHandler.post(new Runnable("ICF.oCFC") {
+                // synchronized on mTelecomLock to enter into Telecom.
+                mHandler.post(new Runnable("ICF.oCFC", mTelecomLock) {
                     @Override
                     public void loggedRun() {
-                        // synchronized to enter into Telecom.
-                        synchronized (mTelecomLock) {
-                            if (mIsPending) {
-                                Log.event(mCall, Log.Events.FILTERING_COMPLETED, mResult);
-                                mListener.onCallFilteringComplete(mCall, mResult);
-                                mIsPending = false;
-                            }
+                        if (mIsPending) {
+                            Log.event(mCall, Log.Events.FILTERING_COMPLETED, mResult);
+                            mListener.onCallFilteringComplete(mCall, mResult);
+                            mIsPending = false;
                         }
                     }
                 }.prepare());
diff --git a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
index 3786724..89ef95f 100644
--- a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
+++ b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
@@ -175,7 +175,7 @@
     }
 
     private void markMissedCallsAsRead(final UserHandle userHandle) {
-        AsyncTask.execute(new Runnable("MCNI.mMCAR") {
+        AsyncTask.execute(new Runnable("MCNI.mMCAR", null /*lock*/) {
             @Override
             public void loggedRun() {
                 // Clear the list of new missed calls from the call log.