diff options
author | Rahul Sabnis <rahulsabnis@google.com> | 2021-05-19 16:00:04 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-05-19 16:00:04 +0000 |
commit | 0b399b27ea2046104838d0c5fbf53b718646e1dc (patch) | |
tree | a4cbdb698f809f3e9e879eca0c07cd4567ef93f8 /framework/java/android/bluetooth | |
parent | 739f619eb30c7e37b0a7449c14220e2ea4f5eb86 (diff) | |
parent | 4c2ce6e1885c73085bd2eece5cdc53e141348258 (diff) |
Merge "Update BluetoothDevice#setAlias based on API council feedback: now accepts null input and returns an int (with error codes). Update CompanionDeviceManager#canPairWithoutPrompt to take a UserHandle instead of an int. Adds BluetoothStatusCodes class for all new Bluetooth error / success codes. Moved OOB and hci disconnect constants to the new BluetoothStatusCodes class." into sc-dev
Diffstat (limited to 'framework/java/android/bluetooth')
3 files changed, 258 insertions, 162 deletions
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java index 9fc1f88c01..54941724b2 100644 --- a/framework/java/android/bluetooth/BluetoothAdapter.java +++ b/framework/java/android/bluetooth/BluetoothAdapter.java @@ -3258,39 +3258,14 @@ public final class BluetoothAdapter { /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "OOB_ERROR_" }, value = { - OOB_ERROR_UNKNOWN, - OOB_ERROR_ANOTHER_ACTIVE_REQUEST, - OOB_ERROR_ADAPTER_DISABLED + @IntDef(value = { + BluetoothStatusCodes.ERROR_UNKNOWN, + BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED, + BluetoothStatusCodes.ERROR_ANOTHER_ACTIVE_OOB_REQUEST, }) 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 {@code * ErrorCode}. @@ -3310,7 +3285,7 @@ public final class BluetoothAdapter { /** * Provides feedback when things don't go as expected. * - * @param errorCode - the code descibing the type of error that occurred. + * @param errorCode - the code describing the type of error that occurred. */ void onError(@OobError int errorCode); } @@ -3407,7 +3382,7 @@ public final class BluetoothAdapter { Preconditions.checkNotNull(callback); if (!isEnabled()) { Log.w(TAG, "generateLocalOobData(): Adapter isn't enabled!"); - callback.onError(OOB_ERROR_ADAPTER_DISABLED); + callback.onError(BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED); } else { try { mService.generateLocalOobData(transport, new WrappedOobDataCallback(callback, @@ -4210,141 +4185,45 @@ public final class BluetoothAdapter { */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "REASON_" }, value = { - REASON_UNKNOWN, - REASON_LOCAL_REQUEST, - REASON_REMOTE_REQUEST, - REASON_LOCAL_ERROR, - REASON_REMOTE_ERROR, - REASON_TIMEOUT, - REASON_SECURITY, - REASON_SYSTEM_POLICY, - REASON_RESOURCE_LIMIT_REACHED, - REASON_CONNECTION_EXISTS, - REASON_BAD_PARAMETERS}) + BluetoothStatusCodes.ERROR_UNKNOWN, + BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL_REQUEST, + BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE_REQUEST, + BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL, + BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE, + BluetoothStatusCodes.ERROR_DISCONNECT_REASON_TIMEOUT, + BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SECURITY, + BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SYSTEM_POLICY, + BluetoothStatusCodes.ERROR_DISCONNECT_REASON_RESOURCE_LIMIT_REACHED, + BluetoothStatusCodes.ERROR_DISCONNECT_REASON_CONNECTION_ALREADY_EXISTS, + BluetoothStatusCodes.ERROR_DISCONNECT_REASON_BAD_PARAMETERS}) public @interface DisconnectReason {} /** - * Indicates that the ACL disconnected due to an unknown reason. - */ - public static final int REASON_UNKNOWN = 0; - - /** - * Indicates that the ACL disconnected due to an explicit request from the local device. - * <p> - * Example cause: This is a normal disconnect reason, e.g., user/app initiates - * disconnection. - */ - public static final int REASON_LOCAL_REQUEST = 1; - - /** - * Indicates that the ACL disconnected due to an explicit request from the remote device. - * <p> - * Example cause: This is a normal disconnect reason, e.g., user/app initiates - * disconnection. - * <p> - * Example solution: The app can also prompt the user to check their remote device. - */ - public static final int REASON_REMOTE_REQUEST = 2; - - /** - * Generic disconnect reason indicating the ACL disconnected due to an error on the local - * device. - * <p> - * Example solution: Prompt the user to check their local device (e.g., phone, car - * headunit). - */ - public static final int REASON_LOCAL_ERROR = 3; - - /** - * Generic disconnect reason indicating the ACL disconnected due to an error on the remote - * device. - * <p> - * Example solution: Prompt the user to check their remote device (e.g., headset, car - * headunit, watch). - */ - public static final int REASON_REMOTE_ERROR = 4; - - /** - * Indicates that the ACL disconnected due to a timeout. - * <p> - * Example cause: remote device might be out of range. - * <p> - * Example solution: Prompt user to verify their remote device is on or in - * connection/pairing mode. - */ - public static final int REASON_TIMEOUT = 5; - - /** - * Indicates that the ACL disconnected due to link key issues. - * <p> - * Example cause: Devices are either unpaired or remote device is refusing our pairing - * request. - * <p> - * Example solution: Prompt user to unpair and pair again. - */ - public static final int REASON_SECURITY = 6; - - /** - * Indicates that the ACL disconnected due to the local device's system policy. - * <p> - * Example cause: privacy policy, power management policy, permissions, etc. - * <p> - * Example solution: Prompt the user to check settings, or check with their system - * administrator (e.g. some corp-managed devices do not allow OPP connection). - */ - public static final int REASON_SYSTEM_POLICY = 7; - - /** - * Indicates that the ACL disconnected due to resource constraints, either on the local - * device or the remote device. - * <p> - * Example cause: controller is busy, memory limit reached, maximum number of connections - * reached. - * <p> - * Example solution: The app should wait and try again. If still failing, prompt the user - * to disconnect some devices, or toggle Bluetooth on the local and/or the remote device. - */ - public static final int REASON_RESOURCE_LIMIT_REACHED = 8; - - /** - * Indicates that the ACL disconnected because another ACL connection already exists. - */ - public static final int REASON_CONNECTION_EXISTS = 9; - - /** - * Indicates that the ACL disconnected due to incorrect parameters passed in from the app. - * <p> - * Example solution: Change parameters and try again. If error persists, the app can report - * telemetry and/or log the error in a bugreport. - */ - public static final int REASON_BAD_PARAMETERS = 10; - - /** * Returns human-readable strings corresponding to {@link DisconnectReason}. */ public static String disconnectReasonText(@DisconnectReason int reason) { switch (reason) { - case REASON_UNKNOWN: + case BluetoothStatusCodes.ERROR_UNKNOWN: return "Reason unknown"; - case REASON_LOCAL_REQUEST: + case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL_REQUEST: return "Local request"; - case REASON_REMOTE_REQUEST: + case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE_REQUEST: return "Remote request"; - case REASON_LOCAL_ERROR: + case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL: return "Local error"; - case REASON_REMOTE_ERROR: + case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE: return "Remote error"; - case REASON_TIMEOUT: + case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_TIMEOUT: return "Timeout"; - case REASON_SECURITY: + case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SECURITY: return "Security"; - case REASON_SYSTEM_POLICY: + case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SYSTEM_POLICY: return "System policy"; - case REASON_RESOURCE_LIMIT_REACHED: + case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_RESOURCE_LIMIT_REACHED: return "Resource constrained"; - case REASON_CONNECTION_EXISTS: + case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_CONNECTION_ALREADY_EXISTS: return "Connection already exists"; - case REASON_BAD_PARAMETERS: + case BluetoothStatusCodes.ERROR_DISCONNECT_REASON_BAD_PARAMETERS: return "Bad parameters"; default: return "Unrecognized disconnect reason: " + reason; diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java index 52d4c7116a..f2496fe0ca 100644 --- a/framework/java/android/bluetooth/BluetoothDevice.java +++ b/framework/java/android/bluetooth/BluetoothDevice.java @@ -1351,6 +1351,17 @@ public final class BluetoothDevice implements Parcelable { return null; } + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + BluetoothStatusCodes.SUCCESS, + BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED, + BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED, + BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION, + BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED + }) + public @interface SetAliasReturnValues{} + /** * Sets the locally modifiable name (alias) of the remote Bluetooth device. This method * overwrites the previously stored alias. The new alias is saved in local @@ -1358,34 +1369,35 @@ public final class BluetoothDevice implements Parcelable { * * <p>This method requires the calling app to be associated with Companion Device Manager (see * {@link android.companion.CompanionDeviceManager#associate(AssociationRequest, - * android.companion.CompanionDeviceManager.Callback, Handler)}) and have the {@link - * android.Manifest.permission#BLUETOOTH} permission. Alternatively, if the caller has the - * {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission, they can bypass the - * Companion Device Manager association requirement. + * android.companion.CompanionDeviceManager.Callback, Handler)}) and have the + * {@link android.Manifest.permission#BLUETOOTH_CONNECT} permission. Alternatively, if the + * caller has the {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission, they can + * bypass the Companion Device Manager association requirement as well as other permission + * requirements. * - * @param alias is the new locally modifiable name for the remote Bluetooth device which must be - * non-null and not the empty string. - * @return {@code true} if the alias is successfully set, {@code false} on error - * @throws IllegalArgumentException if the alias is {@code null} or the empty string + * @param alias is the new locally modifiable name for the remote Bluetooth device which must + * be the empty string. If null, we clear the alias. + * @return whether the alias was successfully changed + * @throws IllegalArgumentException if the alias is the empty string */ @RequiresLegacyBluetoothPermission @RequiresBluetoothConnectPermission @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - public boolean setAlias(@NonNull String alias) { - if (alias == null || alias.isEmpty()) { - throw new IllegalArgumentException("Cannot set the alias to null or the empty string"); + public @SetAliasReturnValues int setAlias(@Nullable String alias) { + if (alias != null && alias.isEmpty()) { + throw new IllegalArgumentException("alias cannot be the empty string"); } final IBluetooth service = sService; if (service == null) { Log.e(TAG, "BT not enabled. Cannot set Remote Device name"); - return false; + return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; } try { return service.setRemoteAlias(this, alias, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, "", e); + throw e.rethrowFromSystemServer(); } - return false; } /** diff --git a/framework/java/android/bluetooth/BluetoothStatusCodes.java b/framework/java/android/bluetooth/BluetoothStatusCodes.java new file mode 100644 index 0000000000..31bb0f68c6 --- /dev/null +++ b/framework/java/android/bluetooth/BluetoothStatusCodes.java @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2021 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; + +import android.annotation.SystemApi; + +/** + * A class with constants representing possible return values for Bluetooth APIs. General return + * values occupy the range 0 to 99. Profile-specific return values occupy the range 100-999. + * API-specific return values start at 1000. The exception to this is the "other" error code which + * occupies the max integer value. + */ +public final class BluetoothStatusCodes { + + private BluetoothStatusCodes() {} + + /** + * Indicates that the API call was successful + */ + public static final int SUCCESS = 0; + + /** + * Error code indicating that Bluetooth is not enabled + */ + public static final int ERROR_BLUETOOTH_NOT_ENABLED = 1; + + /** + * Error code indicating that the API call was initiated by neither the system nor the active + * Zuser + */ + public static final int ERROR_BLUETOOTH_NOT_ALLOWED = 2; + + /** + * Error code indicating that the Bluetooth Device specified is not bonded + */ + public static final int ERROR_DEVICE_NOT_BONDED = 3; + + /** + * Error code indicating that the Bluetooth Device specified is not connected, but is bonded + * + * @hide + */ + public static final int ERROR_DEVICE_NOT_CONNECTED = 4; + + /** + * Error code indicating that the caller does not have the + * {@link android.Manifest.permission#BLUETOOTH_ADVERTISE} permission + * + * @hide + */ + public static final int ERROR_MISSING_BLUETOOTH_ADVERTISE_PERMISSION = 5; + + /** + * Error code indicating that the caller does not have the + * {@link android.Manifest.permission#BLUETOOTH_CONNECT} permission + */ + public static final int ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION = 6; + + /** + * Error code indicating that the caller does not have the + * {@link android.Manifest.permission#BLUETOOTH_SCAN} permission + * + * @hide + */ + public static final int ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION = 7; + + /** + * 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 ERROR_ANOTHER_ACTIVE_OOB_REQUEST = 1000; + + /** + * Indicates that the ACL disconnected due to an explicit request from the local device. + * <p> + * Example cause: This is a normal disconnect reason, e.g., user/app initiates + * disconnection. + * + * @hide + */ + public static final int ERROR_DISCONNECT_REASON_LOCAL_REQUEST = 1100; + + /** + * Indicates that the ACL disconnected due to an explicit request from the remote device. + * <p> + * Example cause: This is a normal disconnect reason, e.g., user/app initiates + * disconnection. + * <p> + * Example solution: The app can also prompt the user to check their remote device. + * + * @hide + */ + public static final int ERROR_DISCONNECT_REASON_REMOTE_REQUEST = 1101; + + /** + * Generic disconnect reason indicating the ACL disconnected due to an error on the local + * device. + * <p> + * Example solution: Prompt the user to check their local device (e.g., phone, car + * headunit). + * + * @hide + */ + public static final int ERROR_DISCONNECT_REASON_LOCAL = 1102; + + /** + * Generic disconnect reason indicating the ACL disconnected due to an error on the remote + * device. + * <p> + * Example solution: Prompt the user to check their remote device (e.g., headset, car + * headunit, watch). + * + * @hide + */ + public static final int ERROR_DISCONNECT_REASON_REMOTE = 1103; + + /** + * Indicates that the ACL disconnected due to a timeout. + * <p> + * Example cause: remote device might be out of range. + * <p> + * Example solution: Prompt user to verify their remote device is on or in + * connection/pairing mode. + * + * @hide + */ + public static final int ERROR_DISCONNECT_REASON_TIMEOUT = 1104; + + /** + * Indicates that the ACL disconnected due to link key issues. + * <p> + * Example cause: Devices are either unpaired or remote device is refusing our pairing + * request. + * <p> + * Example solution: Prompt user to unpair and pair again. + * + * @hide + */ + public static final int ERROR_DISCONNECT_REASON_SECURITY = 1105; + + /** + * Indicates that the ACL disconnected due to the local device's system policy. + * <p> + * Example cause: privacy policy, power management policy, permissions, etc. + * <p> + * Example solution: Prompt the user to check settings, or check with their system + * administrator (e.g. some corp-managed devices do not allow OPP connection). + * + * @hide + */ + public static final int ERROR_DISCONNECT_REASON_SYSTEM_POLICY = 1106; + + /** + * Indicates that the ACL disconnected due to resource constraints, either on the local + * device or the remote device. + * <p> + * Example cause: controller is busy, memory limit reached, maximum number of connections + * reached. + * <p> + * Example solution: The app should wait and try again. If still failing, prompt the user + * to disconnect some devices, or toggle Bluetooth on the local and/or the remote device. + * + * @hide + */ + public static final int ERROR_DISCONNECT_REASON_RESOURCE_LIMIT_REACHED = 1107; + + /** + * Indicates that the ACL disconnected because another ACL connection already exists. + * + * @hide + */ + public static final int ERROR_DISCONNECT_REASON_CONNECTION_ALREADY_EXISTS = 1108; + + /** + * Indicates that the ACL disconnected due to incorrect parameters passed in from the app. + * <p> + * Example solution: Change parameters and try again. If error persists, the app can report + * telemetry and/or log the error in a bugreport. + * + * @hide + */ + public static final int ERROR_DISCONNECT_REASON_BAD_PARAMETERS = 1109; + + /** + * Indicates that an unknown error has occurred has occurred. + */ + public static final int ERROR_UNKNOWN = Integer.MAX_VALUE; +} |