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

Commit 57d86939 authored by Pranav Madapurmath's avatar Pranav Madapurmath Committed by Android (Google) Code Review
Browse files

Merge "Terminate ICS (for BT) after the disconnect tone finishes playing."

parents 62738307 1cd2e8b3
Loading
Loading
Loading
Loading
+48 −2
Original line number Diff line number Diff line
@@ -32,8 +32,10 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

/**
 * A unified virtual device providing a means of voice (and other) communication on a device.
@@ -148,6 +150,14 @@ public final class Phone {

    private final Object mLock = new Object();

    // Future used to delay terminating the InCallService before the call disconnect tone
    // finishes playing.
    private static Map<String, CompletableFuture<Void>> sDisconnectedToneFutures = new ArrayMap<>();

    // Timeout value to be used to ensure future completion for sDisconnectedToneFutures. This is
    // set to 4 seconds to account for the exceptional case (TONE_CONGESTION).
    private static final int DISCONNECTED_TONE_TIMEOUT = 4000;

    Phone(InCallAdapter adapter, String callingPackage, int targetSdkVersion) {
        mInCallAdapter = adapter;
        mCallingPackage = callingPackage;
@@ -456,9 +466,45 @@ public final class Phone {
    }

    private void fireCallRemoved(Call call) {
        String callId = call.internalGetCallId();
        CompletableFuture<Void> disconnectedToneFuture = initializeDisconnectedToneFuture(callId);
        // delay the InCallService termination until after the disconnect tone finishes playing
        disconnectedToneFuture.thenRunAsync(() -> {
            for (Listener listener : mListeners) {
                listener.onCallRemoved(this, call);
            }
            // clean up the future after
            sDisconnectedToneFutures.remove(callId);
        });
    }

    /**
     * Initialize disconnect tone future to be used in delaying ICS termination.
     *
     * @return CompletableFuture to delay InCallService termination until after the disconnect tone
     * finishes playing. A timeout of 4s is used to handle the use case when we play
     * TONE_CONGESTION and to ensure completion so that we don't block the removal of the service.
     */
    private CompletableFuture<Void> initializeDisconnectedToneFuture(String callId) {
        // create the future and map (sDisconnectedToneFutures) it to the corresponding call id
        CompletableFuture<Void> disconnectedToneFuture = new CompletableFuture<Void>()
                .completeOnTimeout(null, DISCONNECTED_TONE_TIMEOUT, TimeUnit.MILLISECONDS);
        // we should not encounter duplicate insertions since call ids are unique
        sDisconnectedToneFutures.put(callId, disconnectedToneFuture);
        return disconnectedToneFuture;
    }

    /**
     * Completes disconnected tone future with passed in result.
     * @hide
     * @return true if future was completed, false otherwise
     */
    public static boolean completeDisconnectedToneFuture(String callId) {
        if (sDisconnectedToneFutures.containsKey(callId)) {
            sDisconnectedToneFutures.get(callId).complete(null);
            return true;
        }
        return false;
    }

    private void fireCallAudioStateChanged(CallAudioState audioState) {