Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 75c3dc9b authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Block Binder thread until incoming call process completes

Ensure that we block the incoming binder thread while setting
up incoming calls. Otherwise, race conditions occur between setting
up incoming call state listeners and receiving state updates on
that listener interface. This causes state updates to be missed
in some scenarios.

Bug: 215302449
Test: manual auto-reject scenario testing (receive two incoming calls)
Change-Id: If8ca66544126664ff5f9e4eaaa903dc5d57326b5
parent 5ecb8b7d
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -137,6 +137,9 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
@@ -315,8 +318,10 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {

        @Override
        public void onIncomingCall(IImsCallSession c, Bundle extras) {
            TelephonyUtils.runWithCleanCallingIdentity(()-> processIncomingCall(c, extras),
                    mExecutor);
            // we want to ensure we block this binder thread until incoming call setup completes
            // as to avoid race conditions where the ImsService tries to update the state of the
            // call before the listeners have been attached.
            executeAndWait(()-> processIncomingCall(c, extras));
        }

        @Override
@@ -330,6 +335,19 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
                }
            }, mExecutor);
        }

        /**
         * Schedule the given Runnable on mExecutor and block this thread until it finishes.
         * @param r The Runnable to run.
         */
        private void executeAndWait(Runnable r) {
            try {
                CompletableFuture.runAsync(
                        () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor).join();
            } catch (CancellationException | CompletionException e) {
                logw("Binder - exception: " + e.getMessage());
            }
        }
    }

    /**