More Binder call AttributionSource assignment.

Since developers can use a BluetoothDevice object can make remote
calls, it needs to have an accurate AttributionSource.  Previous CLs
had updated many places where these BluetoothDevice instances were
passed across Binder interfaces, but this change updates several
remaining locations which had been missed.

Introduces new "Attributable" marker interface to offer consistent
tooling when applying AttributionSource updates.

Bug: 187097694
Test: atest BluetoothInstrumentationTests
Change-Id: Icad3b9726591f0fbad58a493cefa5a0af7648280
This commit is contained in:
Jeff Sharkey
2021-06-03 09:26:53 -06:00
parent e77df8f538
commit 22ca72a675
23 changed files with 201 additions and 95 deletions

View File

@@ -29,6 +29,7 @@ import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -389,8 +390,9 @@ public final class BluetoothA2dp implements BluetoothProfile {
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled()) {
return BluetoothDevice.setAttributionSource(
service.getConnectedDevices(), mAttributionSource);
return Attributable.setAttributionSource(
service.getConnectedDevicesWithAttribution(mAttributionSource),
mAttributionSource);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
@@ -411,8 +413,10 @@ public final class BluetoothA2dp implements BluetoothProfile {
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled()) {
return BluetoothDevice.setAttributionSource(
service.getDevicesMatchingConnectionStates(states), mAttributionSource);
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStatesWithAttribution(states,
mAttributionSource),
mAttributionSource);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<BluetoothDevice>();
@@ -500,7 +504,8 @@ public final class BluetoothA2dp implements BluetoothProfile {
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled()) {
return service.getActiveDevice(mAttributionSource);
return Attributable.setAttributionSource(
service.getActiveDevice(mAttributionSource), mAttributionSource);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
return null;

View File

@@ -27,6 +27,7 @@ import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -206,7 +207,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
@@ -230,7 +231,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {

View File

@@ -46,6 +46,7 @@ import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.BatteryStats;
@@ -719,8 +720,8 @@ public final class BluetoothAdapter {
private final Object mLock = new Object();
private final Map<LeScanCallback, ScanCallback> mLeScanClients;
private static final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>>
sMetadataListeners = new HashMap<>();
private final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>>
mMetadataListeners = new HashMap<>();
private final Map<BluetoothConnectionCallback, Executor>
mBluetoothConnectionCallbackExecutorMap = new HashMap<>();
@@ -729,14 +730,15 @@ public final class BluetoothAdapter {
* implementation.
*/
@SuppressLint("AndroidFrameworkBluetoothPermission")
private static final IBluetoothMetadataListener sBluetoothMetadataListener =
private final IBluetoothMetadataListener mBluetoothMetadataListener =
new IBluetoothMetadataListener.Stub() {
@Override
public void onMetadataChanged(BluetoothDevice device, int key, byte[] value) {
synchronized (sMetadataListeners) {
if (sMetadataListeners.containsKey(device)) {
Attributable.setAttributionSource(device, mAttributionSource);
synchronized (mMetadataListeners) {
if (mMetadataListeners.containsKey(device)) {
List<Pair<OnMetadataChangedListener, Executor>> list =
sMetadataListeners.get(device);
mMetadataListeners.get(device);
for (Pair<OnMetadataChangedListener, Executor> pair : list) {
OnMetadataChangedListener listener = pair.first;
Executor executor = pair.second;
@@ -2445,7 +2447,9 @@ public final class BluetoothAdapter {
try {
mServiceLock.readLock().lock();
if (mService != null) {
return mService.getMostRecentlyConnectedDevices(mAttributionSource);
return Attributable.setAttributionSource(
mService.getMostRecentlyConnectedDevices(mAttributionSource),
mAttributionSource);
}
} catch (RemoteException e) {
Log.e(TAG, "", e);
@@ -2470,14 +2474,16 @@ public final class BluetoothAdapter {
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public Set<BluetoothDevice> getBondedDevices() {
if (getState() != STATE_ON) {
return toDeviceSet(new BluetoothDevice[0]);
return toDeviceSet(Arrays.asList());
}
try {
mServiceLock.readLock().lock();
if (mService != null) {
return toDeviceSet(mService.getBondedDevices(mAttributionSource));
return toDeviceSet(Attributable.setAttributionSource(
Arrays.asList(mService.getBondedDevices(mAttributionSource)),
mAttributionSource));
}
return toDeviceSet(new BluetoothDevice[0]);
return toDeviceSet(Arrays.asList());
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
@@ -3165,10 +3171,10 @@ public final class BluetoothAdapter {
}
}
}
synchronized (sMetadataListeners) {
sMetadataListeners.forEach((device, pair) -> {
synchronized (mMetadataListeners) {
mMetadataListeners.forEach((device, pair) -> {
try {
mService.registerMetadataListener(sBluetoothMetadataListener,
mService.registerMetadataListener(mBluetoothMetadataListener,
device, mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, "Failed to register metadata listener", e);
@@ -3455,8 +3461,8 @@ public final class BluetoothAdapter {
}
}
private Set<BluetoothDevice> toDeviceSet(BluetoothDevice[] devices) {
Set<BluetoothDevice> deviceSet = new HashSet<BluetoothDevice>(Arrays.asList(devices));
private Set<BluetoothDevice> toDeviceSet(List<BluetoothDevice> devices) {
Set<BluetoothDevice> deviceSet = new HashSet<BluetoothDevice>(devices);
return Collections.unmodifiableSet(deviceSet);
}
@@ -3926,13 +3932,13 @@ public final class BluetoothAdapter {
throw new NullPointerException("executor is null");
}
synchronized (sMetadataListeners) {
synchronized (mMetadataListeners) {
List<Pair<OnMetadataChangedListener, Executor>> listenerList =
sMetadataListeners.get(device);
mMetadataListeners.get(device);
if (listenerList == null) {
// Create new listener/executor list for registeration
listenerList = new ArrayList<>();
sMetadataListeners.put(device, listenerList);
mMetadataListeners.put(device, listenerList);
} else {
// Check whether this device was already registed by the lisenter
if (listenerList.stream().anyMatch((pair) -> (pair.first.equals(listener)))) {
@@ -3946,7 +3952,7 @@ public final class BluetoothAdapter {
boolean ret = false;
try {
ret = service.registerMetadataListener(sBluetoothMetadataListener, device,
ret = service.registerMetadataListener(mBluetoothMetadataListener, device,
mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, "registerMetadataListener fail", e);
@@ -3956,7 +3962,7 @@ public final class BluetoothAdapter {
listenerList.remove(listenerPair);
if (listenerList.isEmpty()) {
// Remove the device if its listener list is empty
sMetadataListeners.remove(device);
mMetadataListeners.remove(device);
}
}
}
@@ -3995,17 +4001,17 @@ public final class BluetoothAdapter {
throw new NullPointerException("listener is null");
}
synchronized (sMetadataListeners) {
if (!sMetadataListeners.containsKey(device)) {
synchronized (mMetadataListeners) {
if (!mMetadataListeners.containsKey(device)) {
throw new IllegalArgumentException("device was not registered");
}
// Remove issued listener from the registered device
sMetadataListeners.get(device).removeIf((pair) -> (pair.first.equals(listener)));
mMetadataListeners.get(device).removeIf((pair) -> (pair.first.equals(listener)));
if (sMetadataListeners.get(device).isEmpty()) {
if (mMetadataListeners.get(device).isEmpty()) {
// Unregister to Bluetooth service if all listeners are removed from
// the registered device
sMetadataListeners.remove(device);
mMetadataListeners.remove(device);
final IBluetooth service = mService;
if (service == null) {
// Bluetooth is OFF, do nothing to Bluetooth service.
@@ -4045,6 +4051,7 @@ public final class BluetoothAdapter {
new IBluetoothConnectionCallback.Stub() {
@Override
public void onDeviceConnected(BluetoothDevice device) {
Attributable.setAttributionSource(device, mAttributionSource);
for (Map.Entry<BluetoothConnectionCallback, Executor> callbackExecutorEntry:
mBluetoothConnectionCallbackExecutorMap.entrySet()) {
BluetoothConnectionCallback callback = callbackExecutorEntry.getKey();
@@ -4055,6 +4062,7 @@ public final class BluetoothAdapter {
@Override
public void onDeviceDisconnected(BluetoothDevice device, int hciReason) {
Attributable.setAttributionSource(device, mAttributionSource);
for (Map.Entry<BluetoothConnectionCallback, Executor> callbackExecutorEntry:
mBluetoothConnectionCallbackExecutorMap.entrySet()) {
BluetoothConnectionCallback callback = callbackExecutorEntry.getKey();

View File

@@ -22,6 +22,7 @@ import android.annotation.SuppressLint;
import android.annotation.SdkConstant.SdkConstantType;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -135,7 +136,7 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
@@ -158,7 +159,7 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {

View File

@@ -32,6 +32,7 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.companion.AssociationRequest;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Build;
@@ -47,7 +48,6 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.UUID;
/**
@@ -84,7 +84,7 @@ import java.util.UUID;
* {@see BluetoothAdapter}
* {@see BluetoothSocket}
*/
public final class BluetoothDevice implements Parcelable {
public final class BluetoothDevice implements Parcelable, Attributable {
private static final String TAG = "BluetoothDevice";
private static final boolean DBG = false;
@@ -1170,28 +1170,13 @@ public final class BluetoothDevice implements Parcelable {
mAttributionSource = BluetoothManager.resolveAttributionSource(null);
}
void setAttributionSource(AttributionSource attributionSource) {
/** {@hide} */
public void setAttributionSource(@NonNull AttributionSource attributionSource) {
mAttributionSource = attributionSource;
}
static BluetoothDevice setAttributionSource(BluetoothDevice device,
AttributionSource attributionSource) {
device.setAttributionSource(attributionSource);
return device;
}
static List<BluetoothDevice> setAttributionSource(List<BluetoothDevice> devices,
AttributionSource attributionSource) {
if (devices != null) {
for (BluetoothDevice device : devices) {
device.setAttributionSource(attributionSource);
}
}
return devices;
}
/** {@hide} */
public void prepareToEnterProcess(AttributionSource attributionSource) {
public void prepareToEnterProcess(@NonNull AttributionSource attributionSource) {
setAttributionSource(attributionSource);
}

View File

@@ -28,6 +28,7 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.ComponentName;
import android.content.Context;
@@ -532,8 +533,9 @@ public final class BluetoothHeadset implements BluetoothProfile {
final IBluetoothHeadset service = mService;
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
service.getConnectedDevices(), mAttributionSource);
return Attributable.setAttributionSource(
service.getConnectedDevicesWithAttribution(mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return new ArrayList<BluetoothDevice>();
@@ -554,7 +556,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
final IBluetoothHeadset service = mService;
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {
@@ -1310,7 +1312,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
final IBluetoothHeadset service = mService;
if (service != null && isEnabled()) {
try {
return service.getActiveDevice(mAttributionSource);
return Attributable.setAttributionSource(
service.getActiveDevice(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}

View File

@@ -23,6 +23,7 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -535,7 +536,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
@@ -562,7 +563,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {
@@ -797,7 +798,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.getCurrentCalls(device, mAttributionSource);
return Attributable.setAttributionSource(
service.getCurrentCalls(device, mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}
@@ -1020,7 +1022,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
return service.dial(device, number, mAttributionSource);
return Attributable.setAttributionSource(
service.dial(device, number, mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
}

View File

@@ -16,7 +16,10 @@
package android.bluetooth;
import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,7 +33,7 @@ import java.util.UUID;
*
* @hide
*/
public final class BluetoothHeadsetClientCall implements Parcelable {
public final class BluetoothHeadsetClientCall implements Parcelable, Attributable {
/* Call state */
/**
@@ -98,6 +101,11 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
mCreationElapsedMilli = SystemClock.elapsedRealtime();
}
/** {@hide} */
public void setAttributionSource(@NonNull AttributionSource attributionSource) {
Attributable.setAttributionSource(mDevice, attributionSource);
}
/**
* Sets call's state.
*

View File

@@ -28,6 +28,7 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -248,7 +249,7 @@ public final class BluetoothHearingAid implements BluetoothProfile {
final IBluetoothHearingAid service = getService();
try {
if (service != null && isEnabled()) {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
@@ -271,7 +272,7 @@ public final class BluetoothHearingAid implements BluetoothProfile {
final IBluetoothHearingAid service = getService();
try {
if (service != null && isEnabled()) {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
}
@@ -363,7 +364,8 @@ public final class BluetoothHearingAid implements BluetoothProfile {
final IBluetoothHearingAid service = getService();
try {
if (service != null && isEnabled()) {
return service.getActiveDevices(mAttributionSource);
return Attributable.setAttributionSource(
service.getActiveDevices(mAttributionSource), mAttributionSource);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<>();

View File

@@ -20,11 +20,11 @@ import android.Manifest;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SuppressLint;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.annotation.SystemApi;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -339,14 +339,17 @@ public final class BluetoothHidDevice implements BluetoothProfile {
private final Executor mExecutor;
private final Callback mCallback;
private final AttributionSource mAttributionSource;
CallbackWrapper(Executor executor, Callback callback) {
CallbackWrapper(Executor executor, Callback callback, AttributionSource attributionSource) {
mExecutor = executor;
mCallback = callback;
mAttributionSource = attributionSource;
}
@Override
public void onAppStatusChanged(BluetoothDevice pluggedDevice, boolean registered) {
Attributable.setAttributionSource(pluggedDevice, mAttributionSource);
final long token = clearCallingIdentity();
try {
mExecutor.execute(() -> mCallback.onAppStatusChanged(pluggedDevice, registered));
@@ -357,6 +360,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
@Override
public void onConnectionStateChanged(BluetoothDevice device, int state) {
Attributable.setAttributionSource(device, mAttributionSource);
final long token = clearCallingIdentity();
try {
mExecutor.execute(() -> mCallback.onConnectionStateChanged(device, state));
@@ -367,6 +371,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
@Override
public void onGetReport(BluetoothDevice device, byte type, byte id, int bufferSize) {
Attributable.setAttributionSource(device, mAttributionSource);
final long token = clearCallingIdentity();
try {
mExecutor.execute(() -> mCallback.onGetReport(device, type, id, bufferSize));
@@ -377,6 +382,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
@Override
public void onSetReport(BluetoothDevice device, byte type, byte id, byte[] data) {
Attributable.setAttributionSource(device, mAttributionSource);
final long token = clearCallingIdentity();
try {
mExecutor.execute(() -> mCallback.onSetReport(device, type, id, data));
@@ -387,6 +393,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
@Override
public void onSetProtocol(BluetoothDevice device, byte protocol) {
Attributable.setAttributionSource(device, mAttributionSource);
final long token = clearCallingIdentity();
try {
mExecutor.execute(() -> mCallback.onSetProtocol(device, protocol));
@@ -397,6 +404,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
@Override
public void onInterruptData(BluetoothDevice device, byte reportId, byte[] data) {
Attributable.setAttributionSource(device, mAttributionSource);
final long token = clearCallingIdentity();
try {
mExecutor.execute(() -> mCallback.onInterruptData(device, reportId, data));
@@ -407,6 +415,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
@Override
public void onVirtualCableUnplug(BluetoothDevice device) {
Attributable.setAttributionSource(device, mAttributionSource);
final long token = clearCallingIdentity();
try {
mExecutor.execute(() -> mCallback.onVirtualCableUnplug(device));
@@ -449,7 +458,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
final IBluetoothHidDevice service = getService();
if (service != null) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
@@ -469,7 +478,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
final IBluetoothHidDevice service = getService();
if (service != null) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {
@@ -549,7 +558,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
final IBluetoothHidDevice service = getService();
if (service != null) {
try {
CallbackWrapper cbw = new CallbackWrapper(executor, callback);
CallbackWrapper cbw = new CallbackWrapper(executor, callback, mAttributionSource);
result = service.registerApp(sdp, inQos, outQos, cbw, mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, e.toString());

View File

@@ -26,6 +26,7 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -360,7 +361,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
final IBluetoothHidHost service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
@@ -384,7 +385,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
final IBluetoothHidHost service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {

View File

@@ -26,6 +26,7 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SuppressLint;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -227,7 +228,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
try {
final IBluetoothLeAudio service = getService();
if (service != null && mAdapter.isEnabled()) {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
@@ -250,7 +251,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
try {
final IBluetoothLeAudio service = getService();
if (service != null && mAdapter.isEnabled()) {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
}
@@ -339,7 +340,8 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
try {
final IBluetoothLeAudio service = getService();
if (service != null && mAdapter.isEnabled()) {
return service.getActiveDevices(mAttributionSource);
return Attributable.setAttributionSource(
service.getActiveDevices(mAttributionSource), mAttributionSource);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
return new ArrayList<>();

View File

@@ -16,6 +16,8 @@
package android.bluetooth;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresFeature;
import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
@@ -24,6 +26,7 @@ import android.app.ActivityThread;
import android.app.AppGlobals;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -71,7 +74,7 @@ public final class BluetoothManager {
}
/** {@hide} */
public static AttributionSource resolveAttributionSource(Context context) {
public static @NonNull AttributionSource resolveAttributionSource(@Nullable Context context) {
AttributionSource res = null;
if (context != null) {
res = context.getAttributionSource();
@@ -193,7 +196,7 @@ public final class BluetoothManager {
IBluetoothManager managerService = mAdapter.getBluetoothManager();
IBluetoothGatt iGatt = managerService.getBluetoothGatt();
if (iGatt == null) return devices;
devices = BluetoothDevice.setAttributionSource(
devices = Attributable.setAttributionSource(
iGatt.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {

View File

@@ -26,6 +26,7 @@ import android.annotation.SystemApi;
import android.annotation.SdkConstant.SdkConstantType;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -170,7 +171,8 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
final IBluetoothMap service = getService();
if (service != null) {
try {
return service.getClient(mAttributionSource);
return Attributable.setAttributionSource(
service.getClient(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -285,7 +287,7 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
final IBluetoothMap service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
@@ -310,7 +312,7 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
final IBluetoothMap service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {

View File

@@ -26,6 +26,7 @@ import android.annotation.SystemApi;
import android.app.PendingIntent;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.net.Uri;
@@ -302,7 +303,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
final IBluetoothMapClient service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
@@ -327,7 +328,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
final IBluetoothMapClient service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {

View File

@@ -27,6 +27,7 @@ import android.annotation.SystemApi;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -357,7 +358,7 @@ public final class BluetoothPan implements BluetoothProfile {
final IBluetoothPan service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
@@ -384,7 +385,7 @@ public final class BluetoothPan implements BluetoothProfile {
final IBluetoothPan service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {

View File

@@ -25,6 +25,7 @@ import android.annotation.SystemApi;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.ComponentName;
import android.content.Context;
@@ -243,7 +244,7 @@ public class BluetoothPbap implements BluetoothProfile {
return new ArrayList<BluetoothDevice>();
}
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
@@ -296,7 +297,7 @@ public class BluetoothPbap implements BluetoothProfile {
return new ArrayList<BluetoothDevice>();
}
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {

View File

@@ -23,6 +23,7 @@ import android.annotation.SdkConstant;
import android.annotation.SuppressLint;
import android.annotation.SdkConstant.SdkConstantType;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -187,7 +188,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
final IBluetoothPbapClient service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
@@ -215,7 +216,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
final IBluetoothPbapClient service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {

View File

@@ -24,6 +24,7 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Attributable;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
@@ -182,7 +183,8 @@ public final class BluetoothSap implements BluetoothProfile {
final IBluetoothSap service = getService();
if (service != null) {
try {
return service.getClient(mAttributionSource);
return Attributable.setAttributionSource(
service.getClient(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
@@ -268,7 +270,7 @@ public final class BluetoothSap implements BluetoothProfile {
final IBluetoothSap service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getConnectedDevices(mAttributionSource), mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
@@ -292,7 +294,7 @@ public final class BluetoothSap implements BluetoothProfile {
final IBluetoothSap service = getService();
if (service != null && isEnabled()) {
try {
return BluetoothDevice.setAttributionSource(
return Attributable.setAttributionSource(
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
mAttributionSource);
} catch (RemoteException e) {

View File

@@ -30,6 +30,7 @@ import android.bluetooth.IBluetoothManager;
import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
import android.bluetooth.annotations.RequiresBluetoothScanPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
import android.content.Attributable;
import android.content.AttributionSource;
import android.os.Handler;
import android.os.Looper;
@@ -516,6 +517,7 @@ public final class BluetoothLeScanner {
*/
@Override
public void onScanResult(final ScanResult scanResult) {
Attributable.setAttributionSource(scanResult, mAttributionSource);
if (VDBG) Log.d(TAG, "onScanResult() - " + scanResult.toString());
// Check null in case the scan has been stopped
@@ -533,6 +535,7 @@ public final class BluetoothLeScanner {
@Override
public void onBatchScanResults(final List<ScanResult> results) {
Attributable.setAttributionSource(results, mAttributionSource);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
@@ -544,6 +547,7 @@ public final class BluetoothLeScanner {
@Override
public void onFoundOrLost(final boolean onFound, final ScanResult scanResult) {
Attributable.setAttributionSource(scanResult, mAttributionSource);
if (VDBG) {
Log.d(TAG, "onFoundOrLost() - onFound = " + onFound + " " + scanResult.toString());
}

View File

@@ -25,6 +25,7 @@ import android.bluetooth.IBluetoothManager;
import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
import android.bluetooth.annotations.RequiresBluetoothScanPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
import android.content.Attributable;
import android.content.AttributionSource;
import android.os.Handler;
import android.os.Looper;
@@ -220,7 +221,7 @@ public final class PeriodicAdvertisingManager {
return new IPeriodicAdvertisingCallback.Stub() {
public void onSyncEstablished(int syncHandle, BluetoothDevice device,
int advertisingSid, int skip, int timeout, int status) {
Attributable.setAttributionSource(device, mAttributionSource);
handler.post(new Runnable() {
@Override
public void run() {

View File

@@ -16,8 +16,11 @@
package android.bluetooth.le;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.bluetooth.BluetoothDevice;
import android.content.Attributable;
import android.content.AttributionSource;
import android.os.Parcel;
import android.os.Parcelable;
@@ -26,7 +29,7 @@ import java.util.Objects;
/**
* ScanResult for Bluetooth LE scan.
*/
public final class ScanResult implements Parcelable {
public final class ScanResult implements Parcelable, Attributable {
/**
* For chained advertisements, inidcates tha the data contained in this
@@ -195,6 +198,11 @@ public final class ScanResult implements Parcelable {
return 0;
}
/** {@hide} */
public void setAttributionSource(@NonNull AttributionSource attributionSource) {
Attributable.setAttributionSource(mDevice, attributionSource);
}
/**
* Returns the remote Bluetooth device identified by the Bluetooth device address.
*/

View File

@@ -0,0 +1,54 @@
/*
* 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.content;
import android.annotation.NonNull;
import android.annotation.Nullable;
import java.util.List;
/**
* Marker interface for a class which can have an {@link AttributionSource}
* assigned to it; these are typically {@link android.os.Parcelable} classes
* which need to be updated after crossing Binder transaction boundaries.
*
* @hide
*/
public interface Attributable {
void setAttributionSource(@NonNull AttributionSource attributionSource);
static @Nullable <T extends Attributable> T setAttributionSource(
@Nullable T attributable,
@NonNull AttributionSource attributionSource) {
if (attributable != null) {
attributable.setAttributionSource(attributionSource);
}
return attributable;
}
static @Nullable <T extends Attributable> List<T> setAttributionSource(
@Nullable List<T> attributableList,
@NonNull AttributionSource attributionSource) {
if (attributableList != null) {
final int size = attributableList.size();
for (int i = 0; i < size; i++) {
setAttributionSource(attributableList.get(i), attributionSource);
}
}
return attributableList;
}
}