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

Commit d27bc04b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "bt-phone-policy-fix-auto-connect-multi-dev" into pi-dev

* changes:
  PhonyPolicy: Don't connect other profiles if all profiles are disconnected
  PhonePolicy: Stop auto connecting to devices that failed to connect
  PhonePolicy: Gate CONNECT_OTHER_PROFILE per device
parents de7a8188 e8aa95a6
Loading
Loading
Loading
Loading
+86 −53
Original line number Diff line number Diff line
@@ -80,13 +80,15 @@ class PhonePolicy {
    private static final int MESSAGE_ADAPTER_STATE_TURNED_ON = 4;

    // Timeouts
    private static final int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s
    @VisibleForTesting
    static int sConnectOtherProfilesTimeoutMillis = 6000; // 6s

    private final AdapterService mAdapterService;
    private final ServiceFactory mFactory;
    private final Handler mHandler;
    private final HashSet<BluetoothDevice> mHeadsetRetrySet = new HashSet<>();
    private final HashSet<BluetoothDevice> mA2dpRetrySet = new HashSet<>();
    private final HashSet<BluetoothDevice> mConnectOtherProfilesDeviceSet = new HashSet<>();

    // Broadcast receiver for all changes to states of various profiles
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -167,12 +169,14 @@ class PhonePolicy {
                }
                break;

                case MESSAGE_CONNECT_OTHER_PROFILES:
                case MESSAGE_CONNECT_OTHER_PROFILES: {
                    // Called when we try connect some profiles in processConnectOtherProfiles but
                    // we send a delayed message to try connecting the remaining profiles
                    processConnectOtherProfiles((BluetoothDevice) msg.obj);
                    BluetoothDevice device = (BluetoothDevice) msg.obj;
                    processConnectOtherProfiles(device);
                    mConnectOtherProfilesDeviceSet.remove(device);
                    break;

                }
                case MESSAGE_ADAPTER_STATE_TURNED_ON:
                    // Call auto connect when adapter switches state to ON
                    resetStates();
@@ -254,8 +258,8 @@ class PhonePolicy {
            int prevState) {
        debugLog("processProfileStateChanged, device=" + device + ", profile=" + profileId + ", "
                + prevState + " -> " + nextState);
        if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET)) && (
                nextState == BluetoothProfile.STATE_CONNECTED)) {
        if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET))) {
            if (nextState == BluetoothProfile.STATE_CONNECTED) {
                switch (profileId) {
                    case BluetoothProfile.A2DP:
                        mA2dpRetrySet.remove(device);
@@ -265,7 +269,13 @@ class PhonePolicy {
                        break;
                }
                connectOtherProfile(device);
            setProfileAutoConnectionPriority(device, profileId);
                setProfileAutoConnectionPriority(device, profileId, true);
            }
            if (prevState == BluetoothProfile.STATE_CONNECTING
                    && nextState == BluetoothProfile.STATE_DISCONNECTED) {
                setProfileAutoConnectionPriority(device, profileId, false);
            }

        }
    }

@@ -341,12 +351,18 @@ class PhonePolicy {
    }

    private void connectOtherProfile(BluetoothDevice device) {
        if ((!mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES))
                && (!mAdapterService.isQuietModeEnabled())) {
        if (mAdapterService.isQuietModeEnabled()) {
            debugLog("connectOtherProfile: in quiet mode, skip connect other profile " + device);
            return;
        }
        if (mConnectOtherProfilesDeviceSet.contains(device)) {
            debugLog("connectOtherProfile: already scheduled callback for " + device);
            return;
        }
        mConnectOtherProfilesDeviceSet.add(device);
        Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES);
        m.obj = device;
            mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT);
        }
        mHandler.sendMessageDelayed(m, sConnectOtherProfilesTimeoutMillis);
    }

    // This function is called whenever a profile is connected.  This allows any other bluetooth
@@ -363,6 +379,7 @@ class PhonePolicy {
        A2dpService a2dpService = mFactory.getA2dpService();
        PanService panService = mFactory.getPanService();

        boolean atLeastOneProfileConnectedForDevice = false;
        boolean allProfilesEmpty = true;
        List<BluetoothDevice> a2dpConnDevList = null;
        List<BluetoothDevice> hsConnDevList = null;
@@ -370,38 +387,45 @@ class PhonePolicy {

        if (hsService != null) {
            hsConnDevList = hsService.getConnectedDevices();
            allProfilesEmpty = allProfilesEmpty && hsConnDevList.isEmpty();
            allProfilesEmpty &= hsConnDevList.isEmpty();
            atLeastOneProfileConnectedForDevice |= hsConnDevList.contains(device);
        }
        if (a2dpService != null) {
            a2dpConnDevList = a2dpService.getConnectedDevices();
            allProfilesEmpty = allProfilesEmpty && a2dpConnDevList.isEmpty();
            allProfilesEmpty &= a2dpConnDevList.isEmpty();
            atLeastOneProfileConnectedForDevice |= a2dpConnDevList.contains(device);
        }
        if (panService != null) {
            panConnDevList = panService.getConnectedDevices();
            allProfilesEmpty = allProfilesEmpty && panConnDevList.isEmpty();
            allProfilesEmpty &= panConnDevList.isEmpty();
            atLeastOneProfileConnectedForDevice |= panConnDevList.contains(device);
        }

        if (allProfilesEmpty) {
            // considered as fully disconnected, don't bother connecting others.
        if (!atLeastOneProfileConnectedForDevice) {
            // Consider this device as fully disconnected, don't bother connecting others
            debugLog("processConnectOtherProfiles, all profiles disconnected for " + device);
            // reset retry status so that in the next round we can start retrying connections again
            mHeadsetRetrySet.remove(device);
            mA2dpRetrySet.remove(device);
            if (allProfilesEmpty) {
                debugLog("processConnectOtherProfiles, all profiles disconnected for all devices");
                // reset retry status so that in the next round we can start retrying connections
                resetStates();
            }
            return;
        }

        if (hsService != null) {
            if (!mHeadsetRetrySet.contains(device) && (
                    hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (
                    hsService.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED)) {
            if (!mHeadsetRetrySet.contains(device) && (hsService.getPriority(device)
                    >= BluetoothProfile.PRIORITY_ON) && (hsService.getConnectionState(device)
                    == BluetoothProfile.STATE_DISCONNECTED)) {
                debugLog("Retrying connection to Headset with device " + device);
                mHeadsetRetrySet.add(device);
                hsService.connect(device);
            }
        }
        if (a2dpService != null) {
            if (!mA2dpRetrySet.contains(device) && (
                    a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (
                    a2dpService.getConnectionState(device)
            if (!mA2dpRetrySet.contains(device) && (a2dpService.getPriority(device)
                    >= BluetoothProfile.PRIORITY_ON) && (a2dpService.getConnectionState(device)
                    == BluetoothProfile.STATE_DISCONNECTED)) {
                debugLog("Retrying connection to A2DP with device " + device);
                mA2dpRetrySet.add(device);
@@ -420,51 +444,60 @@ class PhonePolicy {
        }
    }

    private void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) {
    private void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId,
            boolean autoConnect) {
        debugLog("setProfileAutoConnectionPriority: device=" + device + ", profile=" + profileId
                + ", autoConnect=" + autoConnect);
        switch (profileId) {
            case BluetoothProfile.HEADSET:
            case BluetoothProfile.HEADSET: {
                HeadsetService hsService = mFactory.getHeadsetService();
                if ((hsService != null) && (BluetoothProfile.PRIORITY_AUTO_CONNECT
                        != hsService.getPriority(device))) {
                    List<BluetoothDevice> deviceList = hsService.getConnectedDevices();
                    adjustOtherHeadsetPriorities(hsService, deviceList);
                if (hsService == null) {
                    warnLog("setProfileAutoConnectionPriority: HEADSET service is null");
                    break;
                }
                removeAutoConnectFromDisconnectedHeadsets(hsService);
                if (autoConnect) {
                    hsService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT);
                }
                break;

            case BluetoothProfile.A2DP:
            }
            case BluetoothProfile.A2DP: {
                A2dpService a2dpService = mFactory.getA2dpService();
                if ((a2dpService != null) && (BluetoothProfile.PRIORITY_AUTO_CONNECT
                        != a2dpService.getPriority(device))) {
                    List<BluetoothDevice> deviceList = a2dpService.getConnectedDevices();
                    adjustOtherSinkPriorities(a2dpService, deviceList);
                if (a2dpService == null) {
                    warnLog("setProfileAutoConnectionPriority: A2DP service is null");
                    break;
                }
                removeAutoConnectFromDisconnectedA2dpSinks(a2dpService);
                if (autoConnect) {
                    a2dpService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT);
                }
                break;

            }
            default:
                Log.w(TAG, "Tried to set AutoConnect priority on invalid profile " + profileId);
                break;
        }
    }

    private void adjustOtherHeadsetPriorities(HeadsetService hsService,
            List<BluetoothDevice> connectedDeviceList) {
    private void removeAutoConnectFromDisconnectedHeadsets(HeadsetService hsService) {
        List<BluetoothDevice> connectedDeviceList = hsService.getConnectedDevices();
        for (BluetoothDevice device : mAdapterService.getBondedDevices()) {
            if (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT
                    && !connectedDeviceList.contains(device)) {
                debugLog("adjustOtherHeadsetPriorities, device " + device + " PRIORITY_ON");
                debugLog("removeAutoConnectFromDisconnectedHeadsets, device " + device
                        + " PRIORITY_ON");
                hsService.setPriority(device, BluetoothProfile.PRIORITY_ON);
            }
        }
    }

    private void adjustOtherSinkPriorities(A2dpService a2dpService,
            List<BluetoothDevice> connectedDeviceList) {
    private void removeAutoConnectFromDisconnectedA2dpSinks(A2dpService a2dpService) {
        List<BluetoothDevice> connectedDeviceList = a2dpService.getConnectedDevices();
        for (BluetoothDevice device : mAdapterService.getBondedDevices()) {
            if (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT
                    && !connectedDeviceList.contains(device)) {
                debugLog("adjustOtherSinkPriorities, device " + device + " PRIORITY_ON");
                debugLog("removeAutoConnectFromDisconnectedA2dpSinks, device " + device
                        + " PRIORITY_ON");
                a2dpService.setPriority(device, BluetoothProfile.PRIORITY_ON);
            }
        }
+298 −113

File changed.

Preview size limit exceeded, changes collapsed.