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

Commit 84335e55 authored by Hall Liu's avatar Hall Liu Committed by android-build-merger
Browse files

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

am: f491a365

Change-Id: Ib2d4714f699480a6e2daecc6316b7913ef0ed34a
parents 46eb52cf f491a365
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
@@ -109,11 +109,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;
@@ -169,11 +169,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");
@@ -260,6 +260,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,
@@ -267,11 +269,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");
@@ -280,10 +277,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,
@@ -511,7 +511,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 {
@@ -519,7 +519,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:
@@ -706,7 +706,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 {
@@ -714,7 +714,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:
@@ -1018,12 +1018,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;
@@ -1222,7 +1221,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 {
@@ -1230,7 +1229,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() {
@@ -811,4 +785,9 @@ public class BluetoothRouteManager extends StateMachine {
            Log.i(LOG_TAG, "transition for testing done: %s", stateName);
        });
    }

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