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

Commit 55f496f8 authored by Aritra Sen's avatar Aritra Sen
Browse files

Register Adapter state change callback with adapter service instead of relying on callback.

Tag: #refactor
Bug: 296932947
Test: atest BluetoothInstrumentationTests
Change-Id: I34f950a698466bb10c339a204e1e88d28e2991f4
parent 6095d69c
Loading
Loading
Loading
Loading
+15 −30
Original line number Diff line number Diff line
@@ -57,20 +57,6 @@ import java.util.Objects;

// Describes the phone policy
//
// The policy should be as decoupled from the stack as possible. In an ideal world we should not
// need to have this policy talk with any non-public APIs and one way to enforce that would be to
// keep this file outside the Bluetooth process. Unfortunately, keeping a separate process alive is
// an expensive and a tedious task.
//
// Best practices:
// a) PhonePolicy should be ALL private methods
//    -- Use broadcasts which can be listened in on the BroadcastReceiver
// b) NEVER call from the PhonePolicy into the Java stack, unless public APIs. It is OK to call into
// the non public versions as long as public versions exist (so that a 3rd party policy can mimick)
// us.
//
// Policy description:
//
// Policies are usually governed by outside events that may warrant an action. We talk about various
// events and the resulting outcome from this policy:
//
@@ -80,13 +66,12 @@ import java.util.Objects;
// 2. When the profile connection-state changes: At this point if a new profile gets CONNECTED we
// will try to connect other profiles on the same device. This is to avoid collision if devices
// somehow end up trying to connect at same time or general connection issues.
class PhonePolicy {
class PhonePolicy implements AdapterService.BluetoothStateCallback {
    private static final boolean DBG = true;
    private static final String TAG = "BluetoothPhonePolicy";

    // Message types for the handler (internal messages generated by intents or timeouts)
    private static final int MESSAGE_CONNECT_OTHER_PROFILES = 3;
    private static final int MESSAGE_ADAPTER_STATE_TURNED_ON = 4;
    private static final int MESSAGE_DEVICE_CONNECTED = 6;

    @VisibleForTesting static final String AUTO_CONNECT_PROFILES_PROPERTY =
@@ -108,6 +93,16 @@ class PhonePolicy {
    private final HashSet<BluetoothDevice> mConnectOtherProfilesDeviceSet = new HashSet<>();
    @VisibleForTesting boolean mAutoConnectProfilesSupported;

    @Override
    public void onBluetoothStateChange(int prevState, int newState) {
        // Only act if the adapter has actually changed state from non-ON to ON.
        // NOTE: ON is the state depicting BREDR ON and not just BLE ON.
        if (newState == BluetoothAdapter.STATE_ON) {
            resetStates();
            autoConnect();
        }
    }

    public void profileConnectionStateChanged(
            int profile, BluetoothDevice device, int fromState, int toState) {
        switch (profile) {
@@ -144,14 +139,6 @@ class PhonePolicy {
                return;
            }
            switch (action) {
                case BluetoothAdapter.ACTION_STATE_CHANGED:
                    // Only pass the message on if the adapter has actually changed state from
                    // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON.
                    int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
                    if (newState == BluetoothAdapter.STATE_ON) {
                        mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget();
                    }
                    break;
                case BluetoothDevice.ACTION_ACL_CONNECTED:
                    mHandler.obtainMessage(MESSAGE_DEVICE_CONNECTED, intent).sendToTarget();
                    break;
@@ -184,16 +171,12 @@ class PhonePolicy {
                    mConnectOtherProfilesDeviceSet.remove(device);
                    break;
                }
                case MESSAGE_ADAPTER_STATE_TURNED_ON:
                    // Call auto connect when adapter switches state to ON
                    resetStates();
                    autoConnect();
                    break;
                case MESSAGE_DEVICE_CONNECTED:
                    Intent intent = (Intent) msg.obj;
                    BluetoothDevice device =
                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    processDeviceConnected(device);
                    break;
            }
        }
    }
@@ -202,14 +185,16 @@ class PhonePolicy {

    // Policy API functions for lifecycle management (protected)
    protected void start() {
        mAdapterService.registerBluetoothStateCallback((command) -> mHandler.post(command), this);

        IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        mAdapterService.registerReceiver(mReceiver, filter);
    }

    protected void cleanup() {
        mAdapterService.unregisterBluetoothStateCallback(this);
        mAdapterService.unregisterReceiver(mReceiver);
        resetStates();
    }
+3 −5
Original line number Diff line number Diff line
@@ -323,13 +323,11 @@ public class PhonePolicyTest {
                BluetoothProfile.CONNECTION_POLICY_ALLOWED);

        // Inject an event that the adapter is turned on.
        Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
        intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
        mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent);
        mPhonePolicy.onBluetoothStateChange(BluetoothAdapter.STATE_OFF, BluetoothAdapter.STATE_ON);

        // Check that we got a request to connect over HFP and A2DP
        verify(mA2dpService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connect(eq(bondedDevice));
        verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).connect(eq(bondedDevice));
        verify(mA2dpService).connect(eq(bondedDevice));
        verify(mHeadsetService).connect(eq(bondedDevice));
    }

    /**