Merge "Resolve BluetoothDevice hidden API usages by Settings"

am: ce656f7754

Change-Id: I6c9af91fa6338246a872318038dad699c5c3fe04
This commit is contained in:
Rahul Sabnis
2019-12-12 13:19:41 -08:00
committed by android-build-merger
5 changed files with 91 additions and 106 deletions

View File

@@ -1343,15 +1343,24 @@ package android.bluetooth {
public final class BluetoothDevice implements android.os.Parcelable {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean cancelBondProcess();
method public boolean cancelPairing();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getBatteryLevel();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getMessageAccessPermission();
method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public byte[] getMetadata(int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getPhonebookAccessPermission();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getSimAccessPermission();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isBondingInitiatedLocally();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean removeBond();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setAlias(@NonNull String);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMessageAccessPermission(int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, @NonNull byte[]);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPin(@Nullable String);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSilenceMode(boolean);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSimAccessPermission(int);
field public static final int ACCESS_ALLOWED = 1; // 0x1
field public static final int ACCESS_REJECTED = 2; // 0x2
field public static final int ACCESS_UNKNOWN = 0; // 0x0

View File

@@ -17,6 +17,7 @@
package android.bluetooth;
import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -33,8 +34,12 @@ import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.UUID;
/**
@@ -771,6 +776,13 @@ public final class BluetoothDevice implements Parcelable {
@UnsupportedAppUsage
public static final String EXTRA_SDP_SEARCH_STATUS =
"android.bluetooth.device.extra.SDP_SEARCH_STATUS";
/** @hide */
@IntDef(prefix = "ACCESS_", value = {ACCESS_UNKNOWN,
ACCESS_ALLOWED, ACCESS_REJECTED})
@Retention(RetentionPolicy.SOURCE)
public @interface AccessPermission{}
/**
* For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
* {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
@@ -1096,15 +1108,14 @@ public final class BluetoothDevice implements Parcelable {
/**
* Get the most recent identified battery level of this Bluetooth device
* <p>Requires {@link android.Manifest.permission#BLUETOOTH}
*
* @return Battery level in percents from 0 to 100, or {@link #BATTERY_LEVEL_UNKNOWN} if
* Bluetooth is disabled, or device is disconnected, or does not have any battery reporting
* service, or return value is invalid
* @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH)
@UnsupportedAppUsage
public int getBatteryLevel() {
final IBluetooth service = sService;
if (service == null) {
@@ -1187,8 +1198,15 @@ public final class BluetoothDevice implements Parcelable {
return false;
}
/** @hide */
@UnsupportedAppUsage
/**
* Gets whether bonding was initiated locally
*
* @return true if bonding is initiated locally, false otherwise
*
* @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH)
public boolean isBondingInitiatedLocally() {
final IBluetooth service = sService;
if (service == null) {
@@ -1480,15 +1498,20 @@ public final class BluetoothDevice implements Parcelable {
return false;
}
/** @hide */
@UnsupportedAppUsage
public boolean setPasskey(int passkey) {
//TODO(BT)
/*
try {
return sService.setPasskey(this, true, 4, passkey);
} catch (RemoteException e) {Log.e(TAG, "", e);}*/
return false;
/**
* Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
*
* @return true pin has been set false for error
* @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPin(@Nullable String pin) {
byte[] pinBytes = convertPinToBytes(pin);
if (pinBytes == null) {
return false;
}
return setPin(pinBytes);
}
/**
@@ -1511,22 +1534,18 @@ public final class BluetoothDevice implements Parcelable {
return false;
}
/** @hide */
public boolean setRemoteOutOfBandData() {
// TODO(BT)
/*
try {
return sService.setRemoteOutOfBandData(this);
} catch (RemoteException e) {Log.e(TAG, "", e);}*/
return false;
}
/** @hide */
@UnsupportedAppUsage
public boolean cancelPairingUserInput() {
/**
* Cancels pairing to this device
*
* @return true if pairing cancelled successfully, false otherwise
*
* @hide
*/
@SystemApi
public boolean cancelPairing() {
final IBluetooth service = sService;
if (service == null) {
Log.e(TAG, "BT not enabled. Cannot create pairing user input");
Log.e(TAG, "BT not enabled. Cannot cancel pairing");
return false;
}
try {
@@ -1537,17 +1556,6 @@ public final class BluetoothDevice implements Parcelable {
return false;
}
/** @hide */
@UnsupportedAppUsage
public boolean isBluetoothDock() {
// TODO(BT)
/*
try {
return sService.isBluetoothDock(this);
} catch (RemoteException e) {Log.e(TAG, "", e);}*/
return false;
}
boolean isBluetoothEnabled() {
boolean ret = false;
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -1558,13 +1566,14 @@ public final class BluetoothDevice implements Parcelable {
}
/**
* Requires {@link android.Manifest.permission#BLUETOOTH}.
* Gets whether the phonebook access is allowed for this bluetooth device
*
* @return Whether the phonebook access is allowed to this device. Can be {@link
* #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
* @hide
*/
@UnsupportedAppUsage
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPhonebookAccessPermission() {
final IBluetooth service = sService;
if (service == null) {
@@ -1667,14 +1676,14 @@ public final class BluetoothDevice implements Parcelable {
}
/**
* Requires {@link android.Manifest.permission#BLUETOOTH}.
* Gets whether message access is allowed to this bluetooth device
*
* @return Whether the message access is allowed to this device. Can be {@link #ACCESS_UNKNOWN},
* {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
* @return Whether the message access is allowed to this device.
* @hide
*/
@UnsupportedAppUsage
public int getMessageAccessPermission() {
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH)
public @AccessPermission int getMessageAccessPermission() {
final IBluetooth service = sService;
if (service == null) {
return ACCESS_UNKNOWN;
@@ -1689,15 +1698,18 @@ public final class BluetoothDevice implements Parcelable {
/**
* Sets whether the message access is allowed to this device.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
*
* @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
* #ACCESS_REJECTED}.
* @param value is the value we are setting the message access permission to
* @return Whether the value has been successfully set.
* @hide
*/
@UnsupportedAppUsage
public boolean setMessageAccessPermission(int value) {
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setMessageAccessPermission(@AccessPermission int value) {
// Validates param value is one of the accepted constants
if (value != ACCESS_ALLOWED && value != ACCESS_REJECTED && value != ACCESS_UNKNOWN) {
throw new IllegalArgumentException(value + "is not a valid AccessPermission value");
}
final IBluetooth service = sService;
if (service == null) {
return false;
@@ -1711,13 +1723,14 @@ public final class BluetoothDevice implements Parcelable {
}
/**
* Requires {@link android.Manifest.permission#BLUETOOTH}.
* Gets whether sim access is allowed for this bluetooth device
*
* @return Whether the Sim access is allowed to this device. Can be {@link #ACCESS_UNKNOWN},
* {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
* @return Whether the Sim access is allowed to this device.
* @hide
*/
public int getSimAccessPermission() {
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH)
public @AccessPermission int getSimAccessPermission() {
final IBluetooth service = sService;
if (service == null) {
return ACCESS_UNKNOWN;
@@ -1732,14 +1745,14 @@ public final class BluetoothDevice implements Parcelable {
/**
* Sets whether the Sim access is allowed to this device.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
*
* @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
* #ACCESS_REJECTED}.
* @return Whether the value has been successfully set.
* @hide
*/
@UnsupportedAppUsage
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setSimAccessPermission(int value) {
final IBluetooth service = sService;
if (service == null) {
@@ -1970,7 +1983,7 @@ public final class BluetoothDevice implements Parcelable {
* @return the pin code as a UTF-8 byte array, or null if it is an invalid Bluetooth pin.
* @hide
*/
@UnsupportedAppUsage
@VisibleForTesting
public static byte[] convertPinToBytes(String pin) {
if (pin == null) {
return null;

View File

@@ -176,14 +176,12 @@ public class BluetoothTestUtils extends Assert {
mDevice.setPin(mPin);
break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
mDevice.setPasskey(mPasskey);
break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
case BluetoothDevice.PAIRING_VARIANT_CONSENT:
mDevice.setPairingConfirmation(true);
break;
case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
mDevice.setRemoteOutOfBandData();
break;
}
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {

View File

@@ -643,12 +643,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
refresh();
if (bondState == BluetoothDevice.BOND_BONDED) {
if (mDevice.isBluetoothDock()) {
onBondingDockConnect();
} else if (mDevice.isBondingInitiatedLocally()) {
connect(false);
}
if (bondState == BluetoothDevice.BOND_BONDED && mDevice.isBondingInitiatedLocally()) {
connect(false);
}
}

View File

@@ -62,9 +62,6 @@ public class AudioDeviceInventory {
private @NonNull AudioDeviceBroker mDeviceBroker;
// cache of the address of the last dock the device was connected to
private String mDockAddress;
// Monitoring of audio routes. Protected by mAudioRoutes.
final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo();
final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers =
@@ -168,7 +165,7 @@ public class AudioDeviceInventory {
int a2dpVolume = btInfo.getVolume();
if (AudioService.DEBUG_DEVICES) {
Log.d(TAG, "onSetA2dpSinkConnectionState btDevice=" + btDevice + " state="
+ state + " is dock=" + btDevice.isBluetoothDock() + " vol=" + a2dpVolume);
+ state + " vol=" + a2dpVolume);
}
String address = btDevice.getAddress();
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
@@ -196,42 +193,17 @@ public class AudioDeviceInventory {
mDeviceBroker.postBluetoothA2dpDeviceConfigChange(btDevice);
}
} else {
if (btDevice.isBluetoothDock()) {
if (state == BluetoothProfile.STATE_DISCONNECTED) {
// introduction of a delay for transient disconnections of docks when
// power is rapidly turned off/on, this message will be canceled if
// we reconnect the dock under a preset delay
makeA2dpDeviceUnavailableLater(address,
AudioDeviceBroker.BTA2DP_DOCK_TIMEOUT_MS);
// the next time isConnected is evaluated, it will be false for the dock
}
} else {
makeA2dpDeviceUnavailableNow(address, di.mDeviceCodecFormat);
}
makeA2dpDeviceUnavailableNow(address, di.mDeviceCodecFormat);
}
} else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
if (btDevice.isBluetoothDock()) {
// this could be a reconnection after a transient disconnection
mDeviceBroker.cancelA2dpDockTimeout();
mDockAddress = address;
} else {
// this could be a connection of another A2DP device before the timeout of
// a dock: cancel the dock timeout, and make the dock unavailable now
if (mDeviceBroker.hasScheduledA2dpDockTimeout() && mDockAddress != null) {
mDeviceBroker.cancelA2dpDockTimeout();
makeA2dpDeviceUnavailableNow(mDockAddress,
AudioSystem.AUDIO_FORMAT_DEFAULT);
}
}
if (a2dpVolume != -1) {
mDeviceBroker.postSetVolumeIndexOnDevice(AudioSystem.STREAM_MUSIC,
// convert index to internal representation in VolumeStreamState
a2dpVolume * 10,
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "onSetA2dpSinkConnectionState");
}
makeA2dpDeviceAvailable(address, BtHelper.getName(btDevice),
"onSetA2dpSinkConnectionState", a2dpCodec);
}
if (a2dpVolume != -1) {
mDeviceBroker.postSetVolumeIndexOnDevice(AudioSystem.STREAM_MUSIC,
// convert index to internal representation in VolumeStreamState
a2dpVolume * 10,
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "onSetA2dpSinkConnectionState");
}
makeA2dpDeviceAvailable(address, BtHelper.getName(btDevice),
"onSetA2dpSinkConnectionState", a2dpCodec);
}
}
@@ -672,9 +644,6 @@ public class AudioDeviceInventory {
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
// Remove A2DP routes as well
setCurrentAudioRouteNameIfPossible(null);
if (mDockAddress == address) {
mDockAddress = null;
}
}
@GuardedBy("mConnectedDevices")