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

Commit bbdc74d7 authored by Grzegorz Kolodziejczyk's avatar Grzegorz Kolodziejczyk Committed by Automerger Merge Worker
Browse files

Merge "bass_client: Use proxy for Advertising Manager and BluetoothAdapter"...

Merge "bass_client: Use proxy for Advertising Manager and BluetoothAdapter" into main am: 1fa1a181 am: a6bc87c0

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/2952893



Change-Id: I200790a25b4d97ec2e590454d0d908875a0b50af
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 448440ff a6bc87c0
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -239,6 +239,11 @@ public class BluetoothMethodProxy {
        manager.registerSync(scanResult, skip, timeout, callback, handler);
    }

    /** Proxies {@link PeriodicAdvertisingManager#unregisterSync(PeriodicAdvertisingCallback)}. */
    public void periodicAdvertisingManagerUnregisterSync(
            PeriodicAdvertisingManager manager, PeriodicAdvertisingCallback callback) {
        manager.unregisterSync(callback);
    }
    /**
     * Proxies {@link PeriodicAdvertisingManager#transferSync}.
     */
+84 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 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 com.android.bluetooth.bass_client;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.PeriodicAdvertisingManager;
import android.util.Log;

/** Bass Client Periodic Advertising object handler */
class BassClientPeriodicAdvertisingManager {
    private static final String TAG = "BassClientPeriodicAdvertisingManager";

    private static PeriodicAdvertisingManager sPeriodicAdvertisingManager;

    private BassClientPeriodicAdvertisingManager() {}

    /**
     * Return true if initialization of Periodic Advertising Manager instance on Default Bluetooth
     * Adapter is successful.
     */
    public static boolean initializePeriodicAdvertisingManagerOnDefaultAdapter() {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();

        if (sPeriodicAdvertisingManager != null) {
            Log.w(TAG, "Periodic Advertising Manager already initialized - re-initializing");
        }

        if (adapter == null) {
            Log.e(TAG, "Failed to get Default Bluetooth Adapter");
            return false;
        }

        sPeriodicAdvertisingManager = adapter.getPeriodicAdvertisingManager();

        if (sPeriodicAdvertisingManager == null) {
            Log.e(TAG, "Failed to get Default Periodic Advertising Manager");
            return false;
        }

        Log.d(TAG, "BassClientPeriodicAdvertisingManager initialized");

        return true;
    }

    public static synchronized PeriodicAdvertisingManager getPeriodicAdvertisingManager() {
        if (sPeriodicAdvertisingManager == null) {
            Log.e(
                    TAG,
                    "getPeriodicAdvertisingManager: Periodic Advertising Manager is not "
                            + "initialized");
            return null;
        }

        return sPeriodicAdvertisingManager;
    }

    public static void clearPeriodicAdvertisingManager() {
        if (sPeriodicAdvertisingManager == null) {
            Log.e(
                    TAG,
                    "clearPeriodicAdvertisingManager: Periodic Advertising Manager is not "
                            + "initialized");
            return;
        }

        Log.d(TAG, "BassClientPeriodicAdvertisingManager cleared");

        sPeriodicAdvertisingManager = null;
    }
}
+33 −2
Original line number Diff line number Diff line
@@ -717,6 +717,12 @@ public class BassClientService extends ProfileService {
        if (mGroupManagedSources.containsKey(sink)
                && mGroupManagedSources.get(sink).contains(sourceId)) {
            BassClientStateMachine stateMachine = getOrCreateStateMachine(sink);
            if (stateMachine == null) {
                Log.e(TAG, "Can't get state machine for device: " + sink);
                return new Pair<BluetoothLeBroadcastMetadata, Map<BluetoothDevice, Integer>>(
                        null, null);
            }

            BluetoothLeBroadcastMetadata metadata =
                    stateMachine.getCurrentBroadcastMetadata(sourceId);
            if (metadata != null) {
@@ -867,8 +873,15 @@ public class BassClientService extends ProfileService {
            stateMachine =
                    BassObjectsFactory.getInstance()
                            .makeStateMachine(
                                    device, this, mStateMachinesThread.getLooper(), mFeatureFlags);
                                    device,
                                    this,
                                    mAdapterService,
                                    mStateMachinesThread.getLooper(),
                                    mFeatureFlags);
            if (stateMachine != null) {
                mStateMachines.put(device, stateMachine);
            }

            return stateMachine;
        }
    }
@@ -1050,6 +1063,11 @@ public class BassClientService extends ProfileService {
        }
        synchronized (mStateMachines) {
            BassClientStateMachine stateMachine = getOrCreateStateMachine(device);
            if (stateMachine == null) {
                Log.e(TAG, "Can't get state machine for device: " + device);
                return false;
            }

            stateMachine.sendMessage(BassClientStateMachine.CONNECT);
        }
        return true;
@@ -1071,6 +1089,11 @@ public class BassClientService extends ProfileService {
        }
        synchronized (mStateMachines) {
            BassClientStateMachine stateMachine = getOrCreateStateMachine(device);
            if (stateMachine == null) {
                Log.e(TAG, "Can't get state machine for device: " + device);
                return false;
            }

            stateMachine.sendMessage(BassClientStateMachine.DISCONNECT);
        }
        return true;
@@ -1393,6 +1416,10 @@ public class BassClientService extends ProfileService {
            // removing the 1st synced source before proceeding to add new
            synchronized (mStateMachines) {
                BassClientStateMachine stateMachine = getOrCreateStateMachine(sink);
                if (stateMachine == null) {
                    Log.e(TAG, "Can't get state machine for device: " + sink);
                    return;
                }
                Message message =
                        stateMachine.obtainMessage(BassClientStateMachine.REACHED_MAX_SOURCE_LIMIT);
                message.arg1 = syncHandle;
@@ -1404,6 +1431,10 @@ public class BassClientService extends ProfileService {
            sEventLogger.logd(TAG, "Select Broadcast Source");

            BassClientStateMachine stateMachine = getOrCreateStateMachine(sink);
            if (stateMachine == null) {
                Log.e(TAG, "Can't get state machine for device: " + sink);
                return;
            }
            Message message = stateMachine.obtainMessage(
                    BassClientStateMachine.SELECT_BCAST_SOURCE);
            message.obj = result;
+81 −53
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.bluetooth.bass_client;
import static android.Manifest.permission.BLUETOOTH_CONNECT;

import android.annotation.Nullable;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
@@ -38,7 +37,6 @@ import android.bluetooth.BluetoothStatusCodes;
import android.bluetooth.BluetoothUtils;
import android.bluetooth.BluetoothUtils.TypeValueEntry;
import android.bluetooth.le.PeriodicAdvertisingCallback;
import android.bluetooth.le.PeriodicAdvertisingManager;
import android.bluetooth.le.PeriodicAdvertisingReport;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
@@ -53,8 +51,8 @@ import android.util.Pair;

import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.flags.FeatureFlags;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.State;
@@ -148,6 +146,7 @@ public class BassClientStateMachine extends StateMachine {
    boolean mDiscoveryInitiated = false;
    @VisibleForTesting
    BassClientService mService;
    AdapterService mAdapterService;
    @VisibleForTesting
    BluetoothGattCharacteristic mBroadcastScanControlPoint;
    private final Map<Integer, Boolean> mFirstTimeBisDiscoveryMap;
@@ -155,9 +154,6 @@ public class BassClientStateMachine extends StateMachine {
    private ScanResult mScanRes = null;
    @VisibleForTesting
    int mNumOfBroadcastReceiverStates = 0;
    private BluetoothAdapter mBluetoothAdapter =
            BluetoothAdapter.getDefaultAdapter();
    private ServiceFactory mFactory = new ServiceFactory();
    @VisibleForTesting
    int mPendingOperation = -1;
    @VisibleForTesting
@@ -168,8 +164,6 @@ public class BassClientStateMachine extends StateMachine {
    @VisibleForTesting
    boolean mSetBroadcastCodePending = false;
    private final Map<Integer, Boolean> mPendingRemove = new HashMap();
    // Psync and PAST interfaces
    private PeriodicAdvertisingManager mPeriodicAdvManager;
    @VisibleForTesting
    boolean mAutoTriggered = false;
    private boolean mDefNoPAS = false;
@@ -190,12 +184,14 @@ public class BassClientStateMachine extends StateMachine {
    BassClientStateMachine(
            BluetoothDevice device,
            BassClientService svc,
            AdapterService adapterService,
            Looper looper,
            int connectTimeoutMs,
            FeatureFlags featureFlags) {
        super(TAG + "(" + device.toString() + ")", looper);
        mDevice = device;
        mService = svc;
        mAdapterService = adapterService;
        mConnectTimeoutMs = connectTimeoutMs;
        mFeatureFlags = Objects.requireNonNull(featureFlags, "Feature Flags cannot be null");
        addState(mDisconnected);
@@ -203,11 +199,6 @@ public class BassClientStateMachine extends StateMachine {
        addState(mConnecting);
        addState(mConnectedProcessing);
        setInitialState(mDisconnected);
        // PSYNC and PAST instances
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter != null) {
            mPeriodicAdvManager = mBluetoothAdapter.getPeriodicAdvertisingManager();
        }
        mFirstTimeBisDiscoveryMap = new HashMap<Integer, Boolean>();
        long token = Binder.clearCallingIdentity();
        mIsAllowedList = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH,
@@ -222,12 +213,25 @@ public class BassClientStateMachine extends StateMachine {
    static BassClientStateMachine make(
            BluetoothDevice device,
            BassClientService svc,
            AdapterService adapterService,
            Looper looper,
            FeatureFlags featureFlags) {
        Log.d(TAG, "make for device " + device);

        if (!BassClientPeriodicAdvertisingManager
                .initializePeriodicAdvertisingManagerOnDefaultAdapter()) {
            Log.e(TAG, "Failed to initialize Periodic Advertising Manager on Default Adapter");
            return null;
        }

        BassClientStateMachine BassclientSm =
                new BassClientStateMachine(
                        device, svc, looper, BassConstants.CONNECT_TIMEOUT_MS, featureFlags);
                        device,
                        svc,
                        adapterService,
                        looper,
                        BassConstants.CONNECT_TIMEOUT_MS,
                        featureFlags);
        BassclientSm.start();
        return BassclientSm;
    }
@@ -455,9 +459,15 @@ public class BassClientStateMachine extends StateMachine {
            int tempHandle = BassConstants.INVALID_SYNC_HANDLE;
            mPeriodicAdvCallbacksMap.put(tempHandle, paCb);
            try {
                BluetoothMethodProxy.getInstance().periodicAdvertisingManagerRegisterSync(
                        mPeriodicAdvManager, scanRes, 0, BassConstants.PSYNC_TIMEOUT,
                        paCb, null);
                BluetoothMethodProxy.getInstance()
                        .periodicAdvertisingManagerRegisterSync(
                                BassClientPeriodicAdvertisingManager
                                        .getPeriodicAdvertisingManager(),
                                scanRes,
                                0,
                                BassConstants.PSYNC_TIMEOUT,
                                paCb,
                                null);
            } catch (IllegalArgumentException ex) {
                Log.w(TAG, "registerSync:IllegalArgumentException");
                Message message = obtainMessage(STOP_SCAN_OFFLOAD);
@@ -522,7 +532,11 @@ public class BassClientStateMachine extends StateMachine {
        if (syncHandle != BassConstants.INVALID_SYNC_HANDLE
                && mPeriodicAdvCallbacksMap.containsKey(syncHandle)) {
            try {
                mPeriodicAdvManager.unregisterSync(mPeriodicAdvCallbacksMap.get(syncHandle));
                BluetoothMethodProxy.getInstance()
                        .periodicAdvertisingManagerUnregisterSync(
                                BassClientPeriodicAdvertisingManager
                                        .getPeriodicAdvertisingManager(),
                                mPeriodicAdvCallbacksMap.get(syncHandle));
            } catch (IllegalArgumentException ex) {
                Log.w(TAG, "unregisterSync:IllegalArgumentException");
                return false;
@@ -686,7 +700,11 @@ public class BassClientStateMachine extends StateMachine {
                            + "serviceData" + serviceData);
                    BluetoothMethodProxy.getInstance()
                            .periodicAdvertisingManagerTransferSync(
                                    mPeriodicAdvManager, mDevice, serviceData, syncHandle);
                                    BassClientPeriodicAdvertisingManager
                                            .getPeriodicAdvertisingManager(),
                                    mDevice,
                                    serviceData,
                                    syncHandle);
                }
            } else {
                BluetoothLeBroadcastMetadata currentMetadata =
@@ -701,8 +719,13 @@ public class BassClientStateMachine extends StateMachine {
                    log("Initiate local broadcast PAST for: " + mDevice
                            + ", advSID/Handle: " +  advHandle
                            + ", serviceData: " + serviceData);
                    BluetoothMethodProxy.getInstance().periodicAdvertisingManagerTransferSetInfo(
                            mPeriodicAdvManager, mDevice, serviceData, advHandle,
                    BluetoothMethodProxy.getInstance()
                            .periodicAdvertisingManagerTransferSetInfo(
                                    BassClientPeriodicAdvertisingManager
                                            .getPeriodicAdvertisingManager(),
                                    mDevice,
                                    serviceData,
                                    advHandle,
                                    mLocalPeriodicAdvCallback);
                } else {
                    Log.e(TAG, "There is no valid sync handle for this Source");
@@ -744,15 +767,17 @@ public class BassClientStateMachine extends StateMachine {
        }
        log("processBroadcastReceiverState: receiverState length: " + receiverState.length);

        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
        BluetoothLeBroadcastReceiveState recvState = null;
        if (receiverState.length == 0
                || isEmpty(Arrays.copyOfRange(receiverState, 1, receiverState.length - 1))) {
            String emptyBluetoothDevice = "00:00:00:00:00:00";
            byte[] emptyBluetoothDeviceAddress = Utils.getBytesFromAddress("00:00:00:00:00:00");
            if (mPendingOperation == REMOVE_BCAST_SOURCE) {
                recvState = new BluetoothLeBroadcastReceiveState(mPendingSourceId,
                recvState =
                        new BluetoothLeBroadcastReceiveState(
                                mPendingSourceId,
                                BluetoothDevice.ADDRESS_TYPE_PUBLIC, // sourceAddressType
                        btAdapter.getRemoteDevice(emptyBluetoothDevice),  // sourceDevice
                                mAdapterService.getDeviceFromByte(
                                        emptyBluetoothDeviceAddress), // sourceDev
                                0, // sourceAdvertisingSid
                                0, // broadcastId
                                BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState
@@ -761,7 +786,8 @@ public class BassClientStateMachine extends StateMachine {
                                null, // badCode
                                0, // numSubgroups
                                Arrays.asList(new Long[0]), // bisSyncState
                        Arrays.asList(new BluetoothLeAudioContentMetadata[0])    // subgroupMetadata
                                Arrays.asList(
                                        new BluetoothLeAudioContentMetadata[0]) // subgroupMetadata
                                );
            } else if (receiverState.length == 0) {
                if (mBluetoothLeBroadcastReceiveStates != null) {
@@ -772,9 +798,12 @@ public class BassClientStateMachine extends StateMachine {
                    return null;
                }
                mNextSourceId++;
                recvState = new BluetoothLeBroadcastReceiveState(mNextSourceId,
                recvState =
                        new BluetoothLeBroadcastReceiveState(
                                mNextSourceId,
                                BluetoothDevice.ADDRESS_TYPE_PUBLIC, // sourceAddressType
                        btAdapter.getRemoteDevice(emptyBluetoothDevice),   // sourceDevice
                                mAdapterService.getDeviceFromByte(
                                        emptyBluetoothDeviceAddress), // sourceDev
                                0, // sourceAdvertisingSid
                                0, // broadcastId
                                BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState
@@ -783,7 +812,8 @@ public class BassClientStateMachine extends StateMachine {
                                null, // badCode
                                0, // numSubgroups
                                Arrays.asList(new Long[0]), // bisSyncState
                        Arrays.asList(new BluetoothLeAudioContentMetadata[0])    // subgroupMetadata
                                Arrays.asList(
                                        new BluetoothLeAudioContentMetadata[0]) // subgroupMetadata
                                );
            }
        } else {
@@ -845,9 +875,7 @@ public class BassClientStateMachine extends StateMachine {
            byte sourceAddressType = receiverState[BassConstants
                    .BCAST_RCVR_STATE_SRC_ADDR_TYPE_IDX];
            BassUtils.reverse(sourceAddress);
            String address = Utils.getAddressStringFromByte(sourceAddress);
            BluetoothDevice device = btAdapter.getRemoteLeDevice(
                    address, sourceAddressType);
            BluetoothDevice device = mAdapterService.getDeviceFromByte(sourceAddress);
            byte sourceAdvSid = receiverState[BassConstants.BCAST_RCVR_STATE_SRC_ADV_SID_IDX];
            recvState = new BluetoothLeBroadcastReceiveState(
                    sourceId,
+3 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.os.Looper;
import android.util.Log;

import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.flags.FeatureFlags;
import com.android.internal.annotations.VisibleForTesting;

@@ -75,9 +76,10 @@ public class BassObjectsFactory {
    public BassClientStateMachine makeStateMachine(
            BluetoothDevice device,
            BassClientService svc,
            AdapterService adapterService,
            Looper looper,
            FeatureFlags featureFlags) {
        return BassClientStateMachine.make(device, svc, looper, featureFlags);
        return BassClientStateMachine.make(device, svc, adapterService, looper, featureFlags);
    }

    /**
Loading