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

Commit 9abb767f authored by Pulkit Bhuwalka's avatar Pulkit Bhuwalka
Browse files

Get/Set IO capabilities of Bluetooth device

Adds the backend service methods to call into Bluetooth native
stack and store/retrieve Bluetooth IO capabilities of the device. This
allows a user to use different flows of pairing based on their
device.

Bug: 36015413
Test: Used a test activity to set different values and pair accordingly.
Change-Id: I96690f88ea5ca14655e187be416c5066eb072217
(cherry picked from commit cd84c54a0ac6cc549673631eefbde6680a189527)
parent d76d6706
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -52,6 +52,9 @@ public final class AbstractionLayer {
    public static final int BT_DEVICE_TYPE_BLE = 0x02;
    public static final int BT_DEVICE_TYPE_DUAL = 0x03;

    static final int BT_PROPERTY_LOCAL_IO_CAPS = 0x0e;
    static final int BT_PROPERTY_LOCAL_IO_CAPS_BLE = 0x0f;

    static final int BT_BOND_STATE_NONE = 0x00;
    static final int BT_BOND_STATE_BONDING = 0x01;
    static final int BT_BOND_STATE_BONDED = 0x02;
+52 −0
Original line number Diff line number Diff line
@@ -76,6 +76,9 @@ class AdapterProperties {
    private volatile int mScanMode;
    private volatile int mDiscoverableTimeout;
    private volatile ParcelUuid[] mUuids;
    private volatile int mLocalIOCapability = BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
    private volatile int mLocalIOCapabilityBLE = BluetoothAdapter.IO_CAPABILITY_UNKNOWN;

    private CopyOnWriteArrayList<BluetoothDevice> mBondedDevices =
            new CopyOnWriteArrayList<BluetoothDevice>();

@@ -286,6 +289,45 @@ class AdapterProperties {
        }
    }

    boolean setIoCapability(int capability) {
        synchronized (mObject) {
            boolean result = mService.setAdapterPropertyNative(
                    AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS, Utils.intToByteArray(capability));

            if (result) {
                mLocalIOCapability = capability;
            }

            return result;
        }
    }

    int getIoCapability() {
        synchronized (mObject) {
            return mLocalIOCapability;
        }
    }

    boolean setLeIoCapability(int capability) {
        synchronized (mObject) {
            boolean result = mService.setAdapterPropertyNative(
                    AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS_BLE,
                    Utils.intToByteArray(capability));

            if (result) {
                mLocalIOCapabilityBLE = capability;
            }

            return result;
        }
    }

    int getLeIoCapability() {
        synchronized (mObject) {
            return mLocalIOCapabilityBLE;
        }
    }

    /**
     * @return the mScanMode
     */
@@ -792,6 +834,16 @@ class AdapterProperties {
                        updateFeatureSupport(val);
                        break;

                    case AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS:
                        mLocalIOCapability = Utils.byteArrayToInt(val);
                        debugLog("mLocalIOCapability set to " + mLocalIOCapability);
                        break;

                    case AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS_BLE:
                        mLocalIOCapabilityBLE = Utils.byteArrayToInt(val);
                        debugLog("mLocalIOCapabilityBLE set to " + mLocalIOCapabilityBLE);
                        break;

                    default:
                        errorLog("Property change not handled in Java land:" + type);
                }
+93 −0
Original line number Diff line number Diff line
@@ -277,6 +277,8 @@ public class AdapterService extends Service {
                        mAdapterProperties.onBluetoothReady();
                        updateUuids();
                        setBluetoothClassFromConfig();
                        getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS);
                        getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS_BLE);
                        mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
                    }
                    break;
@@ -873,6 +875,7 @@ public class AdapterService extends Service {
            return service.setName(name);
        }

        @Override
        public BluetoothClass getBluetoothClass() {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "getBluetoothClass() - Not allowed for non-active user");
@@ -884,6 +887,7 @@ public class AdapterService extends Service {
            return service.getBluetoothClass();
        }

        @Override
        public boolean setBluetoothClass(BluetoothClass bluetoothClass) {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "setBluetoothClass() - Not allowed for non-active user");
@@ -897,6 +901,54 @@ public class AdapterService extends Service {
            return service.setBluetoothClass(bluetoothClass);
        }

        @Override
        public int getIoCapability() {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "setBluetoothClass() - Not allowed for non-active user");
                return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
            }

            AdapterService service = getService();
            if (service == null) return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
            return service.getIoCapability();
        }

        @Override
        public boolean setIoCapability(int capability) {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "setBluetoothClass() - Not allowed for non-active user");
                return false;
            }

            AdapterService service = getService();
            if (service == null) return false;
            return service.setIoCapability(capability);
        }

        @Override
        public int getLeIoCapability() {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "setBluetoothClass() - Not allowed for non-active user");
                return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
            }

            AdapterService service = getService();
            if (service == null) return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
            return service.getLeIoCapability();
        }

        @Override
        public boolean setLeIoCapability(int capability) {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "setBluetoothClass() - Not allowed for non-active user");
                return false;
            }

            AdapterService service = getService();
            if (service == null) return false;
            return service.setLeIoCapability(capability);
        }

        @Override
        public int getScanMode() {
            if (!Utils.checkCallerAllowManagedProfiles(mService)) {
@@ -1690,6 +1742,47 @@ public class AdapterService extends Service {
        return result && storeBluetoothClassConfig(bluetoothClass.getClassOfDevice());
    }

    private boolean validateInputOutputCapability(int capability) {
        if (capability < 0 || capability >= BluetoothAdapter.IO_CAPABILITY_MAX) {
            Log.e(TAG, "Invalid IO capability value - " + capability);
            return false;
        }

        return true;
    }

    int getIoCapability() {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");

        return mAdapterProperties.getIoCapability();
    }

    boolean setIoCapability(int capability) {
        enforceCallingOrSelfPermission(
                BLUETOOTH_PRIVILEGED, "Need BLUETOOTH PRIVILEGED permission");
        if (!validateInputOutputCapability(capability)) {
            return false;
        }

        return mAdapterProperties.setIoCapability(capability);
    }

    int getLeIoCapability() {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");

        return mAdapterProperties.getLeIoCapability();
    }

    boolean setLeIoCapability(int capability) {
        enforceCallingOrSelfPermission(
                BLUETOOTH_PRIVILEGED, "Need BLUETOOTH PRIVILEGED permission");
        if (!validateInputOutputCapability(capability)) {
            return false;
        }

        return mAdapterProperties.setLeIoCapability(capability);
    }

    int getScanMode() {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");