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

Commit 9bfb94ba authored by Chen Chen's avatar Chen Chen
Browse files

BluetoothInCallService: Wait for disconnect tone at onCallRemoved

Bug: 194979745
Test: BluetoothInstrumentationTests
Manually test disconnect tone

Change-Id: I3ec4e9dae15f621d2605ca9a0576f39ff2d59fd1
parent 16bb1bf4
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -55,6 +56,9 @@ import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * Used to receive updates about calls from the Telecom component. This service is bound to Telecom
@@ -89,6 +93,8 @@ public class BluetoothInCallService extends InCallService {
    // Indicates that no BluetoothCall is ringing
    private static final int DEFAULT_RINGING_ADDRESS_TYPE = 128;

    private static final int DISCONNECT_TONE_TIMEOUT_SECONDS = 1;

    private int mNumActiveCalls = 0;
    private int mNumHeldCalls = 0;
    private int mNumChildrenOfActiveCall = 0;
@@ -102,6 +108,13 @@ public class BluetoothInCallService extends InCallService {
    private static final Object LOCK = new Object();
    private BluetoothHeadsetProxy mBluetoothHeadset;

    private Semaphore mDisconnectionToneSemaphore = new Semaphore(0);
    private int mAudioMode = AudioManager.MODE_INVALID;
    private final Object mAudioModeLock = new Object();

    @VisibleForTesting
    public AudioManager mAudioManager;

    @VisibleForTesting
    public TelephonyManager mTelephonyManager;

@@ -291,6 +304,19 @@ public class BluetoothInCallService extends InCallService {
        }
    }

    class BluetoothOnModeChangedListener implements AudioManager.OnModeChangedListener {
        @Override
        public void onModeChanged(int mode) {
            synchronized (mAudioModeLock) {
                mAudioMode = mode;
            }
            if (mode == AudioManager.MODE_NORMAL) {
                mDisconnectionToneSemaphore.release();
            }
        }
    }
    private BluetoothOnModeChangedListener mBluetoothOnModeChangedListener;

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind. Intent: " + intent);
@@ -525,6 +551,26 @@ public class BluetoothInCallService extends InCallService {
            return;
        }
        Log.d(TAG, "onCallRemoved");
        BluetoothCall heldCall = mCallInfo.getHeldCall();
        if (mCallInfo.isNullCall(heldCall)) {
            // current call is the only call

            mDisconnectionToneSemaphore.drainPermits();
            boolean isAudioModeNormal = false;
            synchronized (mAudioModeLock) {
                isAudioModeNormal = (mAudioMode == AudioManager.MODE_NORMAL);
            }
            if (!isAudioModeNormal) {
                Log.d(TAG, "Acquiring mDisconnectionToneSemaphore");
                try {
                  boolean result = mDisconnectionToneSemaphore.tryAcquire(
                    DISCONNECT_TONE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
                  Log.d(TAG, "Acquiring mDisconnectionToneSemaphore result " + result);
                } catch (InterruptedException e) {
                  Log.w(TAG, "Failed to acquire mDisconnectionToneSemaphore");
                }
            }
        }
        CallStateCallback callback = getCallback(call);
        if (callback != null) {
            call.unregisterCallback(callback);
@@ -565,11 +611,19 @@ public class BluetoothInCallService extends InCallService {
        mBluetoothAdapterReceiver = new BluetoothAdapterReceiver();
        IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        registerReceiver(mBluetoothAdapterReceiver, intentFilter);
        mBluetoothOnModeChangedListener = new BluetoothOnModeChangedListener();
        mAudioManager = getSystemService(AudioManager.class);
        mAudioManager.addOnModeChangedListener(
                Executors.newSingleThreadExecutor(), mBluetoothOnModeChangedListener);
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        if (mBluetoothOnModeChangedListener != null) {
            mAudioManager.removeOnModeChangedListener(mBluetoothOnModeChangedListener);
            mBluetoothOnModeChangedListener = null;
        }
        if (mBluetoothAdapterReceiver != null) {
            unregisterReceiver(mBluetoothAdapterReceiver);
            mBluetoothAdapterReceiver = null;