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

Commit b9c27898 authored by David Duarte's avatar David Duarte Committed by Automerger Merge Worker
Browse files

Merge changes from topic "closeProfileProxy_metric" into main am: c0d1135c

parents 5d1fa6b4 c0d1135c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ java_defaults {
    defaults: ["bluetooth-module-sdk-version-defaults"],
    static_libs: [
        "PlatformProperties",
        "modules-utils-expresslog",
        "modules-utils-synchronous-result-receiver",
    ],
    libs: [
+1 −0
Original line number Diff line number Diff line
@@ -9,3 +9,4 @@ rule android.sysprop.** com.android.bluetooth.x.@0
rule android.hardware.radio.V1_0.** com.android.bluetooth.x.@0
rule com.google.android.mms.** com.android.bluetooth.x.@0
rule com.android.internal.util.** com.android.bluetooth.x.@0
rule com.android.modules.expresslog.** com.android.bluetooth.x.@0
+25 −8
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Build;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.util.Log;
@@ -270,31 +271,47 @@ public final class BluetoothA2dp implements BluetoothProfile {

    private final BluetoothAdapter mAdapter;
    private final AttributionSource mAttributionSource;
    private final BluetoothProfileConnector mProfileConnector =
            new BluetoothProfileConnector(this, BluetoothProfile.A2DP);

    private IBluetoothA2dp mService;

    /**
     * Create a BluetoothA2dp proxy object for interacting with the local
     * Bluetooth A2DP service.
     */
    /* package */ BluetoothA2dp(Context context, ServiceListener listener,
            BluetoothAdapter adapter) {
    /* package */ BluetoothA2dp(Context context, BluetoothAdapter adapter) {
        mAdapter = adapter;
        mAttributionSource = adapter.getAttributionSource();
        mProfileConnector.connect(context, listener);
        mService = null;
    }

    /**
     * @hide
     */
    @UnsupportedAppUsage
    @Override
    public void close() {
        mProfileConnector.disconnect();
        mAdapter.closeProfileProxy(this);
    }

    /** @hide */
    @Override
    public void onServiceConnected(IBinder service) {
        mService = IBluetoothA2dp.Stub.asInterface(service);
    }

    /** @hide */
    @Override
    public void onServiceDisconnected() {
        mService = null;
    }

    private IBluetoothA2dp getService() {
        return IBluetoothA2dp.Stub.asInterface(mProfileConnector.getService());
        return mService;
    }

    /** @hide */
    @Override
    public BluetoothAdapter getAdapter() {
        return mAdapter;
    }

    @Override
+20 −11
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.AttributionSource;
import android.content.Context;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

@@ -84,36 +85,44 @@ public final class BluetoothA2dpSink implements BluetoothProfile {

    private final BluetoothAdapter mAdapter;
    private final AttributionSource mAttributionSource;
    private final BluetoothProfileConnector mProfileConnector =
            new BluetoothProfileConnector(
                    this, BluetoothProfile.A2DP_SINK);

    private IBluetoothA2dpSink mService;

    /**
     * Create a BluetoothA2dp proxy object for interacting with the local
     * Bluetooth A2DP service.
     */
    /* package */ BluetoothA2dpSink(Context context, ServiceListener listener,
            BluetoothAdapter adapter) {
    /* package */ BluetoothA2dpSink(Context context, BluetoothAdapter adapter) {
        mAdapter = adapter;
        mAttributionSource = adapter.getAttributionSource();
        mProfileConnector.connect(context, listener);
        mService = null;
    }

    /** @hide */
    @Override
    public void onServiceConnected(IBinder service) {
        mService = IBluetoothA2dpSink.Stub.asInterface(service);
    }

    /** @hide */
    @Override
    public void close() {
        mProfileConnector.disconnect();
    public void onServiceDisconnected() {
        mService = null;
    }

    private IBluetoothA2dpSink getService() {
        return IBluetoothA2dpSink.Stub.asInterface(mProfileConnector.getService());
        return mService;
    }

    /** @hide */
    @Override
    public void finalize() {
        close();
    public BluetoothAdapter getAdapter() {
        return mAdapter;
    }

    @Override
    public void finalize() {}

    /**
     * Initiate connection to a profile of the remote bluetooth device.
     *
+105 −71
Original line number Diff line number Diff line
@@ -60,12 +60,14 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.IpcDataCache;
import android.os.ParcelUuid;
import android.os.Process;
import android.os.RemoteException;
import android.sysprop.BluetoothProperties;
import android.util.Log;
import android.util.Pair;

import com.android.internal.annotations.GuardedBy;
import com.android.modules.expresslog.StatsExpressLog;
import com.android.modules.utils.SynchronousResultReceiver;

import java.io.IOException;
@@ -83,9 +85,11 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.BiFunction;

/**
 * Represents the local device Bluetooth adapter. The {@link BluetoothAdapter}
@@ -832,6 +836,39 @@ public final class BluetoothAdapter {
     */
    public static final int SOCKET_CHANNEL_AUTO_STATIC_NO_SDP = -2;

    /** @hide */
    public static final Map<Integer, BiFunction<Context, BluetoothAdapter, BluetoothProfile>>
            PROFILE_CONSTRUCTORS =
                    Map.ofEntries(
                            Map.entry(BluetoothProfile.HEADSET, BluetoothHeadset::new),
                            Map.entry(BluetoothProfile.A2DP, BluetoothA2dp::new),
                            Map.entry(BluetoothProfile.A2DP_SINK, BluetoothA2dpSink::new),
                            Map.entry(
                                    BluetoothProfile.AVRCP_CONTROLLER,
                                    BluetoothAvrcpController::new),
                            Map.entry(BluetoothProfile.HID_HOST, BluetoothHidHost::new),
                            Map.entry(BluetoothProfile.PAN, BluetoothPan::new),
                            Map.entry(BluetoothProfile.PBAP, BluetoothPbap::new),
                            Map.entry(BluetoothProfile.MAP, BluetoothMap::new),
                            Map.entry(BluetoothProfile.HEADSET_CLIENT, BluetoothHeadsetClient::new),
                            Map.entry(BluetoothProfile.SAP, BluetoothSap::new),
                            Map.entry(BluetoothProfile.PBAP_CLIENT, BluetoothPbapClient::new),
                            Map.entry(BluetoothProfile.MAP_CLIENT, BluetoothMapClient::new),
                            Map.entry(BluetoothProfile.HID_DEVICE, BluetoothHidDevice::new),
                            Map.entry(BluetoothProfile.HAP_CLIENT, BluetoothHapClient::new),
                            Map.entry(BluetoothProfile.HEARING_AID, BluetoothHearingAid::new),
                            Map.entry(BluetoothProfile.LE_AUDIO, BluetoothLeAudio::new),
                            Map.entry(
                                    BluetoothProfile.LE_AUDIO_BROADCAST, BluetoothLeBroadcast::new),
                            Map.entry(BluetoothProfile.VOLUME_CONTROL, BluetoothVolumeControl::new),
                            Map.entry(
                                    BluetoothProfile.CSIP_SET_COORDINATOR,
                                    BluetoothCsipSetCoordinator::new),
                            Map.entry(
                                    BluetoothProfile.LE_CALL_CONTROL, BluetoothLeCallControl::new),
                            Map.entry(
                                    BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT,
                                    BluetoothLeBroadcastAssistant::new));

    private static final int ADDRESS_LENGTH = 17;

@@ -875,6 +912,9 @@ public final class BluetoothAdapter {
    private final Map<BluetoothQualityReportReadyCallback, Executor>
            mBluetoothQualityReportReadyCallbackExecutorMap = new HashMap<>();

    private final Map<BluetoothProfile, BluetoothProfileConnector> mProfileConnectors =
            new ConcurrentHashMap<>();

    /**
     * Bluetooth metadata listener. Overrides the default BluetoothMetadataListener
     * implementation.
@@ -3627,81 +3667,75 @@ public final class BluetoothAdapter {
            return false;
        }

        if (profile == BluetoothProfile.HEADSET) {
            BluetoothHeadset headset = new BluetoothHeadset(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.A2DP) {
            BluetoothA2dp a2dp = new BluetoothA2dp(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.A2DP_SINK) {
            BluetoothA2dpSink a2dpSink = new BluetoothA2dpSink(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.AVRCP_CONTROLLER) {
            BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.HID_HOST) {
            BluetoothHidHost iDev = new BluetoothHidHost(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.PAN) {
            BluetoothPan pan = new BluetoothPan(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.PBAP) {
            BluetoothPbap pbap = new BluetoothPbap(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.HEALTH) {
        if (profile == BluetoothProfile.HEALTH) {
            Log.e(TAG, "getProfileProxy(): BluetoothHealth is deprecated");
            return false;
        } else if (profile == BluetoothProfile.MAP) {
            BluetoothMap map = new BluetoothMap(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.HEADSET_CLIENT) {
            BluetoothHeadsetClient headsetClient =
                    new BluetoothHeadsetClient(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.SAP) {
            BluetoothSap sap = new BluetoothSap(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.PBAP_CLIENT) {
            BluetoothPbapClient pbapClient = new BluetoothPbapClient(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.MAP_CLIENT) {
            BluetoothMapClient mapClient = new BluetoothMapClient(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.HID_DEVICE) {
            BluetoothHidDevice hidDevice = new BluetoothHidDevice(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.HAP_CLIENT) {
            BluetoothHapClient HapClient = new BluetoothHapClient(context, listener);
            return true;
        } else if (profile == BluetoothProfile.HEARING_AID) {
            if (isHearingAidProfileSupported()) {
                BluetoothHearingAid hearingAid = new BluetoothHearingAid(context, listener, this);
                return true;
        }

        if (profile == BluetoothProfile.HEARING_AID && !isHearingAidProfileSupported()) {
            Log.e(TAG, "getProfileProxy(): BluetoothHearingAid is not supported");
            return false;
        } else if (profile == BluetoothProfile.LE_AUDIO) {
            BluetoothLeAudio leAudio = new BluetoothLeAudio(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.LE_AUDIO_BROADCAST) {
            BluetoothLeBroadcast leAudio = new BluetoothLeBroadcast(context, listener);
            return true;
        } else if (profile == BluetoothProfile.VOLUME_CONTROL) {
            BluetoothVolumeControl vcs = new BluetoothVolumeControl(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.CSIP_SET_COORDINATOR) {
            BluetoothCsipSetCoordinator csipSetCoordinator =
                    new BluetoothCsipSetCoordinator(context, listener, this);
            return true;
        } else if (profile == BluetoothProfile.LE_CALL_CONTROL) {
            BluetoothLeCallControl tbs = new BluetoothLeCallControl(context, listener);
            return true;
        } else if (profile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT) {
            BluetoothLeBroadcastAssistant leAudioBroadcastAssistant =
                    new BluetoothLeBroadcastAssistant(context, listener);
            return true;
        } else {
        }

        BiFunction<Context, BluetoothAdapter, BluetoothProfile> constructor =
                PROFILE_CONSTRUCTORS.get(profile);

        if (constructor == null) {
            Log.e(TAG, "getProfileProxy(): Unknown profile " + profile);
            return false;
        }

        BluetoothProfile profileProxy = constructor.apply(context, this);

        BluetoothProfileConnector connector = new BluetoothProfileConnector(profileProxy, profile);
        mProfileConnectors.put(profileProxy, connector);
        connector.connect(context, listener);

        return true;
    }

    /**
     * Close the connection of the profile proxy to the Service.
     *
     * <p>Clients should call this when they are no longer using the proxy obtained from {@link
     * #getProfileProxy}.
     *
     * @param proxy Profile proxy object
     * @hide
     */
    public void closeProfileProxy(@NonNull BluetoothProfile proxy) {
        if (proxy instanceof BluetoothGatt gatt) {
            gatt.close();
            return;
        } else if (proxy instanceof BluetoothGattServer gatt) {
            gatt.close();
            return;
        }

        if (proxy.getAdapter() != this) {
            Log.e(
                    TAG,
                    "closeProfileProxy(): Called on wrong instance was "
                            + proxy.getAdapter()
                            + " but expected "
                            + this);
            // farmhash::Fingerprint64("bluetooth.value_close_profile_proxy_adapter_mismatch")
            // TODO(b/310684444): Remove this magic value
            long metricIdHash = 5174922474613897731L;
            StatsExpressLog.write(
                    StatsExpressLog.EXPRESS_UID_EVENT_REPORTED, metricIdHash, 1, Process.myUid());
            proxy.getAdapter().closeProfileProxy(proxy);
            return;
        }

        BluetoothProfileConnector connector = mProfileConnectors.remove(proxy);
        if (connector != null) {
            if (proxy instanceof BluetoothLeCallControl callControl) {
                callControl.unregisterBearer();
            }

            connector.disconnect();
        }
    }

    /**
@@ -3719,7 +3753,7 @@ public final class BluetoothAdapter {
        if (proxy == null) {
            return;
        }
        proxy.close();
        closeProfileProxy(proxy);
    }

    private static final IBluetoothManagerCallback sManagerCallback =
Loading