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

Commit e3976aaf authored by android-build-prod (mdb)'s avatar android-build-prod (mdb) Committed by android-build-merger
Browse files

Merge "Hearing Aid: fix logic in connect and disconnect" am: bf668ef0 am: 056519be

am: dd24622c

Change-Id: I101b18fc00e31af0c21928eeac5c67ff12d7d016
parents 3e39bdb8 dd24622c
Loading
Loading
Loading
Loading
+42 −28
Original line number Original line Diff line number Diff line
@@ -212,6 +212,9 @@ public class HearingAidService extends ProfileService {
        if (DBG) {
        if (DBG) {
            Log.d(TAG, "connect(): " + device);
            Log.d(TAG, "connect(): " + device);
        }
        }
        if (device == null) {
            return false;
        }


        if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
        if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
            return false;
            return false;
@@ -222,16 +225,35 @@ public class HearingAidService extends ProfileService {
            return false;
            return false;
        }
        }


        long hiSyncId = mDeviceHiSyncIdMap.getOrDefault(device,
                BluetoothHearingAid.HI_SYNC_ID_INVALID);

        if (hiSyncId != mActiveDeviceHiSyncId) {
            for (BluetoothDevice connectedDevice : getConnectedDevices()) {
                disconnect(connectedDevice);
            }
        }

        for (BluetoothDevice storedDevice : mDeviceHiSyncIdMap.keySet()) {
            if (mDeviceHiSyncIdMap.getOrDefault(storedDevice,
                    BluetoothHearingAid.HI_SYNC_ID_INVALID) == hiSyncId) {
                synchronized (mStateMachines) {
                synchronized (mStateMachines) {
            HearingAidStateMachine smConnect = getOrCreateStateMachine(device);
                    HearingAidStateMachine sm = getOrCreateStateMachine(storedDevice);
            if (smConnect == null) {
                    if (sm == null) {
                Log.e(TAG, "Cannot connect to " + device + " : no state machine");
                        Log.e(TAG, "Ignored connect request for " + device + " : no state machine");
                return false;
                        continue;
                    }
                    }
            smConnect.sendMessage(HearingAidStateMachine.CONNECT);
                    sm.sendMessage(HearingAidStateMachine.CONNECT);
            return true;

                }
                if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID
                        && !device.equals(storedDevice)) {
                    break;
                }
                }
            }
            }
        }
        return true;
    }


    boolean disconnect(BluetoothDevice device) {
    boolean disconnect(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
@@ -243,32 +265,24 @@ public class HearingAidService extends ProfileService {
        }
        }
        long hiSyncId = mDeviceHiSyncIdMap.getOrDefault(device,
        long hiSyncId = mDeviceHiSyncIdMap.getOrDefault(device,
                BluetoothHearingAid.HI_SYNC_ID_INVALID);
                BluetoothHearingAid.HI_SYNC_ID_INVALID);
        synchronized (mStateMachines) {
            HearingAidStateMachine sm = mStateMachines.get(device);
            if (sm == null) {
                Log.e(TAG, "Ignored disconnect request for " + device + " : no state machine");
            } else {
                sm.sendMessage(HearingAidStateMachine.DISCONNECT);
            }
        }
        if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID) {
            return true;
        }


        for (BluetoothDevice storedDevice : mDeviceHiSyncIdMap.keySet()) {
        for (BluetoothDevice storedDevice : mDeviceHiSyncIdMap.keySet()) {
            if (mDeviceHiSyncIdMap.getOrDefault(storedDevice,
            if (mDeviceHiSyncIdMap.getOrDefault(storedDevice,
                    BluetoothHearingAid.HI_SYNC_ID_INVALID) != hiSyncId
                    BluetoothHearingAid.HI_SYNC_ID_INVALID) == hiSyncId) {
                    || storedDevice.equals(device)) {
                continue;
            }
                synchronized (mStateMachines) {
                synchronized (mStateMachines) {
                    HearingAidStateMachine sm = mStateMachines.get(storedDevice);
                    HearingAidStateMachine sm = mStateMachines.get(storedDevice);
                    if (sm == null) {
                    if (sm == null) {
                    Log.e(TAG, "Ignored disconnect request for " + device + " : no state machine");
                        Log.e(TAG, "Ignored disconnect request for " + device
                                + " : no state machine");
                        continue;
                        continue;
                    }
                    }
                    sm.sendMessage(HearingAidStateMachine.DISCONNECT);
                    sm.sendMessage(HearingAidStateMachine.DISCONNECT);
                }
                }
                if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID
                        && !device.equals(storedDevice)) {
                    break;
                }
            }
        }
        }
        return true;
        return true;
    }
    }
+89 −2
Original line number Original line Diff line number Diff line
@@ -106,8 +106,8 @@ public class HearingAidServiceTest {


        // Get a device for testing
        // Get a device for testing
        mLeftDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05");
        mLeftDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05");
        mRightDevice = mAdapter.getRemoteDevice("00:01:02:03:04:06");
        mRightDevice = mAdapter.getRemoteDevice("00:01:02:33:44:55");
        mSingleDevice = mAdapter.getRemoteDevice("00:01:02:03:04:00");
        mSingleDevice = mAdapter.getRemoteDevice("10:11:12:13:14:15");
        mService.setPriority(mLeftDevice, BluetoothProfile.PRIORITY_UNDEFINED);
        mService.setPriority(mLeftDevice, BluetoothProfile.PRIORITY_UNDEFINED);
        mService.setPriority(mRightDevice, BluetoothProfile.PRIORITY_UNDEFINED);
        mService.setPriority(mRightDevice, BluetoothProfile.PRIORITY_UNDEFINED);
        mService.setPriority(mSingleDevice, BluetoothProfile.PRIORITY_UNDEFINED);
        mService.setPriority(mSingleDevice, BluetoothProfile.PRIORITY_UNDEFINED);
@@ -337,6 +337,93 @@ public class HearingAidServiceTest {
                mService.getConnectionState(mLeftDevice));
                mService.getConnectionState(mLeftDevice));
    }
    }


    /**
     * Test that the Hearing Aid Service connects to left and right device at the same time.
     */
    @Test
    public void testConnectAPair_connectBothDevices() {
        HearingAidStackEvent connCompletedEvent;

        // Update the device priority so okToConnect() returns true
        mService.setPriority(mLeftDevice, BluetoothProfile.PRIORITY_ON);
        mService.setPriority(mRightDevice, BluetoothProfile.PRIORITY_ON);
        doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class));
        doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class));

        // Send a connect request
        Assert.assertTrue("Connect failed", mService.connect(mLeftDevice));

        // Verify the connection state broadcast, and that we are in Connecting state
        verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING,
                BluetoothProfile.STATE_DISCONNECTED);
        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
                mService.getConnectionState(mLeftDevice));
        verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTING,
                BluetoothProfile.STATE_DISCONNECTED);
        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
                mService.getConnectionState(mRightDevice));
    }

    /**
     * Test that the service disconnects the current pair before connecting to another pair.
     */
    @Test
    public void testConnectAnotherPair_disconnectCurrentPair() {
        HearingAidStackEvent connCompletedEvent;

        // Update the device priority so okToConnect() returns true
        mService.setPriority(mLeftDevice, BluetoothProfile.PRIORITY_ON);
        mService.setPriority(mRightDevice, BluetoothProfile.PRIORITY_ON);
        mService.setPriority(mSingleDevice, BluetoothProfile.PRIORITY_ON);
        doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class));
        doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class));

        // Send a connect request
        Assert.assertTrue("Connect failed", mService.connect(mLeftDevice));

        // Verify the connection state broadcast, and that we are in Connecting state
        verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING,
                BluetoothProfile.STATE_DISCONNECTED);
        verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTING,
                BluetoothProfile.STATE_DISCONNECTED);


        // Send a message to trigger connection completed
        connCompletedEvent = new HearingAidStackEvent(
                HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
        connCompletedEvent.device = mLeftDevice;
        connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED;
        mService.messageFromNative(connCompletedEvent);
        connCompletedEvent = new HearingAidStackEvent(
                HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
        connCompletedEvent.device = mRightDevice;
        connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED;
        mService.messageFromNative(connCompletedEvent);

        // Verify the connection state broadcast, and that we are in Connected state for right side
        verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTED,
                BluetoothProfile.STATE_CONNECTING);
        verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTED,
                BluetoothProfile.STATE_CONNECTING);

        // Send a connect request for another pair
        Assert.assertTrue("Connect failed", mService.connect(mSingleDevice));

        // Verify the connection state broadcast, and that the first pair is in Disconnecting state
        verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_DISCONNECTING,
                BluetoothProfile.STATE_CONNECTED);
        verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_DISCONNECTING,
                BluetoothProfile.STATE_CONNECTED);
        Assert.assertFalse(mService.getConnectedDevices().contains(mLeftDevice));
        Assert.assertFalse(mService.getConnectedDevices().contains(mRightDevice));

        // Verify the connection state broadcast, and that the second device is in Connecting state
        verifyConnectionStateIntent(TIMEOUT_MS, mSingleDevice, BluetoothProfile.STATE_CONNECTING,
                BluetoothProfile.STATE_DISCONNECTED);
        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
                mService.getConnectionState(mSingleDevice));
    }

    /**
    /**
     * Test that the outgoing connect/disconnect and audio switch is successful.
     * Test that the outgoing connect/disconnect and audio switch is successful.
     */
     */