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

Commit 2948963f authored by jackqdyulei's avatar jackqdyulei
Browse files

Add ACL broadcast for bt devices

When we receive profile state change, the device may still be physically
connected(e.g. BluetoothDevice.isConnected() return true). In this case
UI still show a device is connected.

Add ACL broadcast listener which will be triggered when device is
physically disconnected. In this callback we can refresh UI to make it
show correct information.

Bug: 79947085
Test: RunSettingsLibRoboTests
Change-Id: I8370cc568fcb0d5995f164e7e62391a9525cbe19
parent 7cc7662d
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -127,4 +127,17 @@ public interface BluetoothCallback {
    default void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice,
            int state, int bluetoothProfile) {
    }

    /**
     * Called when ACL connection state is changed. It listens to
     * {@link android.bluetooth.BluetoothDevice#ACTION_ACL_CONNECTED} and {@link
     * android.bluetooth.BluetoothDevice#ACTION_ACL_DISCONNECTED}
     *
     * @param cachedDevice Bluetooth device that changed
     * @param state        the Bluetooth device connection state, the possible values are:
     *                     {@link android.bluetooth.BluetoothAdapter#STATE_DISCONNECTED},
     *                     {@link android.bluetooth.BluetoothAdapter#STATE_CONNECTED}
     */
    default void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
    }
}
+39 −0
Original line number Diff line number Diff line
@@ -119,6 +119,10 @@ public class BluetoothEventManager {
        addHandler(TelephonyManager.ACTION_PHONE_STATE_CHANGED,
                new AudioModeChangedHandler());

        // ACL connection changed broadcasts
        addHandler(BluetoothDevice.ACTION_ACL_CONNECTED, new AclStateChangedHandler());
        addHandler(BluetoothDevice.ACTION_ACL_DISCONNECTED, new AclStateChangedHandler());

        registerAdapterIntentReceiver();
    }

@@ -236,6 +240,15 @@ public class BluetoothEventManager {
        }
    }

    private void dispatchAclStateChanged(CachedBluetoothDevice activeDevice,
            int state) {
        synchronized (mCallbacks) {
            for (BluetoothCallback callback : mCallbacks) {
                callback.onAclConnectionStateChanged(activeDevice, state);
            }
        }
    }

    @VisibleForTesting
    void addHandler(String action, Handler handler) {
        mHandlerMap.put(action, handler);
@@ -447,6 +460,32 @@ public class BluetoothEventManager {
        }
    }

    private class AclStateChangedHandler implements Handler {
        @Override
        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
            final String action = intent.getAction();
            if (action == null) {
                Log.w(TAG, "AclStateChangedHandler: action is null");
                return;
            }
            final CachedBluetoothDevice activeDevice = mDeviceManager.findDevice(device);
            final int state;
            switch (action) {
                case BluetoothDevice.ACTION_ACL_CONNECTED:
                    state = BluetoothAdapter.STATE_CONNECTED;
                    break;
                case BluetoothDevice.ACTION_ACL_DISCONNECTED:
                    state = BluetoothAdapter.STATE_DISCONNECTED;
                    break;
                default:
                    Log.w(TAG, "ActiveDeviceChangedHandler: unknown action " + action);
                    return;

            }
            dispatchAclStateChanged(activeDevice, state);
        }
    }

    private class AudioModeChangedHandler implements Handler {

        @Override
+30 −0
Original line number Diff line number Diff line
@@ -19,7 +19,10 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
@@ -50,6 +53,8 @@ public class BluetoothEventManagerTest {
    private BluetoothCallback mBluetoothCallback;
    @Mock
    private CachedBluetoothDevice mCachedBluetoothDevice;
    @Mock
    private BluetoothDevice mBluetoothDevice;

    private Context mContext;
    private Intent mIntent;
@@ -62,6 +67,7 @@ public class BluetoothEventManagerTest {

        mBluetoothEventManager = new BluetoothEventManager(mLocalAdapter,
                mCachedDeviceManager, mContext, /* handler= */ null, /* userHandle= */ null);
        when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
    }

    @Test
@@ -126,4 +132,28 @@ public class BluetoothEventManagerTest {
        verify(mBluetoothCallback).onProfileConnectionStateChanged(mCachedBluetoothDevice,
                BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
    }

    @Test
    public void dispatchAclConnectionStateChanged_aclDisconnected_shouldDispatchCallback() {
        mBluetoothEventManager.registerCallback(mBluetoothCallback);
        mIntent = new Intent(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);

        mContext.sendBroadcast(mIntent);

        verify(mBluetoothCallback).onAclConnectionStateChanged(mCachedBluetoothDevice,
                BluetoothAdapter.STATE_DISCONNECTED);
    }

    @Test
    public void dispatchAclConnectionStateChanged_aclConnected_shouldDispatchCallback() {
        mBluetoothEventManager.registerCallback(mBluetoothCallback);
        mIntent = new Intent(BluetoothDevice.ACTION_ACL_CONNECTED);
        mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);

        mContext.sendBroadcast(mIntent);

        verify(mBluetoothCallback).onAclConnectionStateChanged(mCachedBluetoothDevice,
                BluetoothAdapter.STATE_CONNECTED);
    }
}