OOB: Implement generateLocalOutOfBand API

CTS-Coverage-Bug: 184395281
Bug: 178007935
Tag: #feature
Test: manual
Change-Id: I5bc11ac13d9cbb8f76f422aa4aea8295ebec95b4
This commit is contained in:
Martin Brabham
2021-03-19 00:07:02 -07:00
parent f7923a9cc2
commit 2093f69721
3 changed files with 189 additions and 0 deletions

View File

@@ -1917,6 +1917,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();
@@ -1928,12 +1929,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();

View File

@@ -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;
@@ -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.
*

View File

@@ -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
*/
@@ -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");
}
};
/**