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

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

Merge "Bring Telecom logic into agreement with Bluetooth" into pi-dev

parents 90d0828e cc74215b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -68,6 +68,10 @@ public class BluetoothHeadsetProxy {
        return mBluetoothHeadset.setActiveDevice(device);
    }

    public BluetoothDevice getActiveDevice() {
        return mBluetoothHeadset.getActiveDevice();
    }

    public boolean isAudioOn() {
        return mBluetoothHeadset.isAudioOn();
    }
+4 −4
Original line number Diff line number Diff line
@@ -52,15 +52,15 @@ public class CallAudioRoutePeripheralAdapter implements WiredHeadsetManager.List
    }

    @Override
    public void onBluetoothDeviceAvailable() {
    public void onBluetoothActiveDevicePresent() {
        mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
                CallAudioRouteStateMachine.CONNECT_BLUETOOTH);
                CallAudioRouteStateMachine.BT_ACTIVE_DEVICE_PRESENT);
    }

    @Override
    public void onBluetoothDeviceUnavailable() {
    public void onBluetoothActiveDeviceGone() {
        mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
                CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH);
                CallAudioRouteStateMachine.BT_ACTIVE_DEVICE_GONE);
    }

    @Override
+22 −23
Original line number Diff line number Diff line
@@ -91,11 +91,11 @@ public class CallAudioRouteStateMachine extends StateMachine {
    /** Valid values for msg.what */
    public static final int CONNECT_WIRED_HEADSET = 1;
    public static final int DISCONNECT_WIRED_HEADSET = 2;
    public static final int CONNECT_BLUETOOTH = 3;
    public static final int DISCONNECT_BLUETOOTH = 4;
    public static final int CONNECT_DOCK = 5;
    public static final int DISCONNECT_DOCK = 6;
    public static final int BLUETOOTH_DEVICE_LIST_CHANGED = 7;
    public static final int BT_ACTIVE_DEVICE_PRESENT = 8;
    public static final int BT_ACTIVE_DEVICE_GONE = 9;

    public static final int SWITCH_EARPIECE = 1001;
    public static final int SWITCH_BLUETOOTH = 1002;
@@ -151,11 +151,11 @@ public class CallAudioRouteStateMachine extends StateMachine {
    private static final SparseArray<String> MESSAGE_CODE_TO_NAME = new SparseArray<String>() {{
        put(CONNECT_WIRED_HEADSET, "CONNECT_WIRED_HEADSET");
        put(DISCONNECT_WIRED_HEADSET, "DISCONNECT_WIRED_HEADSET");
        put(CONNECT_BLUETOOTH, "CONNECT_BLUETOOTH");
        put(DISCONNECT_BLUETOOTH, "DISCONNECT_BLUETOOTH");
        put(CONNECT_DOCK, "CONNECT_DOCK");
        put(DISCONNECT_DOCK, "DISCONNECT_DOCK");
        put(BLUETOOTH_DEVICE_LIST_CHANGED, "BLUETOOTH_DEVICE_LIST_CHANGED");
        put(BT_ACTIVE_DEVICE_PRESENT, "BT_ACTIVE_DEVICE_PRESENT");
        put(BT_ACTIVE_DEVICE_GONE, "BT_ACTIVE_DEVICE_GONE");

        put(SWITCH_EARPIECE, "SWITCH_EARPIECE");
        put(SWITCH_BLUETOOTH, "SWITCH_BLUETOOTH");
@@ -242,6 +242,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
            int removedRoutes = 0;
            boolean isHandled = NOT_HANDLED;

            Log.i(this, "Processing message %s",
                    MESSAGE_CODE_TO_NAME.get(msg.what, Integer.toString(msg.what)));
            switch (msg.what) {
                case CONNECT_WIRED_HEADSET:
                    Log.addEvent(mCallsManager.getForegroundCall(), LogUtils.Events.AUDIO_ROUTE,
@@ -249,11 +251,6 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    removedRoutes |= ROUTE_EARPIECE;
                    addedRoutes |= ROUTE_WIRED_HEADSET;
                    break;
                case CONNECT_BLUETOOTH:
                    Log.addEvent(mCallsManager.getForegroundCall(), LogUtils.Events.AUDIO_ROUTE,
                            "Bluetooth connected");
                    addedRoutes |= ROUTE_BLUETOOTH;
                    break;
                case DISCONNECT_WIRED_HEADSET:
                    Log.addEvent(mCallsManager.getForegroundCall(), LogUtils.Events.AUDIO_ROUTE,
                            "Wired headset disconnected");
@@ -262,10 +259,13 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        addedRoutes |= ROUTE_EARPIECE;
                    }
                    break;
                case DISCONNECT_BLUETOOTH:
                case BT_ACTIVE_DEVICE_PRESENT:
                    Log.addEvent(mCallsManager.getForegroundCall(), LogUtils.Events.AUDIO_ROUTE,
                            "Bluetooth disconnected");
                    removedRoutes |= ROUTE_BLUETOOTH;
                            "Bluetooth active device present");
                    break;
                case BT_ACTIVE_DEVICE_GONE:
                    Log.addEvent(mCallsManager.getForegroundCall(), LogUtils.Events.AUDIO_ROUTE,
                            "Bluetooth active device gone");
                    break;
                case BLUETOOTH_DEVICE_LIST_CHANGED:
                    Log.addEvent(mCallsManager.getForegroundCall(), LogUtils.Events.AUDIO_ROUTE,
@@ -493,7 +493,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case CONNECT_WIRED_HEADSET:
                    sendInternalMessage(SWITCH_HEADSET);
                    return HANDLED;
                case CONNECT_BLUETOOTH:
                case BT_ACTIVE_DEVICE_PRESENT:
                    if (!mHasUserExplicitlyLeftBluetooth) {
                        sendInternalMessage(SWITCH_BLUETOOTH);
                    } else {
@@ -501,7 +501,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                                "explicitly disconnected.");
                    }
                    return HANDLED;
                case DISCONNECT_BLUETOOTH:
                case BT_ACTIVE_DEVICE_GONE:
                    // No change in audio route required
                    return HANDLED;
                case DISCONNECT_WIRED_HEADSET:
@@ -688,7 +688,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    Log.e(this, new IllegalStateException(),
                            "Wired headset should already be connected.");
                    return HANDLED;
                case CONNECT_BLUETOOTH:
                case BT_ACTIVE_DEVICE_PRESENT:
                    if (!mHasUserExplicitlyLeftBluetooth) {
                        sendInternalMessage(SWITCH_BLUETOOTH);
                    } else {
@@ -696,7 +696,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                                "explicitly disconnected.");
                    }
                    return HANDLED;
                case DISCONNECT_BLUETOOTH:
                case BT_ACTIVE_DEVICE_GONE:
                    // No change in audio route required
                    return HANDLED;
                case DISCONNECT_WIRED_HEADSET:
@@ -1000,12 +1000,11 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case CONNECT_WIRED_HEADSET:
                    sendInternalMessage(SWITCH_HEADSET);
                    return HANDLED;
                case CONNECT_BLUETOOTH:
                    // We can't tell when a change in bluetooth state corresponds to an
                    // actual connection or disconnection, so we'll just ignore it if we're already
                    // in the bluetooth route.
                case BT_ACTIVE_DEVICE_PRESENT:
                    Log.w(this, "Bluetooth active device should not"
                            + " have been null while we were in BT route.");
                    return HANDLED;
                case DISCONNECT_BLUETOOTH:
                case BT_ACTIVE_DEVICE_GONE:
                    sendInternalMessage(SWITCH_BASELINE_ROUTE, NO_INCLUDE_BLUETOOTH_IN_BASELINE);
                    mWasOnSpeaker = false;
                    return HANDLED;
@@ -1204,7 +1203,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case CONNECT_WIRED_HEADSET:
                    sendInternalMessage(SWITCH_HEADSET);
                    return HANDLED;
                case CONNECT_BLUETOOTH:
                case BT_ACTIVE_DEVICE_PRESENT:
                    if (!mHasUserExplicitlyLeftBluetooth) {
                        sendInternalMessage(SWITCH_BLUETOOTH);
                    } else {
@@ -1212,7 +1211,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                                "explicitly disconnected.");
                    }
                    return HANDLED;
                case DISCONNECT_BLUETOOTH:
                case BT_ACTIVE_DEVICE_GONE:
                    // No change in audio route required
                    return HANDLED;
                case DISCONNECT_WIRED_HEADSET:
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.telecom.bluetooth;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
+34 −55
Original line number Diff line number Diff line
@@ -72,8 +72,8 @@ public class BluetoothRouteManager extends StateMachine {

    public interface BluetoothStateListener {
        void onBluetoothDeviceListChanged();
        void onBluetoothDeviceAvailable();
        void onBluetoothDeviceUnavailable();
        void onBluetoothActiveDevicePresent();
        void onBluetoothActiveDeviceGone();
        void onBluetoothAudioConnected();
        void onBluetoothAudioDisconnected();
    }
@@ -243,15 +243,8 @@ public class BluetoothRouteManager extends StateMachine {
                        break;
                    case LOST_DEVICE:
                        removeDevice((String) args.arg2);

                        if (Objects.equals(address, mDeviceAddress)) {
                            String newAddress = connectHfpAudio(null);
                            if (newAddress != null) {
                                transitionTo(getConnectingStateForAddress(newAddress,
                                        "AudioConnecting/LOST_DEVICE"));
                            } else {
                                transitionTo(mAudioOffState);
                            }
                            transitionToActualState();
                        }
                        break;
                    case CONNECT_HFP:
@@ -364,13 +357,7 @@ public class BluetoothRouteManager extends StateMachine {
                    case LOST_DEVICE:
                        removeDevice((String) args.arg2);
                        if (Objects.equals(address, mDeviceAddress)) {
                            String newAddress = connectHfpAudio(null);
                            if (newAddress != null) {
                                transitionTo(getConnectingStateForAddress(newAddress,
                                        "AudioConnected/LOST_DEVICE"));
                            } else {
                                transitionTo(mAudioOffState);
                            }
                            transitionToActualState();
                        }
                        break;
                    case CONNECT_HFP:
@@ -421,14 +408,7 @@ public class BluetoothRouteManager extends StateMachine {
                    case HFP_LOST:
                        if (Objects.equals(mDeviceAddress, address)) {
                            Log.i(LOG_TAG, "HFP connection with device %s lost.", mDeviceAddress);
                            String nextAddress = connectHfpAudio(null, mDeviceAddress);
                            if (nextAddress == null) {
                                Log.i(LOG_TAG, "No suitable fallback device. Going to AUDIO_OFF.");
                            transitionToActualState();
                            } else {
                                transitionTo(getConnectingStateForAddress(nextAddress,
                                        "AudioConnected/HFP_LOST"));
                            }
                        } else {
                            Log.w(LOG_TAG, "Got HFP lost message for device %s while" +
                                    " connected to %s.", address, mDeviceAddress);
@@ -458,6 +438,8 @@ public class BluetoothRouteManager extends StateMachine {

    private BluetoothStateListener mListener;
    private BluetoothDeviceManager mDeviceManager;
    // Tracks the active device in the BT stack.
    private BluetoothDevice mActiveDeviceCache = null;

    public BluetoothRouteManager(Context context, TelecomSystem.SyncRoot lock,
            BluetoothDeviceManager deviceManager, Timeouts.Adapter timeoutsAdapter) {
@@ -565,9 +547,6 @@ public class BluetoothRouteManager extends StateMachine {
        sendMessage(NEW_DEVICE_CONNECTED, args);

        mListener.onBluetoothDeviceListChanged();
        if (mDeviceManager.getConnectedDevices().size() == 1) {
            mListener.onBluetoothDeviceAvailable();
        }
    }

    public void onDeviceLost(String lostDeviceAddress) {
@@ -577,8 +556,17 @@ public class BluetoothRouteManager extends StateMachine {
        sendMessage(LOST_DEVICE, args);

        mListener.onBluetoothDeviceListChanged();
        if (mDeviceManager.getConnectedDevices().size() == 0) {
            mListener.onBluetoothDeviceUnavailable();
    }

    public void onActiveDeviceChanged(BluetoothDevice device) {
        BluetoothDevice oldActiveDevice = mActiveDeviceCache;
        mActiveDeviceCache = device;
        if ((oldActiveDevice == null) ^ (device == null)) {
            if (device == null) {
                mListener.onBluetoothActiveDeviceGone();
            } else {
                mListener.onBluetoothActiveDevicePresent();
            }
        }
    }

@@ -588,15 +576,7 @@ public class BluetoothRouteManager extends StateMachine {
    }

    private String connectHfpAudio(String address) {
        return connectHfpAudio(address, 0, null);
    }

    private String connectHfpAudio(String address, int retryCount) {
        return connectHfpAudio(address, retryCount, null);
    }

    private String connectHfpAudio(String address, String excludeAddress) {
        return connectHfpAudio(address, 0, excludeAddress);
        return connectHfpAudio(address, 0);
    }

    /**
@@ -605,23 +585,26 @@ public class BluetoothRouteManager extends StateMachine {
     * Telecom from within it.
     * @param address The address that should be tried first. May be null.
     * @param retryCount The number of times this connection attempt has been retried.
     * @param excludeAddress Don't connect to this address.
     * @return The address of the device that's actually being connected to, or null if no
     * connection was successful.
     */
    private String connectHfpAudio(String address, int retryCount, String excludeAddress) {
    private String connectHfpAudio(String address, int retryCount) {
        Collection<BluetoothDevice> deviceList = getConnectedDevices();
        Optional<BluetoothDevice> matchingDevice = deviceList.stream()
                .filter(d -> Objects.equals(d.getAddress(), address))
                .findAny();

        String actualAddress = matchingDevice.isPresent() ?
                address : getPreferredDevice(excludeAddress);
        String actualAddress = matchingDevice.isPresent()
                ? address : getActiveDeviceAddress();
        if (!matchingDevice.isPresent()) {
            Log.i(this, "No device with address %s available. Using %s instead.",
                    address, actualAddress);
        }
        if (actualAddress != null && !connectAudio(actualAddress)) {
        if (actualAddress == null) {
            Log.i(this, "No device specified and BT stack has no active device. Not connecting.");
            return null;
        }
        if (!connectAudio(actualAddress)) {
            boolean shouldRetry = retryCount < MAX_CONNECTION_RETRIES;
            Log.w(LOG_TAG, "Could not connect to %s. Will %s", actualAddress,
                    shouldRetry ? "retry" : "not retry");
@@ -640,17 +623,8 @@ public class BluetoothRouteManager extends StateMachine {
        return actualAddress;
    }

    private String getPreferredDevice(String excludeAddress) {
        String preferredDevice = null;
        for (String address : mMostRecentlyUsedDevices) {
            if (!Objects.equals(excludeAddress, address)) {
                preferredDevice = address;
            }
        }
        if (preferredDevice == null) {
            return mDeviceManager.getMostRecentlyConnectedDevice(excludeAddress);
        }
        return preferredDevice;
    private String getActiveDeviceAddress() {
        return mActiveDeviceCache == null ? null : mActiveDeviceCache.getAddress();
    }

    private void transitionToActualState() {
@@ -808,4 +782,9 @@ public class BluetoothRouteManager extends StateMachine {
                break;
        }
    }

    @VisibleForTesting
    public void setActiveDeviceCacheForTesting(BluetoothDevice device) {
        mActiveDeviceCache = device;
    }
}
Loading