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

Commit 1cac38b5 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add new @SystemApi for specifying AddressType and IRK" am: 2c15f0cb

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1641559

Change-Id: I616502ee58d95cbc20fd38b395f7f0e294b5713e
parents 91ef4422 2c15f0cb
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -52,6 +52,8 @@ import android.os.SystemProperties;
import android.util.Log;
import android.util.Pair;

import com.android.internal.util.Preconditions;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -3118,6 +3120,25 @@ public final class BluetoothAdapter {
        return true;
    }

    /**
     * Determines whether a String Bluetooth address, such as "00:43:A8:23:10:F0"
     * is a RANDOM STATIC address.
     *
     * RANDOM STATIC: (addr & 0b11) == 0b11
     * RANDOM RESOLVABLE: (addr & 0b11) == 0b10
     * RANDOM non-RESOLVABLE: (addr & 0b11) == 0b00
     *
     * @param address Bluetooth address as string
     * @return true if the 2 Least Significant Bits of the address equals 0b11.
     *
     * @hide
     */
    public static boolean isAddressRandomStatic(@NonNull String address) {
        Preconditions.checkNotNull(address);
        return checkBluetoothAddress(address)
                && (Integer.parseInt(address.split(":")[5], 16) & 0b11) == 0b11;
    }

    @UnsupportedAppUsage
    /*package*/ IBluetoothManager getBluetoothManager() {
        return mManagerService;
+20 −0
Original line number Diff line number Diff line
@@ -1002,6 +1002,24 @@ public final class BluetoothDevice implements Parcelable {
    public static final String EXTRA_MAS_INSTANCE =
            "android.bluetooth.device.extra.MAS_INSTANCE";

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(
        prefix = { "ADDRESS_TYPE_" },
        value = {
            /** Hardware MAC Address */
            ADDRESS_TYPE_PUBLIC,
            /** Address is either resolvable, non-resolvable or static.*/
            ADDRESS_TYPE_RANDOM,
        }
    )
    public @interface AddressType {}

    /** Hardware MAC Address of the device */
    public static final int ADDRESS_TYPE_PUBLIC = 0;
    /** Address is either resolvable, non-resolvable or static. */
    public static final int ADDRESS_TYPE_RANDOM = 1;

    /**
     * Lazy initialization. Guaranteed final after first object constructed, or
     * getService() called.
@@ -1010,6 +1028,7 @@ public final class BluetoothDevice implements Parcelable {
    private static volatile IBluetooth sService;

    private final String mAddress;
    @AddressType private final int mAddressType;

    /*package*/
    @UnsupportedAppUsage
@@ -1064,6 +1083,7 @@ public final class BluetoothDevice implements Parcelable {
        }

        mAddress = address;
        mAddressType = ADDRESS_TYPE_PUBLIC;
    }

    @Override
+158 −5
Original line number Diff line number Diff line
@@ -16,15 +16,19 @@

package android.bluetooth.le;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice.AddressType;
import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.Parcelable;

import com.android.internal.util.BitUtils;
import com.android.internal.util.Preconditions;

import java.util.Arrays;
import java.util.List;
@@ -53,6 +57,11 @@ public final class ScanFilter implements Parcelable {
    @Nullable
    private final String mDeviceAddress;

    private final @AddressType int mAddressType;

    @Nullable
    private final byte[] mIrk;

    @Nullable
    private final ParcelUuid mServiceUuid;
    @Nullable
@@ -79,12 +88,12 @@ public final class ScanFilter implements Parcelable {
    /** @hide */
    public static final ScanFilter EMPTY = new ScanFilter.Builder().build();


    private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
            ParcelUuid uuidMask, ParcelUuid solicitationUuid,
            ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
            byte[] serviceData, byte[] serviceDataMask,
            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask) {
            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask,
            @AddressType int addressType, @Nullable byte[] irk) {
        mDeviceName = name;
        mServiceUuid = uuid;
        mServiceUuidMask = uuidMask;
@@ -97,6 +106,8 @@ public final class ScanFilter implements Parcelable {
        mManufacturerId = manufacturerId;
        mManufacturerData = manufacturerData;
        mManufacturerDataMask = manufacturerDataMask;
        mAddressType = addressType;
        mIrk = irk;
    }

    @Override
@@ -280,6 +291,23 @@ public final class ScanFilter implements Parcelable {
        return mDeviceAddress;
    }

    /**
     * @hide
     */
    @SystemApi
    public @AddressType int getAddressType() {
        return mAddressType;
    }

    /**
     * @hide
     */
    @SystemApi
    @Nullable
    public byte[] getIrk() {
        return mIrk;
    }

    @Nullable
    public byte[] getServiceData() {
        return mServiceData;
@@ -516,8 +544,16 @@ public final class ScanFilter implements Parcelable {
     */
    public static final class Builder {

        /**
         * @hide
         */
        @SystemApi
        public static final int LEN_IRK_OCTETS = 16;

        private String mDeviceName;
        private String mDeviceAddress;
        private @AddressType int mAddressType = BluetoothDevice.ADDRESS_TYPE_PUBLIC;
        private byte[] mIrk;

        private ParcelUuid mServiceUuid;
        private ParcelUuid mUuidMask;
@@ -546,14 +582,130 @@ public final class ScanFilter implements Parcelable {
         *
         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
         * BluetoothAdapter#checkBluetoothAddress}.
         * BluetoothAdapter#checkBluetoothAddress}.  The @AddressType is defaulted to {@link
         * BluetoothDevice#ADDRESS_TYPE_PUBLIC}
         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
         */
        public Builder setDeviceAddress(String deviceAddress) {
            if (deviceAddress != null && !BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
            return setDeviceAddress(mDeviceAddress, BluetoothDevice.ADDRESS_TYPE_PUBLIC);
        }

        /**
         * Set filter on Address with AddressType
         *
         * <p>This key is used to resolve a private address from a public address.
         *
         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
         * BluetoothAdapter#checkBluetoothAddress}. May be any type of address.
         * @param addressType indication of the type of address
         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
         * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM}
         *
         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
         * @throws IllegalArgumentException If the {@code addressType} is invalid length
         * @throws NullPointerException if {@code deviceAddress} is null.
         *
         * @hide
         */
        @NonNull
        @SystemApi
        public Builder setDeviceAddress(@NonNull String deviceAddress,
                                        @AddressType int addressType) {
            return setDeviceAddressInternal(deviceAddress, addressType, null);
        }

        /**
         * Set filter on Address with AddressType and the Identity Resolving Key (IRK).
         *
         * <p>The IRK is used to resolve a {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} from
         * a PRIVATE_ADDRESS type.
         *
         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
         * BluetoothAdapter#checkBluetoothAddress}.  This Address type must only be PUBLIC OR RANDOM
         * STATIC.
         * @param addressType indication of the type of address
         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
         * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM}
         * @param irk non-null byte array representing the Identity Resolving Key
         *
         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
         * @throws IllegalArgumentException if the {@code irk} is invalid length.
         * @throws IllegalArgumentException If the {@code addressType} is invalid length or is not
         * PUBLIC or RANDOM STATIC when an IRK is present.
         * @throws NullPointerException if {@code deviceAddress} or {@code irk} is null.
         *
         * @hide
         */
        @NonNull
        @SystemApi
        public Builder setDeviceAddress(@NonNull String deviceAddress,
                                        @AddressType int addressType,
                                        @NonNull byte[] irk) {
            Preconditions.checkNotNull(irk);
            if (irk.length != LEN_IRK_OCTETS) {
                throw new IllegalArgumentException("'irk' is invalid length!");
            }
            return setDeviceAddressInternal(deviceAddress, addressType, irk);
        }

        /**
         * Set filter on Address with AddressType and the Identity Resolving Key (IRK).
         *
         * <p>Internal setter for the device address
         *
         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
         * BluetoothAdapter#checkBluetoothAddress}.
         * @param addressType indication of the type of address
         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
         * @param irk non-null byte array representing the Identity Resolving Address; nullable
         * internally.
         *
         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
         * @throws IllegalArgumentException If the {@code addressType} is invalid length.
         * @throws NullPointerException if {@code deviceAddress} is null.
         *
         * @hide
         */
        @NonNull
        private Builder setDeviceAddressInternal(@NonNull String deviceAddress,
                                                 @AddressType int addressType,
                                                 @Nullable byte[] irk) {

            // Make sure our deviceAddress is valid!
            Preconditions.checkNotNull(deviceAddress);
            if (!BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
                throw new IllegalArgumentException("invalid device address " + deviceAddress);
            }

            // Verify type range
            if (addressType < BluetoothDevice.ADDRESS_TYPE_PUBLIC
                || addressType > BluetoothDevice.ADDRESS_TYPE_RANDOM) {
                throw new IllegalArgumentException("'addressType' is invalid!");
            }

            // IRK can only be used for a PUBLIC or RANDOM (STATIC) Address.
            if (addressType == BluetoothDevice.ADDRESS_TYPE_RANDOM) {
                // Don't want a bad combination of address and irk!
                if (irk != null) {
                    // Since there are 3 possible RANDOM subtypes we must check to make sure
                    // the correct type of address is used.
                    if (!BluetoothAdapter.isAddressRandomStatic(deviceAddress)) {
                        throw new IllegalArgumentException(
                                "Invalid combination: IRK requires either a PUBLIC or "
                                + "RANDOM (STATIC) Address");
                    }
                }
            }

            // PUBLIC doesn't require extra work
            // Without an IRK any address may be accepted

            mDeviceAddress = deviceAddress;
            mAddressType = addressType;
            mIrk = irk;
            return this;
        }

@@ -727,7 +879,8 @@ public final class ScanFilter implements Parcelable {
                    mServiceUuid, mUuidMask, mServiceSolicitationUuid,
                    mServiceSolicitationUuidMask,
                    mServiceDataUuid, mServiceData, mServiceDataMask,
                    mManufacturerId, mManufacturerData, mManufacturerDataMask);
                    mManufacturerId, mManufacturerData, mManufacturerDataMask,
                    mAddressType, mIrk);
        }
    }
}