Loading android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorNativeInterface.java +10 −63 Original line number Diff line number Diff line Loading @@ -17,12 +17,13 @@ package com.android.bluetooth.csip; import static java.util.Objects.requireNonNull; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.util.Log; import com.android.bluetooth.Utils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.util.UUID; Loading @@ -30,83 +31,29 @@ import java.util.UUID; /** CSIP Set Coordinator role native interface */ public class CsipSetCoordinatorNativeInterface { private static final String TAG = "CsipSetCoordinatorNativeInterface"; private BluetoothAdapter mAdapter; @GuardedBy("INSTANCE_LOCK") private static CsipSetCoordinatorNativeInterface sInstance; private static final Object INSTANCE_LOCK = new Object(); private CsipSetCoordinatorNativeInterface() { mAdapter = BluetoothAdapter.getDefaultAdapter(); if (mAdapter == null) { Log.wtf(TAG, "No Bluetooth Adapter Available"); } } private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter(); /** Get singleton instance. */ public static CsipSetCoordinatorNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { sInstance = new CsipSetCoordinatorNativeInterface(); } return sInstance; } CsipSetCoordinatorNativeInterface() { requireNonNull(mAdapter); } /** Set singleton instance. */ @VisibleForTesting public static void setInstance(CsipSetCoordinatorNativeInterface instance) { synchronized (INSTANCE_LOCK) { sInstance = instance; } } /** * Initializes the native interface. * * <p>priorities to configure. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void init() { void init() { initNative(); } /** Cleanup the native interface. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void cleanup() { void cleanup() { cleanupNative(); } /** * Initiates CsipSetCoordinator connection to a remote device. * * @param device the remote device * @return true on success, otherwise false. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public boolean connect(BluetoothDevice device) { boolean connect(BluetoothDevice device) { return connectNative(getByteAddress(device)); } /** * Disconnects CsipSetCoordinator from a remote device. * * @param device the remote device * @return true on success, otherwise false. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public boolean disconnect(BluetoothDevice device) { boolean disconnect(BluetoothDevice device) { return disconnectNative(getByteAddress(device)); } /** * Get the device by the address * * @return the device */ @VisibleForTesting public BluetoothDevice getDevice(byte[] address) { BluetoothDevice getDevice(byte[] address) { return mAdapter.getRemoteDevice(address); } Loading android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java +67 −113 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ package com.android.bluetooth.csip; import static android.Manifest.permission.BLUETOOTH_CONNECT; import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNullElseGet; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -33,9 +36,7 @@ import android.bluetooth.IBluetoothCsipSetCoordinator; import android.bluetooth.IBluetoothCsipSetCoordinatorCallback; import android.bluetooth.IBluetoothCsipSetCoordinatorLockCallback; import android.content.AttributionSource; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; Loading @@ -60,7 +61,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; Loading @@ -76,15 +76,13 @@ public class CsipSetCoordinatorService extends ProfileService { private static CsipSetCoordinatorService sCsipSetCoordinatorService; private Handler mHandler = null; private AdapterService mAdapterService; private LeAudioService mLeAudioService; private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; @VisibleForTesting ServiceFactory mServiceFactory = new ServiceFactory(); @VisibleForTesting CsipSetCoordinatorNativeInterface mCsipSetCoordinatorNativeInterface; private final AdapterService mAdapterService; private final DatabaseManager mDatabaseManager; private final Handler mHandler; private final HandlerThread mStateMachinesThread; private final Looper mStateMachinesLooper; private final CsipSetCoordinatorNativeInterface mNativeInterface; private final ServiceFactory mServiceFactory; @GuardedBy("mStateMachines") private final Map<BluetoothDevice, CsipSetCoordinatorStateMachine> mStateMachines = Loading @@ -103,66 +101,53 @@ public class CsipSetCoordinatorService extends ProfileService { private final Map<Integer, Pair<UUID, IBluetoothCsipSetCoordinatorLockCallback>> mLocks = new ConcurrentHashMap<>(); public CsipSetCoordinatorService(Context ctx) { super(ctx); } private LeAudioService mLeAudioService; public static boolean isEnabled() { return BluetoothProperties.isProfileCsipSetCoordinatorEnabled().orElse(false); public CsipSetCoordinatorService(AdapterService adapterService) { this(adapterService, null, null, new ServiceFactory()); } @Override protected IProfileServiceBinder initBinder() { return new BluetoothCsisBinder(this); @VisibleForTesting CsipSetCoordinatorService( AdapterService adapterService, Looper looper, CsipSetCoordinatorNativeInterface nativeInterface, ServiceFactory serviceFactory) { super(requireNonNull(adapterService)); mAdapterService = adapterService; mDatabaseManager = requireNonNull(mAdapterService.getDatabase()); mNativeInterface = requireNonNullElseGet( nativeInterface, () -> new CsipSetCoordinatorNativeInterface()); mServiceFactory = requireNonNull(serviceFactory); if (looper == null) { mHandler = new Handler(requireNonNull(Looper.getMainLooper())); mStateMachinesThread = new HandlerThread("CsipSetCoordinatorService.StateMachines"); mStateMachinesThread.start(); mStateMachinesLooper = mStateMachinesThread.getLooper(); } else { mHandler = new Handler(looper); mStateMachinesThread = null; mStateMachinesLooper = looper; } @Override public void start() { Log.d(TAG, "start()"); if (sCsipSetCoordinatorService != null) { throw new IllegalStateException("start() called twice"); } // Get AdapterService, DatabaseManager, CsipSetCoordinatorNativeInterface. // None of them can be null. mAdapterService = Objects.requireNonNull( AdapterService.getAdapterService(), "AdapterService cannot be null when CsipSetCoordinatorService starts"); mDatabaseManager = Objects.requireNonNull( mAdapterService.getDatabase(), "DatabaseManager cannot be null when CsipSetCoordinatorService starts"); mCsipSetCoordinatorNativeInterface = Objects.requireNonNull( CsipSetCoordinatorNativeInterface.getInstance(), "CsipSetCoordinatorNativeInterface cannot be null when" .concat("CsipSetCoordinatorService starts")); // Setup Handler. mHandler = new Handler(Looper.getMainLooper()); // Get LE Audio service (can be null) mLeAudioService = mServiceFactory.getLeAudioService(); synchronized (mStateMachines) { mStateMachines.clear(); } // Start handler thread for state machines mStateMachinesThread = new HandlerThread("CsipSetCoordinatorService.StateMachines"); mStateMachinesThread.start(); // Setup broadcast receivers IntentFilter filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); // Mark service as started setCsipSetCoordinatorService(this); // Initialize native interface mCsipSetCoordinatorNativeInterface.init(); mNativeInterface.init(); } public static boolean isEnabled() { return BluetoothProperties.isProfileCsipSetCoordinatorEnabled().orElse(false); } @Override protected IProfileServiceBinder initBinder() { return new BluetoothCsisBinder(this); } @Override Loading @@ -174,8 +159,7 @@ public class CsipSetCoordinatorService extends ProfileService { } // Cleanup native interface mCsipSetCoordinatorNativeInterface.cleanup(); mCsipSetCoordinatorNativeInterface = null; mNativeInterface.cleanup(); // Mark service as stopped setCsipSetCoordinatorService(null); Loading @@ -193,17 +177,13 @@ public class CsipSetCoordinatorService extends ProfileService { try { mStateMachinesThread.quitSafely(); mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS); mStateMachinesThread = null; } catch (InterruptedException e) { // Do not rethrow as we are shutting down anyway } } // Unregister Handler and stop all queued messages. if (mHandler != null) { mHandler.removeCallbacksAndMessages(null); mHandler = null; } mDeviceGroupIdRankMap.clear(); mCallbacks.clear(); Loading @@ -213,10 +193,6 @@ public class CsipSetCoordinatorService extends ProfileService { mGroupIdToUuidMap.clear(); mLocks.clear(); // Clear AdapterService, CsipSetCoordinatorNativeInterface mCsipSetCoordinatorNativeInterface = null; mAdapterService = null; } @Override Loading Loading @@ -515,7 +491,7 @@ public class CsipSetCoordinatorService extends ProfileService { } Log.d(TAG, "lockGroup(): locking group: " + groupId); mCsipSetCoordinatorNativeInterface.groupLockSet(groupId, true); mNativeInterface.groupLockSet(groupId, true); return uuid; } Loading @@ -536,7 +512,7 @@ public class CsipSetCoordinatorService extends ProfileService { Pair<UUID, IBluetoothCsipSetCoordinatorLockCallback> uuidCbPair = entry.getValue(); if (uuidCbPair.first.equals(lockUuid)) { Log.d(TAG, "unlockGroup(): unlocking ... " + lockUuid); mCsipSetCoordinatorNativeInterface.groupLockSet(entry.getKey(), false); mNativeInterface.groupLockSet(entry.getKey(), false); return; } } Loading Loading @@ -823,7 +799,7 @@ public class CsipSetCoordinatorService extends ProfileService { Intent intent = null; int groupId = stackEvent.valueInt1; if (stackEvent.type == CsipSetCoordinatorStackEvent.EVENT_TYPE_DEVICE_AVAILABLE) { Objects.requireNonNull(device); requireNonNull(device); intent = new Intent(BluetoothCsipSetCoordinator.ACTION_CSIS_DEVICE_AVAILABLE); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, stackEvent.device); Loading @@ -841,7 +817,7 @@ public class CsipSetCoordinatorService extends ProfileService { stackEvent.valueInt2); } else if (stackEvent.type == CsipSetCoordinatorStackEvent.EVENT_TYPE_SET_MEMBER_AVAILABLE) { Objects.requireNonNull(device); requireNonNull(device); if (!mFoundSetMemberToGroupId.containsKey(device)) { mFoundSetMemberToGroupId.put(device, groupId); } Loading Loading @@ -900,10 +876,7 @@ public class CsipSetCoordinatorService extends ProfileService { Log.d(TAG, "Creating a new state machine for " + device); sm = CsipSetCoordinatorStateMachine.make( device, this, mCsipSetCoordinatorNativeInterface, mStateMachinesThread.getLooper()); device, this, mNativeInterface, mStateMachinesLooper); mStateMachines.put(device, sm); return sm; } Loading @@ -911,16 +884,6 @@ public class CsipSetCoordinatorService extends ProfileService { /** Process a change in the bonding state for a device */ public void handleBondStateChanged(BluetoothDevice device, int fromState, int toState) { if (mHandler == null) { Log.e( TAG, "mHandler is null, service is stopped. Ignore Bond State for " + device + " to state: " + toState); return; } mHandler.post(() -> bondStateChanged(device, toState)); } Loading Loading @@ -982,15 +945,6 @@ public class CsipSetCoordinatorService extends ProfileService { } void handleConnectionStateChanged(BluetoothDevice device, int fromState, int toState) { if (mHandler == null) { Log.e( TAG, "mHandler is null, service is stopped. Ignore Connection State for " + device + " to state: " + toState); return; } mHandler.post(() -> connectionStateChanged(device, fromState, toState)); } Loading Loading @@ -1074,7 +1028,7 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public List<BluetoothDevice> getConnectedDevices(AttributionSource source) { Objects.requireNonNull(source, "source cannot be null"); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1087,7 +1041,7 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public List<BluetoothDevice> getDevicesMatchingConnectionStates( int[] states, AttributionSource source) { Objects.requireNonNull(source, "source cannot be null"); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1099,8 +1053,8 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public int getConnectionState(BluetoothDevice device, AttributionSource source) { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(device); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1113,8 +1067,8 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public boolean setConnectionPolicy( BluetoothDevice device, int connectionPolicy, AttributionSource source) { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(device); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1126,8 +1080,8 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(device); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1142,8 +1096,8 @@ public class CsipSetCoordinatorService extends ProfileService { int groupId, @NonNull IBluetoothCsipSetCoordinatorLockCallback callback, AttributionSource source) { Objects.requireNonNull(callback, "callback cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(callback); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1156,8 +1110,8 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public void unlockGroup(@NonNull ParcelUuid lockUuid, AttributionSource source) { Objects.requireNonNull(lockUuid, "lockUuid cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(lockUuid); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1169,8 +1123,8 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public List<Integer> getAllGroupIds(ParcelUuid uuid, AttributionSource source) { Objects.requireNonNull(uuid, "uuid cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(uuid); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java +1 −4 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import com.android.bluetooth.a2dpsink.A2dpSinkNativeInterface; import com.android.bluetooth.avrcp.AvrcpNativeInterface; import com.android.bluetooth.avrcpcontroller.AvrcpControllerNativeInterface; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.csip.CsipSetCoordinatorNativeInterface; import com.android.bluetooth.hearingaid.HearingAidNativeInterface; import com.android.bluetooth.hfp.HeadsetNativeInterface; import com.android.bluetooth.hfpclient.NativeInterface; Loading Loading @@ -91,7 +90,6 @@ public class ProfileServiceTest { @Mock private HidDeviceNativeInterface mHidDeviceNativeInterface; @Mock private HidHostNativeInterface mHidHostNativeInterface; @Mock private PanNativeInterface mPanNativeInterface; @Mock private CsipSetCoordinatorNativeInterface mCsipSetCoordinatorInterface; @Mock private LeAudioNativeInterface mLeAudioInterface; private void setProfileState(int profile, int state) { Loading Loading @@ -156,6 +154,7 @@ public class ProfileServiceTest { profile -> profile != BluetoothProfile.HAP_CLIENT && profile != BluetoothProfile.VOLUME_CONTROL && profile != BluetoothProfile.CSIP_SET_COORDINATOR && profile != BluetoothProfile.GATT) .toArray(); TestUtils.setAdapterService(mAdapterService); Loading @@ -172,7 +171,6 @@ public class ProfileServiceTest { HidDeviceNativeInterface.setInstance(mHidDeviceNativeInterface); HidHostNativeInterface.setInstance(mHidHostNativeInterface); PanNativeInterface.setInstance(mPanNativeInterface); CsipSetCoordinatorNativeInterface.setInstance(mCsipSetCoordinatorInterface); LeAudioNativeInterface.setInstance(mLeAudioInterface); } Loading @@ -192,7 +190,6 @@ public class ProfileServiceTest { HidDeviceNativeInterface.setInstance(null); HidHostNativeInterface.setInstance(null); PanNativeInterface.setInstance(null); CsipSetCoordinatorNativeInterface.setInstance(null); LeAudioNativeInterface.setInstance(null); } Loading android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java +237 −509 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorNativeInterface.java +10 −63 Original line number Diff line number Diff line Loading @@ -17,12 +17,13 @@ package com.android.bluetooth.csip; import static java.util.Objects.requireNonNull; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.util.Log; import com.android.bluetooth.Utils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.util.UUID; Loading @@ -30,83 +31,29 @@ import java.util.UUID; /** CSIP Set Coordinator role native interface */ public class CsipSetCoordinatorNativeInterface { private static final String TAG = "CsipSetCoordinatorNativeInterface"; private BluetoothAdapter mAdapter; @GuardedBy("INSTANCE_LOCK") private static CsipSetCoordinatorNativeInterface sInstance; private static final Object INSTANCE_LOCK = new Object(); private CsipSetCoordinatorNativeInterface() { mAdapter = BluetoothAdapter.getDefaultAdapter(); if (mAdapter == null) { Log.wtf(TAG, "No Bluetooth Adapter Available"); } } private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter(); /** Get singleton instance. */ public static CsipSetCoordinatorNativeInterface getInstance() { synchronized (INSTANCE_LOCK) { if (sInstance == null) { sInstance = new CsipSetCoordinatorNativeInterface(); } return sInstance; } CsipSetCoordinatorNativeInterface() { requireNonNull(mAdapter); } /** Set singleton instance. */ @VisibleForTesting public static void setInstance(CsipSetCoordinatorNativeInterface instance) { synchronized (INSTANCE_LOCK) { sInstance = instance; } } /** * Initializes the native interface. * * <p>priorities to configure. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void init() { void init() { initNative(); } /** Cleanup the native interface. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void cleanup() { void cleanup() { cleanupNative(); } /** * Initiates CsipSetCoordinator connection to a remote device. * * @param device the remote device * @return true on success, otherwise false. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public boolean connect(BluetoothDevice device) { boolean connect(BluetoothDevice device) { return connectNative(getByteAddress(device)); } /** * Disconnects CsipSetCoordinator from a remote device. * * @param device the remote device * @return true on success, otherwise false. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public boolean disconnect(BluetoothDevice device) { boolean disconnect(BluetoothDevice device) { return disconnectNative(getByteAddress(device)); } /** * Get the device by the address * * @return the device */ @VisibleForTesting public BluetoothDevice getDevice(byte[] address) { BluetoothDevice getDevice(byte[] address) { return mAdapter.getRemoteDevice(address); } Loading
android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java +67 −113 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ package com.android.bluetooth.csip; import static android.Manifest.permission.BLUETOOTH_CONNECT; import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNullElseGet; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -33,9 +36,7 @@ import android.bluetooth.IBluetoothCsipSetCoordinator; import android.bluetooth.IBluetoothCsipSetCoordinatorCallback; import android.bluetooth.IBluetoothCsipSetCoordinatorLockCallback; import android.content.AttributionSource; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; Loading @@ -60,7 +61,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; Loading @@ -76,15 +76,13 @@ public class CsipSetCoordinatorService extends ProfileService { private static CsipSetCoordinatorService sCsipSetCoordinatorService; private Handler mHandler = null; private AdapterService mAdapterService; private LeAudioService mLeAudioService; private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; @VisibleForTesting ServiceFactory mServiceFactory = new ServiceFactory(); @VisibleForTesting CsipSetCoordinatorNativeInterface mCsipSetCoordinatorNativeInterface; private final AdapterService mAdapterService; private final DatabaseManager mDatabaseManager; private final Handler mHandler; private final HandlerThread mStateMachinesThread; private final Looper mStateMachinesLooper; private final CsipSetCoordinatorNativeInterface mNativeInterface; private final ServiceFactory mServiceFactory; @GuardedBy("mStateMachines") private final Map<BluetoothDevice, CsipSetCoordinatorStateMachine> mStateMachines = Loading @@ -103,66 +101,53 @@ public class CsipSetCoordinatorService extends ProfileService { private final Map<Integer, Pair<UUID, IBluetoothCsipSetCoordinatorLockCallback>> mLocks = new ConcurrentHashMap<>(); public CsipSetCoordinatorService(Context ctx) { super(ctx); } private LeAudioService mLeAudioService; public static boolean isEnabled() { return BluetoothProperties.isProfileCsipSetCoordinatorEnabled().orElse(false); public CsipSetCoordinatorService(AdapterService adapterService) { this(adapterService, null, null, new ServiceFactory()); } @Override protected IProfileServiceBinder initBinder() { return new BluetoothCsisBinder(this); @VisibleForTesting CsipSetCoordinatorService( AdapterService adapterService, Looper looper, CsipSetCoordinatorNativeInterface nativeInterface, ServiceFactory serviceFactory) { super(requireNonNull(adapterService)); mAdapterService = adapterService; mDatabaseManager = requireNonNull(mAdapterService.getDatabase()); mNativeInterface = requireNonNullElseGet( nativeInterface, () -> new CsipSetCoordinatorNativeInterface()); mServiceFactory = requireNonNull(serviceFactory); if (looper == null) { mHandler = new Handler(requireNonNull(Looper.getMainLooper())); mStateMachinesThread = new HandlerThread("CsipSetCoordinatorService.StateMachines"); mStateMachinesThread.start(); mStateMachinesLooper = mStateMachinesThread.getLooper(); } else { mHandler = new Handler(looper); mStateMachinesThread = null; mStateMachinesLooper = looper; } @Override public void start() { Log.d(TAG, "start()"); if (sCsipSetCoordinatorService != null) { throw new IllegalStateException("start() called twice"); } // Get AdapterService, DatabaseManager, CsipSetCoordinatorNativeInterface. // None of them can be null. mAdapterService = Objects.requireNonNull( AdapterService.getAdapterService(), "AdapterService cannot be null when CsipSetCoordinatorService starts"); mDatabaseManager = Objects.requireNonNull( mAdapterService.getDatabase(), "DatabaseManager cannot be null when CsipSetCoordinatorService starts"); mCsipSetCoordinatorNativeInterface = Objects.requireNonNull( CsipSetCoordinatorNativeInterface.getInstance(), "CsipSetCoordinatorNativeInterface cannot be null when" .concat("CsipSetCoordinatorService starts")); // Setup Handler. mHandler = new Handler(Looper.getMainLooper()); // Get LE Audio service (can be null) mLeAudioService = mServiceFactory.getLeAudioService(); synchronized (mStateMachines) { mStateMachines.clear(); } // Start handler thread for state machines mStateMachinesThread = new HandlerThread("CsipSetCoordinatorService.StateMachines"); mStateMachinesThread.start(); // Setup broadcast receivers IntentFilter filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); // Mark service as started setCsipSetCoordinatorService(this); // Initialize native interface mCsipSetCoordinatorNativeInterface.init(); mNativeInterface.init(); } public static boolean isEnabled() { return BluetoothProperties.isProfileCsipSetCoordinatorEnabled().orElse(false); } @Override protected IProfileServiceBinder initBinder() { return new BluetoothCsisBinder(this); } @Override Loading @@ -174,8 +159,7 @@ public class CsipSetCoordinatorService extends ProfileService { } // Cleanup native interface mCsipSetCoordinatorNativeInterface.cleanup(); mCsipSetCoordinatorNativeInterface = null; mNativeInterface.cleanup(); // Mark service as stopped setCsipSetCoordinatorService(null); Loading @@ -193,17 +177,13 @@ public class CsipSetCoordinatorService extends ProfileService { try { mStateMachinesThread.quitSafely(); mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS); mStateMachinesThread = null; } catch (InterruptedException e) { // Do not rethrow as we are shutting down anyway } } // Unregister Handler and stop all queued messages. if (mHandler != null) { mHandler.removeCallbacksAndMessages(null); mHandler = null; } mDeviceGroupIdRankMap.clear(); mCallbacks.clear(); Loading @@ -213,10 +193,6 @@ public class CsipSetCoordinatorService extends ProfileService { mGroupIdToUuidMap.clear(); mLocks.clear(); // Clear AdapterService, CsipSetCoordinatorNativeInterface mCsipSetCoordinatorNativeInterface = null; mAdapterService = null; } @Override Loading Loading @@ -515,7 +491,7 @@ public class CsipSetCoordinatorService extends ProfileService { } Log.d(TAG, "lockGroup(): locking group: " + groupId); mCsipSetCoordinatorNativeInterface.groupLockSet(groupId, true); mNativeInterface.groupLockSet(groupId, true); return uuid; } Loading @@ -536,7 +512,7 @@ public class CsipSetCoordinatorService extends ProfileService { Pair<UUID, IBluetoothCsipSetCoordinatorLockCallback> uuidCbPair = entry.getValue(); if (uuidCbPair.first.equals(lockUuid)) { Log.d(TAG, "unlockGroup(): unlocking ... " + lockUuid); mCsipSetCoordinatorNativeInterface.groupLockSet(entry.getKey(), false); mNativeInterface.groupLockSet(entry.getKey(), false); return; } } Loading Loading @@ -823,7 +799,7 @@ public class CsipSetCoordinatorService extends ProfileService { Intent intent = null; int groupId = stackEvent.valueInt1; if (stackEvent.type == CsipSetCoordinatorStackEvent.EVENT_TYPE_DEVICE_AVAILABLE) { Objects.requireNonNull(device); requireNonNull(device); intent = new Intent(BluetoothCsipSetCoordinator.ACTION_CSIS_DEVICE_AVAILABLE); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, stackEvent.device); Loading @@ -841,7 +817,7 @@ public class CsipSetCoordinatorService extends ProfileService { stackEvent.valueInt2); } else if (stackEvent.type == CsipSetCoordinatorStackEvent.EVENT_TYPE_SET_MEMBER_AVAILABLE) { Objects.requireNonNull(device); requireNonNull(device); if (!mFoundSetMemberToGroupId.containsKey(device)) { mFoundSetMemberToGroupId.put(device, groupId); } Loading Loading @@ -900,10 +876,7 @@ public class CsipSetCoordinatorService extends ProfileService { Log.d(TAG, "Creating a new state machine for " + device); sm = CsipSetCoordinatorStateMachine.make( device, this, mCsipSetCoordinatorNativeInterface, mStateMachinesThread.getLooper()); device, this, mNativeInterface, mStateMachinesLooper); mStateMachines.put(device, sm); return sm; } Loading @@ -911,16 +884,6 @@ public class CsipSetCoordinatorService extends ProfileService { /** Process a change in the bonding state for a device */ public void handleBondStateChanged(BluetoothDevice device, int fromState, int toState) { if (mHandler == null) { Log.e( TAG, "mHandler is null, service is stopped. Ignore Bond State for " + device + " to state: " + toState); return; } mHandler.post(() -> bondStateChanged(device, toState)); } Loading Loading @@ -982,15 +945,6 @@ public class CsipSetCoordinatorService extends ProfileService { } void handleConnectionStateChanged(BluetoothDevice device, int fromState, int toState) { if (mHandler == null) { Log.e( TAG, "mHandler is null, service is stopped. Ignore Connection State for " + device + " to state: " + toState); return; } mHandler.post(() -> connectionStateChanged(device, fromState, toState)); } Loading Loading @@ -1074,7 +1028,7 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public List<BluetoothDevice> getConnectedDevices(AttributionSource source) { Objects.requireNonNull(source, "source cannot be null"); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1087,7 +1041,7 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public List<BluetoothDevice> getDevicesMatchingConnectionStates( int[] states, AttributionSource source) { Objects.requireNonNull(source, "source cannot be null"); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1099,8 +1053,8 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public int getConnectionState(BluetoothDevice device, AttributionSource source) { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(device); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1113,8 +1067,8 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public boolean setConnectionPolicy( BluetoothDevice device, int connectionPolicy, AttributionSource source) { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(device); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1126,8 +1080,8 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public int getConnectionPolicy(BluetoothDevice device, AttributionSource source) { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(device); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1142,8 +1096,8 @@ public class CsipSetCoordinatorService extends ProfileService { int groupId, @NonNull IBluetoothCsipSetCoordinatorLockCallback callback, AttributionSource source) { Objects.requireNonNull(callback, "callback cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(callback); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1156,8 +1110,8 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public void unlockGroup(@NonNull ParcelUuid lockUuid, AttributionSource source) { Objects.requireNonNull(lockUuid, "lockUuid cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(lockUuid); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading @@ -1169,8 +1123,8 @@ public class CsipSetCoordinatorService extends ProfileService { @Override public List<Integer> getAllGroupIds(ParcelUuid uuid, AttributionSource source) { Objects.requireNonNull(uuid, "uuid cannot be null"); Objects.requireNonNull(source, "source cannot be null"); requireNonNull(uuid); requireNonNull(source); CsipSetCoordinatorService service = getService(source); if (service == null) { Loading
android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java +1 −4 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import com.android.bluetooth.a2dpsink.A2dpSinkNativeInterface; import com.android.bluetooth.avrcp.AvrcpNativeInterface; import com.android.bluetooth.avrcpcontroller.AvrcpControllerNativeInterface; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.csip.CsipSetCoordinatorNativeInterface; import com.android.bluetooth.hearingaid.HearingAidNativeInterface; import com.android.bluetooth.hfp.HeadsetNativeInterface; import com.android.bluetooth.hfpclient.NativeInterface; Loading Loading @@ -91,7 +90,6 @@ public class ProfileServiceTest { @Mock private HidDeviceNativeInterface mHidDeviceNativeInterface; @Mock private HidHostNativeInterface mHidHostNativeInterface; @Mock private PanNativeInterface mPanNativeInterface; @Mock private CsipSetCoordinatorNativeInterface mCsipSetCoordinatorInterface; @Mock private LeAudioNativeInterface mLeAudioInterface; private void setProfileState(int profile, int state) { Loading Loading @@ -156,6 +154,7 @@ public class ProfileServiceTest { profile -> profile != BluetoothProfile.HAP_CLIENT && profile != BluetoothProfile.VOLUME_CONTROL && profile != BluetoothProfile.CSIP_SET_COORDINATOR && profile != BluetoothProfile.GATT) .toArray(); TestUtils.setAdapterService(mAdapterService); Loading @@ -172,7 +171,6 @@ public class ProfileServiceTest { HidDeviceNativeInterface.setInstance(mHidDeviceNativeInterface); HidHostNativeInterface.setInstance(mHidHostNativeInterface); PanNativeInterface.setInstance(mPanNativeInterface); CsipSetCoordinatorNativeInterface.setInstance(mCsipSetCoordinatorInterface); LeAudioNativeInterface.setInstance(mLeAudioInterface); } Loading @@ -192,7 +190,6 @@ public class ProfileServiceTest { HidDeviceNativeInterface.setInstance(null); HidHostNativeInterface.setInstance(null); PanNativeInterface.setInstance(null); CsipSetCoordinatorNativeInterface.setInstance(null); LeAudioNativeInterface.setInstance(null); } Loading
android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java +237 −509 File changed.Preview size limit exceeded, changes collapsed. Show changes