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
This commit is contained in:
@@ -9039,7 +9039,7 @@ package android.bluetooth {
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getName();
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getType();
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.os.ParcelUuid[] getUuids();
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setAlias(@NonNull String);
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int setAlias(@Nullable String);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setPairingConfirmation(boolean);
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setPin(byte[]);
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
@@ -9487,6 +9487,15 @@ package android.bluetooth {
|
||||
field public static final int TYPE_SCO = 2; // 0x2
|
||||
}
|
||||
|
||||
public final class BluetoothStatusCodes {
|
||||
field public static final int ERROR_BLUETOOTH_NOT_ALLOWED = 2; // 0x2
|
||||
field public static final int ERROR_BLUETOOTH_NOT_ENABLED = 1; // 0x1
|
||||
field public static final int ERROR_DEVICE_NOT_BONDED = 3; // 0x3
|
||||
field public static final int ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION = 6; // 0x6
|
||||
field public static final int ERROR_UNKNOWN = 2147483647; // 0x7fffffff
|
||||
field public static final int SUCCESS = 0; // 0x0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.bluetooth.le {
|
||||
|
||||
@@ -1950,9 +1950,6 @@ 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 {
|
||||
@@ -2090,6 +2087,10 @@ package android.bluetooth {
|
||||
field @Deprecated public static final int PRIORITY_ON = 100; // 0x64
|
||||
}
|
||||
|
||||
public final class BluetoothStatusCodes {
|
||||
field public static final int ERROR_ANOTHER_ACTIVE_OOB_REQUEST = 1000; // 0x3e8
|
||||
}
|
||||
|
||||
public final class BluetoothUuid {
|
||||
method public static boolean containsAnyUuid(@Nullable android.os.ParcelUuid[], @Nullable android.os.ParcelUuid[]);
|
||||
method @NonNull public static android.os.ParcelUuid parseUuidFrom(@Nullable byte[]);
|
||||
@@ -2245,7 +2246,7 @@ package android.companion {
|
||||
|
||||
public final class CompanionDeviceManager {
|
||||
method @RequiresPermission(android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES) public void associate(@NonNull String, @NonNull android.net.MacAddress);
|
||||
method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean canPairWithoutPrompt(@NonNull String, @NonNull String, int);
|
||||
method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean canPairWithoutPrompt(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
|
||||
method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociatedForWifiConnection(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle);
|
||||
}
|
||||
|
||||
|
||||
@@ -3258,38 +3258,13 @@ 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
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
205
core/java/android/bluetooth/BluetoothStatusCodes.java
Normal file
205
core/java/android/bluetooth/BluetoothStatusCodes.java
Normal file
@@ -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;
|
||||
}
|
||||
@@ -338,21 +338,24 @@ public final class CompanionDeviceManager {
|
||||
*
|
||||
* @param packageName the package name of the calling app
|
||||
* @param deviceMacAddress the bluetooth device's mac address
|
||||
* @param userId the calling user's identifier
|
||||
* @param user the user handle that currently hosts the package being queried for a companion
|
||||
* device association
|
||||
* @return true if it was recently associated and we can bypass the dialog, false otherwise
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
|
||||
public boolean canPairWithoutPrompt(@NonNull String packageName,
|
||||
@NonNull String deviceMacAddress, int userId) {
|
||||
@NonNull String deviceMacAddress, @NonNull UserHandle user) {
|
||||
if (!checkFeaturePresent()) {
|
||||
return false;
|
||||
}
|
||||
Objects.requireNonNull(packageName, "package name cannot be null");
|
||||
Objects.requireNonNull(deviceMacAddress, "device mac address cannot be null");
|
||||
Objects.requireNonNull(user, "user handle cannot be null");
|
||||
try {
|
||||
return mService.canPairWithoutPrompt(packageName, deviceMacAddress, userId);
|
||||
return mService.canPairWithoutPrompt(packageName, deviceMacAddress,
|
||||
user.getIdentifier());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user