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

Commit 531324d7 authored by Hall Liu's avatar Hall Liu Committed by Android (Google) Code Review
Browse files

Merge "Retry connectAudio if it returns false." into nyc-dev

parents 482e43fc c4e71f87
Loading
Loading
Loading
Loading
+34 −11
Original line number Original line Diff line number Diff line
@@ -16,7 +16,6 @@


package com.android.server.telecom;
package com.android.server.telecom;


import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile;
@@ -32,7 +31,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.IndentingPrintWriter;


import java.util.List;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;


/**
/**
 * Listens to and caches bluetooth headset state.  Used By the CallAudioManager for maintaining
 * Listens to and caches bluetooth headset state.  Used By the CallAudioManager for maintaining
@@ -94,18 +92,21 @@ public class BluetoothManager {
                if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
                if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
                    int bluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
                    int bluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
                            BluetoothHeadset.STATE_DISCONNECTED);
                            BluetoothHeadset.STATE_DISCONNECTED);
                    Log.d(this, "mReceiver: HEADSET_STATE_CHANGED_ACTION");
                    Log.i(this, "mReceiver: HEADSET_STATE_CHANGED_ACTION");
                    Log.d(this, "==> new state: %s ", bluetoothHeadsetState);
                    Log.i(this, "==> new state: %s ", bluetoothHeadsetState);
                    updateListenerOfBluetoothState(
                    updateListenerOfBluetoothState(
                            bluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTING);
                            bluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTING);
                } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
                } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
                    int bluetoothHeadsetAudioState =
                    int bluetoothHeadsetAudioState =
                            intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
                            intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
                                    BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
                                    BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
                    Log.d(this, "mReceiver: HEADSET_AUDIO_STATE_CHANGED_ACTION");
                    Log.i(this, "mReceiver: HEADSET_AUDIO_STATE_CHANGED_ACTION");
                    Log.d(this, "==> new state: %s", bluetoothHeadsetAudioState);
                    Log.i(this, "==> new state: %s", bluetoothHeadsetAudioState);
                    updateListenerOfBluetoothState(
                    updateListenerOfBluetoothState(
                            bluetoothHeadsetAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTING);
                            bluetoothHeadsetAudioState ==
                                    BluetoothHeadset.STATE_AUDIO_CONNECTING
                            || bluetoothHeadsetAudioState ==
                                    BluetoothHeadset.STATE_AUDIO_CONNECTED);
                }
                }
            } finally {
            } finally {
                Log.endSession();
                Log.endSession();
@@ -130,6 +131,19 @@ public class BluetoothManager {
            updateListenerOfBluetoothState(false);
            updateListenerOfBluetoothState(false);
        }
        }
    };
    };

    private final Runnable mRetryConnectAudio = new Runnable("BM.rCA") {
        @Override
        public void loggedRun() {
            Log.i(this, "Retrying connecting to bluetooth audio.");
            if (!mBluetoothHeadset.connectAudio()) {
                Log.w(this, "Retry of bluetooth audio connection failed. Giving up.");
            } else {
                setBluetoothStatePending();
            }
        }
    };

    private final Context mContext;
    private final Context mContext;
    private int mBluetoothState = BLUETOOTH_UNINITIALIZED;
    private int mBluetoothState = BLUETOOTH_UNINITIALIZED;


@@ -294,12 +308,21 @@ public class BluetoothManager {
    public void connectBluetoothAudio() {
    public void connectBluetoothAudio() {
        Log.v(this, "connectBluetoothAudio()...");
        Log.v(this, "connectBluetoothAudio()...");
        if (mBluetoothHeadset != null) {
        if (mBluetoothHeadset != null) {
            mBluetoothHeadset.connectAudio();
            if (!mBluetoothHeadset.connectAudio()) {
                mHandler.postDelayed(mRetryConnectAudio.prepare(),
                        Timeouts.getRetryBluetoothConnectAudioBackoffMillis(
                                mContext.getContentResolver()));
            }
        }
        // The call to connectAudio is asynchronous and may take some time to complete. However,
        // if connectAudio() returns false, we know that it has failed and therefore will
        // schedule a retry to happen some time later. We set bluetooth state to pending now and
        // show bluetooth as connected in the UI, but confirmation that we are connected will
        // arrive through mReceiver.
        setBluetoothStatePending();
    }
    }


        // Watch out: The bluetooth connection doesn't happen instantly;
    private void setBluetoothStatePending() {
        // the connectAudio() call returns instantly but does its real
        // work in another thread.
        mBluetoothState = BLUETOOTH_AUDIO_PENDING;
        mBluetoothState = BLUETOOTH_AUDIO_PENDING;
        mBluetoothConnectionRequestTime = SystemClock.elapsedRealtime();
        mBluetoothConnectionRequestTime = SystemClock.elapsedRealtime();
        mHandler.removeCallbacks(mBluetoothConnectionTimeout.getRunnableToCancel());
        mHandler.removeCallbacks(mBluetoothConnectionTimeout.getRunnableToCancel());
+9 −0
Original line number Original line Diff line number Diff line
@@ -108,6 +108,15 @@ public final class Timeouts {
        return get(contentResolver, "bluetooth_pending_timeout_millis", 5000L);
        return get(contentResolver, "bluetooth_pending_timeout_millis", 5000L);
    }
    }


    /**
     * Returns the amount of time to wait before retrying the connectAudio call. This is
     * necessary to account for the HeadsetStateMachine sometimes not being ready when we want to
     * connect to bluetooth audio immediately after a device connects.
     */
    public static long getRetryBluetoothConnectAudioBackoffMillis(ContentResolver contentResolver) {
        return get(contentResolver, "retry_bluetooth_connect_audio_backoff_millis", 500L);
    }

    /**
    /**
     * Returns the amount of time after a Logging session has been started that Telecom is set to
     * Returns the amount of time after a Logging session has been started that Telecom is set to
     * perform a sweep to check and make sure that the session is still not incomplete (stale).
     * perform a sweep to check and make sure that the session is still not incomplete (stale).