Loading core/api/system-current.txt +7 −0 Original line number Diff line number Diff line Loading @@ -1924,6 +1924,7 @@ package android.bluetooth { method public boolean disableBLE(); method public boolean enableBLE(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void generateLocalOobData(int, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OobDataCallback); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public long getDiscoveryEndMillis(); method public boolean isBleScanAlwaysAvailable(); method public boolean isLeEnabled(); Loading @@ -1935,12 +1936,18 @@ package android.bluetooth { field public static final int ACTIVE_DEVICE_ALL = 2; // 0x2 field public static final int ACTIVE_DEVICE_AUDIO = 0; // 0x0 field public static final int ACTIVE_DEVICE_PHONE_CALL = 1; // 0x1 field public static final int OOB_ERROR_ADAPTER_DISABLED = 2; // 0x2 field public static final int OOB_ERROR_ANOTHER_ACTIVE_REQUEST = 1; // 0x1 field public static final int OOB_ERROR_UNKNOWN = 0; // 0x0 } public static interface BluetoothAdapter.OnMetadataChangedListener { method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]); } public static interface BluetoothAdapter.OobDataCallback { } public final class BluetoothDevice implements android.os.Parcelable { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean canBondWithoutDialog(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean cancelBondProcess(); Loading core/java/android/bluetooth/BluetoothAdapter.java +163 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.app.ActivityThread; import android.app.PropertyInvalidatedCache; import android.bluetooth.BluetoothDevice.Transport; import android.bluetooth.BluetoothProfile.ConnectionPolicy; import android.bluetooth.le.BluetoothLeAdvertiser; import android.bluetooth.le.BluetoothLeScanner; Loading Loading @@ -3046,6 +3047,168 @@ public final class BluetoothAdapter { return false; } /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "OOB_ERROR_" }, value = { OOB_ERROR_UNKNOWN, OOB_ERROR_ANOTHER_ACTIVE_REQUEST, OOB_ERROR_ADAPTER_DISABLED }) public @interface OobError {} /** * An unknown error has occurred in the controller, stack, or callback pipeline. * * @hide */ @SystemApi public static final int OOB_ERROR_UNKNOWN = 0; /** * If another application has already requested {@link OobData} then another fetch will be * disallowed until the callback is removed. * * @hide */ @SystemApi public static final int OOB_ERROR_ANOTHER_ACTIVE_REQUEST = 1; /** * The adapter is currently disabled, please enable it. * * @hide */ @SystemApi public static final int OOB_ERROR_ADAPTER_DISABLED = 2; /** * Provides callback methods for receiving {@link OobData} from the host stack, as well as an * error interface in order to allow the caller to determine next steps based on the {@link * ErrorCode}. * * @hide */ @SystemApi public interface OobDataCallback { /** * Handles the {@link OobData} received from the host stack. * * @param transport - whether the {@link OobData} is generated for LE or Classic. * @param oobData - data generated in the host stack(LE) or controller (Classic) * * @hide */ void onOobData(@Transport int transport, @Nullable OobData oobData); /** * Provides feedback when things don't go as expected. * * @param errorCode - the code descibing the type of error that occurred. * * @hide */ void onError(@OobError int errorCode); } /** * Wraps an AIDL interface around an {@link OobDataCallback} interface. * * @see {@link IBluetoothOobDataCallback} for interface definition. * * @hide */ public class WrappedOobDataCallback extends IBluetoothOobDataCallback.Stub { private final OobDataCallback mCallback; private final Executor mExecutor; /** * @param callback - object to receive {@link OobData} must be a non null argument * * @throws NullPointerException if the callback is null. */ WrappedOobDataCallback(@NonNull OobDataCallback callback, @NonNull @CallbackExecutor Executor executor) { Preconditions.checkNotNull(callback); Preconditions.checkNotNull(executor); mCallback = callback; mExecutor = executor; } /** * Wrapper function to relay to the {@link OobDataCallback#onOobData} * * @param transport - whether the {@link OobData} is generated for LE or Classic. * @param oobData - data generated in the host stack(LE) or controller (Classic) * * @hide */ public void onOobData(@Transport int transport, OobData oobData) { mExecutor.execute(new Runnable() { public void run() { mCallback.onOobData(transport, oobData); } }); } /** * Wrapper function to relay to the {@link OobDataCallback#onError} * * @param errorCode - the code descibing the type of error that occurred. * * @hide */ public void onError(@OobError int errorCode) { mExecutor.execute(new Runnable() { public void run() { mCallback.onError(errorCode); } }); } } /** * Fetches a secret data value that can be used for a secure and simple pairing experience. * * <p>This is the Local Out of Band data the comes from the * * <p>This secret is the local Out of Band data. This data is used to securely and quickly * pair two devices with minimal user interaction. * * <p>For example, this secret can be transferred to a remote device out of band (meaning any * other way besides using bluetooth). Once the remote device finds this device using the * information given in the data, such as the PUBLIC ADDRESS, the remote device could then * connect to this device using this secret when the pairing sequenece asks for the secret. * This device will respond by automatically accepting the pairing due to the secret being so * trustworthy. * * @param transport - provide type of transport (e.g. LE or Classic). * @param callback - target object to receive the {@link OobData} value. * * @throws NullPointerException if callback is null. * @throws IllegalArgumentException if the transport is not valid. * * @hide */ @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public void generateLocalOobData(@Transport int transport, @NonNull @CallbackExecutor Executor executor, @NonNull OobDataCallback callback) { if (transport != BluetoothDevice.TRANSPORT_BREDR && transport != BluetoothDevice.TRANSPORT_LE) { throw new IllegalArgumentException("Invalid transport '" + transport + "'!"); } Preconditions.checkNotNull(callback); if (!isEnabled()) { Log.w(TAG, "generateLocalOobData(): Adapter isn't enabled!"); callback.onError(OOB_ERROR_ADAPTER_DISABLED); } else { try { mService.generateLocalOobData(transport, new WrappedOobDataCallback(callback, executor)); } catch (RemoteException e) { Log.e(TAG, "", e); } } } /** * Enable control of the Bluetooth Adapter for a single application. * Loading core/java/android/bluetooth/BluetoothDevice.java +19 −0 Original line number Diff line number Diff line Loading @@ -952,6 +952,21 @@ public final class BluetoothDevice implements Parcelable { @SystemApi public static final int ACCESS_REJECTED = 2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef( prefix = { "TRANSPORT_" }, value = { /** Allow host to automatically select a transport (dual-mode only) */ TRANSPORT_AUTO, /** Use Classic or BR/EDR transport.*/ TRANSPORT_BREDR, /** Use Low Energy transport.*/ TRANSPORT_LE, } ) public @interface Transport {} /** * No preference of physical transport for GATT connections to remote dual-mode devices */ Loading Loading @@ -1084,6 +1099,10 @@ public final class BluetoothDevice implements Parcelable { public void onBrEdrDown() { if (DBG) Log.d(TAG, "onBrEdrDown: reached BLE ON state"); } public void onOobData(@Transport int transport, OobData oobData) { if (DBG) Log.d(TAG, "onOobData: got data"); } }; /** Loading Loading
core/api/system-current.txt +7 −0 Original line number Diff line number Diff line Loading @@ -1924,6 +1924,7 @@ package android.bluetooth { method public boolean disableBLE(); method public boolean enableBLE(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void generateLocalOobData(int, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OobDataCallback); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public long getDiscoveryEndMillis(); method public boolean isBleScanAlwaysAvailable(); method public boolean isLeEnabled(); Loading @@ -1935,12 +1936,18 @@ package android.bluetooth { field public static final int ACTIVE_DEVICE_ALL = 2; // 0x2 field public static final int ACTIVE_DEVICE_AUDIO = 0; // 0x0 field public static final int ACTIVE_DEVICE_PHONE_CALL = 1; // 0x1 field public static final int OOB_ERROR_ADAPTER_DISABLED = 2; // 0x2 field public static final int OOB_ERROR_ANOTHER_ACTIVE_REQUEST = 1; // 0x1 field public static final int OOB_ERROR_UNKNOWN = 0; // 0x0 } public static interface BluetoothAdapter.OnMetadataChangedListener { method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]); } public static interface BluetoothAdapter.OobDataCallback { } public final class BluetoothDevice implements android.os.Parcelable { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean canBondWithoutDialog(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean cancelBondProcess(); Loading
core/java/android/bluetooth/BluetoothAdapter.java +163 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.app.ActivityThread; import android.app.PropertyInvalidatedCache; import android.bluetooth.BluetoothDevice.Transport; import android.bluetooth.BluetoothProfile.ConnectionPolicy; import android.bluetooth.le.BluetoothLeAdvertiser; import android.bluetooth.le.BluetoothLeScanner; Loading Loading @@ -3046,6 +3047,168 @@ public final class BluetoothAdapter { return false; } /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "OOB_ERROR_" }, value = { OOB_ERROR_UNKNOWN, OOB_ERROR_ANOTHER_ACTIVE_REQUEST, OOB_ERROR_ADAPTER_DISABLED }) public @interface OobError {} /** * An unknown error has occurred in the controller, stack, or callback pipeline. * * @hide */ @SystemApi public static final int OOB_ERROR_UNKNOWN = 0; /** * If another application has already requested {@link OobData} then another fetch will be * disallowed until the callback is removed. * * @hide */ @SystemApi public static final int OOB_ERROR_ANOTHER_ACTIVE_REQUEST = 1; /** * The adapter is currently disabled, please enable it. * * @hide */ @SystemApi public static final int OOB_ERROR_ADAPTER_DISABLED = 2; /** * Provides callback methods for receiving {@link OobData} from the host stack, as well as an * error interface in order to allow the caller to determine next steps based on the {@link * ErrorCode}. * * @hide */ @SystemApi public interface OobDataCallback { /** * Handles the {@link OobData} received from the host stack. * * @param transport - whether the {@link OobData} is generated for LE or Classic. * @param oobData - data generated in the host stack(LE) or controller (Classic) * * @hide */ void onOobData(@Transport int transport, @Nullable OobData oobData); /** * Provides feedback when things don't go as expected. * * @param errorCode - the code descibing the type of error that occurred. * * @hide */ void onError(@OobError int errorCode); } /** * Wraps an AIDL interface around an {@link OobDataCallback} interface. * * @see {@link IBluetoothOobDataCallback} for interface definition. * * @hide */ public class WrappedOobDataCallback extends IBluetoothOobDataCallback.Stub { private final OobDataCallback mCallback; private final Executor mExecutor; /** * @param callback - object to receive {@link OobData} must be a non null argument * * @throws NullPointerException if the callback is null. */ WrappedOobDataCallback(@NonNull OobDataCallback callback, @NonNull @CallbackExecutor Executor executor) { Preconditions.checkNotNull(callback); Preconditions.checkNotNull(executor); mCallback = callback; mExecutor = executor; } /** * Wrapper function to relay to the {@link OobDataCallback#onOobData} * * @param transport - whether the {@link OobData} is generated for LE or Classic. * @param oobData - data generated in the host stack(LE) or controller (Classic) * * @hide */ public void onOobData(@Transport int transport, OobData oobData) { mExecutor.execute(new Runnable() { public void run() { mCallback.onOobData(transport, oobData); } }); } /** * Wrapper function to relay to the {@link OobDataCallback#onError} * * @param errorCode - the code descibing the type of error that occurred. * * @hide */ public void onError(@OobError int errorCode) { mExecutor.execute(new Runnable() { public void run() { mCallback.onError(errorCode); } }); } } /** * Fetches a secret data value that can be used for a secure and simple pairing experience. * * <p>This is the Local Out of Band data the comes from the * * <p>This secret is the local Out of Band data. This data is used to securely and quickly * pair two devices with minimal user interaction. * * <p>For example, this secret can be transferred to a remote device out of band (meaning any * other way besides using bluetooth). Once the remote device finds this device using the * information given in the data, such as the PUBLIC ADDRESS, the remote device could then * connect to this device using this secret when the pairing sequenece asks for the secret. * This device will respond by automatically accepting the pairing due to the secret being so * trustworthy. * * @param transport - provide type of transport (e.g. LE or Classic). * @param callback - target object to receive the {@link OobData} value. * * @throws NullPointerException if callback is null. * @throws IllegalArgumentException if the transport is not valid. * * @hide */ @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public void generateLocalOobData(@Transport int transport, @NonNull @CallbackExecutor Executor executor, @NonNull OobDataCallback callback) { if (transport != BluetoothDevice.TRANSPORT_BREDR && transport != BluetoothDevice.TRANSPORT_LE) { throw new IllegalArgumentException("Invalid transport '" + transport + "'!"); } Preconditions.checkNotNull(callback); if (!isEnabled()) { Log.w(TAG, "generateLocalOobData(): Adapter isn't enabled!"); callback.onError(OOB_ERROR_ADAPTER_DISABLED); } else { try { mService.generateLocalOobData(transport, new WrappedOobDataCallback(callback, executor)); } catch (RemoteException e) { Log.e(TAG, "", e); } } } /** * Enable control of the Bluetooth Adapter for a single application. * Loading
core/java/android/bluetooth/BluetoothDevice.java +19 −0 Original line number Diff line number Diff line Loading @@ -952,6 +952,21 @@ public final class BluetoothDevice implements Parcelable { @SystemApi public static final int ACCESS_REJECTED = 2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef( prefix = { "TRANSPORT_" }, value = { /** Allow host to automatically select a transport (dual-mode only) */ TRANSPORT_AUTO, /** Use Classic or BR/EDR transport.*/ TRANSPORT_BREDR, /** Use Low Energy transport.*/ TRANSPORT_LE, } ) public @interface Transport {} /** * No preference of physical transport for GATT connections to remote dual-mode devices */ Loading Loading @@ -1084,6 +1099,10 @@ public final class BluetoothDevice implements Parcelable { public void onBrEdrDown() { if (DBG) Log.d(TAG, "onBrEdrDown: reached BLE ON state"); } public void onOobData(@Transport int transport, OobData oobData) { if (DBG) Log.d(TAG, "onOobData: got data"); } }; /** Loading