Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit efe1110b authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

More AttributionSource plumbing.

To prepare for future work which will plumb AttributionSource values
through all remaining AIDLs, we need profiles to interact directly
with the specific BluetoothAdapter they were created from.  This is
how we'll ensure that the relevant AttributionSource can be chained
down from the original Context they're obtained from.

This change also marks getDefaultAdapter() as deprecated to clearly
communicate that BluetoothManager.getAdapter() is the best-practice
path to obtaining a correctly scoped BluetoothAdapter instance.

Bug: 183626112
Test: atest BluetoothInstrumentationTests
Change-Id: I1e15170d7679019bbb6e396279d6e633e3dad4d6
parent 52f8d4c9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -8633,7 +8633,7 @@ package android.bluetooth {
    method public android.bluetooth.le.BluetoothLeAdvertiser getBluetoothLeAdvertiser();
    method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices();
    method public static android.bluetooth.BluetoothAdapter getDefaultAdapter();
    method @Deprecated public static android.bluetooth.BluetoothAdapter getDefaultAdapter();
    method public int getLeMaximumAdvertisingDataLength();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getName();
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getProfileConnectionState(int);
+12 −7
Original line number Diff line number Diff line
@@ -23,13 +23,13 @@ import android.annotation.Nullable;
import android.annotation.RequiresNoPermission;
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.RequiresLegacyBluetoothAdminPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
import android.os.Build;
@@ -265,7 +265,8 @@ public final class BluetoothA2dp implements BluetoothProfile {
    @SystemApi
    public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING = 2;

    private BluetoothAdapter mAdapter;
    private final BluetoothAdapter mAdapter;
    private final AttributionSource mAttributionSource;
    private final BluetoothProfileConnector<IBluetoothA2dp> mProfileConnector =
            new BluetoothProfileConnector(this, BluetoothProfile.A2DP, "BluetoothA2dp",
                    IBluetoothA2dp.class.getName()) {
@@ -279,8 +280,10 @@ public final class BluetoothA2dp implements BluetoothProfile {
     * Create a BluetoothA2dp proxy object for interacting with the local
     * Bluetooth A2DP service.
     */
    /*package*/ BluetoothA2dp(Context context, ServiceListener listener) {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
    /* package */ BluetoothA2dp(Context context, ServiceListener listener,
            BluetoothAdapter adapter) {
        mAdapter = adapter;
        mAttributionSource = adapter.getAttributionSource();
        mProfileConnector.connect(context, listener);
    }

@@ -386,7 +389,8 @@ public final class BluetoothA2dp implements BluetoothProfile {
        try {
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                return service.getConnectedDevices();
                return BluetoothDevice.setAttributionSource(
                        service.getConnectedDevices(), mAttributionSource);
            }
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return new ArrayList<BluetoothDevice>();
@@ -407,7 +411,8 @@ public final class BluetoothA2dp implements BluetoothProfile {
        try {
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                return service.getDevicesMatchingConnectionStates(states);
                return BluetoothDevice.setAttributionSource(
                        service.getDevicesMatchingConnectionStates(states), mAttributionSource);
            }
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return new ArrayList<BluetoothDevice>();
+11 −5
Original line number Diff line number Diff line
@@ -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.AttributionSource;
import android.content.Context;
import android.os.Binder;
import android.os.Build;
@@ -78,7 +79,8 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
    public static final String ACTION_CONNECTION_STATE_CHANGED =
            "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";

    private BluetoothAdapter mAdapter;
    private final BluetoothAdapter mAdapter;
    private final AttributionSource mAttributionSource;
    private final BluetoothProfileConnector<IBluetoothA2dpSink> mProfileConnector =
            new BluetoothProfileConnector(this, BluetoothProfile.A2DP_SINK,
                    "BluetoothA2dpSink", IBluetoothA2dpSink.class.getName()) {
@@ -92,8 +94,10 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
     * Create a BluetoothA2dp proxy object for interacting with the local
     * Bluetooth A2DP service.
     */
    /*package*/ BluetoothA2dpSink(Context context, ServiceListener listener) {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
    /* package */ BluetoothA2dpSink(Context context, ServiceListener listener,
            BluetoothAdapter adapter) {
        mAdapter = adapter;
        mAttributionSource = adapter.getAttributionSource();
        mProfileConnector.connect(context, listener);
    }

@@ -198,7 +202,8 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
        final IBluetoothA2dpSink service = getService();
        if (service != null && isEnabled()) {
            try {
                return service.getConnectedDevices();
                return BluetoothDevice.setAttributionSource(
                        service.getConnectedDevices(), mAttributionSource);
            } catch (RemoteException e) {
                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                return new ArrayList<BluetoothDevice>();
@@ -221,7 +226,8 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
        final IBluetoothA2dpSink service = getService();
        if (service != null && isEnabled()) {
            try {
                return service.getDevicesMatchingConnectionStates(states);
                return BluetoothDevice.setAttributionSource(
                        service.getDevicesMatchingConnectionStates(states), mAttributionSource);
            } catch (RemoteException e) {
                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                return new ArrayList<BluetoothDevice>();
+26 −20
Original line number Diff line number Diff line
@@ -752,18 +752,23 @@ public final class BluetoothAdapter {

    /**
     * Get a handle to the default local Bluetooth adapter.
     * <p>Currently Android only supports one Bluetooth adapter, but the API
     * could be extended to support more. This will always return the default
     * adapter.
     * <p>
     * Currently Android only supports one Bluetooth adapter, but the API could
     * be extended to support more. This will always return the default adapter.
     * </p>
     *
     * @return the default local adapter, or null if Bluetooth is not supported on this hardware
     * platform
     * @return the default local adapter, or null if Bluetooth is not supported
     *         on this hardware platform
     * @deprecated this method will continue to work, but developers are
     *             strongly encouraged to migrate to using
     *             {@link BluetoothManager#getAdapter()}, since that approach
     *             enables support for {@link Context#createAttributionContext}.
     */
    @Deprecated
    @RequiresNoPermission
    public static synchronized BluetoothAdapter getDefaultAdapter() {
        if (sAdapter == null) {
            sAdapter = createAdapter(ActivityThread.currentAttributionSource());
            sAdapter = createAdapter(BluetoothManager.resolveAttributionSource(null));
        }
        return sAdapter;
    }
@@ -2966,50 +2971,51 @@ public final class BluetoothAdapter {
        }

        if (profile == BluetoothProfile.HEADSET) {
            BluetoothHeadset headset = new BluetoothHeadset(context, listener);
            BluetoothHeadset headset = new BluetoothHeadset(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.A2DP) {
            BluetoothA2dp a2dp = new BluetoothA2dp(context, listener);
            BluetoothA2dp a2dp = new BluetoothA2dp(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.A2DP_SINK) {
            BluetoothA2dpSink a2dpSink = new BluetoothA2dpSink(context, listener);
            BluetoothA2dpSink a2dpSink = new BluetoothA2dpSink(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.AVRCP_CONTROLLER) {
            BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener);
            BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.HID_HOST) {
            BluetoothHidHost iDev = new BluetoothHidHost(context, listener);
            BluetoothHidHost iDev = new BluetoothHidHost(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.PAN) {
            BluetoothPan pan = new BluetoothPan(context, listener);
            BluetoothPan pan = new BluetoothPan(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.PBAP) {
            BluetoothPbap pbap = new BluetoothPbap(context, listener);
            BluetoothPbap pbap = new BluetoothPbap(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.HEALTH) {
            Log.e(TAG, "getProfileProxy(): BluetoothHealth is deprecated");
            return false;
        } else if (profile == BluetoothProfile.MAP) {
            BluetoothMap map = new BluetoothMap(context, listener);
            BluetoothMap map = new BluetoothMap(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.HEADSET_CLIENT) {
            BluetoothHeadsetClient headsetClient = new BluetoothHeadsetClient(context, listener);
            BluetoothHeadsetClient headsetClient =
                    new BluetoothHeadsetClient(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.SAP) {
            BluetoothSap sap = new BluetoothSap(context, listener);
            BluetoothSap sap = new BluetoothSap(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.PBAP_CLIENT) {
            BluetoothPbapClient pbapClient = new BluetoothPbapClient(context, listener);
            BluetoothPbapClient pbapClient = new BluetoothPbapClient(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.MAP_CLIENT) {
            BluetoothMapClient mapClient = new BluetoothMapClient(context, listener);
            BluetoothMapClient mapClient = new BluetoothMapClient(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.HID_DEVICE) {
            BluetoothHidDevice hidDevice = new BluetoothHidDevice(context, listener);
            BluetoothHidDevice hidDevice = new BluetoothHidDevice(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.HEARING_AID) {
            if (isHearingAidProfileSupported()) {
                BluetoothHearingAid hearingAid = new BluetoothHearingAid(context, listener);
                BluetoothHearingAid hearingAid = new BluetoothHearingAid(context, listener, this);
                return true;
            }
            return false;
+11 −5
Original line number Diff line number Diff line
@@ -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.AttributionSource;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
@@ -86,7 +87,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
    public static final String EXTRA_PLAYER_SETTING =
            "android.bluetooth.avrcp-controller.profile.extra.PLAYER_SETTING";

    private BluetoothAdapter mAdapter;
    private final BluetoothAdapter mAdapter;
    private final AttributionSource mAttributionSource;
    private final BluetoothProfileConnector<IBluetoothAvrcpController> mProfileConnector =
            new BluetoothProfileConnector(this, BluetoothProfile.AVRCP_CONTROLLER,
                    "BluetoothAvrcpController", IBluetoothAvrcpController.class.getName()) {
@@ -101,8 +103,10 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
     * Create a BluetoothAvrcpController proxy object for interacting with the local
     * Bluetooth AVRCP service.
     */
    /*package*/ BluetoothAvrcpController(Context context, ServiceListener listener) {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
    /* package */ BluetoothAvrcpController(Context context, ServiceListener listener,
            BluetoothAdapter adapter) {
        mAdapter = adapter;
        mAttributionSource = adapter.getAttributionSource();
        mProfileConnector.connect(context, listener);
    }

@@ -131,7 +135,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
                getService();
        if (service != null && isEnabled()) {
            try {
                return service.getConnectedDevices();
                return BluetoothDevice.setAttributionSource(
                        service.getConnectedDevices(), mAttributionSource);
            } catch (RemoteException e) {
                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                return new ArrayList<BluetoothDevice>();
@@ -153,7 +158,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
                getService();
        if (service != null && isEnabled()) {
            try {
                return service.getDevicesMatchingConnectionStates(states);
                return BluetoothDevice.setAttributionSource(
                        service.getDevicesMatchingConnectionStates(states), mAttributionSource);
            } catch (RemoteException e) {
                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                return new ArrayList<BluetoothDevice>();
Loading