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

Commit 45c32a86 authored by Chienyuan Huang's avatar Chienyuan Huang Committed by Gerrit Code Review
Browse files

Merge "Add new API for directed advertising" into main

parents f6f67d6b b3f4f5d3
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -2400,6 +2400,14 @@ static AdvertiseParameters parseParams(JNIEnv* env, jobject i) {
  int8_t txPowerLevel = env->CallIntMethod(i, methodId);
  methodId = env->GetMethodID(clazz, "getOwnAddressType", "()I");
  int8_t ownAddressType = env->CallIntMethod(i, methodId);
  methodId = env->GetMethodID(clazz, "isDirected", "()Z");
  jboolean isDirected = env->CallBooleanMethod(i, methodId);
  methodId = env->GetMethodID(clazz, "isHighDutyCycle", "()Z");
  jboolean isHighDutyCycle = env->CallIntMethod(i, methodId);
  methodId = env->GetMethodID(clazz, "getPeerAddress", "()Ljava/lang/String;");
  jstring peerAddress = (jstring)env->CallObjectMethod(i, methodId);
  methodId = env->GetMethodID(clazz, "getPeerAddressType", "()I");
  int8_t peerAddressType = env->CallIntMethod(i, methodId);

  uint16_t props = 0;
  if (isConnectable) {
@@ -2408,9 +2416,12 @@ static AdvertiseParameters parseParams(JNIEnv* env, jobject i) {
  if (isScannable) {
    props |= 0x02;
  }
  if (isDiscoverable) {
  if (isDirected) {
    props |= 0x04;
  }
  if (isHighDutyCycle) {
    props |= 0x08;
  }
  if (isLegacy) {
    props |= 0x10;
  }
@@ -2434,6 +2445,9 @@ static AdvertiseParameters parseParams(JNIEnv* env, jobject i) {
  p.secondary_advertising_phy = secondaryPhy;
  p.scan_request_notification_enable = false;
  p.own_address_type = ownAddressType;
  p.peer_address = str2addr(env, peerAddress);
  p.peer_address_type = peerAddressType;
  p.discoverable = isDiscoverable;
  return p;
}

+8 −0
Original line number Diff line number Diff line
@@ -1306,6 +1306,10 @@ package android.bluetooth.le {

  public final class AdvertisingSetParameters implements android.os.Parcelable {
    method public int getOwnAddressType();
    method @FlaggedApi("com.android.bluetooth.flags.directed_advertising_api") @Nullable public String getPeerAddress();
    method @FlaggedApi("com.android.bluetooth.flags.directed_advertising_api") public int getPeerAddressType();
    method @FlaggedApi("com.android.bluetooth.flags.directed_advertising_api") public boolean isDirected();
    method @FlaggedApi("com.android.bluetooth.flags.directed_advertising_api") public boolean isHighDutyCycle();
    field public static final int ADDRESS_TYPE_DEFAULT = -1; // 0xffffffff
    field public static final int ADDRESS_TYPE_PUBLIC = 0; // 0x0
    field public static final int ADDRESS_TYPE_RANDOM = 1; // 0x1
@@ -1313,7 +1317,11 @@ package android.bluetooth.le {
  }

  public static final class AdvertisingSetParameters.Builder {
    method @FlaggedApi("com.android.bluetooth.flags.directed_advertising_api") @NonNull public android.bluetooth.le.AdvertisingSetParameters.Builder setDirected(boolean);
    method @FlaggedApi("com.android.bluetooth.flags.directed_advertising_api") @NonNull public android.bluetooth.le.AdvertisingSetParameters.Builder setHighDutyCycle(boolean);
    method @NonNull public android.bluetooth.le.AdvertisingSetParameters.Builder setOwnAddressType(int);
    method @FlaggedApi("com.android.bluetooth.flags.directed_advertising_api") @NonNull public android.bluetooth.le.AdvertisingSetParameters.Builder setPeerAddress(@NonNull String);
    method @FlaggedApi("com.android.bluetooth.flags.directed_advertising_api") @NonNull public android.bluetooth.le.AdvertisingSetParameters.Builder setPeerAddressType(int);
  }

  public final class BluetoothLeAdvertiser {
+195 −4
Original line number Diff line number Diff line
@@ -16,16 +16,22 @@

package android.bluetooth.le;

import android.annotation.FlaggedApi;
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.Parcelable;

import com.android.bluetooth.flags.Flags;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * The {@link AdvertisingSetParameters} provide a way to adjust advertising preferences for each
@@ -133,6 +139,10 @@ public final class AdvertisingSetParameters implements Parcelable {
    private final int mInterval;
    private final int mTxPowerLevel;
    private final int mOwnAddressType;
    private final boolean mIsDirected;
    private final boolean mIsHighDutyCycle;
    private final String mPeerAddress;
    private final @AddressType int mPeerAddressType;

    private AdvertisingSetParameters(
            boolean connectable,
@@ -145,7 +155,11 @@ public final class AdvertisingSetParameters implements Parcelable {
            int secondaryPhy,
            int interval,
            int txPowerLevel,
            @AddressTypeStatus int ownAddressType) {
            @AddressTypeStatus int ownAddressType,
            boolean isDirected,
            boolean isHighDutyCycle,
            String peerAddress,
            @AddressType int peerAddressType) {
        mConnectable = connectable;
        mDiscoverable = discoverable;
        mScannable = scannable;
@@ -157,6 +171,10 @@ public final class AdvertisingSetParameters implements Parcelable {
        mInterval = interval;
        mTxPowerLevel = txPowerLevel;
        mOwnAddressType = ownAddressType;
        mIsDirected = isDirected;
        mIsHighDutyCycle = isHighDutyCycle;
        mPeerAddress = peerAddress;
        mPeerAddressType = peerAddressType;
    }

    private AdvertisingSetParameters(Parcel in) {
@@ -171,6 +189,10 @@ public final class AdvertisingSetParameters implements Parcelable {
        mTxPowerLevel = in.readInt();
        mOwnAddressType = in.readInt();
        mDiscoverable = in.readInt() != 0;
        mIsDirected = in.readBoolean();
        mIsHighDutyCycle = in.readBoolean();
        mPeerAddress = in.readString();
        mPeerAddressType = in.readInt();
    }

    /** Returns whether the advertisement will be connectable. */
@@ -232,6 +254,50 @@ public final class AdvertisingSetParameters implements Parcelable {
        return mOwnAddressType;
    }

    /**
     * @return Whether the advertisement is directed
     * @hide This API is not publicly available as it is mainly intended for accessory devices
     *     running Android to broadcast their availability and which can thus leverage system APIs.
     */
    @FlaggedApi(Flags.FLAG_DIRECTED_ADVERTISING_API)
    @SystemApi
    public boolean isDirected() {
        return mIsDirected;
    }

    /**
     * @return Whether the advertisement is high duty cycle or not
     * @hide This API is not publicly available as it is mainly intended for accessory devices
     *     running Android to broadcast their availability and which can thus leverage system APIs.
     */
    @FlaggedApi(Flags.FLAG_DIRECTED_ADVERTISING_API)
    @SystemApi
    public boolean isHighDutyCycle() {
        return mIsHighDutyCycle;
    }

    /**
     * @return Peer address for directed advertising
     * @hide This API is not publicly available as it is mainly intended for accessory devices
     *     running Android to broadcast their availability and which can thus leverage system APIs.
     */
    @FlaggedApi(Flags.FLAG_DIRECTED_ADVERTISING_API)
    @SystemApi
    public @Nullable String getPeerAddress() {
        return mPeerAddress;
    }

    /**
     * @return Peer address type for directed advertising
     * @hide This API is not publicly available as it is mainly intended for accessory devices
     *     running Android to broadcast their availability and which can thus leverage system APIs.
     */
    @FlaggedApi(Flags.FLAG_DIRECTED_ADVERTISING_API)
    @SystemApi
    public @AddressType int getPeerAddressType() {
        return mPeerAddressType;
    }

    @Override
    public String toString() {
        return "AdvertisingSetParameters [connectable="
@@ -254,6 +320,14 @@ public final class AdvertisingSetParameters implements Parcelable {
                + mTxPowerLevel
                + ", ownAddressType="
                + mOwnAddressType
                + ", isDirected="
                + mIsDirected
                + ", isHighDutyCycle="
                + mIsHighDutyCycle
                + ", peerAddress="
                + mPeerAddress
                + ", peerAddressType="
                + mPeerAddressType
                + "]";
    }

@@ -275,6 +349,10 @@ public final class AdvertisingSetParameters implements Parcelable {
        dest.writeInt(mTxPowerLevel);
        dest.writeInt(mOwnAddressType);
        dest.writeInt(mDiscoverable ? 1 : 0);
        dest.writeBoolean(mIsDirected);
        dest.writeBoolean(mIsHighDutyCycle);
        android.bluetooth.BluetoothUtils.writeStringToParcel(dest, mPeerAddress);
        dest.writeInt(mPeerAddressType);
    }

    public static final @android.annotation.NonNull Parcelable.Creator<AdvertisingSetParameters>
@@ -304,6 +382,10 @@ public final class AdvertisingSetParameters implements Parcelable {
        private int mInterval = INTERVAL_LOW;
        private int mTxPowerLevel = TX_POWER_MEDIUM;
        private int mOwnAddressType = ADDRESS_TYPE_DEFAULT;
        private boolean mIsDirected = false;
        private boolean mIsHighDutyCycle = false;
        private String mPeerAddress = null;
        private @AddressType int mPeerAddressType = BluetoothDevice.ADDRESS_TYPE_PUBLIC;

        /**
         * Set whether the advertisement type should be connectable or non-connectable. Legacy
@@ -481,6 +563,85 @@ public final class AdvertisingSetParameters implements Parcelable {
            return this;
        }

        /**
         * Set whether the advertising is a directed advertising.
         *
         * @param isDirected Controls whether the advertising is directed or not
         * @hide This API is not publicly available as it is mainly intended for accessory devices
         *     running Android to broadcast their availability and which can thus leverage system
         *     APIs.
         */
        @FlaggedApi(Flags.FLAG_DIRECTED_ADVERTISING_API)
        @SystemApi
        public @NonNull Builder setDirected(boolean isDirected) {
            mIsDirected = isDirected;
            return this;
        }

        /**
         * Set whether the advertising is high duty cycle or not.
         *
         * @param isHighDutyCycle Controls whether the advertising high duty cycle or not
         * @hide This API is not publicly available as it is mainly intended for accessory devices
         *     running Android to broadcast their availability and which can thus leverage system
         *     APIs.
         */
        @FlaggedApi(Flags.FLAG_DIRECTED_ADVERTISING_API)
        @SystemApi
        public @NonNull Builder setHighDutyCycle(boolean isHighDutyCycle) {
            mIsHighDutyCycle = isHighDutyCycle;
            return this;
        }

        /**
         * Set peer address for directed advertising.
         *
         * @param peerAddress peer address for the directed advertising
         * @throws IllegalArgumentException peer address is invalid
         * @hide This API is not publicly available as it is mainly intended for accessory devices
         *     running Android to broadcast their availability and which can thus leverage system
         *     APIs.
         */
        @FlaggedApi(Flags.FLAG_DIRECTED_ADVERTISING_API)
        @SystemApi
        public @NonNull Builder setPeerAddress(@NonNull String peerAddress) {
            Objects.requireNonNull(peerAddress, "peerAddress is null");
            if (!BluetoothAdapter.checkBluetoothAddress(peerAddress)) {
                throw new IllegalArgumentException(
                        peerAddress + " is not a valid Bluetooth address");
            }
            mPeerAddress = peerAddress;
            return this;
        }

        /**
         * Set peer address type for directed advertising.
         *
         * @param peerAddressType peer address type for the directed advertising
         * @throws IllegalArgumentException if {@code peerAddressType} is invalid
         * @hide This API is not publicly available as it is mainly intended for accessory devices
         *     running Android to broadcast their availability and which can thus leverage system
         *     APIs.
         */
        @FlaggedApi(Flags.FLAG_DIRECTED_ADVERTISING_API)
        @SystemApi
        public @NonNull Builder setPeerAddressType(@AddressType int peerAddressType) {
            switch (peerAddressType) {
                case BluetoothDevice.ADDRESS_TYPE_PUBLIC:
                case BluetoothDevice.ADDRESS_TYPE_RANDOM:
                    mPeerAddressType = peerAddressType;
                    break;
                case BluetoothDevice.ADDRESS_TYPE_UNKNOWN:
                case BluetoothDevice.ADDRESS_TYPE_ANONYMOUS:
                    throw new IllegalArgumentException(
                            "unsupported peer address type " + peerAddressType);
                default:
                    throw new IllegalArgumentException(
                            "unknown peer address type " + peerAddressType);
            }
            return this;
        }

        /**
         * Build the {@link AdvertisingSetParameters} object.
         *
@@ -492,9 +653,25 @@ public final class AdvertisingSetParameters implements Parcelable {
                    throw new IllegalArgumentException("Legacy advertising can't be anonymous");
                }

                if (mConnectable && !mScannable) {
                if (mIsDirected && !mConnectable) {
                    throw new IllegalStateException(
                            "Legacy directed advertising must be connectable");
                }

                if (mIsDirected && mScannable) {
                    throw new IllegalStateException(
                            "Legacy directed advertising can't be scannable");
                }

                if (!mIsDirected && mIsHighDutyCycle) {
                    throw new IllegalStateException(
                            "Non-directed legacy advertising can't be high duty cycle");
                }

                if (!mIsDirected && mConnectable && !mScannable) {
                    throw new IllegalStateException(
                            "Legacy advertisement can't be connectable and non-scannable");
                            "Non-directed legacy advertising can't be connectable and"
                                    + " non-scannable");
                }

                if (mIncludeTxPower) {
@@ -511,6 +688,16 @@ public final class AdvertisingSetParameters implements Parcelable {
                    throw new IllegalStateException(
                            "Advertising can't be both connectable and anonymous");
                }

                if (mIsHighDutyCycle) {
                    throw new IllegalStateException(
                            "Non-legacy advertising can't be high duty cycle");
                }
            }

            if (mIsDirected && mPeerAddress == null) {
                throw new IllegalStateException(
                        "Peer address should not be null for directed advertising");
            }

            return new AdvertisingSetParameters(
@@ -524,7 +711,11 @@ public final class AdvertisingSetParameters implements Parcelable {
                    mSecondaryPhy,
                    mInterval,
                    mTxPowerLevel,
                    mOwnAddressType);
                    mOwnAddressType,
                    mIsDirected,
                    mIsHighDutyCycle,
                    mPeerAddress,
                    mPeerAddressType);
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ bool AdvertisingConfigFromProto(const AdvertisingConfig& config_proto,
    case AdvertisingType::ADV_DIRECT_IND_HIGH: {
      config->connectable = true;
      config->directed = true;
      config->high_duty_directed_connectable = true;
      config->high_duty_cycle = true;
    } break;
    case AdvertisingType::ADV_SCAN_IND: {
      config->scannable = true;
@@ -150,7 +150,7 @@ bool ExtendedAdvertisingConfigFromProto(const ExtendedAdvertisingConfig& config_
  config->connectable = config_proto.connectable();
  config->scannable = config_proto.scannable();
  config->directed = config_proto.directed();
  config->high_duty_directed_connectable = config_proto.high_duty_directed_connectable();
  config->high_duty_cycle = config_proto.high_duty_directed_connectable();
  config->legacy_pdus = config_proto.legacy_pdus();
  config->anonymous = config_proto.anonymous();
  config->include_tx_power = config_proto.include_tx_power();
+3 −3
Original line number Diff line number Diff line
@@ -945,7 +945,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
          LegacyAdvertisingEventProperties legacy_properties =
                  LegacyAdvertisingEventProperties::ADV_IND;
          if (config.connectable && config.directed) {
            if (config.high_duty_directed_connectable) {
            if (config.high_duty_cycle) {
              legacy_properties = LegacyAdvertisingEventProperties::ADV_DIRECT_IND_HIGH;
            } else {
              legacy_properties = LegacyAdvertisingEventProperties::ADV_DIRECT_IND_LOW;
@@ -974,7 +974,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb
          extended_properties.connectable_ = config.connectable;
          extended_properties.scannable_ = config.scannable;
          extended_properties.directed_ = config.directed;
          extended_properties.high_duty_cycle_ = config.high_duty_directed_connectable;
          extended_properties.high_duty_cycle_ = config.high_duty_cycle;
          extended_properties.legacy_ = false;
          extended_properties.anonymous_ = config.anonymous;
          extended_properties.tx_power_ = config.include_tx_power;
@@ -1868,7 +1868,7 @@ void LeAdvertisingManager::ExtendedCreateAdvertiser(
             AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
      return;
    }
    if (config.high_duty_directed_connectable) {
    if (config.high_duty_cycle) {
      log::info("Extended advertising PDUs can not be high duty cycle");
      CallOn(pimpl_.get(), &impl::start_advertising_fail, reg_id,
             AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR);
Loading