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

Commit cc2b17ae authored by Hall Liu's avatar Hall Liu Committed by Gerrit Code Review
Browse files

Merge "Make changes to CARSM and BRM for multi-hfp"

parents 18bfe89e 132a557c
Loading
Loading
Loading
Loading
+28 −38
Original line number Diff line number Diff line
@@ -46,45 +46,35 @@ public class CallAudioRoutePeripheralAdapter implements WiredHeadsetManager.List
    }

    @Override
    public void onBluetoothStateChange(int oldState, int newState) {
        switch (oldState) {
            case BluetoothRouteManager.BLUETOOTH_DISCONNECTED:
            case BluetoothRouteManager.BLUETOOTH_UNINITIALIZED:
                switch (newState) {
                    case BluetoothRouteManager.BLUETOOTH_DEVICE_CONNECTED:
                    case BluetoothRouteManager.BLUETOOTH_AUDIO_CONNECTED:
    public void onBluetoothDeviceListChanged() {
        mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
                                CallAudioRouteStateMachine.CONNECT_BLUETOOTH);
                        break;
                CallAudioRouteStateMachine.BLUETOOTH_DEVICE_LIST_CHANGED);
    }
                break;
            case BluetoothRouteManager.BLUETOOTH_DEVICE_CONNECTED:
                switch (newState) {
                    case BluetoothRouteManager.BLUETOOTH_DISCONNECTED:
                        mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
                                CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH);
                        break;
                    case BluetoothRouteManager.BLUETOOTH_AUDIO_CONNECTED:

    @Override
    public void onBluetoothDeviceAvailable() {
        mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
                                CallAudioRouteStateMachine.SWITCH_BLUETOOTH);
                        break;
                CallAudioRouteStateMachine.CONNECT_BLUETOOTH);
    }
                break;
            case BluetoothRouteManager.BLUETOOTH_AUDIO_CONNECTED:
            case BluetoothRouteManager.BLUETOOTH_AUDIO_PENDING:
                switch (newState) {
                    case BluetoothRouteManager.BLUETOOTH_DISCONNECTED:

    @Override
    public void onBluetoothDeviceUnavailable() {
        mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
                CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH);
                        break;
                    case BluetoothRouteManager.BLUETOOTH_DEVICE_CONNECTED:
                        mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
                                CallAudioRouteStateMachine.BT_AUDIO_DISCONNECT);
                        break;
    }
                break;

    @Override
    public void onBluetoothAudioConnected() {
        mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
                CallAudioRouteStateMachine.BT_AUDIO_CONNECTED);
    }

    @Override
    public void onBluetoothAudioDisconnected() {
        mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
                CallAudioRouteStateMachine.BT_AUDIO_DISCONNECTED);
    }

    /**
      * Updates the audio route when the headset plugged in state changes. For example, if audio is
      * being routed over speakerphone and a headset is plugged in then switch to wired headset.
+123 −40
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.server.telecom;


import android.app.ActivityManager;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.content.Context;
import android.content.pm.UserInfo;
import android.media.AudioManager;
@@ -39,6 +41,7 @@ import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;

import java.util.Collection;
import java.util.HashMap;

/**
@@ -63,9 +66,6 @@ import java.util.HashMap;
 * mIsMuted: a boolean indicating whether the audio is muted
 */
public class CallAudioRouteStateMachine extends StateMachine {
    private static final String TELECOM_PACKAGE =
            CallAudioRouteStateMachine.class.getPackage().getName();

    /** Direct the audio stream through the device's earpiece. */
    public static final int ROUTE_EARPIECE      = CallAudioState.ROUTE_EARPIECE;

@@ -85,6 +85,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
    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 SWITCH_EARPIECE = 1001;
    public static final int SWITCH_BLUETOOTH = 1002;
@@ -92,7 +93,6 @@ public class CallAudioRouteStateMachine extends StateMachine {
    public static final int SWITCH_SPEAKER = 1004;
    // Wired headset, earpiece, or speakerphone, in that order of precedence.
    public static final int SWITCH_BASELINE_ROUTE = 1005;
    public static final int BT_AUDIO_DISCONNECT = 1006;

    public static final int USER_SWITCH_EARPIECE = 1101;
    public static final int USER_SWITCH_BLUETOOTH = 1102;
@@ -102,6 +102,15 @@ public class CallAudioRouteStateMachine extends StateMachine {

    public static final int UPDATE_SYSTEM_AUDIO_ROUTE = 1201;

    // These three messages indicate state changes that come from BluetoothRouteManager.
    // They may be triggered by the BT stack doing something on its own or they may be sent after
    // we request that the BT stack do something. Any logic for these messages should take into
    // account the possibility that the event indicated has already been processed (i.e. handling
    // should be idempotent).
    public static final int BT_AUDIO_DISCONNECTED = 1301;
    public static final int BT_AUDIO_CONNECTED = 1302;
    public static final int BT_AUDIO_PENDING = 1303;

    public static final int MUTE_ON = 3001;
    public static final int MUTE_OFF = 3002;
    public static final int TOGGLE_MUTE = 3003;
@@ -135,13 +144,13 @@ public class CallAudioRouteStateMachine extends StateMachine {
        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(SWITCH_EARPIECE, "SWITCH_EARPIECE");
        put(SWITCH_BLUETOOTH, "SWITCH_BLUETOOTH");
        put(SWITCH_HEADSET, "SWITCH_HEADSET");
        put(SWITCH_SPEAKER, "SWITCH_SPEAKER");
        put(SWITCH_BASELINE_ROUTE, "SWITCH_BASELINE_ROUTE");
        put(BT_AUDIO_DISCONNECT, "BT_AUDIO_DISCONNECT");

        put(USER_SWITCH_EARPIECE, "USER_SWITCH_EARPIECE");
        put(USER_SWITCH_BLUETOOTH, "USER_SWITCH_BLUETOOTH");
@@ -151,6 +160,10 @@ public class CallAudioRouteStateMachine extends StateMachine {

        put(UPDATE_SYSTEM_AUDIO_ROUTE, "UPDATE_SYSTEM_AUDIO_ROUTE");

        put(BT_AUDIO_DISCONNECTED, "BT_AUDIO_DISCONNECTED");
        put(BT_AUDIO_CONNECTED, "BT_AUDIO_CONNECTED");
        put(BT_AUDIO_PENDING, "BT_AUDIO_PENDING");

        put(MUTE_ON, "MUTE_ON");
        put(MUTE_OFF, "MUTE_OFF");
        put(TOGGLE_MUTE, "TOGGLE_MUTE");
@@ -209,6 +222,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        public boolean processMessage(Message msg) {
            int addedRoutes = 0;
            int removedRoutes = 0;
            boolean isHandled = NOT_HANDLED;

            switch (msg.what) {
                case CONNECT_WIRED_HEADSET:
@@ -235,6 +249,19 @@ public class CallAudioRouteStateMachine extends StateMachine {
                            "Bluetooth disconnected");
                    removedRoutes |= ROUTE_BLUETOOTH;
                    break;
                case BLUETOOTH_DEVICE_LIST_CHANGED:
                    Log.addEvent(mCallsManager.getForegroundCall(), LogUtils.Events.AUDIO_ROUTE,
                            "Bluetooth device list changed");
                    Collection<BluetoothDevice> connectedDevices =
                            mBluetoothRouteManager.getConnectedDevices();
                    if (connectedDevices.size() > 0) {
                        addedRoutes |= ROUTE_BLUETOOTH;
                    } else {
                        removedRoutes |= ROUTE_BLUETOOTH;
                    }
                    // TODO: update in-call app on the list of BT devices.
                    isHandled = HANDLED;
                    break;
                case SWITCH_BASELINE_ROUTE:
                    sendInternalMessage(calculateBaselineRouteMessage(false,
                            msg.arg1 == INCLUDE_BLUETOOTH_IN_BASELINE));
@@ -256,7 +283,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        addedRoutes, false);
            }

            return NOT_HANDLED;
            return isHandled;
        }

        // Behavior will depend on whether the state is an active one or a quiescent one.
@@ -280,7 +307,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        public void enter() {
            super.enter();
            setSpeakerphoneOn(false);
            setBluetoothOn(false);
            setBluetoothOff();
            CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_EARPIECE,
                    mAvailableRoutes);
            setSystemAudioState(newState, true);
@@ -303,11 +330,18 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case USER_SWITCH_EARPIECE:
                    // Nothing to do here
                    return HANDLED;
                case BT_AUDIO_CONNECTED:
                    transitionTo(mActiveBluetoothRoute);
                    return HANDLED;
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0) {
                        transitionTo(mAudioFocusType == ACTIVE_FOCUS ?
                                mActiveBluetoothRoute : mRingingBluetoothRoute);
                        if (mAudioFocusType == ACTIVE_FOCUS || mIsInbandRingSupported) {
                            // Omit transition to ActiveBluetoothRoute
                            setBluetoothOn();
                        } else {
                            transitionTo(mRingingBluetoothRoute);
                        }
                    } else {
                        Log.w(this, "Ignoring switch to bluetooth command. Not available.");
                    }
@@ -368,6 +402,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case USER_SWITCH_EARPIECE:
                    // Nothing to do here
                    return HANDLED;
                case BT_AUDIO_CONNECTED:
                    Log.w(this, "BT Audio came on in quiescent earpiece route.");
                    transitionTo(mActiveBluetoothRoute);
                    return HANDLED;
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0) {
@@ -433,7 +471,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                            "earpiece");
                    updateSystemAudioState();
                    return HANDLED;
                case BT_AUDIO_DISCONNECT:
                case BT_AUDIO_DISCONNECTED:
                    // This may be sent as a confirmation by the BT stack after switch off BT.
                    return HANDLED;
                case CONNECT_DOCK:
@@ -463,7 +501,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        public void enter() {
            super.enter();
            setSpeakerphoneOn(false);
            setBluetoothOn(false);
            setBluetoothOff();
            CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_WIRED_HEADSET,
                    mAvailableRoutes);
            setSystemAudioState(newState, true);
@@ -490,11 +528,18 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        Log.w(this, "Ignoring switch to earpiece command. Not available.");
                    }
                    return HANDLED;
                case BT_AUDIO_CONNECTED:
                    transitionTo(mActiveBluetoothRoute);
                    return HANDLED;
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0) {
                        transitionTo(mAudioFocusType == ACTIVE_FOCUS ?
                                mActiveBluetoothRoute : mRingingBluetoothRoute);
                        if (mAudioFocusType == ACTIVE_FOCUS || mIsInbandRingSupported) {
                            // Omit transition to ActiveBluetoothRoute until actual connection.
                            setBluetoothOn();
                        } else {
                            transitionTo(mRingingBluetoothRoute);
                        }
                    } else {
                        Log.w(this, "Ignoring switch to bluetooth command. Not available.");
                    }
@@ -555,6 +600,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        Log.w(this, "Ignoring switch to earpiece command. Not available.");
                    }
                    return HANDLED;
                case BT_AUDIO_CONNECTED:
                    transitionTo(mActiveBluetoothRoute);
                    Log.w(this, "BT Audio came on in quiescent headset route.");
                    return HANDLED;
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0) {
@@ -620,7 +669,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        sendInternalMessage(SWITCH_BASELINE_ROUTE, INCLUDE_BLUETOOTH_IN_BASELINE);
                    }
                    return HANDLED;
                case BT_AUDIO_DISCONNECT:
                case BT_AUDIO_DISCONNECTED:
                    // This may be sent as a confirmation by the BT stack after switch off BT.
                    return HANDLED;
                case CONNECT_DOCK:
@@ -635,6 +684,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
        }
    }

    // Note: transitions to/from this class work a bit differently -- we delegate to
    // BluetoothRouteManager to manage all Bluetooth state, so instead of transitioning to one of
    // the bluetooth states immediately when there's an request to do so, we wait for
    // BluetoothRouteManager to report its state before we go into this state.
    class ActiveBluetoothRoute extends BluetoothRoute {
        @Override
        public String getName() {
@@ -650,7 +703,6 @@ public class CallAudioRouteStateMachine extends StateMachine {
        public void enter() {
            super.enter();
            setSpeakerphoneOn(false);
            setBluetoothOn(true);
            CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_BLUETOOTH,
                    mAvailableRoutes);
            setSystemAudioState(newState, true);
@@ -679,6 +731,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        Log.w(this, "Ignoring switch to earpiece command. Not available.");
                    }
                    return HANDLED;
                case BT_AUDIO_CONNECTED:
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    // Nothing to do
@@ -701,12 +754,14 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    return HANDLED;
                case SWITCH_FOCUS:
                    if (msg.arg1 == NO_FOCUS) {
                        setBluetoothOff();
                        reinitialize();
                    } else if (msg.arg1 == RINGING_FOCUS) {
                    } else if (msg.arg1 == RINGING_FOCUS && !mIsInbandRingSupported) {
                        setBluetoothOff();
                        transitionTo(mRingingBluetoothRoute);
                    }
                    return HANDLED;
                case BT_AUDIO_DISCONNECT:
                case BT_AUDIO_DISCONNECTED:
                    sendInternalMessage(SWITCH_BASELINE_ROUTE, NO_INCLUDE_BLUETOOTH_IN_BASELINE);
                    return HANDLED;
                default:
@@ -715,6 +770,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
        }
    }

    // This state is only used when the device doesn't support in-band ring. If it does,
    // ActiveBluetoothRoute is used instead.
    class RingingBluetoothRoute extends BluetoothRoute {
        @Override
        public String getName() {
@@ -759,6 +816,9 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        Log.w(this, "Ignoring switch to earpiece command. Not available.");
                    }
                    return HANDLED;
                case BT_AUDIO_CONNECTED:
                    transitionTo(mActiveBluetoothRoute);
                    return HANDLED;
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    // Nothing to do
@@ -783,12 +843,12 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    if (msg.arg1 == NO_FOCUS) {
                        reinitialize();
                    } else if (msg.arg1 == ACTIVE_FOCUS) {
                        transitionTo(mActiveBluetoothRoute);
                        setBluetoothOn();
                    }
                    return HANDLED;
                case BT_AUDIO_DISCONNECT:
                    // BT SCO might be connected when in-band ringing is enabled
                    sendInternalMessage(SWITCH_BASELINE_ROUTE, NO_INCLUDE_BLUETOOTH_IN_BASELINE);
                case BT_AUDIO_DISCONNECTED:
                    // Ignore this -- audio disconnecting while ringing w/o in-band should not
                    // cause a route switch, since the device is still connected.
                    return HANDLED;
                default:
                    return NOT_HANDLED;
@@ -812,7 +872,6 @@ public class CallAudioRouteStateMachine extends StateMachine {
            super.enter();
            mHasUserExplicitlyLeftBluetooth = false;
            updateInternalCallAudioState();
            setBluetoothOn(false);
        }

        @Override
@@ -834,6 +893,9 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        Log.w(this, "Ignoring switch to earpiece command. Not available.");
                    }
                    return HANDLED;
                case BT_AUDIO_CONNECTED:
                    transitionTo(mActiveBluetoothRoute);
                    return HANDLED;
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    // Nothing to do
@@ -852,12 +914,16 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    return HANDLED;
                case SWITCH_FOCUS:
                    if (msg.arg1 == ACTIVE_FOCUS) {
                        transitionTo(mActiveBluetoothRoute);
                        setBluetoothOn();
                    } else if (msg.arg1 == RINGING_FOCUS) {
                        if (mIsInbandRingSupported) {
                            setBluetoothOn();
                        } else {
                            transitionTo(mRingingBluetoothRoute);
                        }
                    }
                    return HANDLED;
                case BT_AUDIO_DISCONNECT:
                case BT_AUDIO_DISCONNECTED:
                    // Ignore this -- audio disconnecting while quiescent should not cause a
                    // route switch, since the device is still connected.
                    return HANDLED;
@@ -923,7 +989,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
            super.enter();
            mWasOnSpeaker = true;
            setSpeakerphoneOn(true);
            setBluetoothOn(false);
            setBluetoothOff();
            CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_SPEAKER,
                    mAvailableRoutes);
            setSystemAudioState(newState);
@@ -952,13 +1018,20 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        Log.w(this, "Ignoring switch to earpiece command. Not available.");
                    }
                    return HANDLED;
                case BT_AUDIO_CONNECTED:
                    transitionTo(mActiveBluetoothRoute);
                    return HANDLED;
                case USER_SWITCH_BLUETOOTH:
                    mWasOnSpeaker = false;
                    // fall through
                case SWITCH_BLUETOOTH:
                    if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0) {
                        transitionTo(mAudioFocusType == ACTIVE_FOCUS ?
                                mActiveBluetoothRoute : mRingingBluetoothRoute);
                        if (mAudioFocusType == ACTIVE_FOCUS || mIsInbandRingSupported) {
                            // Omit transition to ActiveBluetoothRoute
                            setBluetoothOn();
                        } else {
                            transitionTo(mRingingBluetoothRoute);
                        }
                    } else {
                        Log.w(this, "Ignoring switch to bluetooth command. Not available.");
                    }
@@ -1027,6 +1100,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                        Log.w(this, "Ignoring switch to earpiece command. Not available.");
                    }
                    return HANDLED;
                case BT_AUDIO_CONNECTED:
                    transitionTo(mActiveBluetoothRoute);
                    Log.w(this, "BT audio reported as connected while in quiescent speaker");
                    return HANDLED;
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0) {
@@ -1090,7 +1167,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    updateSystemAudioState();
                    // No change in audio route required
                    return HANDLED;
                case BT_AUDIO_DISCONNECT:
                case BT_AUDIO_DISCONNECTED:
                    // This may be sent as a confirmation by the BT stack after switch off BT.
                    return HANDLED;
                case CONNECT_DOCK:
@@ -1144,6 +1221,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
    private CallAudioState mCurrentCallAudioState;
    private CallAudioState mLastKnownCallAudioState;

    private final boolean mIsInbandRingSupported;

    public CallAudioRouteStateMachine(
            Context context,
            CallsManager callsManager,
@@ -1171,6 +1250,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        mStatusBarNotifier = statusBarNotifier;
        mAudioServiceFactory = audioServiceFactory;
        mDoesDeviceSupportEarpieceRoute = doesDeviceSupportEarpieceRoute;
        mIsInbandRingSupported = BluetoothHeadset.isInbandRingingSupported(mContext);
        mLock = callsManager.getLock();

        mStateNameToRouteCode = new HashMap<>(8);
@@ -1275,8 +1355,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                r.run();
                return;
            default:
                Log.e(this, new IllegalStateException(),
                        "Unexpected message code %d", msg.what);
                Log.e(this, new IllegalStateException(), "Unexpected message code %d", msg.what);
        }
    }

@@ -1300,17 +1379,22 @@ public class CallAudioRouteStateMachine extends StateMachine {
        }
    }

    private void setBluetoothOn(boolean on) {
    private void setBluetoothOn() {
        if (mBluetoothRouteManager.isBluetoothAvailable()) {
            if (on != mBluetoothRouteManager.isBluetoothAudioConnectedOrPending()) {
                Log.i(this, "connecting bluetooth %s", on);
                if (on) {
            if (!mBluetoothRouteManager.isBluetoothAudioConnectedOrPending()) {
                Log.i(this, "connecting bluetooth audio");
                mBluetoothRouteManager.connectBluetoothAudio(null /*TODO: add real address*/);
                } else {
                    mBluetoothRouteManager.disconnectBluetoothAudio();
            }
        }
    }

    private void setBluetoothOff() {
        if (mBluetoothRouteManager.isBluetoothAvailable()) {
            if (mBluetoothRouteManager.isBluetoothAudioConnectedOrPending()) {
                Log.i(this, "disconnecting bluetooth audio");
                mBluetoothRouteManager.disconnectBluetoothAudio();
            }
        }
    }

    private void setMuteOn(boolean mute) {
@@ -1331,7 +1415,6 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    audio.setMicrophoneMute(
                            mute, mContext.getOpPackageName(), getCurrentUserId());
                    mStatusBarNotifier.notifyMute(mute);

                } catch (RemoteException e) {
                    Log.e(this, e, "Remote exception while toggling mute.");
                }
+7 −3
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ public class BluetoothDeviceManager {
                                    mConnectedDevicesByAddress.values());
                            mConnectedDevicesByAddress.clear();
                            for (BluetoothDevice device : devicesToRemove) {
                                mBluetoothRouteManager.onDeviceLost(device);
                                mBluetoothRouteManager.onDeviceLost(device.getAddress());
                            }
                        }
                    } finally {
@@ -106,13 +106,13 @@ public class BluetoothDeviceManager {
                        if (bluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED) {
                            if (!mConnectedDevicesByAddress.containsKey(device.getAddress())) {
                                mConnectedDevicesByAddress.put(device.getAddress(), device);
                                mBluetoothRouteManager.onDeviceAdded(device);
                                mBluetoothRouteManager.onDeviceAdded(device.getAddress());
                            }
                        } else if (bluetoothHeadsetState == BluetoothHeadset.STATE_DISCONNECTED
                                || bluetoothHeadsetState == BluetoothHeadset.STATE_DISCONNECTING) {
                            if (mConnectedDevicesByAddress.containsKey(device.getAddress())) {
                                mConnectedDevicesByAddress.remove(device.getAddress());
                                mBluetoothRouteManager.onDeviceLost(device);
                                mBluetoothRouteManager.onDeviceLost(device.getAddress());
                            }
                        }
                    }
@@ -151,6 +151,10 @@ public class BluetoothDeviceManager {
        return mConnectedDevicesByAddress.size();
    }

    public Collection<BluetoothDevice> getConnectedDevices() {
        return mConnectedDevicesByAddress.values();
    }

    public String getMostRecentlyConnectedDevice(String excludeAddress) {
        String result = null;
        synchronized (mLock) {
Loading