summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Pawlowski <jpawlowski@google.com>2017-01-10 06:15:54 -0800
committerJakub Pawlowski <jpawlowski@google.com>2017-03-08 19:04:49 +0000
commita9d1a32e5e51ebc3c141370c9d5045c6c938aaf9 (patch)
tree3bd35731d8a36b738fb06452c160842458e576e7
parent104eeedb42d8de557056c0f70018c5d4fa8f6540 (diff)
downloadbase-a9d1a32e5e51ebc3c141370c9d5045c6c938aaf9.tar.gz
Bluetooth 5 Advertising API
Test: manual Bug: 30622771 Change-Id: Id6856e6110872ec50ff1af54ddc75c0104a6459c (cherry picked from commit 5324a14cf490656269ef862d7f8f6b139a21c0e6)
-rw-r--r--Android.mk1
-rw-r--r--api/current.txt92
-rw-r--r--api/system-current.txt92
-rw-r--r--api/test-current.txt92
-rw-r--r--core/java/android/bluetooth/IBluetoothGatt.aidl17
-rw-r--r--core/java/android/bluetooth/le/AdvertisingSet.java162
-rw-r--r--core/java/android/bluetooth/le/AdvertisingSetCallback.java144
-rw-r--r--core/java/android/bluetooth/le/AdvertisingSetParameters.aidl19
-rw-r--r--core/java/android/bluetooth/le/AdvertisingSetParameters.java409
-rw-r--r--core/java/android/bluetooth/le/BluetoothLeAdvertiser.java194
-rw-r--r--core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl32
-rw-r--r--core/java/android/bluetooth/le/PeriodicAdvertisingParameters.aidl19
-rw-r--r--core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java134
-rw-r--r--core/java/android/bluetooth/le/ScanResult.java2
14 files changed, 1408 insertions, 1 deletions
diff --git a/Android.mk b/Android.mk
index f7e8310fc0fa..a07fd016eab8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -131,6 +131,7 @@ LOCAL_SRC_FILES += \
core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl \
core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl \
core/java/android/bluetooth/le/IAdvertiserCallback.aidl \
+ core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl \
core/java/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl \
core/java/android/bluetooth/le/IScannerCallback.aidl \
core/java/android/content/IClipboard.aidl \
diff --git a/api/current.txt b/api/current.txt
index c8917ae2376e..b69cf01fb8ba 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7504,10 +7504,85 @@ package android.bluetooth.le {
method public android.bluetooth.le.AdvertiseSettings.Builder setTxPowerLevel(int);
}
+ public final class AdvertisingSet {
+ method public void enableAdvertising(boolean);
+ method public void periodicAdvertisingEnable(boolean);
+ method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
+ method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
+ method public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
+ method public void setPeriodicAdvertisingParameters(android.bluetooth.le.PeriodicAdvertisingParameters);
+ method public void setScanResponseData(android.bluetooth.le.AdvertiseData);
+ }
+
+ public abstract class AdvertisingSetCallback {
+ ctor public AdvertisingSetCallback();
+ method public void onAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
+ method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingSetStopped(android.bluetooth.le.AdvertisingSet);
+ method public void onPeriodicAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
+ method public void onPeriodicAdvertisingEnable(android.bluetooth.le.AdvertisingSet, boolean, int);
+ method public void onPeriodicAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
+ method public void onScanResponseDataSet(android.bluetooth.le.AdvertisingSet, int);
+ field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
+ field public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1; // 0x1
+ field public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; // 0x5
+ field public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; // 0x4
+ field public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; // 0x2
+ field public static final int ADVERTISE_SUCCESS = 0; // 0x0
+ }
+
+ public final class AdvertisingSetParameters implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getInterval();
+ method public int getPrimaryPhy();
+ method public int getSecondaryPhy();
+ method public int getTimeout();
+ method public int getTxPowerLevel();
+ method public boolean includeTxPower();
+ method public boolean isAnonymous();
+ method public boolean isConnectable();
+ method public boolean isLegacy();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
+ field public static final int INTERVAL_HIGH = 160; // 0xa0
+ field public static final int INTERVAL_LOW = 1600; // 0x640
+ field public static final int INTERVAL_MAX = 16777215; // 0xffffff
+ field public static final int INTERVAL_MEDIUM = 400; // 0x190
+ field public static final int INTERVAL_MIN = 160; // 0xa0
+ field public static final int PHY_LE_1M = 1; // 0x1
+ field public static final int PHY_LE_2M = 2; // 0x2
+ field public static final int PHY_LE_CODED = 3; // 0x3
+ field public static final int TX_POWER_HIGH = 1; // 0x1
+ field public static final int TX_POWER_LOW = -15; // 0xfffffff1
+ field public static final int TX_POWER_MAX = 1; // 0x1
+ field public static final int TX_POWER_MEDIUM = -7; // 0xfffffff9
+ field public static final int TX_POWER_MIN = -127; // 0xffffff81
+ field public static final int TX_POWER_ULTRA_LOW = -21; // 0xffffffeb
+ }
+
+ public static final class AdvertisingSetParameters.Builder {
+ ctor public AdvertisingSetParameters.Builder();
+ method public android.bluetooth.le.AdvertisingSetParameters build();
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymouus(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setLegacyMode(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setPrimaryPhy(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setSecondaryPhy(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setTimeout(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
+ }
+
public final class BluetoothLeAdvertiser {
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
method public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
+ method public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
}
public final class BluetoothLeScanner {
@@ -7532,6 +7607,23 @@ package android.bluetooth.le {
method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback);
}
+ public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
+ method public int describeContents();
+ method public boolean getEnable();
+ method public boolean getIncludeTxPower();
+ method public int getInterval();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingParameters> CREATOR;
+ }
+
+ public static final class PeriodicAdvertisingParameters.Builder {
+ ctor public PeriodicAdvertisingParameters.Builder();
+ method public android.bluetooth.le.PeriodicAdvertisingParameters build();
+ method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setEnable(boolean);
+ method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setIncludeTxPower(boolean);
+ method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
+ }
+
public final class PeriodicAdvertisingReport implements android.os.Parcelable {
ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord);
method public int describeContents();
diff --git a/api/system-current.txt b/api/system-current.txt
index 28dfbe8a109d..914cda1a68d4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -7808,10 +7808,85 @@ package android.bluetooth.le {
method public android.bluetooth.le.AdvertiseSettings.Builder setTxPowerLevel(int);
}
+ public final class AdvertisingSet {
+ method public void enableAdvertising(boolean);
+ method public void periodicAdvertisingEnable(boolean);
+ method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
+ method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
+ method public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
+ method public void setPeriodicAdvertisingParameters(android.bluetooth.le.PeriodicAdvertisingParameters);
+ method public void setScanResponseData(android.bluetooth.le.AdvertiseData);
+ }
+
+ public abstract class AdvertisingSetCallback {
+ ctor public AdvertisingSetCallback();
+ method public void onAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
+ method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingSetStopped(android.bluetooth.le.AdvertisingSet);
+ method public void onPeriodicAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
+ method public void onPeriodicAdvertisingEnable(android.bluetooth.le.AdvertisingSet, boolean, int);
+ method public void onPeriodicAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
+ method public void onScanResponseDataSet(android.bluetooth.le.AdvertisingSet, int);
+ field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
+ field public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1; // 0x1
+ field public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; // 0x5
+ field public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; // 0x4
+ field public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; // 0x2
+ field public static final int ADVERTISE_SUCCESS = 0; // 0x0
+ }
+
+ public final class AdvertisingSetParameters implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getInterval();
+ method public int getPrimaryPhy();
+ method public int getSecondaryPhy();
+ method public int getTimeout();
+ method public int getTxPowerLevel();
+ method public boolean includeTxPower();
+ method public boolean isAnonymous();
+ method public boolean isConnectable();
+ method public boolean isLegacy();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
+ field public static final int INTERVAL_HIGH = 160; // 0xa0
+ field public static final int INTERVAL_LOW = 1600; // 0x640
+ field public static final int INTERVAL_MAX = 16777215; // 0xffffff
+ field public static final int INTERVAL_MEDIUM = 400; // 0x190
+ field public static final int INTERVAL_MIN = 160; // 0xa0
+ field public static final int PHY_LE_1M = 1; // 0x1
+ field public static final int PHY_LE_2M = 2; // 0x2
+ field public static final int PHY_LE_CODED = 3; // 0x3
+ field public static final int TX_POWER_HIGH = 1; // 0x1
+ field public static final int TX_POWER_LOW = -15; // 0xfffffff1
+ field public static final int TX_POWER_MAX = 1; // 0x1
+ field public static final int TX_POWER_MEDIUM = -7; // 0xfffffff9
+ field public static final int TX_POWER_MIN = -127; // 0xffffff81
+ field public static final int TX_POWER_ULTRA_LOW = -21; // 0xffffffeb
+ }
+
+ public static final class AdvertisingSetParameters.Builder {
+ ctor public AdvertisingSetParameters.Builder();
+ method public android.bluetooth.le.AdvertisingSetParameters build();
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymouus(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setLegacyMode(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setPrimaryPhy(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setSecondaryPhy(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setTimeout(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
+ }
+
public final class BluetoothLeAdvertiser {
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
method public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
+ method public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
}
public final class BluetoothLeScanner {
@@ -7839,6 +7914,23 @@ package android.bluetooth.le {
method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback);
}
+ public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
+ method public int describeContents();
+ method public boolean getEnable();
+ method public boolean getIncludeTxPower();
+ method public int getInterval();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingParameters> CREATOR;
+ }
+
+ public static final class PeriodicAdvertisingParameters.Builder {
+ ctor public PeriodicAdvertisingParameters.Builder();
+ method public android.bluetooth.le.PeriodicAdvertisingParameters build();
+ method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setEnable(boolean);
+ method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setIncludeTxPower(boolean);
+ method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
+ }
+
public final class PeriodicAdvertisingReport implements android.os.Parcelable {
ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord);
method public int describeContents();
diff --git a/api/test-current.txt b/api/test-current.txt
index cfdbf370de4d..317328d6e57d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -7513,10 +7513,85 @@ package android.bluetooth.le {
method public android.bluetooth.le.AdvertiseSettings.Builder setTxPowerLevel(int);
}
+ public final class AdvertisingSet {
+ method public void enableAdvertising(boolean);
+ method public void periodicAdvertisingEnable(boolean);
+ method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
+ method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
+ method public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
+ method public void setPeriodicAdvertisingParameters(android.bluetooth.le.PeriodicAdvertisingParameters);
+ method public void setScanResponseData(android.bluetooth.le.AdvertiseData);
+ }
+
+ public abstract class AdvertisingSetCallback {
+ ctor public AdvertisingSetCallback();
+ method public void onAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
+ method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingSetStopped(android.bluetooth.le.AdvertisingSet);
+ method public void onPeriodicAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
+ method public void onPeriodicAdvertisingEnable(android.bluetooth.le.AdvertisingSet, boolean, int);
+ method public void onPeriodicAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
+ method public void onScanResponseDataSet(android.bluetooth.le.AdvertisingSet, int);
+ field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
+ field public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1; // 0x1
+ field public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; // 0x5
+ field public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; // 0x4
+ field public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; // 0x2
+ field public static final int ADVERTISE_SUCCESS = 0; // 0x0
+ }
+
+ public final class AdvertisingSetParameters implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getInterval();
+ method public int getPrimaryPhy();
+ method public int getSecondaryPhy();
+ method public int getTimeout();
+ method public int getTxPowerLevel();
+ method public boolean includeTxPower();
+ method public boolean isAnonymous();
+ method public boolean isConnectable();
+ method public boolean isLegacy();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
+ field public static final int INTERVAL_HIGH = 160; // 0xa0
+ field public static final int INTERVAL_LOW = 1600; // 0x640
+ field public static final int INTERVAL_MAX = 16777215; // 0xffffff
+ field public static final int INTERVAL_MEDIUM = 400; // 0x190
+ field public static final int INTERVAL_MIN = 160; // 0xa0
+ field public static final int PHY_LE_1M = 1; // 0x1
+ field public static final int PHY_LE_2M = 2; // 0x2
+ field public static final int PHY_LE_CODED = 3; // 0x3
+ field public static final int TX_POWER_HIGH = 1; // 0x1
+ field public static final int TX_POWER_LOW = -15; // 0xfffffff1
+ field public static final int TX_POWER_MAX = 1; // 0x1
+ field public static final int TX_POWER_MEDIUM = -7; // 0xfffffff9
+ field public static final int TX_POWER_MIN = -127; // 0xffffff81
+ field public static final int TX_POWER_ULTRA_LOW = -21; // 0xffffffeb
+ }
+
+ public static final class AdvertisingSetParameters.Builder {
+ ctor public AdvertisingSetParameters.Builder();
+ method public android.bluetooth.le.AdvertisingSetParameters build();
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymouus(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setLegacyMode(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setPrimaryPhy(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setSecondaryPhy(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setTimeout(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
+ }
+
public final class BluetoothLeAdvertiser {
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
method public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
+ method public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
}
public final class BluetoothLeScanner {
@@ -7541,6 +7616,23 @@ package android.bluetooth.le {
method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback);
}
+ public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
+ method public int describeContents();
+ method public boolean getEnable();
+ method public boolean getIncludeTxPower();
+ method public int getInterval();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingParameters> CREATOR;
+ }
+
+ public static final class PeriodicAdvertisingParameters.Builder {
+ ctor public PeriodicAdvertisingParameters.Builder();
+ method public android.bluetooth.le.PeriodicAdvertisingParameters build();
+ method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setEnable(boolean);
+ method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setIncludeTxPower(boolean);
+ method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
+ }
+
public final class PeriodicAdvertisingReport implements android.os.Parcelable {
ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord);
method public int describeContents();
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 5282e9fceba5..33fedc718980 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -20,6 +20,8 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertisingSetParameters;
+import android.bluetooth.le.PeriodicAdvertisingParameters;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
@@ -30,6 +32,7 @@ import android.os.WorkSource;
import android.bluetooth.IBluetoothGattCallbackExt;
import android.bluetooth.IBluetoothGattServerCallbackExt;
import android.bluetooth.le.IAdvertiserCallback;
+import android.bluetooth.le.IAdvertisingSetCallback;
import android.bluetooth.le.IPeriodicAdvertisingCallback;
import android.bluetooth.le.IScannerCallback;
@@ -55,10 +58,24 @@ interface IBluetoothGatt {
in AdvertiseSettings settings);
void stopMultiAdvertising(in int advertiserId);
+ void startAdvertisingSet(in AdvertisingSetParameters parameters, in AdvertiseData advertiseData,
+ in AdvertiseData scanResponse, in PeriodicAdvertisingParameters periodicParameters,
+ in AdvertiseData periodicData, in IAdvertisingSetCallback callback);
+ void stopAdvertisingSet(in IAdvertisingSetCallback callback);
+
+ void enableAdverisingSet(in int advertiserId, in boolean enable);
+ void setAdvertisingData(in int advertiserId, in AdvertiseData data);
+ void setScanResponseData(in int advertiserId, in AdvertiseData data);
+ void setAdvertisingParameters(in int advertiserId, in AdvertisingSetParameters parameters);
+ void setPeriodicAdvertisingParameters(in int advertiserId, in PeriodicAdvertisingParameters parameters);
+ void setPeriodicAdvertisingData(in int advertiserId, in AdvertiseData data);
+ void periodicAdvertisingEnable(in int advertiserId, in boolean enable);
+
void registerSync(in ScanResult scanResult, in int skip, in int timeout, in IPeriodicAdvertisingCallback callback);
void unregisterSync(in IPeriodicAdvertisingCallback callback);
void registerClient(in ParcelUuid appId, in IBluetoothGattCallbackExt callback);
+
void unregisterClient(in int clientIf);
void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport, in int phy);
void clientDisconnect(in int clientIf, in String address);
diff --git a/core/java/android/bluetooth/le/AdvertisingSet.java b/core/java/android/bluetooth/le/AdvertisingSet.java
new file mode 100644
index 000000000000..1524022b1f0f
--- /dev/null
+++ b/core/java/android/bluetooth/le/AdvertisingSet.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+import android.bluetooth.IBluetoothGatt;
+import android.bluetooth.IBluetoothManager;
+import android.bluetooth.le.IAdvertisingSetCallback;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * This class provides a way to control single Bluetooth LE advertising instance.
+ * <p>
+ * To get an instance of {@link AdvertisingSet}, call the
+ * {@link BluetoothLeAdvertiser#startAdvertisingSet} method.
+ * <p>
+ * <b>Note:</b> Most of the methods here require {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+ * permission.
+ *
+ * @see AdvertiseData
+ */
+public final class AdvertisingSet {
+ private static final String TAG = "AdvertisingSet";
+
+ private final IBluetoothGatt gatt;
+ private int advertiserId;
+
+ /* package */ AdvertisingSet(int advertiserId,
+ IBluetoothManager bluetoothManager) {
+ this.advertiserId = advertiserId;
+
+ try {
+ this.gatt = bluetoothManager.getBluetoothGatt();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+ throw new IllegalStateException("Failed to get Bluetooth");
+ }
+ }
+
+ /* package */ void setAdvertiserId(int advertiserId) {
+ this.advertiserId = advertiserId;
+ }
+
+ /**
+ * Enables Advertising. This method returns immediately, the operation status is
+ * delivered
+ * through {@code callback.onAdvertisingEnabled()}.
+ * <p>
+ * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+ *
+ */
+ public void enableAdvertising(boolean enable) {
+ try {
+ gatt.enableAdverisingSet(this.advertiserId, enable);
+ } catch (RemoteException e) {
+ Log.e(TAG, "remote exception - ", e);
+ }
+ }
+
+ /**
+ * Set/update data being Advertised. Make sure that data doesn't exceed the size limit for
+ * specified AdvertisingSetParameters. This method returns immediately, the operation status is
+ * delivered through {@code callback.onAdvertisingDataSet()}.
+ * <p>
+ * Advertising data must be empty if non-legacy scannable advertising is used.
+ */
+ public void setAdvertisingData(AdvertiseData data) {
+ try {
+ gatt.setAdvertisingData(this.advertiserId, data);
+ } catch (RemoteException e) {
+ Log.e(TAG, "remote exception - ", e);
+ }
+ }
+
+ /**
+ * Set/update scan response data. Make sure that data doesn't exceed the size limit for
+ * specified AdvertisingSetParameters. This method returns immediately, the operation status
+ * is delivered through {@code callback.onScanResponseDataSet()}.
+ */
+ public void setScanResponseData(AdvertiseData data) {
+ try {
+ gatt.setScanResponseData(this.advertiserId, data);
+ } catch (RemoteException e) {
+ Log.e(TAG, "remote exception - ", e);
+ }
+ }
+
+ /**
+ * Update advertising parameters associated with this AdvertisingSet. Must be called when
+ * advertising is not active. This method returns immediately, the operation status is delivered
+ * through {@code callback.onAdvertisingParametersUpdated}.
+ */
+ public void setAdvertisingParameters(AdvertisingSetParameters parameters) {
+ try {
+ gatt.setAdvertisingParameters(this.advertiserId, parameters);
+ } catch (RemoteException e) {
+ Log.e(TAG, "remote exception - ", e);
+ }
+ }
+
+ /**
+ * Update periodic advertising parameters associated with this set. Must be called when
+ * periodic advertising is not enabled. This method returns immediately, the operation
+ * status is delivered through {@code callback.onPeriodicAdvertisingParametersUpdated()}.
+ */
+ public void setPeriodicAdvertisingParameters(PeriodicAdvertisingParameters parameters) {
+ try {
+ gatt.setPeriodicAdvertisingParameters(this.advertiserId, parameters);
+ } catch (RemoteException e) {
+ Log.e(TAG, "remote exception - ", e);
+ }
+ }
+
+ /**
+ * Used to set periodic advertising data, must be called after setPeriodicAdvertisingParameters,
+ * or after advertising was started with periodic advertising data set. This method returns
+ * immediately, the operation status is delivered through
+ * {@code callback.onPeriodicAdvertisingDataSet()}.
+ */
+ public void setPeriodicAdvertisingData(AdvertiseData data) {
+ try {
+ gatt.setPeriodicAdvertisingData(this.advertiserId, data);
+ } catch (RemoteException e) {
+ Log.e(TAG, "remote exception - ", e);
+ }
+ }
+
+ /**
+ * Used to enable/disable periodic advertising. This method returns immediately, the operation
+ * status is delivered through {@code callback.onPeriodicAdvertisingEnable()}.
+ */
+ public void periodicAdvertisingEnable(boolean enable) {
+ try {
+ gatt.periodicAdvertisingEnable(this.advertiserId, enable);
+ } catch (RemoteException e) {
+ Log.e(TAG, "remote exception - ", e);
+ }
+ }
+
+ /**
+ * Returns advertiserId associated with thsi advertising set.
+ *
+ * @hide
+ */
+ public int getAdvertiserId(){
+ return advertiserId;
+ }
+} \ No newline at end of file
diff --git a/core/java/android/bluetooth/le/AdvertisingSetCallback.java b/core/java/android/bluetooth/le/AdvertisingSetCallback.java
new file mode 100644
index 000000000000..ceed8d9e3c60
--- /dev/null
+++ b/core/java/android/bluetooth/le/AdvertisingSetCallback.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * Bluetooth LE advertising set callbacks, used to deliver advertising operation
+ * status.
+ */
+public abstract class AdvertisingSetCallback {
+
+ /**
+ * The requested operation was successful.
+ */
+ public static final int ADVERTISE_SUCCESS = 0;
+
+ /**
+ * Failed to start advertising as the advertise data to be broadcasted is too
+ * large.
+ */
+ public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1;
+
+ /**
+ * Failed to start advertising because no advertising instance is available.
+ */
+ public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2;
+
+ /**
+ * Failed to start advertising as the advertising is already started.
+ */
+ public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3;
+
+ /**
+ * Operation failed due to an internal error.
+ */
+ public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4;
+
+ /**
+ * This feature is not supported on this platform.
+ */
+ public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5;
+
+ /**
+ * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet}
+ * indicating result of the operation. If status is ADVERTISE_SUCCESS, then advertisingSet
+ * contains the started set and it is advertising. If error occured, advertisingSet is
+ * null, and status will be set to proper error code.
+ *
+ * @param advertisingSet The advertising set that was started or null if error.
+ * @param status Status of the operation.
+ */
+ public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int status) {}
+
+ /**
+ * Callback triggered in response to {@link BluetoothLeAdvertiser#stopAdvertisingSet}
+ * indicating advertising set is stopped.
+ *
+ * @param advertisingSet The advertising set.
+ */
+ public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {}
+
+ /**
+ * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet} indicating
+ * result of the operation. If status is ADVERTISE_SUCCESS, then advertising set is advertising.
+ *
+ * @param advertisingSet The advertising set.
+ * @param status Status of the operation.
+ */
+ public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable, int status) {}
+
+ /**
+ * Callback triggered in response to {@link AdvertisingSet#setAdvertisingData} indicating
+ * result of the operation. If status is ADVERTISE_SUCCESS, then data was changed.
+ *
+ * @param advertisingSet The advertising set.
+ * @param status Status of the operation.
+ */
+ public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {}
+
+ /**
+ * Callback triggered in response to {@link AdvertisingSet#setAdvertisingData} indicating
+ * result of the operation.
+ *
+ * @param advertisingSet The advertising set.
+ * @param status Status of the operation.
+ */
+ public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {}
+
+ /**
+ * Callback triggered in response to {@link AdvertisingSet#setAdvertisingParameters}
+ * indicating result of the operation.
+ *
+ * @param advertisingSet The advertising set.
+ * @param status Status of the operation.
+ */
+ public void onAdvertisingParametersUpdated(AdvertisingSet advertisingSet,
+ int status) {}
+
+ /**
+ * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingParameters}
+ * indicating result of the operation.
+ *
+ * @param advertisingSet The advertising set.
+ * @param status Status of the operation.
+ */
+ public void
+ onPeriodicAdvertisingParametersUpdated(AdvertisingSet advertisingSet,
+ int status) {}
+
+ /**
+ * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingData}
+ * indicating result of the operation.
+ *
+ * @param advertisingSet The advertising set.
+ * @param status Status of the operation.
+ */
+ public void onPeriodicAdvertisingDataSet(AdvertisingSet advertisingSet,
+ int status) {}
+
+ /**
+ * Callback triggered in response to {@link AdvertisingSet#periodicAdvertisingEnable}
+ * indicating result of the operation.
+ *
+ * @param advertisingSet The advertising set.
+ * @param status Status of the operation.
+ */
+ public void onPeriodicAdvertisingEnable(AdvertisingSet advertisingSet, boolean enable,
+ int status) {}
+} \ No newline at end of file
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.aidl b/core/java/android/bluetooth/le/AdvertisingSetParameters.aidl
new file mode 100644
index 000000000000..39034a001faa
--- /dev/null
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+parcelable AdvertisingSetParameters;
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
new file mode 100644
index 000000000000..03a01e171ba4
--- /dev/null
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * The {@link AdvertisingSetParameters} provide a way to adjust advertising
+ * preferences for each
+ * Bluetooth LE advertising set. Use {@link AdvertisingSetParameters.Builder} to
+ * create an
+ * instance of this class.
+ */
+public final class AdvertisingSetParameters implements Parcelable {
+
+ /**
+ * 1M advertiser PHY.
+ */
+ public static final int PHY_LE_1M = 1;
+
+ /**
+ * 2M advertiser PHY.
+ */
+ public static final int PHY_LE_2M = 2;
+
+ /**
+ * LE Coded advertiser PHY.
+ */
+ public static final int PHY_LE_CODED = 3;
+
+ /**
+ * Advertise on low frequency, around every 1000ms. This is the default and
+ * preferred advertising mode as it consumes the least power.
+ */
+ public static final int INTERVAL_LOW = 1600;
+
+ /**
+ * Advertise on medium frequency, around every 250ms. This is balanced
+ * between advertising frequency and power consumption.
+ */
+ public static final int INTERVAL_MEDIUM = 400;
+
+ /**
+ * Perform high frequency, low latency advertising, around every 100ms. This
+ * has the highest power consumption and should not be used for continuous
+ * background advertising.
+ */
+ public static final int INTERVAL_HIGH = 160;
+
+ /**
+ * Minimum value for advertising interval.
+ */
+ public static final int INTERVAL_MIN = 160;
+
+ /**
+ * Maximum value for advertising interval.
+ */
+ public static final int INTERVAL_MAX = 16777215;
+
+ /**
+ * Advertise using the lowest transmission (TX) power level. Low transmission
+ * power can be used to restrict the visibility range of advertising packets.
+ */
+ public static final int TX_POWER_ULTRA_LOW = -21;
+
+ /**
+ * Advertise using low TX power level.
+ */
+ public static final int TX_POWER_LOW = -15;
+
+ /**
+ * Advertise using medium TX power level.
+ */
+ public static final int TX_POWER_MEDIUM = -7;
+
+ /**
+ * Advertise using high TX power level. This corresponds to largest visibility
+ * range of the advertising packet.
+ */
+ public static final int TX_POWER_HIGH = 1;
+
+ /**
+ * Minimum value for TX power.
+ */
+ public static final int TX_POWER_MIN = -127;
+
+ /**
+ * Maximum value for TX power.
+ */
+ public static final int TX_POWER_MAX = 1;
+
+ /**
+ * The maximum limited advertisement duration as specified by the Bluetooth
+ * SIG
+ */
+ private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000;
+
+ private final boolean isLegacy;
+ private final boolean isAnonymous;
+ private final boolean includeTxPower;
+ private final int primaryPhy;
+ private final int secondaryPhy;
+ private final boolean connectable;
+ private final int interval;
+ private final int txPowerLevel;
+ private final int timeoutMillis;
+
+ private AdvertisingSetParameters(boolean connectable, boolean isLegacy,
+ boolean isAnonymous, boolean includeTxPower,
+ int primaryPhy, int secondaryPhy,
+ int interval, int txPowerLevel,
+ int timeoutMillis) {
+ this.connectable = connectable;
+ this.isLegacy = isLegacy;
+ this.isAnonymous = isAnonymous;
+ this.includeTxPower = includeTxPower;
+ this.primaryPhy = primaryPhy;
+ this.secondaryPhy = secondaryPhy;
+ this.interval = interval;
+ this.txPowerLevel = txPowerLevel;
+ this.timeoutMillis = timeoutMillis;
+ }
+
+ private AdvertisingSetParameters(Parcel in) {
+ connectable = in.readInt() != 0 ? true : false;
+ isLegacy = in.readInt() != 0 ? true : false;
+ isAnonymous = in.readInt() != 0 ? true : false;
+ includeTxPower = in.readInt() != 0 ? true : false;
+ primaryPhy = in.readInt();
+ secondaryPhy = in.readInt();
+ interval = in.readInt();
+ txPowerLevel = in.readInt();
+ timeoutMillis = in.readInt();
+ }
+
+ /**
+ * Returns whether the advertisement will be connectable.
+ */
+ public boolean isConnectable() { return connectable; }
+
+ /**
+ * Returns whether the legacy advertisement will be used.
+ */
+ public boolean isLegacy() { return isLegacy; }
+
+ /**
+ * Returns whether the advertisement will be anonymous.
+ */
+ public boolean isAnonymous() { return isAnonymous; }
+
+ /**
+ * Returns whether the TX Power will be included.
+ */
+ public boolean includeTxPower() { return includeTxPower; }
+
+ /**
+ * Returns the primary advertising phy.
+ */
+ public int getPrimaryPhy() { return primaryPhy; }
+
+ /**
+ * Returns the secondary advertising phy.
+ */
+ public int getSecondaryPhy() { return secondaryPhy; }
+
+ /**
+ * Returns the advertising interval.
+ */
+ public int getInterval() { return interval; }
+
+ /**
+ * Returns the TX power level for advertising.
+ */
+ public int getTxPowerLevel() { return txPowerLevel; }
+
+ /**
+ * Returns the advertising time limit in milliseconds.
+ */
+ public int getTimeout() { return timeoutMillis; }
+
+ @Override
+ public String toString() {
+ return "AdvertisingSetParameters [connectable=" + connectable
+ + ", isLegacy=" + isLegacy
+ + ", isAnonymous=" + isAnonymous
+ + ", includeTxPower=" + includeTxPower
+ + ", primaryPhy=" + primaryPhy
+ + ", secondaryPhy=" + secondaryPhy
+ + ", interval=" + interval
+ + ", txPowerLevel=" + txPowerLevel
+ + ", timeoutMillis=" + timeoutMillis + "]";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(connectable ? 1 : 0);
+ dest.writeInt(isLegacy ? 1 : 0);
+ dest.writeInt(isAnonymous ? 1 : 0);
+ dest.writeInt(includeTxPower ? 1 : 0);
+ dest.writeInt(primaryPhy);
+ dest.writeInt(secondaryPhy);
+ dest.writeInt(interval);
+ dest.writeInt(txPowerLevel);
+ dest.writeInt(timeoutMillis);
+ }
+
+ public static final Parcelable.Creator<AdvertisingSetParameters> CREATOR =
+ new Creator<AdvertisingSetParameters>() {
+ @Override
+ public AdvertisingSetParameters[] newArray(int size) {
+ return new AdvertisingSetParameters[size];
+ }
+
+ @Override
+ public AdvertisingSetParameters createFromParcel(Parcel in) {
+ return new AdvertisingSetParameters(in);
+ }
+ };
+
+ /**
+ * Builder class for {@link AdvertisingSetParameters}.
+ */
+ public static final class Builder {
+
+ private boolean connectable = true;
+ private boolean isLegacy = false;
+ private boolean isAnonymous = false;
+ private boolean includeTxPower = false;
+ private int primaryPhy = PHY_LE_1M;
+ private int secondaryPhy = PHY_LE_1M;
+ private int interval = INTERVAL_LOW;
+ private int txPowerLevel = TX_POWER_MEDIUM;
+ private int timeoutMillis = 0;
+
+ /**
+ * Set whether the advertisement type should be connectable or
+ * non-connectable.
+ * Legacy advertisements can be both connectable and scannable. Other
+ * advertisements can be connectable only if not scannable.
+ * @param connectable Controls whether the advertisment type will be
+ * connectable (true) or non-connectable (false).
+ */
+ public Builder setConnectable(boolean connectable) {
+ this.connectable = connectable;
+ return this;
+ }
+
+ /**
+ * When set to true, advertising set will advertise 4.x Spec compliant
+ * advertisements.
+ *
+ * @param isLegacy wether legacy advertising mode should be used.
+ */
+ public Builder setLegacyMode(boolean isLegacy) {
+ this.isLegacy = isLegacy;
+ return this;
+ }
+
+ /**
+ * Set wether advertiser address should be ommited from all packets. If this
+ * mode is used, periodic advertising can't be enabled for this set.
+ *
+ * This is used only if legacy mode is not used.
+ *
+ * @param isAnonymous wether anonymous advertising should be used.
+ */
+ public Builder setAnonymouus(boolean isAnonymous) {
+ this.isAnonymous = isAnonymous;
+ return this;
+ }
+
+ /**
+ * Set wether TX power should be included in the extended header.
+ *
+ * This is used only if legacy mode is not used.
+ *
+ * @param includeTxPower wether TX power should be included in extended
+ * header
+ */
+ public Builder setIncludeTxPower(boolean includeTxPower) {
+ this.includeTxPower = includeTxPower;
+ return this;
+ }
+
+ /**
+ * Set the primary physical channel used for this advertising set.
+ *
+ * This is used only if legacy mode is not used.
+ *
+ * @param primaryPhy Primary advertising physical channel, can only be
+ * {@link AdvertisingSetParameters#PHY_LE_1M} or
+ * {@link AdvertisingSetParameters#PHY_LE_CODED}.
+ * @throws IllegalArgumentException If the primaryPhy is invalid.
+ */
+ public Builder setPrimaryPhy(int primaryPhy) {
+ if (primaryPhy != PHY_LE_1M && primaryPhy != PHY_LE_CODED) {
+ throw new IllegalArgumentException("bad primaryPhy " + primaryPhy);
+ }
+ this.primaryPhy = primaryPhy;
+ return this;
+ }
+
+ /**
+ * Set the secondary physical channel used for this advertising set.
+ *
+ * This is used only if legacy mode is not used.
+ *
+ * @param secondaryPhy Secondary advertising physical channel, can only be
+ * one of {@link AdvertisingSetParameters#PHY_LE_1M},
+ * {@link AdvertisingSetParameters#PHY_LE_2M} or
+ * {@link AdvertisingSetParameters#PHY_LE_CODED}.
+ * @throws IllegalArgumentException If the secondaryPhy is invalid.
+ */
+ public Builder setSecondaryPhy(int secondaryPhy) {
+ if (secondaryPhy != PHY_LE_1M && secondaryPhy !=PHY_LE_2M &&
+ secondaryPhy != PHY_LE_CODED) {
+ throw new IllegalArgumentException("bad secondaryPhy " + secondaryPhy);
+ }
+ this.secondaryPhy = secondaryPhy;
+ return this;
+ }
+
+ /**
+ * Set advertising interval.
+ *
+ * @param interval Bluetooth LE Advertising interval, in 0.625ms unit. Valid
+ * range is from 160 (100ms) to 16777215 (10,485.759375 s).
+ * Recommended values are:
+ * {@link AdvertisingSetParameters#INTERVAL_LOW},
+ * {@link AdvertisingSetParameters#INTERVAL_MEDIUM}, or
+ * {@link AdvertisingSetParameters#INTERVAL_HIGH}.
+ * @throws IllegalArgumentException If the interval is invalid.
+ */
+ public Builder setInterval(int interval) {
+ if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
+ throw new IllegalArgumentException("unknown interval " + interval);
+ }
+ this.interval = interval;
+ return this;
+ }
+
+ /**
+ * Set the transmission power level for the advertising.
+ * @param txPowerLevel Transmission power of Bluetooth LE Advertising, in
+ * dBm. The valid range is [-127, 1] Recommended values are:
+ * {@link AdvertisingSetParameters#TX_POWER_ULTRA_LOW},
+ * {@link AdvertisingSetParameters#TX_POWER_LOW},
+ * {@link AdvertisingSetParameters#TX_POWER_MEDIUM}, or
+ * {@link AdvertisingSetParameters#TX_POWER_HIGH}.
+ *
+ * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
+ */
+ public Builder setTxPowerLevel(int txPowerLevel) {
+ if (txPowerLevel < TX_POWER_MIN || txPowerLevel > TX_POWER_MAX) {
+ throw new IllegalArgumentException("unknown txPowerLevel " +
+ txPowerLevel);
+ }
+ this.txPowerLevel = txPowerLevel;
+ return this;
+ }
+
+ /**
+ * Limit advertising to a given amount of time.
+ * @param timeoutMillis Advertising time limit. May not exceed 180000
+ * milliseconds. A value of 0 will disable the time limit.
+ * @throws IllegalArgumentException If the provided timeout is over 180000
+ * ms.
+ */
+ public Builder setTimeout(int timeoutMillis) {
+ if (timeoutMillis < 0 || timeoutMillis > LIMITED_ADVERTISING_MAX_MILLIS) {
+ throw new IllegalArgumentException("timeoutMillis invalid (must be 0-" +
+ LIMITED_ADVERTISING_MAX_MILLIS +
+ " milliseconds)");
+ }
+ this.timeoutMillis = timeoutMillis;
+ return this;
+ }
+
+ /**
+ * Build the {@link AdvertisingSetParameters} object.
+ */
+ public AdvertisingSetParameters build() {
+ return new AdvertisingSetParameters(connectable, isLegacy, isAnonymous,
+ includeTxPower, primaryPhy,
+ secondaryPhy, interval, txPowerLevel,
+ timeoutMillis);
+ }
+ }
+} \ No newline at end of file
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 94d03e533dff..e03c9477a6a3 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -62,6 +62,9 @@ public final class BluetoothLeAdvertiser {
private BluetoothAdapter mBluetoothAdapter;
private final Map<AdvertiseCallback, AdvertiseCallbackWrapper>
mLeAdvertisers = new HashMap<AdvertiseCallback, AdvertiseCallbackWrapper>();
+ private final Map<AdvertisingSetCallback, IAdvertisingSetCallback>
+ advertisingSetCallbackWrappers = new HashMap<>();
+ private final Map<Integer, AdvertisingSet> advertisingSets = new HashMap<>();
/**
* Use BluetoothAdapter.getLeAdvertiser() instead.
@@ -156,6 +159,93 @@ public final class BluetoothLeAdvertiser {
}
/**
+ * Creates a new advertising set. If operation succeed, device will start advertising. This
+ * method returns immediately, the operation status is delivered through
+ * {@code callback.onNewAdvertisingSet()}.
+ * <p>
+ * @param parameters advertising set parameters.
+ * @param advertiseData Advertisement data to be broadcasted.
+ * @param scanResponse Scan response associated with the advertisement data.
+ * @param periodicData Periodic advertising data.
+ * @param callback Callback for advertising set.
+ */
+ public void startAdvertisingSet(AdvertisingSetParameters parameters,
+ AdvertiseData advertiseData, AdvertiseData scanResponse,
+ PeriodicAdvertisingParameters periodicParameters,
+ AdvertiseData periodicData, AdvertisingSetCallback callback) {
+ startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
+ periodicData, callback, new Handler(Looper.getMainLooper()));
+ }
+
+ /**
+ * Creates a new advertising set. If operation succeed, device will start advertising. This
+ * method returns immediately, the operation status is delivered through
+ * {@code callback.onNewAdvertisingSet()}.
+ * <p>
+ * @param parameters advertising set parameters.
+ * @param advertiseData Advertisement data to be broadcasted.
+ * @param scanResponse Scan response associated with the advertisement data.
+ * @param periodicData Periodic advertising data.
+ * @param callback Callback for advertising set.
+ * @param handler thread upon which the callbacks will be invoked.
+ */
+ public void startAdvertisingSet(AdvertisingSetParameters parameters,
+ AdvertiseData advertiseData, AdvertiseData scanResponse,
+ PeriodicAdvertisingParameters periodicParameters,
+ AdvertiseData periodicData, AdvertisingSetCallback callback,
+ Handler handler) {
+ BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
+
+ if (callback == null) {
+ throw new IllegalArgumentException("callback cannot be null");
+ }
+
+ IBluetoothGatt gatt;
+ try {
+ gatt = mBluetoothManager.getBluetoothGatt();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+ throw new IllegalStateException("Failed to get Bluetooth");
+ }
+
+ IAdvertisingSetCallback wrapped = wrap(callback, handler);
+ advertisingSetCallbackWrappers.put(callback, wrapped);
+
+ try {
+ gatt.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
+ periodicData, wrapped);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to start advertising set - ", e);
+ throw new IllegalStateException("Failed to start advertising set");
+ }
+ }
+
+ /**
+ * Used to dispose of a {@link AdvertisingSet} object, obtained with {@link
+ * BluetoothLeAdvertiser#startAdvertisingSet}.
+ */
+ public void stopAdvertisingSet(AdvertisingSetCallback callback) {
+ if (callback == null) {
+ throw new IllegalArgumentException("callback cannot be null");
+ }
+
+ IAdvertisingSetCallback wrapped = advertisingSetCallbackWrappers.remove(callback);
+ if (wrapped == null) {
+ throw new IllegalArgumentException(
+ "callback does not represent valid registered callback.");
+ }
+
+ IBluetoothGatt gatt;
+ try {
+ gatt = mBluetoothManager.getBluetoothGatt();
+ gatt.stopAdvertisingSet(wrapped);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to stop advertising - ", e);
+ throw new IllegalStateException("Failed to stop advertising");
+ }
+ }
+
+ /**
* Cleans up advertisers. Should be called when bluetooth is down.
*
* @hide
@@ -219,6 +309,110 @@ public final class BluetoothLeAdvertiser {
return array == null ? 0 : array.length;
}
+ IAdvertisingSetCallback wrap(AdvertisingSetCallback callback, Handler handler) {
+ return new IAdvertisingSetCallback.Stub() {
+ public void onAdvertisingSetStarted(int advertiserId, int status) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
+ callback.onAdvertisingSetStarted(null, status);
+ advertisingSetCallbackWrappers.remove(callback);
+ return;
+ }
+
+ AdvertisingSet advertisingSet =
+ new AdvertisingSet(advertiserId, mBluetoothManager);
+ advertisingSets.put(advertiserId, advertisingSet);
+ callback.onAdvertisingSetStarted(advertisingSet, status);
+ }
+ });
+ }
+
+ public void onAdvertisingSetStopped(int advertiserId) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ callback.onAdvertisingSetStopped(advertisingSet);
+ advertisingSets.remove(advertiserId);
+ advertisingSetCallbackWrappers.remove(callback);
+ }
+ });
+ }
+
+ public void onAdvertisingEnabled(int advertiserId, boolean enabled, int status) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ callback.onAdvertisingEnabled(advertisingSet, enabled, status);
+ }
+ });
+ }
+
+ public void onAdvertisingDataSet(int advertiserId, int status) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ callback.onAdvertisingDataSet(advertisingSet, status);
+ }
+ });
+ }
+
+ public void onScanResponseDataSet(int advertiserId, int status) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ callback.onScanResponseDataSet(advertisingSet, status);
+ }
+ });
+ }
+
+ public void onAdvertisingParametersUpdated(int advertiserId, int status) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ callback.onAdvertisingParametersUpdated(advertisingSet, status);
+ }
+ });
+ }
+
+ public void onPeriodicAdvertisingParametersUpdated(int advertiserId, int status) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ callback.onPeriodicAdvertisingParametersUpdated(advertisingSet, status);
+ }
+ });
+ }
+
+ public void onPeriodicAdvertisingDataSet(int advertiserId, int status) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ callback.onPeriodicAdvertisingDataSet(advertisingSet, status);
+ }
+ });
+ }
+
+ public void onPeriodicAdvertisingEnable(int advertiserId, boolean enable, int status) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ callback.onPeriodicAdvertisingEnable(advertisingSet, enable, status);
+ }
+ });
+ }
+ };
+ }
+
/**
* Bluetooth GATT interface callbacks for advertising.
*/
diff --git a/core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl b/core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl
new file mode 100644
index 000000000000..4b0a111fa3d8
--- /dev/null
+++ b/core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.bluetooth.le;
+
+/**
+ * Callback definitions for interacting with Advertiser
+ * @hide
+ */
+oneway interface IAdvertisingSetCallback {
+ void onAdvertisingSetStarted(in int advertiserId, in int status);
+ void onAdvertisingSetStopped(in int advertiserId);
+ void onAdvertisingEnabled(in int advertiserId, in boolean enable, in int status);
+ void onAdvertisingDataSet(in int advertiserId, in int status);
+ void onScanResponseDataSet(in int advertiserId, in int status);
+ void onAdvertisingParametersUpdated(in int advertiserId, in int status);
+ void onPeriodicAdvertisingParametersUpdated(in int advertiserId, in int status);
+ void onPeriodicAdvertisingDataSet(in int advertiserId, in int status);
+ void onPeriodicAdvertisingEnable(in int advertiserId, in boolean enable, in int status);
+}
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.aidl b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.aidl
new file mode 100644
index 000000000000..f4bea22a12f2
--- /dev/null
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+parcelable PeriodicAdvertisingParameters;
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
new file mode 100644
index 000000000000..ebc92bd0bcf8
--- /dev/null
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * The {@link PeriodicAdvertisingParameters} provide a way to adjust periodic
+ * advertising preferences for each Bluetooth LE advertising set. Use {@link
+ * AdvertisingSetParameters.Builder} to create an instance of this class.
+ */
+public final class PeriodicAdvertisingParameters implements Parcelable {
+
+ private static final int INTERVAL_MAX = 80;
+ private static final int INTERVAL_MIN = 65519;
+
+ private final boolean enable;
+ private final boolean includeTxPower;
+ private final int interval;
+
+ private PeriodicAdvertisingParameters(boolean enable, boolean includeTxPower, int interval) {
+ this.enable = enable;
+ this.includeTxPower = includeTxPower;
+ this.interval = interval;
+ }
+
+ private PeriodicAdvertisingParameters(Parcel in) {
+ enable = in.readInt() != 0 ? true : false;
+ includeTxPower = in.readInt() != 0 ? true : false;
+ interval = in.readInt();
+ }
+
+ /**
+ * Returns whether the periodic advertising shall be enabled.
+ */
+ public boolean getEnable() { return enable; }
+
+ /**
+ * Returns whether the TX Power will be included.
+ */
+ public boolean getIncludeTxPower() { return includeTxPower; }
+
+ /**
+ * Returns the periodic advertising interval, in 1.25ms unit.
+ * Valid values are from 80 (100ms) to 65519 (81.89875s).
+ */
+ public int getInterval() { return interval; }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(enable ? 1 : 0);
+ dest.writeInt(includeTxPower ? 1 : 0);
+ dest.writeInt(interval);
+ }
+
+ public static final Parcelable
+ .Creator<PeriodicAdvertisingParameters> CREATOR =
+ new Creator<PeriodicAdvertisingParameters>() {
+ @Override
+ public PeriodicAdvertisingParameters[] newArray(int size) {
+ return new PeriodicAdvertisingParameters[size];
+ }
+
+ @Override
+ public PeriodicAdvertisingParameters createFromParcel(Parcel in) {
+ return new PeriodicAdvertisingParameters(in);
+ }
+ };
+
+ public static final class Builder {
+ private boolean includeTxPower = false;
+ private boolean enable = false;
+ private int interval = INTERVAL_MAX;
+
+ /**
+ * Set wether the Periodic Advertising should be enabled for this set.
+ */
+ public Builder setEnable(boolean enable) {
+ this.enable = enable;
+ return this;
+ }
+
+ /**
+ * Whether the transmission power level should be included in the periodic
+ * packet.
+ */
+ public Builder setIncludeTxPower(boolean includeTxPower) {
+ this.includeTxPower = includeTxPower;
+ return this;
+ }
+
+ /**
+ * Set advertising interval for periodic advertising, in 1.25ms unit.
+ * Valid values are from 80 (100ms) to 65519 (81.89875s).
+ * Value from range [interval, interval+20ms] will be picked as the actual value.
+ * @throws IllegalArgumentException If the interval is invalid.
+ */
+ public Builder setInterval(int interval) {
+ if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
+ throw new IllegalArgumentException("Invalid interval (must be " + INTERVAL_MIN +
+ "-" + INTERVAL_MAX + ")");
+ }
+ this.interval = interval;
+ return this;
+ }
+
+ /**
+ * Build the {@link AdvertisingSetParameters} object.
+ */
+ public PeriodicAdvertisingParameters build() {
+ return new PeriodicAdvertisingParameters(enable, includeTxPower, interval);
+ }
+ }
+}
diff --git a/core/java/android/bluetooth/le/ScanResult.java b/core/java/android/bluetooth/le/ScanResult.java
index f92357b59c7d..583ddd20fd7f 100644
--- a/core/java/android/bluetooth/le/ScanResult.java
+++ b/core/java/android/bluetooth/le/ScanResult.java
@@ -214,7 +214,7 @@ public final class ScanResult implements Parcelable {
}
/**
- * Returns the received signal strength in dBm. The valid range is [-127, 127].
+ * Returns the received signal strength in dBm. The valid range is [-127, 126].
*/
public int getRssi() {
return mRssi;