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

Commit 00636461 authored by Ugo Yu's avatar Ugo Yu Committed by Hansong Zhang
Browse files

DO NOT MERGE Separate SDP procedure from bonding state (2/2)

- Do not stay in bonding state if the device is paried but still
  discovering service.
- Report BOND_BONDED to Java after authentication is completed.
- Change bond state to bond none if a classic Bluetooth device
  SDP failed while pairing.
- Hold BOND_BONDED intent util SDP is findished.
- Only accept profile connection for the device is at bonded
  state. Any attempt to connect while bonding would potentially
  lead to an unauthorized connection.

Bug: 79703832
Test: runtest bluetooth, regression test
Change-Id: Ic43bb63fa5d4f10e08e577483f568f8025f0b1f3
Merged-In: Ic43bb63fa5d4f10e08e577483f568f8025f0b1f3
(cherry picked from commit c9c30ef6f8b4f54f66fbfa2c1c0a9826f89b05e2)
parent c82e3831
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -878,8 +878,10 @@ final class A2dpStateMachine extends StateMachine {
        else if((BluetoothProfile.PRIORITY_OFF < priority) ||
                ((BluetoothProfile.PRIORITY_UNDEFINED == priority) &&
                (device.getBondState() != BluetoothDevice.BOND_NONE))){
            if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                ret = true;
            }
        }
        return ret;
    }

+3 −1
Original line number Diff line number Diff line
@@ -716,8 +716,10 @@ public class A2dpSinkStateMachine extends StateMachine {
        if((BluetoothProfile.PRIORITY_OFF < priority) ||
                ((BluetoothProfile.PRIORITY_UNDEFINED == priority) &&
                (device.getBondState() != BluetoothDevice.BOND_NONE))){
            if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                return true;
            }
        }
        logw("okToConnect not OK to connect " + device);
        return false;
    }
+12 −0
Original line number Diff line number Diff line
@@ -1582,6 +1582,18 @@ public class AdapterService extends Service {
        }
    }

    /**
     * Update device UUID changed to {@link BondStateMachine}
     *
     * @param device remote device of interest
     */
    public void deviceUuidUpdated(BluetoothDevice device) {
        // Notify BondStateMachine for SDP complete / UUID changed.
        Message msg = mBondStateMachine.obtainMessage(BondStateMachine.UUID_UPDATE);
        msg.obj = device;
        mBondStateMachine.sendMessage(msg);
    }

    boolean cancelBondProcess(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        byte[] addr = Utils.getBytesFromAddress(device.getAddress());
+42 −1
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ import com.android.internal.util.State;
import com.android.internal.util.StateMachine;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

/**
 * This state machine handles Bluetooth Adapter State.
@@ -59,6 +61,7 @@ final class BondStateMachine extends StateMachine {
    static final int BONDING_STATE_CHANGE = 4;
    static final int SSP_REQUEST = 5;
    static final int PIN_REQUEST = 6;
    static final int UUID_UPDATE = 10;
    static final int BOND_STATE_NONE = 0;
    static final int BOND_STATE_BONDING = 1;
    static final int BOND_STATE_BONDED = 2;
@@ -68,6 +71,7 @@ final class BondStateMachine extends StateMachine {
    private RemoteDevices mRemoteDevices;
    private BluetoothAdapter mAdapter;

    private Set<BluetoothDevice> mPendingBondedDevices = new HashSet<>();
    private PendingCommandState mPendingCommandState = new PendingCommandState();
    private StableState mStableState = new StableState();

@@ -144,6 +148,11 @@ final class BondStateMachine extends StateMachine {
                    Log.e(TAG, "In stable state, received invalid newState: " + newState);
                }
                break;
              case UUID_UPDATE:
                  if (mPendingBondedDevices.contains(dev)) {
                      sendIntent(dev, BluetoothDevice.BOND_BONDED, 0);
                  }
                  break;

              case CANCEL_BOND:
              default:
@@ -332,12 +341,44 @@ final class BondStateMachine extends StateMachine {
    private void sendIntent(BluetoothDevice device, int newState, int reason) {
        DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device);
        int oldState = BluetoothDevice.BOND_NONE;
        if (newState != BluetoothDevice.BOND_NONE && newState != BluetoothDevice.BOND_BONDING
                && newState != BluetoothDevice.BOND_BONDED) {
            infoLog("Invalid bond state " + newState);
            return;
        }
        if (devProp != null) {
            oldState = devProp.getBondState();
        }
        if (oldState == newState) return;
        if (mPendingBondedDevices.contains(device)) {
            mPendingBondedDevices.remove(device);
            if (oldState == BluetoothDevice.BOND_BONDED) {
                if (newState == BluetoothDevice.BOND_BONDING) {
                    mAdapterProperties.onBondStateChanged(device, newState);
                }
                oldState = BluetoothDevice.BOND_BONDING;
            } else {
                // Should not enter here.
                throw new IllegalArgumentException("Invalid old state " + oldState);
            }
        }

        mAdapterProperties.onBondStateChanged(device, newState);

        if ((devProp.getDeviceType() == BluetoothDevice.DEVICE_TYPE_CLASSIC
                    || devProp.getDeviceType() == BluetoothDevice.DEVICE_TYPE_DUAL)
                && newState == BluetoothDevice.BOND_BONDED && devProp.getUuids() == null) {
            infoLog(device + " is bonded, wait for SDP complete to broadcast bonded intent");
            if (!mPendingBondedDevices.contains(device)) {
                mPendingBondedDevices.add(device);
            }
            if (oldState == BluetoothDevice.BOND_NONE) {
                // Broadcast NONE->BONDING for NONE->BONDED case.
                newState = BluetoothDevice.BOND_BONDING;
            } else {
                return;
            }
        }

        Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, newState);
+3 −1
Original line number Diff line number Diff line
@@ -347,8 +347,10 @@ final class RemoteDevices {
                        case AbstractionLayer.BT_PROPERTY_UUIDS:
                            int numUuids = val.length/AbstractionLayer.BT_UUID_SIZE;
                            device.mUuids = Utils.byteArrayToUuid(val);
                            if (mAdapterService.getState() == BluetoothAdapter.STATE_ON)
                            if (mAdapterService.getState() == BluetoothAdapter.STATE_ON) {
                                mAdapterService.deviceUuidUpdated(bdDevice);
                                sendUuidIntent(bdDevice);
                            }
                            break;
                        case AbstractionLayer.BT_PROPERTY_TYPE_OF_DEVICE:
                            // The device type from hal layer, defined in bluetooth.h,
Loading