Merge "Remove incorrect logging for BTM_SecBond" into main
diff --git a/android/app/src/com/android/bluetooth/ObexServerSockets.java b/android/app/src/com/android/bluetooth/ObexServerSockets.java
index efd361d..b898cc7 100644
--- a/android/app/src/com/android/bluetooth/ObexServerSockets.java
+++ b/android/app/src/com/android/bluetooth/ObexServerSockets.java
@@ -18,10 +18,12 @@
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
+import com.android.bluetooth.btservice.AdapterService;
import com.android.obex.ResponseCodes;
import com.android.obex.ServerSession;
@@ -35,7 +37,7 @@
* Use {@link #getRfcommChannel()} and {@link #getL2capPsm()} to get the channel numbers to put into
* the SDP record.<br>
* Call {@link #shutdown(boolean)} to terminate the accept threads created by the call to {@link
- * #create(IObexConnectionHandler)}.<br>
+ * #create(AdapterService, IObexConnectionHandler)}.<br>
* A reference to an object of this type cannot be reused, and the {@link BluetoothServerSocket}
* object references passed to this object will be closed by this object, hence cannot be reused
* either (This is needed, as the only way to interrupt an accept call is to close the socket...)
@@ -49,6 +51,7 @@
public class ObexServerSockets {
private static final String TAG = ObexServerSockets.class.getSimpleName();
+ private final BluetoothAdapter mAdapter;
private final IObexConnectionHandler mConHandler;
/* The wrapped sockets */
private final BluetoothServerSocket mRfcommSocket;
@@ -58,9 +61,11 @@
private SocketAcceptThread mL2capThread;
private ObexServerSockets(
+ BluetoothAdapter adapter,
IObexConnectionHandler conHandler,
BluetoothServerSocket rfcommSocket,
BluetoothServerSocket l2capSocket) {
+ mAdapter = adapter;
mConHandler = conHandler;
mRfcommSocket = rfcommSocket;
mL2capSocket = l2capSocket;
@@ -73,8 +78,10 @@
* an incoming connection.
* @return a reference to a {@link ObexServerSockets} object instance.
*/
- public static ObexServerSockets create(IObexConnectionHandler validator) {
+ public static ObexServerSockets create(
+ AdapterService adapterService, IObexConnectionHandler validator) {
return create(
+ adapterService,
validator,
BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP,
BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP,
@@ -89,8 +96,10 @@
* an incoming connection.
* @return a reference to a {@link ObexServerSockets} object instance.
*/
- public static ObexServerSockets createInsecure(IObexConnectionHandler validator) {
+ public static ObexServerSockets createInsecure(
+ AdapterService adapterService, IObexConnectionHandler validator) {
return create(
+ adapterService,
validator,
BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP,
BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP,
@@ -114,32 +123,35 @@
*/
@SuppressLint("AndroidFrameworkRequiresPermission") // TODO: b/350563786
private static ObexServerSockets create(
- IObexConnectionHandler validator, int rfcommChannel, int l2capPsm, boolean isSecure) {
+ AdapterService adapterService,
+ IObexConnectionHandler validator,
+ int rfcommChannel,
+ int l2capPsm,
+ boolean isSecure) {
Log.d(TAG, "create(rfcomm = " + rfcommChannel + ", l2capPsm = " + l2capPsm + ")");
- BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
- if (bt == null) {
- throw new RuntimeException("No bluetooth adapter...");
- }
+
BluetoothServerSocket rfcommSocket = null;
BluetoothServerSocket l2capSocket = null;
boolean initSocketOK = false;
+ final var adapter = adapterService.getSystemService(BluetoothManager.class).getAdapter();
+
// It's possible that create will fail in some cases. retry for 10 times
for (int i = 0; i < CREATE_RETRY_TIME; i++) {
initSocketOK = true;
try {
if (rfcommSocket == null) {
if (isSecure) {
- rfcommSocket = bt.listenUsingRfcommOn(rfcommChannel);
+ rfcommSocket = adapter.listenUsingRfcommOn(rfcommChannel);
} else {
- rfcommSocket = bt.listenUsingInsecureRfcommOn(rfcommChannel);
+ rfcommSocket = adapter.listenUsingInsecureRfcommOn(rfcommChannel);
}
}
if (l2capSocket == null) {
if (isSecure) {
- l2capSocket = bt.listenUsingL2capOn(l2capPsm);
+ l2capSocket = adapter.listenUsingL2capOn(l2capPsm);
} else {
- l2capSocket = bt.listenUsingInsecureL2capOn(l2capPsm);
+ l2capSocket = adapter.listenUsingInsecureL2capOn(l2capPsm);
}
}
} catch (IOException e) {
@@ -152,7 +164,7 @@
}
if (!initSocketOK) {
// Need to break out of this loop if BT is being turned off.
- int state = bt.getState();
+ int state = adapter.getState();
if ((state != BluetoothAdapter.STATE_TURNING_ON)
&& (state != BluetoothAdapter.STATE_ON)) {
Log.w(TAG, "initServerSockets failed as BT is (being) turned off");
@@ -171,7 +183,8 @@
if (initSocketOK) {
Log.d(TAG, "Succeed to create listening sockets ");
- ObexServerSockets sockets = new ObexServerSockets(validator, rfcommSocket, l2capSocket);
+ final ObexServerSockets sockets =
+ new ObexServerSockets(adapter, validator, rfcommSocket, l2capSocket);
sockets.startAccept();
return sockets;
} else {
@@ -230,8 +243,7 @@
/** Signal to the {@link IObexConnectionHandler} that an error have occurred. */
private synchronized void onAcceptFailed() {
shutdown(false);
- BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
- if ((mAdapter != null) && (mAdapter.getState() == BluetoothAdapter.STATE_ON)) {
+ if (mAdapter.getState() == BluetoothAdapter.STATE_ON) {
Log.d(TAG, "onAcceptFailed() calling shutdown...");
mConHandler.onAcceptFailed();
}
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
index 92c6709..8ce3384 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -81,7 +81,6 @@
private final A2dpNativeInterface mNativeInterface;
private final A2dpCodecConfig mA2dpCodecConfig;
- private final AdapterService mAdapterService;
private final AudioManager mAudioManager;
private final DatabaseManager mDatabaseManager;
private final CompanionDeviceManager mCompanionDeviceManager;
@@ -117,7 +116,6 @@
@VisibleForTesting
A2dpService(AdapterService adapterService, A2dpNativeInterface nativeInterface, Looper looper) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mNativeInterface =
requireNonNullElseGet(
nativeInterface,
@@ -126,9 +124,8 @@
adapterService,
new A2dpNativeCallback(adapterService, this)));
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
- mAudioManager = requireNonNull(mAdapterService.getSystemService(AudioManager.class));
- mCompanionDeviceManager =
- requireNonNull(mAdapterService.getSystemService(CompanionDeviceManager.class));
+ mAudioManager = requireNonNull(obtainSystemService(AudioManager.class));
+ mCompanionDeviceManager = requireNonNull(obtainSystemService(CompanionDeviceManager.class));
mLooper = requireNonNull(looper);
mHandler = new Handler(mLooper);
diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
index 037d85e..b02f5d2 100644
--- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
+++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
@@ -57,7 +57,6 @@
private final Object mActiveDeviceLock = new Object();
private final Object mStreamHandlerLock = new Object();
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final A2dpSinkNativeInterface mNativeInterface;
private final Looper mLooper;
@@ -80,7 +79,6 @@
A2dpSinkService(
AdapterService adapterService, A2dpSinkNativeInterface nativeInterface, Looper looper) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mNativeInterface = requireNonNull(nativeInterface);
mLooper = looper;
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
index 7f8823e..e739cc8 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
@@ -24,6 +24,7 @@
import com.android.bluetooth.IObexConnectionHandler;
import com.android.bluetooth.ObexServerSockets;
import com.android.bluetooth.audio_util.Image;
+import com.android.bluetooth.btservice.AdapterService;
import com.android.obex.ServerSession;
import java.io.IOException;
@@ -47,6 +48,7 @@
*/
private static final int MAX_TRANSMIT_PACKET_SIZE = 1024;
+ private final AdapterService mAdapterService;
// Cover Art and Image Handle objects
private final AvrcpCoverArtStorage mStorage;
@@ -63,7 +65,9 @@
private final AvrcpNativeInterface mNativeInterface;
// The native interface must be a parameter here in order to be able to mock AvrcpTargetService
- public AvrcpCoverArtService(AvrcpNativeInterface nativeInterface) {
+ public AvrcpCoverArtService(
+ AdapterService adapterService, AvrcpNativeInterface nativeInterface) {
+ mAdapterService = adapterService;
mNativeInterface = nativeInterface;
mAcceptThread = new SocketAcceptor();
mStorage = new AvrcpCoverArtStorage(COVER_ART_STORAGE_MAX_ITEMS);
@@ -106,7 +110,7 @@
private boolean startBipServer() {
debug("Starting BIP OBEX server");
synchronized (mServerLock) {
- mServerSockets = ObexServerSockets.create(mAcceptThread);
+ mServerSockets = ObexServerSockets.create(mAdapterService, mAcceptThread);
if (mServerSockets == null) {
error("Failed to get a server socket. Can't setup cover art service");
return false;
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
index 822a64c..a5eab30 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
@@ -19,6 +19,7 @@
import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
import static java.util.Objects.requireNonNull;
+import static java.util.Objects.requireNonNullElseGet;
import android.annotation.NonNull;
import android.bluetooth.BluetoothDevice;
@@ -102,11 +103,10 @@
public AvrcpTargetService(AdapterService adapterService) {
this(
requireNonNull(adapterService),
- adapterService.getSystemService(AudioManager.class),
+ null,
AvrcpNativeInterface.getInstance(adapterService),
new AvrcpVolumeManager(
requireNonNull(adapterService),
- adapterService.getSystemService(AudioManager.class),
AvrcpNativeInterface.getInstance(adapterService)),
Looper.myLooper());
}
@@ -119,7 +119,8 @@
AvrcpVolumeManager volumeManager,
Looper looper) {
super(requireNonNull(adapterService));
- mAudioManager = requireNonNull(audioManager);
+ mAudioManager =
+ requireNonNullElseGet(audioManager, () -> obtainSystemService(AudioManager.class));
mNativeInterface = requireNonNull(nativeInterface);
mMediaPlayerList = new MediaPlayerList(adapterService, looper);
@@ -138,7 +139,7 @@
mAvrcpVersion = AvrcpVersion.getCurrentSystemPropertiesValue();
mVolumeManager = requireNonNull(volumeManager);
- UserManager userManager = getApplicationContext().getSystemService(UserManager.class);
+ UserManager userManager = obtainSystemService(UserManager.class);
if (userManager.isUserUnlocked()) {
mMediaPlayerList.init(new ListCallback());
}
@@ -147,7 +148,8 @@
Log.e(TAG, "Please use AVRCP version 1.6 to enable cover art");
mAvrcpCoverArtService = null;
} else {
- AvrcpCoverArtService coverArtService = new AvrcpCoverArtService(mNativeInterface);
+ AvrcpCoverArtService coverArtService =
+ new AvrcpCoverArtService(adapterService, mNativeInterface);
if (coverArtService.start()) {
mAvrcpCoverArtService = coverArtService;
} else {
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
index 5daa0fd..3cd588e 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
@@ -173,12 +173,9 @@
* <p>Fills {@code mVolumeMap} with content from {@link #getVolumeMap}, removing unbonded
* devices if necessary.
*/
- AvrcpVolumeManager(
- AdapterService adapterService,
- AudioManager audioManager,
- AvrcpNativeInterface nativeInterface) {
+ AvrcpVolumeManager(AdapterService adapterService, AvrcpNativeInterface nativeInterface) {
mAdapterService = adapterService;
- mAudioManager = audioManager;
+ mAudioManager = mAdapterService.getSystemService(AudioManager.class);
mNativeInterface = nativeInterface;
mDeviceMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
mSafeMediaVolume = getSafeMediaVolume(adapterService, mDeviceMaxVolume);
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
index 5a77073..6e95905 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
@@ -97,7 +97,6 @@
private final Object mActiveDeviceLock = new Object();
- private final AdapterService mAdapterService;
private final AvrcpControllerNativeInterface mNativeInterface;
private final AvrcpCoverArtManager mCoverArtManager;
private final boolean mCoverArtEnabled;
@@ -141,7 +140,6 @@
public AvrcpControllerService(
AdapterService adapterService, AvrcpControllerNativeInterface nativeInterface) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mNativeInterface = requireNonNull(nativeInterface);
mNativeInterface.init(this);
diff --git a/android/app/src/com/android/bluetooth/bas/BatteryService.java b/android/app/src/com/android/bluetooth/bas/BatteryService.java
index af31814..3162ace 100644
--- a/android/app/src/com/android/bluetooth/bas/BatteryService.java
+++ b/android/app/src/com/android/bluetooth/bas/BatteryService.java
@@ -55,7 +55,6 @@
private static BatteryService sBatteryService;
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final HandlerThread mStateMachinesThread;
private final Looper mStateMachinesLooper;
@@ -71,7 +70,6 @@
@VisibleForTesting
BatteryService(AdapterService adapterService, Looper looper) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mHandler = new Handler(requireNonNull(looper));
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
index aabd2b0..103d604 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
@@ -174,7 +174,6 @@
new ConcurrentHashMap<>();
private final BassScanCallbackWrapper mBassScanCallback = new BassScanCallbackWrapper();
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final BluetoothAdapter mAdapter;
private final PeriodicAdvertisingManager mPeriodicAdvertisingManager;
@@ -480,9 +479,8 @@
public BassClientService(AdapterService adapterService) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
- mAdapter = mAdapterService.getSystemService(BluetoothManager.class).getAdapter();
+ mAdapter = obtainSystemService(BluetoothManager.class).getAdapter();
mPeriodicAdvertisingManager = mAdapter.getPeriodicAdvertisingManager();
mHandler = new Handler(requireNonNull(Looper.getMainLooper()));
mStateMachinesThread = new HandlerThread("BassClientService.StateMachines");
diff --git a/android/app/src/com/android/bluetooth/btservice/ProfileService.java b/android/app/src/com/android/bluetooth/btservice/ProfileService.java
index e8ea20d..d6acf61 100644
--- a/android/app/src/com/android/bluetooth/btservice/ProfileService.java
+++ b/android/app/src/com/android/bluetooth/btservice/ProfileService.java
@@ -18,7 +18,6 @@
import android.annotation.SuppressLint;
import android.content.ComponentName;
-import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
import android.os.IBinder;
@@ -33,6 +32,7 @@
void cleanup();
}
+ protected final AdapterService mAdapterService;
private final IProfileServiceBinder mBinder;
private final String mName;
private boolean mAvailable = false;
@@ -71,8 +71,9 @@
mTestModeEnabled = testModeEnabled;
}
- protected ProfileService(Context ctx) {
- super(ctx);
+ protected ProfileService(AdapterService adapterService) {
+ super(adapterService);
+ mAdapterService = adapterService;
mName = getName();
Log.d(mName, "Service created");
mBinder = initBinder();
@@ -132,6 +133,10 @@
PackageManager.DONT_KILL_APP | PackageManager.SYNCHRONOUS);
}
+ protected <T> T obtainSystemService(Class<T> serviceClass) {
+ return mAdapterService.getSystemService(serviceClass);
+ }
+
/**
* Support dumping profile-specific information for dumpsys
*
diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
index be2601b..61fc656 100644
--- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
+++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
@@ -78,7 +78,6 @@
private static CsipSetCoordinatorService sCsipSetCoordinatorService;
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final Handler mHandler;
private final HandlerThread mStateMachinesThread;
@@ -116,7 +115,6 @@
CsipSetCoordinatorNativeInterface nativeInterface,
ServiceFactory serviceFactory) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mNativeInterface =
requireNonNullElseGet(
diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java
index ea97c19..f092b96 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattService.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattService.java
@@ -158,7 +158,6 @@
*/
private final HashMap<BluetoothDevice, Integer> mPermits = new HashMap<>();
- private final AdapterService mAdapterService;
private final ActivityManager mActivityManager;
private final PackageManager mPackageManager;
private final CompanionDeviceManager mCompanionDeviceManager;
@@ -170,11 +169,9 @@
public GattService(AdapterService adapterService) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
- mActivityManager = requireNonNull(mAdapterService.getSystemService(ActivityManager.class));
+ mActivityManager = requireNonNull(obtainSystemService(ActivityManager.class));
mPackageManager = requireNonNull(mAdapterService.getPackageManager());
- mCompanionDeviceManager =
- requireNonNull(mAdapterService.getSystemService(CompanionDeviceManager.class));
+ mCompanionDeviceManager = requireNonNull(obtainSystemService(CompanionDeviceManager.class));
Settings.Global.putInt(
getContentResolver(), "bluetooth_sanitized_exposure_notification_supported", 1);
diff --git a/android/app/src/com/android/bluetooth/hap/HapClientService.java b/android/app/src/com/android/bluetooth/hap/HapClientService.java
index ef9a778..662783b 100644
--- a/android/app/src/com/android/bluetooth/hap/HapClientService.java
+++ b/android/app/src/com/android/bluetooth/hap/HapClientService.java
@@ -79,7 +79,6 @@
private final Map<BluetoothDevice, Integer> mDeviceCurrentPresetMap = new HashMap<>();
private final Map<BluetoothDevice, Integer> mDeviceFeaturesMap = new HashMap<>();
private final Map<BluetoothDevice, List<BluetoothHapPresetInfo>> mPresetsMap = new HashMap<>();
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final Handler mHandler;
private final Looper mStateMachinesLooper;
@@ -130,7 +129,6 @@
Looper looper,
HapClientNativeInterface nativeInterface) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mNativeInterface =
requireNonNullElseGet(
nativeInterface,
diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
index b3126c9..f998ace 100644
--- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
+++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
@@ -68,7 +68,6 @@
private static HearingAidService sHearingAidService;
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final HearingAidNativeInterface mNativeInterface;
private final AudioManager mAudioManager;
@@ -99,7 +98,6 @@
Looper looper,
HearingAidNativeInterface nativeInterface) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
if (looper == null) {
mHandler = new Handler(requireNonNull(Looper.getMainLooper()));
@@ -112,7 +110,7 @@
mStateMachinesLooper = looper;
}
mNativeInterface = requireNonNull(nativeInterface);
- mAudioManager = requireNonNull(mAdapterService.getSystemService(AudioManager.class));
+ mAudioManager = requireNonNull(obtainSystemService(AudioManager.class));
setHearingAidService(this);
mNativeInterface.init();
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
index afcb7ee..37416a0 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -125,7 +125,6 @@
// Timeout for state machine thread join, to prevent potential ANR.
private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final HeadsetNativeInterface mNativeInterface;
private final HashMap<BluetoothDevice, HeadsetStateMachine> mStateMachines = new HashMap<>();
@@ -176,7 +175,6 @@
HeadsetService(
AdapterService adapterService, HeadsetNativeInterface nativeInterface, Looper looper) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mNativeInterface = requireNonNull(nativeInterface);
if (looper != null) {
diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
index 382c1f0..af88e4b 100644
--- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
+++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
@@ -79,7 +79,6 @@
new HashMap<>();
private final HandlerThread mSmThread;
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final AudioManager mAudioManager;
private final HeadsetClientNativeInterface mNativeInterface;
@@ -91,9 +90,8 @@
public HeadsetClientService(AdapterService adapterService) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(adapterService.getDatabase());
- mAudioManager = requireNonNull(mAdapterService.getSystemService(AudioManager.class));
+ mAudioManager = requireNonNull(obtainSystemService(AudioManager.class));
mMaxAmVcVol = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
mMinAmVcVol = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL);
@@ -101,7 +99,7 @@
mNativeInterface = HeadsetClientNativeInterface.getInstance(mAdapterService);
mNativeInterface.initialize();
- mBatteryManager = mAdapterService.getSystemService(BatteryManager.class);
+ mBatteryManager = obtainSystemService(BatteryManager.class);
// start AudioManager in a known state
mAudioManager.setHfpEnabled(false);
diff --git a/android/app/src/com/android/bluetooth/hid/HidDeviceService.java b/android/app/src/com/android/bluetooth/hid/HidDeviceService.java
index 8137b2b..5934155 100644
--- a/android/app/src/com/android/bluetooth/hid/HidDeviceService.java
+++ b/android/app/src/com/android/bluetooth/hid/HidDeviceService.java
@@ -75,7 +75,6 @@
private static HidDeviceService sHidDeviceService;
private final HidDeviceServiceHandler mHandler;
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final ActivityManager mActivityManager;
private final HidDeviceNativeInterface mHidDeviceNativeInterface;
@@ -96,7 +95,6 @@
Looper looper,
HidDeviceNativeInterface nativeInterface) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mHandler = new HidDeviceServiceHandler(requireNonNull(looper));
@@ -104,7 +102,7 @@
requireNonNullElseGet(
nativeInterface, () -> new HidDeviceNativeInterface(adapterService));
mHidDeviceNativeInterface.init();
- mActivityManager = requireNonNull(mAdapterService.getSystemService(ActivityManager.class));
+ mActivityManager = requireNonNull(obtainSystemService(ActivityManager.class));
mActivityManager.addOnUidImportanceListener(
mUidImportanceListener, FOREGROUND_IMPORTANCE_CUTOFF);
setHidDeviceService(this);
diff --git a/android/app/src/com/android/bluetooth/hid/HidHostService.java b/android/app/src/com/android/bluetooth/hid/HidHostService.java
index 7cf235e..c4f80af 100644
--- a/android/app/src/com/android/bluetooth/hid/HidHostService.java
+++ b/android/app/src/com/android/bluetooth/hid/HidHostService.java
@@ -100,7 +100,6 @@
private final Map<BluetoothDevice, InputDevice> mInputDevices =
Collections.synchronizedMap(new HashMap<>());
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final HidHostNativeInterface mNativeInterface;
@@ -126,11 +125,8 @@
public HidHostService(AdapterService adapterService) {
super(requireNonNull(adapterService));
-
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mNativeInterface = requireNonNull(HidHostNativeInterface.getInstance());
-
mNativeInterface.init(this);
setHidHostService(this);
}
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
index c432e51..4fd3e93 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -175,7 +175,6 @@
private final ArrayDeque<BluetoothLeBroadcastSettings> mCreateBroadcastQueue =
new ArrayDeque<>();
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final LeAudioNativeInterface mNativeInterface;
private final HandlerThread mStateMachinesThread;
@@ -253,9 +252,8 @@
LeAudioService(AdapterService adapterService, LeAudioNativeInterface nativeInterface) {
super(requireNonNull(adapterService));
mNativeInterface = requireNonNull(nativeInterface);
- mAdapterService = requireNonNull(adapterService);
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
- mAudioManager = requireNonNull(mAdapterService.getSystemService(AudioManager.class));
+ mAudioManager = requireNonNull(obtainSystemService(AudioManager.class));
// Start handler thread for state machines
mStateMachinesThread = new HandlerThread("LeAudioService.StateMachines");
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java b/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java
index 3119036..9776172 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java
@@ -32,6 +32,7 @@
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.IObexConnectionHandler;
import com.android.bluetooth.ObexServerSockets;
+import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils;
import com.android.bluetooth.map.BluetoothMapContentObserver.Msg;
import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
@@ -69,6 +70,7 @@
static final int SDP_MAP_MAS_FEATURES_1_3 = 0x000603FF;
static final int SDP_MAP_MAS_FEATURES_1_4 = 0x000603FF;
+ private final AdapterService mAdapterService;
private final BluetoothAdapter mAdapter;
private ServerSession mServerSession = null;
@@ -84,7 +86,6 @@
private Handler mServiceHandler = null; // MAP service message handler
private BluetoothMapService mMapService = null; // Handle to the outer MAP service
- private Context mContext = null; // MAP service context
private BluetoothMnsObexClient mMnsClient = null; // Shared MAP MNS client
private BluetoothMapAccountItem mAccount = null; //
private String mBaseUri = null; // Client base URI for this instance
@@ -114,15 +115,16 @@
/** Create a e-mail MAS instance */
BluetoothMapMasInstance(
+ AdapterService adapterService,
BluetoothMapService mapService,
BluetoothMapAccountItem account,
int masId,
boolean enableSmsMms) {
+ mAdapterService = adapterService;
mObjectInstanceId = sInstanceCounter++;
mMapService = mapService;
mServiceHandler = mapService.getHandler();
- mContext = mapService;
- mAdapter = mContext.getSystemService(BluetoothManager.class).getAdapter();
+ mAdapter = mAdapterService.getSystemService(BluetoothManager.class).getAdapter();
mAccount = account;
if (account != null) {
mBaseUri = account.mBase_uri;
@@ -276,8 +278,7 @@
if (mServerSockets != null) {
mAcceptNewConnections = true;
} else {
-
- mServerSockets = ObexServerSockets.create(this);
+ mServerSockets = ObexServerSockets.create(mAdapterService, this);
mAcceptNewConnections = true;
if (mServerSockets == null) {
@@ -387,11 +388,16 @@
mMnsClient = mnsClient;
mObserver =
new BluetoothMapContentObserver(
- mContext, mMnsClient, this, mAccount, mEnableSmsMms);
+ mAdapterService, mMnsClient, this, mAccount, mEnableSmsMms);
mObserver.init();
mMapServer =
new BluetoothMapObexServer(
- mServiceHandler, mContext, mObserver, this, mAccount, mEnableSmsMms);
+ mAdapterService,
+ mServiceHandler,
+ mObserver,
+ this,
+ mAccount,
+ mEnableSmsMms);
mMapServer.setRemoteFeatureMask(mRemoteFeatureMask);
// setup transport
BluetoothObexTransport transport = new BluetoothObexTransport(mConnSocket);
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java b/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java
index 5257e07..59328da 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java
@@ -103,10 +103,11 @@
private static final int MAS_INSTANCE_INFORMATION_LENGTH = 200;
+ private final Context mContext;
+
private BluetoothMapFolderElement mCurrentFolder;
private BluetoothMapContentObserver mObserver = null;
private Handler mCallback = null;
- private final Context mContext;
private boolean mIsAborted = false;
BluetoothMapContent mOutContent;
private String mBaseUriString = null;
@@ -126,16 +127,16 @@
private ContentProviderClient mProviderClient = null;
public BluetoothMapObexServer(
- Handler callback,
Context context,
+ Handler callback,
BluetoothMapContentObserver observer,
BluetoothMapMasInstance mas,
BluetoothMapAccountItem account,
boolean enableSmsMms)
throws RemoteException {
super();
- mCallback = callback;
mContext = context;
+ mCallback = callback;
mObserver = observer;
mEnableSmsMms = enableSmsMms;
mAccount = account;
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java
index 46537c8..7128ec3 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java
@@ -113,7 +113,6 @@
private final MapBroadcastReceiver mMapReceiver = new MapBroadcastReceiver();
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final Handler mSessionStatusHandler;
private final BluetoothMapAppObserver mAppObserver;
@@ -157,7 +156,6 @@
super(requireNonNull(adapterService));
BluetoothMap.invalidateBluetoothGetConnectionStateCache();
- mAdapterService = requireNonNull(adapterService);
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
setComponentAvailable(MAP_FILE_PROVIDER, true);
@@ -190,10 +188,8 @@
registerReceiver(mMapReceiver, filterMessageSent);
mAppObserver = new BluetoothMapAppObserver(this, this);
- mSmsCapable =
- requireNonNull(mAdapterService.getSystemService(TelephonyManager.class))
- .isSmsCapable();
- mAlarmManager = requireNonNull(mAdapterService.getSystemService(AlarmManager.class));
+ mSmsCapable = requireNonNull(obtainSystemService(TelephonyManager.class)).isSmsCapable();
+ mAlarmManager = requireNonNull(obtainSystemService(AlarmManager.class));
mEnabledAccounts = mAppObserver.getEnabledAccountItems();
createMasInstances(); // Uses mEnabledAccounts
@@ -265,7 +261,7 @@
// Acquire the wakeLock before starting Obex transaction thread
if (mWakeLock == null) {
- PowerManager pm = mAdapterService.getSystemService(PowerManager.class);
+ PowerManager pm = obtainSystemService(PowerManager.class);
mWakeLock =
pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "StartingObexMapTransaction");
mWakeLock.setReferenceCounted(false);
@@ -444,7 +440,7 @@
case MSG_ACQUIRE_WAKE_LOCK:
Log.v(TAG, "Acquire Wake Lock request message");
if (mWakeLock == null) {
- PowerManager pm = mAdapterService.getSystemService(PowerManager.class);
+ PowerManager pm = obtainSystemService(PowerManager.class);
mWakeLock =
pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
@@ -787,7 +783,7 @@
Log.v(TAG, " Adding account: " + account);
int masId = getNextMasId();
BluetoothMapMasInstance newInst =
- new BluetoothMapMasInstance(this, account, masId, false);
+ new BluetoothMapMasInstance(mAdapterService, this, account, masId, false);
mMasInstances.append(masId, newInst);
mMasInstanceMap.put(account, newInst);
// Start the new instance
@@ -849,7 +845,7 @@
if (mSmsCapable) {
// Add the SMS/MMS instance
BluetoothMapMasInstance smsMmsInst =
- new BluetoothMapMasInstance(this, null, masId, true);
+ new BluetoothMapMasInstance(mAdapterService, this, null, masId, true);
mMasInstances.append(masId, smsMmsInst);
mMasInstanceMap.put(null, smsMmsInst);
masId++;
@@ -858,7 +854,7 @@
// get list of accounts already set to be visible through MAP
for (BluetoothMapAccountItem account : mEnabledAccounts) {
BluetoothMapMasInstance newInst =
- new BluetoothMapMasInstance(this, account, masId, false);
+ new BluetoothMapMasInstance(mAdapterService, this, account, masId, false);
mMasInstances.append(masId, newInst);
mMasInstanceMap.put(account, newInst);
masId++;
@@ -974,7 +970,7 @@
PendingIntent.getBroadcast(this, 0, timeoutIntent, PendingIntent.FLAG_IMMUTABLE);
pIntent.cancel();
- AlarmManager alarmManager = this.getSystemService(AlarmManager.class);
+ AlarmManager alarmManager = obtainSystemService(AlarmManager.class);
alarmManager.cancel(pIntent);
mRemoveTimeoutMsg = false;
}
diff --git a/android/app/src/com/android/bluetooth/mapclient/MapClientService.java b/android/app/src/com/android/bluetooth/mapclient/MapClientService.java
index 6a5c27b..92352dd 100644
--- a/android/app/src/com/android/bluetooth/mapclient/MapClientService.java
+++ b/android/app/src/com/android/bluetooth/mapclient/MapClientService.java
@@ -59,7 +59,6 @@
private final Map<BluetoothDevice, MceStateMachine> mMapInstanceMap =
new ConcurrentHashMap<>(1);
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final MnsService mMnsServer;
private final Looper mStateMachinesLooper;
@@ -74,9 +73,8 @@
@VisibleForTesting
MapClientService(AdapterService adapterService, Looper looper, MnsService mnsServer) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(adapterService.getDatabase());
- mMnsServer = requireNonNullElseGet(mnsServer, () -> new MnsService(this));
+ mMnsServer = requireNonNullElseGet(mnsServer, () -> new MnsService(mAdapterService, this));
if (looper == null) {
mHandler = new Handler(requireNonNull(Looper.getMainLooper()));
diff --git a/android/app/src/com/android/bluetooth/mapclient/MnsService.java b/android/app/src/com/android/bluetooth/mapclient/MnsService.java
index 1b5b945..501c48f 100644
--- a/android/app/src/com/android/bluetooth/mapclient/MnsService.java
+++ b/android/app/src/com/android/bluetooth/mapclient/MnsService.java
@@ -26,6 +26,7 @@
import com.android.bluetooth.IObexConnectionHandler;
import com.android.bluetooth.ObexServerSockets;
import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.sdp.SdpManagerNativeInterface;
import com.android.obex.ServerSession;
@@ -39,6 +40,7 @@
private static final int MNS_VERSION = 0x0104; // MAP version 1.4
private final SocketAcceptor mAcceptThread = new SocketAcceptor();
+
private final MapClientService mMapClientService;
private ObexServerSockets mServerSockets;
@@ -46,10 +48,10 @@
private volatile boolean mShutdown = false; // Used to interrupt socket accept thread
private int mSdpHandle = -1;
- MnsService(MapClientService service) {
+ MnsService(AdapterService adapterService, MapClientService service) {
Log.v(TAG, "MnsService()");
mMapClientService = service;
- mServerSockets = ObexServerSockets.create(mAcceptThread);
+ mServerSockets = ObexServerSockets.create(adapterService, mAcceptThread);
SdpManagerNativeInterface nativeInterface = SdpManagerNativeInterface.getInstance();
if (!nativeInterface.isAvailable()) {
Log.e(TAG, "SdpManagerNativeInterface is not available");
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java
index f9e1794..af98415 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java
@@ -169,8 +169,6 @@
boolean mAcceptNewConnections;
- private final AdapterService mAdapterService;
-
private static final String INVISIBLE =
BluetoothShare.VISIBILITY + "=" + BluetoothShare.VISIBILITY_HIDDEN;
@@ -223,8 +221,6 @@
BluetoothOppService(AdapterService adapterService, BluetoothOppPreference oppPreference) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
-
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
registerReceiver(mBluetoothReceiver, filter);
@@ -504,7 +500,7 @@
private void startSocketListener() {
Log.d(TAG, "start Socket Listeners");
stopListeners();
- mServerSocket = ObexServerSockets.createInsecure(this);
+ mServerSocket = ObexServerSockets.createInsecure(mAdapterService, this);
acceptNewConnections();
SdpManagerNativeInterface nativeInterface = SdpManagerNativeInterface.getInstance();
if (!nativeInterface.isAvailable()) {
diff --git a/android/app/src/com/android/bluetooth/pan/PanService.java b/android/app/src/com/android/bluetooth/pan/PanService.java
index 5100110..4a1ba0f 100644
--- a/android/app/src/com/android/bluetooth/pan/PanService.java
+++ b/android/app/src/com/android/bluetooth/pan/PanService.java
@@ -76,7 +76,6 @@
new ConcurrentHashMap<>();
private final Map<String, IBluetoothPanCallback> mBluetoothTetheringCallbacks = new HashMap<>();
- private final AdapterService mAdapterService;
private final PanNativeInterface mNativeInterface;
private final DatabaseManager mDatabaseManager;
private final TetheringManager mTetheringManager;
@@ -113,13 +112,11 @@
@VisibleForTesting
PanService(AdapterService adapterService, PanNativeInterface nativeInterface, Looper looper) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mNativeInterface =
requireNonNullElseGet(nativeInterface, () -> new PanNativeInterface(this));
- mUserManager = requireNonNull(mAdapterService.getSystemService(UserManager.class));
- mTetheringManager =
- requireNonNull(mAdapterService.getSystemService(TetheringManager.class));
+ mUserManager = requireNonNull(obtainSystemService(UserManager.class));
+ mTetheringManager = requireNonNull(obtainSystemService(TetheringManager.class));
mHandler = new PanServiceHandler(looper);
int maxPanDevice;
@@ -302,7 +299,7 @@
IBluetoothPanCallback callback, int id, int callerUid, boolean value) {
Log.d(TAG, "setBluetoothTethering: " + value + ", mTetherOn: " + mTetherOn);
- UserManager um = mAdapterService.getSystemService(UserManager.class);
+ UserManager um = obtainSystemService(UserManager.class);
if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING) && value) {
throw new SecurityException("DISALLOW_CONFIG_TETHERING is enabled for this user.");
}
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java
index a8a4c72..bdcfcc7 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java
@@ -26,6 +26,7 @@
import static com.android.bluetooth.Utils.joinUninterruptibly;
import static java.util.Objects.requireNonNull;
+import static java.util.Objects.requireNonNullElseGet;
import android.app.Activity;
import android.app.Notification;
@@ -150,7 +151,6 @@
private final BluetoothPbapContentObserver mContactChangeObserver =
new BluetoothPbapContentObserver();
- private final AdapterService mAdapterService;
private final DatabaseManager mDatabaseManager;
private final NotificationManager mNotificationManager;
private final PbapHandler mSessionStatusHandler;
@@ -173,17 +173,16 @@
private static BluetoothPbapService sBluetoothPbapService;
public BluetoothPbapService(AdapterService adapterService) {
- this(
- requireNonNull(adapterService),
- adapterService.getSystemService(NotificationManager.class));
+ this(requireNonNull(adapterService), null);
}
@VisibleForTesting
BluetoothPbapService(AdapterService adapterService, NotificationManager notificationManager) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
- mNotificationManager = requireNonNull(notificationManager);
+ mNotificationManager =
+ requireNonNullElseGet(
+ notificationManager, () -> obtainSystemService(NotificationManager.class));
IntentFilter userFilter = new IntentFilter();
userFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
@@ -360,7 +359,7 @@
return;
}
Log.d(TAG, "Got " + action + " to userId " + userId);
- UserManager userManager = mAdapterService.getSystemService(UserManager.class);
+ UserManager userManager = obtainSystemService(UserManager.class);
if (userManager.isUserUnlocked(UserHandle.of(userId))) {
sendUpdateRequest();
}
@@ -517,7 +516,8 @@
switch (msg.what) {
case START_LISTENER:
- mServerSockets = ObexServerSockets.create(BluetoothPbapService.this);
+ mServerSockets =
+ ObexServerSockets.create(mAdapterService, BluetoothPbapService.this);
if (mServerSockets == null) {
Log.w(TAG, "ObexServerSockets.create() returned null");
ContentProfileErrorReportUtils.report(
@@ -549,7 +549,7 @@
break;
case MSG_ACQUIRE_WAKE_LOCK:
if (mWakeLock == null) {
- PowerManager pm = mAdapterService.getSystemService(PowerManager.class);
+ PowerManager pm = obtainSystemService(PowerManager.class);
mWakeLock =
pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
@@ -913,7 +913,7 @@
}
private void getLocalTelephonyDetails() {
- TelephonyManager tm = mAdapterService.getSystemService(TelephonyManager.class);
+ TelephonyManager tm = obtainSystemService(TelephonyManager.class);
if (tm != null) {
sLocalPhoneNum = tm.getLine1Number();
sLocalPhoneName = this.getString(R.string.localPhoneName);
diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java
index 1e0f5b0..4405965 100644
--- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java
+++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java
@@ -70,7 +70,6 @@
final Map<BluetoothDevice, PbapClientStateMachineOld> mPbapClientStateMachineOldMap =
new ConcurrentHashMap<>();
- private final AdapterService mAdapterService;
private final PbapClientContactsStorage mPbapClientContactsStorage;
private final PbapClientAccountManager mPbapClientAccountManager;
private final DatabaseManager mDatabaseManager;
@@ -117,7 +116,6 @@
public PbapClientService(AdapterService adapterService) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mHandler = new Handler(Looper.getMainLooper());
@@ -147,7 +145,6 @@
PbapClientContactsStorage storage,
Map<BluetoothDevice, PbapClientStateMachine> deviceMap) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mHandler = new Handler(Looper.getMainLooper());
@@ -725,7 +722,6 @@
@VisibleForTesting
PbapClientService(AdapterService adapterService, PbapClientAccountManager accountManager) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mHandler = new Handler(Looper.getMainLooper());
diff --git a/android/app/src/com/android/bluetooth/sap/SapService.java b/android/app/src/com/android/bluetooth/sap/SapService.java
index 8815fad..0d28825 100644
--- a/android/app/src/com/android/bluetooth/sap/SapService.java
+++ b/android/app/src/com/android/bluetooth/sap/SapService.java
@@ -97,7 +97,6 @@
"com.android.bluetooth.sap.USER_CONFIRM_TIMEOUT";
private static final int USER_CONFIRM_TIMEOUT_VALUE = 25000;
- private final AdapterService mAdapterService;
private final BluetoothAdapter mAdapter;
private PowerManager.WakeLock mWakeLock = null;
@@ -122,8 +121,7 @@
public SapService(AdapterService adapterService) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
- mAdapter = mAdapterService.getSystemService(BluetoothManager.class).getAdapter();
+ mAdapter = obtainSystemService(BluetoothManager.class).getAdapter();
BluetoothSap.invalidateBluetoothGetConnectionStateCache();
IntentFilter filter = new IntentFilter();
@@ -295,7 +293,7 @@
// acquire the wakeLock before start SAP transaction thread
if (mWakeLock == null) {
- PowerManager pm = mAdapterService.getSystemService(PowerManager.class);
+ PowerManager pm = obtainSystemService(PowerManager.class);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "StartingSapTransaction");
mWakeLock.setReferenceCounted(false);
mWakeLock.acquire();
@@ -488,8 +486,7 @@
case MSG_ACQUIRE_WAKE_LOCK:
Log.v(TAG, "Acquire Wake Lock request message");
if (mWakeLock == null) {
- PowerManager pm =
- mAdapterService.getSystemService(PowerManager.class);
+ PowerManager pm = obtainSystemService(PowerManager.class);
mWakeLock =
pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
@@ -737,7 +734,7 @@
private void cancelUserTimeoutAlarm() {
Log.d(TAG, "cancelUserTimeOutAlarm()");
if (mAlarmManager == null) {
- mAlarmManager = this.getSystemService(AlarmManager.class);
+ mAlarmManager = obtainSystemService(AlarmManager.class);
}
if (mRemoveTimeoutMsg) {
Intent timeoutIntent = new Intent(USER_CONFIRM_TIMEOUT_ACTION);
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
index a355c49..1036760 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
@@ -89,7 +89,6 @@
final RemoteCallbackList<IBluetoothVolumeControlCallback> mCallbacks =
new RemoteCallbackList<>();
- private final AdapterService mAdapterService;
private final AudioManager mAudioManager;
private final DatabaseManager mDatabaseManager;
private final Handler mHandler;
@@ -122,7 +121,6 @@
Looper looper,
VolumeControlNativeInterface nativeInterface) {
super(requireNonNull(adapterService));
- mAdapterService = adapterService;
mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
mNativeInterface =
requireNonNullElseGet(
@@ -130,7 +128,7 @@
() ->
new VolumeControlNativeInterface(
new VolumeControlNativeCallback(adapterService, this)));
- mAudioManager = requireNonNull(mAdapterService.getSystemService(AudioManager.class));
+ mAudioManager = requireNonNull(obtainSystemService(AudioManager.class));
if (looper == null) {
mHandler = new Handler(requireNonNull(Looper.getMainLooper()));
mStateMachinesThread = new HandlerThread("VolumeControlService.StateMachines");
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java
index 41ea02a..4fb2aa6 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpTargetServiceTest.java
@@ -91,7 +91,6 @@
mLooper.startAutoDispatch();
mockGetSystemService(mMockAdapterService, AudioManager.class, mMockAudioManager);
-
mockGetSystemService(mMockAdapterService, MediaSessionManager.class, mMediaSessionManager);
doReturn(mLooper.getNewExecutor()).when(mMockAdapterService).getMainExecutor();
@@ -153,8 +152,7 @@
@Test
public void testServiceInstance() {
AvrcpVolumeManager volumeManager =
- new AvrcpVolumeManager(
- mMockAdapterService, mMockAudioManager, mMockNativeInterface);
+ new AvrcpVolumeManager(mMockAdapterService, mMockNativeInterface);
AvrcpTargetService service =
new AvrcpTargetService(
mMockAdapterService,
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java
index 06cafa6..2574ea7 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcp/AvrcpVolumeManagerTest.java
@@ -18,6 +18,7 @@
import static com.android.bluetooth.TestUtils.MockitoRule;
import static com.android.bluetooth.TestUtils.getTestDevice;
+import static com.android.bluetooth.TestUtils.mockGetSystemService;
import static com.android.bluetooth.avrcp.AvrcpVolumeManager.AVRCP_MAX_VOL;
import static com.google.common.truth.Truth.assertThat;
@@ -58,7 +59,7 @@
@Mock private Resources mResources;
@Mock private AvrcpNativeInterface mNativeInterface;
@Mock private AdapterService mAdapterService;
- @Mock AudioManager mAudioManager;
+ @Mock private AudioManager mAudioManager;
private static final int TEST_DEVICE_MAX_VOLUME = 25;
@@ -79,8 +80,8 @@
testName.getMethodName() + "TmpPref", Context.MODE_PRIVATE))
.when(mAdapterService)
.getSharedPreferences(anyString(), anyInt());
- mAvrcpVolumeManager =
- new AvrcpVolumeManager(mAdapterService, mAudioManager, mNativeInterface);
+ mockGetSystemService(mAdapterService, AudioManager.class, mAudioManager);
+ mAvrcpVolumeManager = new AvrcpVolumeManager(mAdapterService, mNativeInterface);
}
@Test
@@ -105,14 +106,12 @@
@Test
public void sendVolumeChanged() {
mAvrcpVolumeManager.sendVolumeChanged(mDevice, TEST_DEVICE_MAX_VOLUME);
-
verify(mNativeInterface).sendVolumeChanged(mDevice, AVRCP_MAX_VOL);
}
@Test
public void setVolume() {
mAvrcpVolumeManager.setVolume(mDevice, AVRCP_MAX_VOL);
-
verify(mAudioManager)
.setStreamVolume(
eq(AudioManager.STREAM_MUSIC), eq(TEST_DEVICE_MAX_VOLUME), anyInt());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java
index 3435eb7..98c7d6e 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java
@@ -17,21 +17,19 @@
package com.android.bluetooth.map;
import static com.android.bluetooth.TestUtils.MockitoRule;
+import static com.android.bluetooth.TestUtils.mockContextGetBluetoothManager;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import android.bluetooth.BluetoothManager;
-import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.TestUtils.MockitoRule;
+import com.android.bluetooth.btservice.AdapterService;
import org.junit.Before;
import org.junit.Rule;
@@ -45,6 +43,7 @@
public class BluetoothMapMasInstanceTest {
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
+ @Mock private AdapterService mAdapterService;
@Mock private BluetoothMapService mMapService;
private static final int TEST_MAS_ID = 1;
@@ -76,14 +75,15 @@
@Test
public void toString_returnsInfo() {
- final Context context = InstrumentationRegistry.getInstrumentation().getContext();
- final BluetoothManager manager = context.getSystemService(BluetoothManager.class);
- assertThat(manager).isNotNull();
- doReturn(manager).when(mMapService).getSystemService(BluetoothManager.class);
+ mockContextGetBluetoothManager(mAdapterService);
BluetoothMapMasInstance instance =
new BluetoothMapMasInstance(
- mMapService, mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS);
+ mAdapterService,
+ mMapService,
+ mAccountItem,
+ TEST_MAS_ID,
+ TEST_ENABLE_SMS_MMS);
String expected =
"MasId: "
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java
index 1edd67c..f4d6145 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java
@@ -17,6 +17,7 @@
package com.android.bluetooth.map;
import static com.android.bluetooth.TestUtils.MockitoRule;
+import static com.android.bluetooth.TestUtils.mockContextGetBluetoothManager;
import static com.google.common.truth.Truth.assertThat;
@@ -28,7 +29,6 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import android.bluetooth.BluetoothManager;
import android.content.ContentProviderClient;
import android.content.Context;
import android.database.MatrixCursor;
@@ -37,11 +37,11 @@
import android.os.RemoteException;
import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.TestUtils.MockitoRule;
+import com.android.bluetooth.btservice.AdapterService;
import com.android.obex.ResponseCodes;
import org.junit.Before;
@@ -58,6 +58,7 @@
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private Context mMockContext;
+ @Mock private AdapterService mAdapterService;
@Mock private BluetoothMapService mMapService;
@Mock private ContentProviderClient mProviderClient;
@Mock private BluetoothMapContentObserver mObserver;
@@ -98,19 +99,20 @@
TEST_UCI,
TEST_UCI_PREFIX);
- final Context context = InstrumentationRegistry.getInstrumentation().getContext();
- final BluetoothManager manager = context.getSystemService(BluetoothManager.class);
- assertThat(manager).isNotNull();
- doReturn(manager).when(mMapService).getSystemService(BluetoothManager.class);
+ mockContextGetBluetoothManager(mAdapterService);
mMasInstance =
new BluetoothMapMasInstance(
- mMapService, mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS);
+ mAdapterService,
+ mMapService,
+ mAccountItem,
+ TEST_MAS_ID,
+ TEST_ENABLE_SMS_MMS);
mParams = new BluetoothMapAppParams();
mObexServer =
new BluetoothMapObexServer(
- null,
mMockContext,
+ null,
mObserver,
mMasInstance,
mAccountItem,
@@ -132,8 +134,8 @@
TEST_UCI_PREFIX);
BluetoothMapObexServer obexServer =
new BluetoothMapObexServer(
- null,
mMockContext,
+ null,
mObserver,
mMasInstance,
accountItemWithTypeEmail,
@@ -235,7 +237,7 @@
public void setMsgTypeFilterParams_withAccountNull_andOverwriteTrue() throws Exception {
BluetoothMapObexServer obexServer =
new BluetoothMapObexServer(
- null, mMockContext, mObserver, mMasInstance, null, false);
+ mMockContext, null, mObserver, mMasInstance, null, false);
obexServer.setMsgTypeFilterParams(mParams, true);
@@ -262,8 +264,8 @@
TEST_UCI_PREFIX);
BluetoothMapObexServer obexServer =
new BluetoothMapObexServer(
- null,
mMockContext,
+ null,
mObserver,
mMasInstance,
accountItemWithTypeEmail,
@@ -289,8 +291,8 @@
TEST_UCI_PREFIX);
BluetoothMapObexServer obexServer =
new BluetoothMapObexServer(
- null,
mMockContext,
+ null,
mObserver,
mMasInstance,
accountItemWithTypeIm,
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java
index 749df0e..a2b0688 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java
@@ -20,6 +20,7 @@
import static com.android.bluetooth.TestUtils.MockitoRule;
import static com.android.bluetooth.TestUtils.getTestDevice;
+import static com.android.bluetooth.TestUtils.mockContextGetBluetoothManager;
import static com.google.common.truth.Truth.assertThat;
@@ -109,6 +110,7 @@
doNothing().when(mMethodProxy).threadStart(any());
mTestLooper.startAutoDispatch();
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
+ mockContextGetBluetoothManager(mAdapterService);
mService = new BluetoothPbapService(mAdapterService, mNotificationManager);
mService.setAvailable(true);
diff --git a/flags/le_scanning.aconfig b/flags/le_scanning.aconfig
index 0b4985e..c86ac7d 100644
--- a/flags/le_scanning.aconfig
+++ b/flags/le_scanning.aconfig
@@ -10,3 +10,10 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "support_passive_scanning"
+ namespace: "bluetooth"
+ description: "Support passive scannign by delivering adv packet w/o scan response"
+ bug: "414501027"
+}
diff --git a/flags/leaudio.aconfig b/flags/leaudio.aconfig
index 1609a2b..1900845 100644
--- a/flags/leaudio.aconfig
+++ b/flags/leaudio.aconfig
@@ -358,3 +358,13 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "dsa_configure_first_cis"
+ namespace: "bluetooth"
+ description: "Configure only the first CIS for DSA"
+ bug: "417561299"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/rfcomm.aconfig b/flags/rfcomm.aconfig
index a46f9f6..1374c76 100644
--- a/flags/rfcomm.aconfig
+++ b/flags/rfcomm.aconfig
@@ -40,3 +40,13 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "rfcomm_fix_bta_ag_rfc_acp_open_error"
+ namespace: "bluetooth"
+ description: "Properly handle bta_ag_rfc_acp_open when check connection fail"
+ bug: "417997444"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index 33c0d10..28a40c5 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -206,15 +206,18 @@
*
******************************************************************************/
static void bta_dm_deinit_cb(void) {
- /*
- * TODO: Should alarm_free() the bta_dm_cb timers during graceful
- * shutdown.
- */
alarm_free(bta_dm_cb.disable_timer);
alarm_free(bta_dm_cb.switch_delay_timer);
+ if (com::android::bluetooth::flags::set_ptr_null_after_free()) {
+ bta_dm_cb.switch_delay_timer = nullptr;
+ bta_dm_cb.disable_timer = nullptr;
+ }
for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
alarm_free(bta_dm_cb.pm_timer[i].timer[j]);
+ if (com::android::bluetooth::flags::set_ptr_null_after_free()) {
+ bta_dm_cb.pm_timer[i].timer[j] = nullptr;
+ }
}
}
bta_dm_cb.pending_removals.clear();
diff --git a/system/bta/dm/bta_dm_device_search.cc b/system/bta/dm/bta_dm_device_search.cc
index b1e905f..67bcd2c 100644
--- a/system/bta/dm/bta_dm_device_search.cc
+++ b/system/bta/dm/bta_dm_device_search.cc
@@ -179,7 +179,7 @@
result.inq_res.bd_addr = p_inq->remote_bd_addr;
- // Pass the original address to GattService#onScanResult
+ // Pass the original address to ScanController#onScanResult
result.inq_res.original_bda = p_inq->original_bda;
result.inq_res.dev_class = p_inq->dev_class;
@@ -208,6 +208,8 @@
}
if (bta_dm_search_cb.p_device_search_cback) {
+ log::debug("Inquiry results callback from BTM, bda={}, original_bda={}", result.inq_res.bd_addr,
+ result.inq_res.original_bda);
bta_dm_search_cb.p_device_search_cback(BTA_DM_INQ_RES_EVT, &result);
}
diff --git a/system/gd/Android.bp b/system/gd/Android.bp
index 95cba20..6dec98a 100644
--- a/system/gd/Android.bp
+++ b/system/gd/Android.bp
@@ -57,8 +57,8 @@
},
host: {
srcs: [
- "hal/hci_hal_host_rootcanal.cc",
"hal/socket_hal_host.cc",
+ "hal/hci_hal_impl_host_rootcanal.cc",
"os/host/parameter_provider.cc",
"os/host/system_properties.cc",
"os/host/wakelock_native.cc",
@@ -69,7 +69,7 @@
srcs: [
"hal/hci_backend_aidl.cc",
"hal/hci_backend_hidl.cc",
- "hal/hci_hal_android.cc",
+ "hal/hci_hal_impl_android.cc",
"hal/ranging_hal_impl_android.cc",
"hal/socket_hal_android.cc",
"os/android/parameter_provider.cc",
@@ -320,13 +320,13 @@
},
host: {
srcs: [
- "hal/hci_hal_host_test.cc",
+ "hal/hci_hal_impl_host_rootcanal_test.cc",
"sysprops/sysprops_module_test.cc",
],
},
android: {
srcs: [
- "hal/hci_hal_android_test.cc",
+ "hal/hci_hal_impl_android_test.cc",
"os/android/wakelock_native_test.cc",
],
static_libs: [
diff --git a/system/gd/BUILD.gn b/system/gd/BUILD.gn
index 90f17c3..aed96ed 100644
--- a/system/gd/BUILD.gn
+++ b/system/gd/BUILD.gn
@@ -99,9 +99,9 @@
]
if (use.floss_rootcanal) {
- sources += [ "hal/hci_hal_host_rootcanal.cc" ]
+ sources += [ "hal/hci_hal_impl_host_rootcanal.cc" ]
} else {
- sources += [ "hal/hci_hal_host.cc" ]
+ sources += [ "hal/hci_hal_impl_host.cc" ]
}
include_dirs = [ "." ]
diff --git a/system/gd/hal/fuzz/fuzz_hci_hal.cc b/system/gd/hal/fuzz/fuzz_hci_hal.cc
index 3d9afec..1e7b548 100644
--- a/system/gd/hal/fuzz/fuzz_hci_hal.cc
+++ b/system/gd/hal/fuzz/fuzz_hci_hal.cc
@@ -111,8 +111,6 @@
callbacks_->isoDataReceived(data);
}
-const ModuleFactory FuzzHciHal::Factory = ModuleFactory([]() { return new FuzzHciHal(); });
-
} // namespace fuzz
} // namespace hal
} // namespace bluetooth
diff --git a/system/gd/hal/fuzz/fuzz_hci_hal.h b/system/gd/hal/fuzz/fuzz_hci_hal.h
index ab9fc7e..e144932 100644
--- a/system/gd/hal/fuzz/fuzz_hci_hal.h
+++ b/system/gd/hal/fuzz/fuzz_hci_hal.h
@@ -36,15 +36,6 @@
void injectArbitrary(FuzzedDataProvider& fdp);
- std::string ToString() const override { return "HciHalFuzz"; }
-
- static const ModuleFactory Factory;
-
-protected:
- void ListDependencies(ModuleList* /* list */) const override {}
- void Start() override {}
- void Stop() override {}
-
private:
void injectAclData(std::vector<uint8_t> data);
void injectHciEvent(std::vector<uint8_t> data);
diff --git a/system/gd/hal/hci_hal.h b/system/gd/hal/hci_hal.h
index 2c028c3..dba985a 100644
--- a/system/gd/hal/hci_hal.h
+++ b/system/gd/hal/hci_hal.h
@@ -18,8 +18,6 @@
#include <vector>
-#include "module.h"
-
namespace bluetooth {
namespace hal {
@@ -65,10 +63,8 @@
// the stack and abstracts away power management, initialization, and other
// implementation-specific details related to the hardware.
// LINT.IfChange
-class HciHal : public ::bluetooth::Module {
+class HciHal {
public:
- static const ModuleFactory Factory;
-
virtual ~HciHal() = default;
// Register the callback for incoming packets. All incoming packets are dropped before
diff --git a/system/gd/hal/hci_hal_fake.cc b/system/gd/hal/hci_hal_fake.cc
index 781dde6..2a5ee1a 100644
--- a/system/gd/hal/hci_hal_fake.cc
+++ b/system/gd/hal/hci_hal_fake.cc
@@ -84,6 +84,5 @@
callbacks->hciEventReceived(view);
}
-const ModuleFactory TestHciHal::Factory = ModuleFactory([]() { return new TestHciHal(); });
} // namespace hal
} // namespace bluetooth
diff --git a/system/gd/hal/hci_hal_fake.h b/system/gd/hal/hci_hal_fake.h
index 9d58064..1436fde 100644
--- a/system/gd/hal/hci_hal_fake.h
+++ b/system/gd/hal/hci_hal_fake.h
@@ -72,16 +72,6 @@
void InjectEvent(std::unique_ptr<packet::BasePacketBuilder> event);
- void Start() {}
-
- void Stop() {}
-
- void ListDependencies(ModuleList* /* list */) const {}
-
- std::string ToString() const override { return std::string("TestHciHal"); }
-
- static const ModuleFactory Factory;
-
private:
common::BlockingQueue<hal::HciPacket> outgoing_commands_;
common::BlockingQueue<hal::HciPacket> outgoing_acl_;
diff --git a/system/gd/hal/hci_hal_host_rootcanal.cc b/system/gd/hal/hci_hal_host_rootcanal.cc
deleted file mode 100644
index a15a69a..0000000
--- a/system/gd/hal/hci_hal_host_rootcanal.cc
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#include <bluetooth/log.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <poll.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <csignal>
-#include <mutex>
-#include <queue>
-
-#include "hal/hci_hal.h"
-#include "hal/hci_hal_host.h"
-#include "hal/snoop_logger.h"
-#include "main/shim/entry.h"
-#include "os/reactor.h"
-#include "os/thread.h"
-
-namespace {
-constexpr int INVALID_FD = -1;
-
-constexpr uint8_t kH4Command = 0x01;
-constexpr uint8_t kH4Acl = 0x02;
-constexpr uint8_t kH4Sco = 0x03;
-constexpr uint8_t kH4Event = 0x04;
-constexpr uint8_t kH4Iso = 0x05;
-
-constexpr uint8_t kH4HeaderSize = 1;
-constexpr uint8_t kHciAclHeaderSize = 4;
-constexpr uint8_t kHciScoHeaderSize = 3;
-constexpr uint8_t kHciEvtHeaderSize = 2;
-constexpr uint8_t kHciIsoHeaderSize = 4;
-constexpr int kBufSize =
- 1024 + 4 + 1; // DeviceProperties::acl_data_packet_size_ + ACL header + H4 header
-
-int ConnectToSocket() {
- auto* config = bluetooth::hal::HciHalHostRootcanalConfig::Get();
- const std::string& server = config->GetServerAddress();
- int port = config->GetPort();
-
- int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
- if (socket_fd < 1) {
- bluetooth::log::error("can't create socket: {}", strerror(errno));
- return INVALID_FD;
- }
-
- struct hostent* host;
- host = gethostbyname(server.c_str());
- if (host == nullptr) {
- bluetooth::log::error("can't get server name");
- return INVALID_FD;
- }
-
- struct sockaddr_in serv_addr;
- memset((void*)&serv_addr, 0, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = INADDR_ANY;
- serv_addr.sin_port = htons(port);
-
- int result = connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
- if (result < 0) {
- bluetooth::log::error("can't connect: {}", strerror(errno));
- return INVALID_FD;
- }
-
- timeval socket_timeout{
- .tv_sec = 3,
- .tv_usec = 0,
- };
- int ret = setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, &socket_timeout, sizeof(socket_timeout));
- if (ret == -1) {
- bluetooth::log::error("can't control socket fd: {}", strerror(errno));
- return INVALID_FD;
- }
- return socket_fd;
-}
-} // namespace
-
-namespace bluetooth {
-namespace hal {
-
-class HciHalHost : public HciHal {
-public:
- void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
- std::lock_guard<std::mutex> lock(api_mutex_);
- log::info("before");
- {
- std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
- log::assert_that(
- incoming_packet_callback_ == nullptr && callback != nullptr,
- "assert failed: incoming_packet_callback_ == nullptr && callback != nullptr");
- incoming_packet_callback_ = callback;
- }
- log::info("after");
- }
-
- void unregisterIncomingPacketCallback() override {
- std::lock_guard<std::mutex> lock(api_mutex_);
- log::info("before");
- {
- std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
- incoming_packet_callback_ = nullptr;
- }
- log::info("after");
- }
-
- void sendHciCommand(HciPacket command) override {
- std::lock_guard<std::mutex> lock(api_mutex_);
- log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
- std::vector<uint8_t> packet = std::move(command);
- if (btsnoop_logger_) {
- btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
- SnoopLogger::PacketType::CMD);
- }
- packet.insert(packet.cbegin(), kH4Command);
- write_to_fd(packet);
- }
-
- void sendAclData(HciPacket data) override {
- std::lock_guard<std::mutex> lock(api_mutex_);
- log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
- std::vector<uint8_t> packet = std::move(data);
- if (btsnoop_logger_) {
- btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
- SnoopLogger::PacketType::ACL);
- }
- packet.insert(packet.cbegin(), kH4Acl);
- write_to_fd(packet);
- }
-
- void sendScoData(HciPacket data) override {
- std::lock_guard<std::mutex> lock(api_mutex_);
- log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
- std::vector<uint8_t> packet = std::move(data);
- if (btsnoop_logger_) {
- btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
- SnoopLogger::PacketType::SCO);
- }
- packet.insert(packet.cbegin(), kH4Sco);
- write_to_fd(packet);
- }
-
- void sendIsoData(HciPacket data) override {
- std::lock_guard<std::mutex> lock(api_mutex_);
- log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
- std::vector<uint8_t> packet = std::move(data);
- if (btsnoop_logger_) {
- btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
- SnoopLogger::PacketType::ISO);
- }
- packet.insert(packet.cbegin(), kH4Iso);
- write_to_fd(packet);
- }
-
-protected:
- void ListDependencies(ModuleList* /*list*/) const {}
-
- void Start() override {
- std::lock_guard<std::mutex> lock(api_mutex_);
- log::assert_that(sock_fd_ == INVALID_FD, "assert failed: sock_fd_ == INVALID_FD");
- sock_fd_ = ConnectToSocket();
- log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
- reactable_ = hci_incoming_thread_.GetReactor()->Register(
- sock_fd_, common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)),
- common::Bind(&HciHalHost::send_packet_ready, common::Unretained(this)));
- hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
- os::Reactor::REACT_ON_READ_ONLY);
- btsnoop_logger_ = shim::GetSnoopLogger();
- log::info("HAL opened successfully");
- }
-
- void Stop() override {
- std::lock_guard<std::mutex> lock(api_mutex_);
- log::info("HAL is closing");
- if (reactable_ != nullptr) {
- hci_incoming_thread_.GetReactor()->Unregister(reactable_);
- log::info("HAL is stopping, start waiting for last callback");
- // Wait up to 1 second for the last incoming packet callback to finish
- hci_incoming_thread_.GetReactor()->WaitForUnregisteredReactable(
- std::chrono::milliseconds(1000));
- log::info("HAL is stopping, finished waiting for last callback");
- log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
- }
- reactable_ = nullptr;
- {
- std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
- incoming_packet_callback_ = nullptr;
- }
- ::close(sock_fd_);
- sock_fd_ = INVALID_FD;
- log::info("HAL is closed");
- }
-
- std::string ToString() const override { return std::string("HciHalHost"); }
-
-private:
- // Held when APIs are called, NOT to be held during callbacks
- std::mutex api_mutex_;
- HciHalCallbacks* incoming_packet_callback_ = nullptr;
- std::mutex incoming_packet_callback_mutex_;
- int sock_fd_ = INVALID_FD;
- bluetooth::os::Thread hci_incoming_thread_ =
- bluetooth::os::Thread("hci_incoming_thread", bluetooth::os::Thread::Priority::NORMAL);
- bluetooth::os::Reactor::Reactable* reactable_ = nullptr;
- std::queue<std::vector<uint8_t>> hci_outgoing_queue_;
- SnoopLogger* btsnoop_logger_ = nullptr;
-
- void write_to_fd(HciPacket packet) {
- // TODO: replace this with new queue when it's ready
- hci_outgoing_queue_.emplace(packet);
- if (hci_outgoing_queue_.size() == 1) {
- hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
- os::Reactor::REACT_ON_READ_WRITE);
- }
- }
-
- void send_packet_ready() {
- std::lock_guard<std::mutex> lock(api_mutex_);
- if (hci_outgoing_queue_.empty()) {
- return;
- }
- auto packet_to_send = hci_outgoing_queue_.front();
- auto bytes_written = write(sock_fd_, (void*)packet_to_send.data(), packet_to_send.size());
- hci_outgoing_queue_.pop();
- if (bytes_written == -1) {
- abort();
- }
- if (hci_outgoing_queue_.empty()) {
- hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
- os::Reactor::REACT_ON_READ_ONLY);
- }
- }
-
- bool socketRecvAll(void* buffer, int bufferLen) {
- auto buf = static_cast<char*>(buffer);
- while (bufferLen > 0) {
- ssize_t ret;
- RUN_NO_INTR(ret = recv(sock_fd_, buf, bufferLen, 0));
- if (ret <= 0) {
- return false;
- }
- buf += ret;
- bufferLen -= ret;
- }
- return true;
- }
-
- void incoming_packet_received() {
- {
- std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
- if (incoming_packet_callback_ == nullptr) {
- log::info("Dropping a packet");
- return;
- }
- }
- uint8_t buf[kBufSize] = {};
-
- ssize_t received_size;
- RUN_NO_INTR(received_size = recv(sock_fd_, buf, kH4HeaderSize, 0));
- log::assert_that(received_size != -1, "Can't receive from socket: {}", strerror(errno));
- if (received_size == 0) {
- log::warn("Can't read H4 header. EOF received");
- raise(SIGINT);
- return;
- }
-
- if (buf[0] == kH4Event) {
- log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciEvtHeaderSize),
- "Can't receive from socket: {}", strerror(errno));
-
- uint8_t hci_evt_parameter_total_length = buf[2];
- log::assert_that(socketRecvAll(buf + kH4HeaderSize + kHciEvtHeaderSize,
- hci_evt_parameter_total_length),
- "Can't receive from socket: {}", strerror(errno));
-
- HciPacket receivedHciPacket;
- receivedHciPacket.assign(buf + kH4HeaderSize, buf + kH4HeaderSize + kHciEvtHeaderSize +
- hci_evt_parameter_total_length);
- if (btsnoop_logger_) {
- btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
- SnoopLogger::PacketType::EVT);
- }
- {
- std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
- if (incoming_packet_callback_ == nullptr) {
- log::info("Dropping an event after processing");
- return;
- }
- incoming_packet_callback_->hciEventReceived(receivedHciPacket);
- }
- }
-
- if (buf[0] == kH4Acl) {
- log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciAclHeaderSize),
- "Can't receive from socket: {}", strerror(errno));
-
- uint16_t hci_acl_data_total_length = (buf[4] << 8) + buf[3];
- log::assert_that(
- socketRecvAll(buf + kH4HeaderSize + kHciAclHeaderSize, hci_acl_data_total_length),
- "Can't receive from socket: {}", strerror(errno));
-
- HciPacket receivedHciPacket;
- receivedHciPacket.assign(buf + kH4HeaderSize,
- buf + kH4HeaderSize + kHciAclHeaderSize + hci_acl_data_total_length);
- if (btsnoop_logger_) {
- btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
- SnoopLogger::PacketType::ACL);
- }
- {
- std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
- if (incoming_packet_callback_ == nullptr) {
- log::info("Dropping an ACL packet after processing");
- return;
- }
- incoming_packet_callback_->aclDataReceived(receivedHciPacket);
- }
- }
-
- if (buf[0] == kH4Sco) {
- log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciScoHeaderSize),
- "Can't receive from socket: {}", strerror(errno));
-
- uint8_t hci_sco_data_total_length = buf[3];
- log::assert_that(
- socketRecvAll(buf + kH4HeaderSize + kHciScoHeaderSize, hci_sco_data_total_length),
- "Can't receive from socket: {}", strerror(errno));
-
- HciPacket receivedHciPacket;
- receivedHciPacket.assign(buf + kH4HeaderSize,
- buf + kH4HeaderSize + kHciScoHeaderSize + hci_sco_data_total_length);
- if (btsnoop_logger_) {
- btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
- SnoopLogger::PacketType::SCO);
- }
- {
- std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
- if (incoming_packet_callback_ == nullptr) {
- log::info("Dropping a SCO packet after processing");
- return;
- }
- incoming_packet_callback_->scoDataReceived(receivedHciPacket);
- }
- }
-
- if (buf[0] == kH4Iso) {
- log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciIsoHeaderSize),
- "Can't receive from socket: {}", strerror(errno));
-
- uint16_t hci_iso_data_total_length = ((buf[4] & 0x3f) << 8) + buf[3];
- log::assert_that(
- socketRecvAll(buf + kH4HeaderSize + kHciIsoHeaderSize, hci_iso_data_total_length),
- "Can't receive from socket: {}", strerror(errno));
-
- HciPacket receivedHciPacket;
- receivedHciPacket.assign(buf + kH4HeaderSize,
- buf + kH4HeaderSize + kHciIsoHeaderSize + hci_iso_data_total_length);
- if (btsnoop_logger_) {
- btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
- SnoopLogger::PacketType::ISO);
- }
- {
- std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
- if (incoming_packet_callback_ == nullptr) {
- log::info("Dropping a ISO packet after processing");
- return;
- }
- incoming_packet_callback_->isoDataReceived(receivedHciPacket);
- }
- }
- memset(buf, 0, kBufSize);
- }
-};
-
-const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHost(); });
-
-} // namespace hal
-} // namespace bluetooth
diff --git a/system/gd/hal/hci_hal_host.h b/system/gd/hal/hci_hal_host_rootcanal_config.h
similarity index 100%
rename from system/gd/hal/hci_hal_host.h
rename to system/gd/hal/hci_hal_host_rootcanal_config.h
diff --git a/system/gd/hal/hci_hal_impl.h b/system/gd/hal/hci_hal_impl.h
new file mode 100644
index 0000000..8c081ce
--- /dev/null
+++ b/system/gd/hal/hci_hal_impl.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#pragma once
+
+#ifdef __ANDROID__
+#include "hal/hci_hal_impl_android.h"
+#else
+#include "hal/hci_hal_impl_host.h"
+#endif
diff --git a/system/gd/hal/hci_hal_android.cc b/system/gd/hal/hci_hal_impl_android.cc
similarity index 61%
rename from system/gd/hal/hci_hal_android.cc
rename to system/gd/hal/hci_hal_impl_android.cc
index 4ac4fc8..9230f99 100644
--- a/system/gd/hal/hci_hal_android.cc
+++ b/system/gd/hal/hci_hal_impl_android.cc
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "hci_hal_impl_android.h"
+
#include <android_bluetooth_sysprop.h>
#include <bluetooth/log.h>
#include <com_android_bluetooth_flags.h>
@@ -129,89 +131,66 @@
SnoopLogger* btsnoop_logger_;
};
-class HciHalImpl : public HciHal {
-public:
- void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
- callbacks_->SetCallback(callback);
+void HciHalImpl::registerIncomingPacketCallback(HciHalCallbacks* callback) {
+ callbacks_->SetCallback(callback);
+}
+
+void HciHalImpl::unregisterIncomingPacketCallback() { callbacks_->ResetCallback(); }
+
+void HciHalImpl::sendHciCommand(HciPacket packet) {
+ btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
+ backend_->sendHciCommand(packet);
+}
+
+void HciHalImpl::sendAclData(HciPacket packet) {
+ btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
+ backend_->sendAclData(packet);
+}
+
+void HciHalImpl::sendScoData(HciPacket packet) {
+ btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::SCO);
+ backend_->sendScoData(packet);
+}
+
+void HciHalImpl::sendIsoData(HciPacket packet) {
+ btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ISO);
+ backend_->sendIsoData(packet);
+}
+
+uint16_t HciHalImpl::getMsftOpcode() {
+ if (com::android::bluetooth::flags::le_scan_msft_support()) {
+ return android::sysprop::bluetooth::Hci::msft_vendor_opcode().value_or(0);
+ }
+ return 0;
+}
+
+HciHalImpl::HciHalImpl(os::Handler* handler, LinkClocker* link_clocker, SnoopLogger* btsnoop_logger)
+ : link_clocker_(link_clocker), btsnoop_logger_(btsnoop_logger) {
+ common::StopWatch stop_watch(__func__);
+ log::assert_that(backend_ == nullptr,
+ "Start can't be called more than once before Stop is called.");
+
+ if (com::android::bluetooth::flags::hci_instance_name_use_injected()) {
+ backend_ = HciBackend::CreateAidl(bluetooth::os::ParameterProvider::GetHciInstanceName());
+ } else {
+ backend_ = HciBackend::CreateAidl();
+ }
+ if (!backend_) {
+ backend_ = HciBackend::CreateHidl(handler);
}
- void unregisterIncomingPacketCallback() override { callbacks_->ResetCallback(); }
+ log::assert_that(backend_ != nullptr, "No backend available");
- void sendHciCommand(HciPacket packet) override {
- btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
- SnoopLogger::PacketType::CMD);
- backend_->sendHciCommand(packet);
- }
+ callbacks_ = std::make_shared<HciCallbacksImpl>(btsnoop_logger_, link_clocker_);
- void sendAclData(HciPacket packet) override {
- btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
- SnoopLogger::PacketType::ACL);
- backend_->sendAclData(packet);
- }
+ backend_->initialize(callbacks_);
+ callbacks_->init_promise->get_future().wait();
+}
- void sendScoData(HciPacket packet) override {
- btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
- SnoopLogger::PacketType::SCO);
- backend_->sendScoData(packet);
- }
-
- void sendIsoData(HciPacket packet) override {
- btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
- SnoopLogger::PacketType::ISO);
- backend_->sendIsoData(packet);
- }
-
- uint16_t getMsftOpcode() override {
- if (com::android::bluetooth::flags::le_scan_msft_support()) {
- return android::sysprop::bluetooth::Hci::msft_vendor_opcode().value_or(0);
- }
- return 0;
- }
-
-protected:
- void ListDependencies(ModuleList* list) const override { list->add<LinkClocker>(); }
-
- void Start() override {
- common::StopWatch stop_watch(__func__);
- log::assert_that(backend_ == nullptr,
- "Start can't be called more than once before Stop is called.");
-
- link_clocker_ = GetDependency<LinkClocker>();
- btsnoop_logger_ = shim::GetSnoopLogger();
-
- if (com::android::bluetooth::flags::hci_instance_name_use_injected()) {
- backend_ = HciBackend::CreateAidl(bluetooth::os::ParameterProvider::GetHciInstanceName());
- } else {
- backend_ = HciBackend::CreateAidl();
- }
- if (!backend_) {
- backend_ = HciBackend::CreateHidl(GetHandler());
- }
-
- log::assert_that(backend_ != nullptr, "No backend available");
-
- callbacks_ = std::make_shared<HciCallbacksImpl>(btsnoop_logger_, link_clocker_);
-
- backend_->initialize(callbacks_);
- callbacks_->init_promise->get_future().wait();
- }
-
- void Stop() override {
- backend_.reset();
- callbacks_.reset();
- btsnoop_logger_ = nullptr;
- link_clocker_ = nullptr;
- }
-
- std::string ToString() const override { return std::string("HciHal"); }
-
-private:
- std::shared_ptr<HciCallbacksImpl> callbacks_;
- std::shared_ptr<HciBackend> backend_;
- SnoopLogger* btsnoop_logger_ = nullptr;
- LinkClocker* link_clocker_ = nullptr;
-};
-
-const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalImpl(); });
-
+HciHalImpl::~HciHalImpl() {
+ backend_.reset();
+ callbacks_.reset();
+ btsnoop_logger_ = nullptr;
+ link_clocker_ = nullptr;
+}
} // namespace bluetooth::hal
diff --git a/system/gd/hal/hci_hal_impl_android.h b/system/gd/hal/hci_hal_impl_android.h
new file mode 100644
index 0000000..e5a52cb
--- /dev/null
+++ b/system/gd/hal/hci_hal_impl_android.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#pragma once
+
+#include "hal/hci_backend.h"
+#include "hal/hci_hal.h"
+#include "hal/link_clocker.h"
+#include "hal/snoop_logger.h"
+
+namespace bluetooth::hal {
+class HciCallbacksImpl;
+
+class HciHalImpl : public HciHal {
+public:
+ HciHalImpl(os::Handler* handler, LinkClocker* link_clocker, SnoopLogger* btsnoop_logger);
+ ~HciHalImpl();
+
+ void sendHciCommand(HciPacket packet) override;
+ void sendAclData(HciPacket packet) override;
+ void sendScoData(HciPacket packet) override;
+ void sendIsoData(HciPacket packet) override;
+
+ void registerIncomingPacketCallback(HciHalCallbacks* callback) override;
+ void unregisterIncomingPacketCallback() override;
+ uint16_t getMsftOpcode() override;
+
+private:
+ std::shared_ptr<HciCallbacksImpl> callbacks_;
+ std::shared_ptr<HciBackend> backend_;
+ LinkClocker* link_clocker_ = nullptr;
+ SnoopLogger* btsnoop_logger_ = nullptr;
+};
+
+} // namespace bluetooth::hal
diff --git a/system/gd/hal/hci_hal_android_test.cc b/system/gd/hal/hci_hal_impl_android_test.cc
similarity index 89%
rename from system/gd/hal/hci_hal_android_test.cc
rename to system/gd/hal/hci_hal_impl_android_test.cc
index a43b0ec..690b15e 100644
--- a/system/gd/hal/hci_hal_android_test.cc
+++ b/system/gd/hal/hci_hal_impl_android_test.cc
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "hal/hci_hal_impl_android.h"
+
#include <gtest/gtest.h>
#include <chrono>
@@ -22,7 +24,8 @@
#include "com_android_bluetooth_flags.h"
#include "hal/hci_backend.h"
-#include "hal/hci_hal.h"
+#include "hal/link_clocker.h"
+#include "module.h" // FakeRegistry
#include "os/thread.h"
using ::bluetooth::os::Thread;
@@ -81,7 +84,9 @@
void SetUp() override {
thread_ = new Thread("test_thread", Thread::Priority::NORMAL);
handler_ = new os::Handler(thread_);
- hal = fake_registry_.Start<HciHal>(thread_, handler_);
+
+ link_clocker = std::make_unique<LinkClocker>();
+ hal = std::make_unique<HciHalImpl>(handler_, link_clocker.get(), nullptr /* snoop_logger */);
}
void TearDown() override {
@@ -89,12 +94,14 @@
if (com::android::bluetooth::flags::same_handler_for_all_modules()) {
handler_->WaitUntilStopped(bluetooth::kHandlerStopTimeout);
}
- fake_registry_.StopAll();
+ hal.reset();
+ link_clocker.reset();
delete handler_;
delete thread_;
}
- HciHal* hal;
+ std::unique_ptr<LinkClocker> link_clocker;
+ std::unique_ptr<HciHal> hal;
private:
ModuleRegistry fake_registry_;
diff --git a/system/gd/hal/hci_hal_host.cc b/system/gd/hal/hci_hal_impl_host.cc
similarity index 96%
rename from system/gd/hal/hci_hal_host.cc
rename to system/gd/hal/hci_hal_impl_host.cc
index 4976258..a0ea0e5 100644
--- a/system/gd/hal/hci_hal_host.cc
+++ b/system/gd/hal/hci_hal_impl_host.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "hal/hci_hal_host.h"
+#include "hal/hci_hal_impl_host.h"
#include <bluetooth/log.h>
#include <netdb.h>
@@ -234,7 +234,7 @@
namespace bluetooth {
namespace hal {
-class HciHalHost : public HciHal {
+class HciHalImpl : public HciHal {
public:
void registerIncomingPacketCallback(HciHalCallbacks* callback) override {
std::lock_guard<std::mutex> lock(api_mutex_);
@@ -308,10 +308,8 @@
return os::Management::getInstance().getVendorSpecificCode(MGMT_VS_OPCODE_MSFT);
}
-protected:
- void ListDependencies(ModuleList* list) const { list->add<LinkClocker>(); }
-
- void Start() override {
+ HciHalImpl(LinkClocker* link_clocker, SnoopLogger* snoop_logger)
+ : link_clocker_(link_clocker), btsnoop_logger_(snoop_logger) {
std::lock_guard<std::mutex> lock(api_mutex_);
log::assert_that(sock_fd_ == INVALID_FD, "assert failed: sock_fd_ == INVALID_FD");
sock_fd_ = ConnectToSocket();
@@ -324,16 +322,17 @@
}
reactable_ = hci_incoming_thread_.GetReactor()->Register(
- sock_fd_, common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)),
- common::Bind(&HciHalHost::send_packet_ready, common::Unretained(this)));
+ sock_fd_, common::Bind(&HciHalImpl::incoming_packet_received, common::Unretained(this)),
+ common::Bind(&HciHalImpl::send_packet_ready, common::Unretained(this)));
hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
os::Reactor::REACT_ON_READ_ONLY);
- link_clocker_ = GetDependency<LinkClocker>();
- btsnoop_logger_ = shim::GetSnoopLogger();
log::info("HAL opened successfully");
}
- void Stop() override {
+ HciHalImpl(os::Handler*, LinkClocker* link_clocker, SnoopLogger* btsnoop_logger)
+ : HciHalImpl(link_clocker, btsnoop_logger) {}
+
+ ~HciHalImpl() {
std::lock_guard<std::mutex> lock(api_mutex_);
log::info("HAL is closing");
if (reactable_ != nullptr) {
@@ -359,8 +358,6 @@
log::info("HAL is closed");
}
- std::string ToString() const override { return std::string("HciHalHost"); }
-
private:
// Held when APIs are called, NOT to be held during callbacks
std::mutex api_mutex_;
@@ -371,8 +368,8 @@
bluetooth::os::Thread("hci_incoming_thread", bluetooth::os::Thread::Priority::NORMAL);
bluetooth::os::Reactor::Reactable* reactable_ = nullptr;
std::queue<std::vector<uint8_t>> hci_outgoing_queue_;
- SnoopLogger* btsnoop_logger_ = nullptr;
LinkClocker* link_clocker_ = nullptr;
+ SnoopLogger* btsnoop_logger_ = nullptr;
void write_to_fd(HciPacket packet) {
// TODO(chromeos-bt-team@): replace this with new queue when it's ready
@@ -531,7 +528,5 @@
}
};
-const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHost(); });
-
} // namespace hal
} // namespace bluetooth
diff --git a/system/gd/hal/hci_hal_impl_host.h b/system/gd/hal/hci_hal_impl_host.h
new file mode 100644
index 0000000..4ed8cd7
--- /dev/null
+++ b/system/gd/hal/hci_hal_impl_host.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <mutex>
+#include <queue>
+
+#include "hal/hci_hal.h"
+#include "hal/link_clocker.h"
+#include "hal/snoop_logger.h"
+#include "main/shim/entry.h"
+#include "os/reactor.h"
+#include "os/thread.h"
+
+namespace bluetooth {
+namespace hal {
+
+namespace {
+constexpr int INVALID_FD = -1;
+}
+
+class HciHalImpl : public HciHal {
+public:
+ HciHalImpl(os::Handler*, LinkClocker*, SnoopLogger*) : HciHalImpl() {}
+ HciHalImpl();
+ ~HciHalImpl();
+
+ void registerIncomingPacketCallback(HciHalCallbacks* callback) override;
+ void unregisterIncomingPacketCallback() override;
+ void sendHciCommand(HciPacket command) override;
+ void sendAclData(HciPacket data) override;
+ void sendScoData(HciPacket data) override;
+ void sendIsoData(HciPacket data) override;
+
+private:
+ // Held when APIs are called, NOT to be held during callbacks
+ std::mutex api_mutex_;
+ HciHalCallbacks* incoming_packet_callback_ = nullptr;
+ std::mutex incoming_packet_callback_mutex_;
+ int sock_fd_ = INVALID_FD;
+ bluetooth::os::Thread hci_incoming_thread_ =
+ bluetooth::os::Thread("hci_incoming_thread", bluetooth::os::Thread::Priority::NORMAL);
+ bluetooth::os::Reactor::Reactable* reactable_ = nullptr;
+ std::queue<std::vector<uint8_t>> hci_outgoing_queue_;
+ SnoopLogger* btsnoop_logger_ = nullptr;
+
+ void write_to_fd(HciPacket packet);
+ void send_packet_ready();
+ bool socketRecvAll(void* buffer, int bufferLen);
+ void incoming_packet_received();
+};
+
+} // namespace hal
+} // namespace bluetooth
diff --git a/system/gd/hal/hci_hal_impl_host_rootcanal.cc b/system/gd/hal/hci_hal_impl_host_rootcanal.cc
new file mode 100644
index 0000000..39c2ad9
--- /dev/null
+++ b/system/gd/hal/hci_hal_impl_host_rootcanal.cc
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include "hal/hci_hal_impl_host.h"
+
+#include <bluetooth/log.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <chrono>
+#include <csignal>
+#include <mutex>
+#include <queue>
+
+#include "hal/hci_hal.h"
+#include "hal/hci_hal_host_rootcanal_config.h"
+#include "hal/snoop_logger.h"
+#include "main/shim/entry.h"
+#include "os/reactor.h"
+#include "os/thread.h"
+
+namespace {
+constexpr int INVALID_FD = -1;
+
+constexpr uint8_t kH4Command = 0x01;
+constexpr uint8_t kH4Acl = 0x02;
+constexpr uint8_t kH4Sco = 0x03;
+constexpr uint8_t kH4Event = 0x04;
+constexpr uint8_t kH4Iso = 0x05;
+
+constexpr uint8_t kH4HeaderSize = 1;
+constexpr uint8_t kHciAclHeaderSize = 4;
+constexpr uint8_t kHciScoHeaderSize = 3;
+constexpr uint8_t kHciEvtHeaderSize = 2;
+constexpr uint8_t kHciIsoHeaderSize = 4;
+constexpr int kBufSize =
+ 1024 + 4 + 1; // DeviceProperties::acl_data_packet_size_ + ACL header + H4 header
+
+int ConnectToSocket() {
+ auto* config = bluetooth::hal::HciHalHostRootcanalConfig::Get();
+ const std::string& server = config->GetServerAddress();
+ int port = config->GetPort();
+
+ int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (socket_fd < 1) {
+ bluetooth::log::error("can't create socket: {}", strerror(errno));
+ return INVALID_FD;
+ }
+
+ struct hostent* host;
+ host = gethostbyname(server.c_str());
+ if (host == nullptr) {
+ bluetooth::log::error("can't get server name");
+ return INVALID_FD;
+ }
+
+ struct sockaddr_in serv_addr;
+ memset((void*)&serv_addr, 0, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = INADDR_ANY;
+ serv_addr.sin_port = htons(port);
+
+ int result = connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
+ if (result < 0) {
+ bluetooth::log::error("can't connect: {}", strerror(errno));
+ return INVALID_FD;
+ }
+
+ timeval socket_timeout{
+ .tv_sec = 3,
+ .tv_usec = 0,
+ };
+ int ret = setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, &socket_timeout, sizeof(socket_timeout));
+ if (ret == -1) {
+ bluetooth::log::error("can't control socket fd: {}", strerror(errno));
+ return INVALID_FD;
+ }
+ return socket_fd;
+}
+} // namespace
+
+namespace bluetooth {
+namespace hal {
+
+void HciHalImpl::registerIncomingPacketCallback(HciHalCallbacks* callback) {
+ std::lock_guard<std::mutex> lock(api_mutex_);
+ log::info("before");
+ {
+ std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
+ log::assert_that(incoming_packet_callback_ == nullptr && callback != nullptr,
+ "assert failed: incoming_packet_callback_ == nullptr && callback != nullptr");
+ incoming_packet_callback_ = callback;
+ }
+ log::info("after");
+}
+
+void HciHalImpl::unregisterIncomingPacketCallback() {
+ std::lock_guard<std::mutex> lock(api_mutex_);
+ log::info("before");
+ {
+ std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
+ incoming_packet_callback_ = nullptr;
+ }
+ log::info("after");
+}
+
+void HciHalImpl::sendHciCommand(HciPacket command) {
+ std::lock_guard<std::mutex> lock(api_mutex_);
+ log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
+ std::vector<uint8_t> packet = std::move(command);
+ if (btsnoop_logger_) {
+ btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
+ SnoopLogger::PacketType::CMD);
+ }
+ packet.insert(packet.cbegin(), kH4Command);
+ write_to_fd(packet);
+}
+
+void HciHalImpl::sendAclData(HciPacket data) {
+ std::lock_guard<std::mutex> lock(api_mutex_);
+ log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
+ std::vector<uint8_t> packet = std::move(data);
+ if (btsnoop_logger_) {
+ btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
+ SnoopLogger::PacketType::ACL);
+ }
+ packet.insert(packet.cbegin(), kH4Acl);
+ write_to_fd(packet);
+}
+
+void HciHalImpl::sendScoData(HciPacket data) {
+ std::lock_guard<std::mutex> lock(api_mutex_);
+ log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
+ std::vector<uint8_t> packet = std::move(data);
+ if (btsnoop_logger_) {
+ btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
+ SnoopLogger::PacketType::SCO);
+ }
+ packet.insert(packet.cbegin(), kH4Sco);
+ write_to_fd(packet);
+}
+
+void HciHalImpl::sendIsoData(HciPacket data) {
+ std::lock_guard<std::mutex> lock(api_mutex_);
+ log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
+ std::vector<uint8_t> packet = std::move(data);
+ if (btsnoop_logger_) {
+ btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING,
+ SnoopLogger::PacketType::ISO);
+ }
+ packet.insert(packet.cbegin(), kH4Iso);
+ write_to_fd(packet);
+}
+
+HciHalImpl::HciHalImpl() {
+ std::lock_guard<std::mutex> lock(api_mutex_);
+ log::assert_that(sock_fd_ == INVALID_FD, "assert failed: sock_fd_ == INVALID_FD");
+ sock_fd_ = ConnectToSocket();
+ log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
+ reactable_ = hci_incoming_thread_.GetReactor()->Register(
+ sock_fd_, common::Bind(&HciHalImpl::incoming_packet_received, common::Unretained(this)),
+ common::Bind(&HciHalImpl::send_packet_ready, common::Unretained(this)));
+ hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
+ os::Reactor::REACT_ON_READ_ONLY);
+ btsnoop_logger_ = shim::GetSnoopLogger();
+ log::info("HAL opened successfully");
+}
+
+HciHalImpl::~HciHalImpl() {
+ std::lock_guard<std::mutex> lock(api_mutex_);
+ log::info("HAL is closing");
+ if (reactable_ != nullptr) {
+ hci_incoming_thread_.GetReactor()->Unregister(reactable_);
+ log::info("HAL is stopping, start waiting for last callback");
+ // Wait up to 1 second for the last incoming packet callback to finish
+ hci_incoming_thread_.GetReactor()->WaitForUnregisteredReactable(
+ std::chrono::milliseconds(1000));
+ log::info("HAL is stopping, finished waiting for last callback");
+ log::assert_that(sock_fd_ != INVALID_FD, "assert failed: sock_fd_ != INVALID_FD");
+ }
+ reactable_ = nullptr;
+ {
+ std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
+ incoming_packet_callback_ = nullptr;
+ }
+ ::close(sock_fd_);
+ sock_fd_ = INVALID_FD;
+ log::info("HAL is closed");
+}
+
+void HciHalImpl::write_to_fd(HciPacket packet) {
+ // TODO: replace this with new queue when it's ready
+ hci_outgoing_queue_.emplace(packet);
+ if (hci_outgoing_queue_.size() == 1) {
+ hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
+ os::Reactor::REACT_ON_READ_WRITE);
+ }
+}
+
+void HciHalImpl::send_packet_ready() {
+ std::lock_guard<std::mutex> lock(api_mutex_);
+ if (hci_outgoing_queue_.empty()) {
+ return;
+ }
+ auto packet_to_send = hci_outgoing_queue_.front();
+ auto bytes_written = write(sock_fd_, (void*)packet_to_send.data(), packet_to_send.size());
+ hci_outgoing_queue_.pop();
+ if (bytes_written == -1) {
+ abort();
+ }
+ if (hci_outgoing_queue_.empty()) {
+ hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
+ os::Reactor::REACT_ON_READ_ONLY);
+ }
+}
+
+bool HciHalImpl::socketRecvAll(void* buffer, int bufferLen) {
+ auto buf = static_cast<char*>(buffer);
+ while (bufferLen > 0) {
+ ssize_t ret;
+ RUN_NO_INTR(ret = recv(sock_fd_, buf, bufferLen, 0));
+ if (ret <= 0) {
+ return false;
+ }
+ buf += ret;
+ bufferLen -= ret;
+ }
+ return true;
+}
+
+void HciHalImpl::incoming_packet_received() {
+ {
+ std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
+ if (incoming_packet_callback_ == nullptr) {
+ log::info("Dropping a packet");
+ return;
+ }
+ }
+ uint8_t buf[kBufSize] = {};
+
+ ssize_t received_size;
+ RUN_NO_INTR(received_size = recv(sock_fd_, buf, kH4HeaderSize, 0));
+ log::assert_that(received_size != -1, "Can't receive from socket: {}", strerror(errno));
+ if (received_size == 0) {
+ log::warn("Can't read H4 header. EOF received");
+ raise(SIGINT);
+ return;
+ }
+
+ if (buf[0] == kH4Event) {
+ log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciEvtHeaderSize),
+ "Can't receive from socket: {}", strerror(errno));
+
+ uint8_t hci_evt_parameter_total_length = buf[2];
+ log::assert_that(
+ socketRecvAll(buf + kH4HeaderSize + kHciEvtHeaderSize, hci_evt_parameter_total_length),
+ "Can't receive from socket: {}", strerror(errno));
+
+ HciPacket receivedHciPacket;
+ receivedHciPacket.assign(buf + kH4HeaderSize, buf + kH4HeaderSize + kHciEvtHeaderSize +
+ hci_evt_parameter_total_length);
+ if (btsnoop_logger_) {
+ btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
+ SnoopLogger::PacketType::EVT);
+ }
+ {
+ std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
+ if (incoming_packet_callback_ == nullptr) {
+ log::info("Dropping an event after processing");
+ return;
+ }
+ incoming_packet_callback_->hciEventReceived(receivedHciPacket);
+ }
+ }
+
+ if (buf[0] == kH4Acl) {
+ log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciAclHeaderSize),
+ "Can't receive from socket: {}", strerror(errno));
+
+ uint16_t hci_acl_data_total_length = (buf[4] << 8) + buf[3];
+ log::assert_that(
+ socketRecvAll(buf + kH4HeaderSize + kHciAclHeaderSize, hci_acl_data_total_length),
+ "Can't receive from socket: {}", strerror(errno));
+
+ HciPacket receivedHciPacket;
+ receivedHciPacket.assign(buf + kH4HeaderSize,
+ buf + kH4HeaderSize + kHciAclHeaderSize + hci_acl_data_total_length);
+ if (btsnoop_logger_) {
+ btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
+ SnoopLogger::PacketType::ACL);
+ }
+ {
+ std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
+ if (incoming_packet_callback_ == nullptr) {
+ log::info("Dropping an ACL packet after processing");
+ return;
+ }
+ incoming_packet_callback_->aclDataReceived(receivedHciPacket);
+ }
+ }
+
+ if (buf[0] == kH4Sco) {
+ log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciScoHeaderSize),
+ "Can't receive from socket: {}", strerror(errno));
+
+ uint8_t hci_sco_data_total_length = buf[3];
+ log::assert_that(
+ socketRecvAll(buf + kH4HeaderSize + kHciScoHeaderSize, hci_sco_data_total_length),
+ "Can't receive from socket: {}", strerror(errno));
+
+ HciPacket receivedHciPacket;
+ receivedHciPacket.assign(buf + kH4HeaderSize,
+ buf + kH4HeaderSize + kHciScoHeaderSize + hci_sco_data_total_length);
+ if (btsnoop_logger_) {
+ btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
+ SnoopLogger::PacketType::SCO);
+ }
+ {
+ std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
+ if (incoming_packet_callback_ == nullptr) {
+ log::info("Dropping a SCO packet after processing");
+ return;
+ }
+ incoming_packet_callback_->scoDataReceived(receivedHciPacket);
+ }
+ }
+
+ if (buf[0] == kH4Iso) {
+ log::assert_that(socketRecvAll(buf + kH4HeaderSize, kHciIsoHeaderSize),
+ "Can't receive from socket: {}", strerror(errno));
+
+ uint16_t hci_iso_data_total_length = ((buf[4] & 0x3f) << 8) + buf[3];
+ log::assert_that(
+ socketRecvAll(buf + kH4HeaderSize + kHciIsoHeaderSize, hci_iso_data_total_length),
+ "Can't receive from socket: {}", strerror(errno));
+
+ HciPacket receivedHciPacket;
+ receivedHciPacket.assign(buf + kH4HeaderSize,
+ buf + kH4HeaderSize + kHciIsoHeaderSize + hci_iso_data_total_length);
+ if (btsnoop_logger_) {
+ btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING,
+ SnoopLogger::PacketType::ISO);
+ }
+ {
+ std::lock_guard<std::mutex> incoming_packet_callback_lock(incoming_packet_callback_mutex_);
+ if (incoming_packet_callback_ == nullptr) {
+ log::info("Dropping a ISO packet after processing");
+ return;
+ }
+ incoming_packet_callback_->isoDataReceived(receivedHciPacket);
+ }
+ }
+ memset(buf, 0, kBufSize);
+}
+} // namespace hal
+} // namespace bluetooth
diff --git a/system/gd/hal/hci_hal_host_test.cc b/system/gd/hal/hci_hal_impl_host_rootcanal_test.cc
similarity index 98%
rename from system/gd/hal/hci_hal_host_test.cc
rename to system/gd/hal/hci_hal_impl_host_rootcanal_test.cc
index d4539d6..5f67fe3 100644
--- a/system/gd/hal/hci_hal_host_test.cc
+++ b/system/gd/hal/hci_hal_impl_host_rootcanal_test.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "hal/hci_hal_host.h"
+#include "hal/hci_hal_impl_host.h"
#include <bluetooth/log.h>
#include <fcntl.h>
@@ -33,8 +33,9 @@
#include <vector>
#include "com_android_bluetooth_flags.h"
-#include "hal/hci_hal.h"
+#include "hal/hci_hal_host_rootcanal_config.h"
#include "hal/serialize_packet.h"
+#include "module.h" // ModuleRegistry
#include "os/thread.h"
#include "os/utils.h"
#include "packet/raw_builder.h"
@@ -146,7 +147,8 @@
HciHalHostRootcanalConfig::Get()->SetPort(kTestPort);
fake_server_ = new FakeRootcanalDesktopHciServer;
- hal_ = fake_registry_.Start<HciHal>(thread_, handler_);
+
+ hal_ = std::make_unique<HciHalImpl>();
hal_->registerIncomingPacketCallback(&callbacks_);
fake_server_socket_ =
fake_server_->Accept(); // accept() after client is connected to avoid blocking
@@ -160,6 +162,7 @@
if (com::android::bluetooth::flags::same_handler_for_all_modules()) {
handler_->WaitUntilStopped(bluetooth::kHandlerStopTimeout);
}
+ hal_.reset();
fake_registry_.StopAll();
delete handler_;
close(fake_server_socket_);
@@ -174,7 +177,7 @@
}
FakeRootcanalDesktopHciServer* fake_server_ = nullptr;
- HciHal* hal_ = nullptr;
+ std::unique_ptr<HciHal> hal_ = nullptr;
ModuleRegistry fake_registry_;
TestHciHalCallbacks callbacks_;
int fake_server_socket_ = -1;
diff --git a/system/gd/hal/link_clocker.cc b/system/gd/hal/link_clocker.cc
index 0a7ee83..98f0b4f 100644
--- a/system/gd/hal/link_clocker.cc
+++ b/system/gd/hal/link_clocker.cc
@@ -102,6 +102,4 @@
(*g_read_clock_handler).OnEvent(timestamp_us, bt_clock << 4);
}
-const ModuleFactory LinkClocker::Factory = ModuleFactory([]() { return new LinkClocker(); });
-
} // namespace bluetooth::hal
diff --git a/system/gd/hal/link_clocker.h b/system/gd/hal/link_clocker.h
index 34286bf..30e023c 100644
--- a/system/gd/hal/link_clocker.h
+++ b/system/gd/hal/link_clocker.h
@@ -32,23 +32,12 @@
virtual void OnEvent(uint32_t timestamp, uint32_t bt_clock) = 0;
};
-class LinkClocker : public ::bluetooth::Module {
+class LinkClocker {
public:
- static const ModuleFactory Factory;
-
void OnHciEvent(const HciPacket& packet);
static void Register(ReadClockHandler*);
static void Unregister();
-
-protected:
- LinkClocker() = default;
-
- void ListDependencies(ModuleList*) const override {}
- void Start() override {}
- void Stop() override {}
-
- std::string ToString() const override { return std::string("LinkClocker"); }
};
} // namespace bluetooth::hal
diff --git a/system/gd/hci/controller_impl_test.cc b/system/gd/hci/controller_impl_test.cc
index a05179e..3e10443 100644
--- a/system/gd/hci/controller_impl_test.cc
+++ b/system/gd/hci/controller_impl_test.cc
@@ -29,6 +29,7 @@
#include "common/bind.h"
#include "hci/address.h"
#include "hci/hci_layer_fake.h"
+#include "module.h" // FakeModuleRegistry
#include "os/thread.h"
#include "packet/raw_builder.h"
diff --git a/system/gd/hci/fuzz/fuzz_hci_layer.h b/system/gd/hci/fuzz/fuzz_hci_layer.h
index ee2db74..15e54d7 100644
--- a/system/gd/hci/fuzz/fuzz_hci_layer.h
+++ b/system/gd/hci/fuzz/fuzz_hci_layer.h
@@ -18,6 +18,7 @@
#include <fuzzer/FuzzedDataProvider.h>
+#include <map>
#include <vector>
#include "fuzz/helpers.h"
diff --git a/system/gd/hci/fuzz/hci_layer_fuzz_test.cc b/system/gd/hci/fuzz/hci_layer_fuzz_test.cc
index a5dac3f..c55eb6a 100644
--- a/system/gd/hci/fuzz/hci_layer_fuzz_test.cc
+++ b/system/gd/hci/fuzz/hci_layer_fuzz_test.cc
@@ -38,9 +38,9 @@
FuzzedDataProvider dataProvider(data, size);
static FuzzTestModuleRegistry moduleRegistry = FuzzTestModuleRegistry();
- FuzzHciHal* fuzzHal = moduleRegistry.Inject<FuzzHciHal>(&HciHal::Factory);
+ std::unique_ptr<FuzzHciHal> fuzzHal = std::make_unique<FuzzHciHal>();
std::unique_ptr<HciInterface> hciLayer =
- std::make_unique<HciLayer>(moduleRegistry.GetTestHandler(), fuzzHal);
+ std::make_unique<HciLayer>(moduleRegistry.GetTestHandler(), fuzzHal.get());
std::unique_ptr<HciLayerFuzzClient> fuzzClient =
std::make_unique<HciLayerFuzzClient>(moduleRegistry.GetTestHandler(), hciLayer.get());
@@ -58,6 +58,7 @@
fuzzClient.reset();
hciLayer.reset();
+ fuzzHal.reset();
moduleRegistry.WaitForIdleAndStopAll();
fake_timerfd_reset();
return 0;
diff --git a/system/gd/hci/hci_layer_test.cc b/system/gd/hci/hci_layer_test.cc
index 81bde41..6346542 100644
--- a/system/gd/hci/hci_layer_test.cc
+++ b/system/gd/hci/hci_layer_test.cc
@@ -199,18 +199,15 @@
counting_bytes.push_back(i);
counting_down_bytes.push_back(~i);
}
- hal = new hal::TestHciHal();
- fake_registry_.InjectTestModule(&hal::HciHal::Factory, hal);
- fake_registry_.Start<hal::HciHal>(&fake_registry_.GetTestThread(),
- fake_registry_.GetTestHandler());
+ hal = std::make_unique<hal::TestHciHal>();
bluetooth::hci::testing::mock_storage_ = new storage::StorageModule(
com::android::bluetooth::flags::same_handler_for_all_modules()
? fake_registry_.GetTestHandler()
: new os::Handler(&fake_registry_.GetTestThread()));
bluetooth::hci::testing::mock_storage_->Start();
- hci = std::make_unique<HciLayer>(fake_registry_.GetTestHandler(), hal);
+ hci = std::make_unique<HciLayer>(fake_registry_.GetTestHandler(), hal.get());
upper = std::make_unique<DependsOnHci>(fake_registry_.GetTestHandler(), hci.get());
// Verify that reset was received
@@ -233,6 +230,7 @@
std::chrono::milliseconds(20));
upper.reset();
hci.reset();
+ hal.reset();
fake_registry_.StopAll();
}
@@ -245,7 +243,7 @@
}
std::unique_ptr<DependsOnHci> upper = nullptr;
- hal::TestHciHal* hal = nullptr;
+ std::unique_ptr<hal::TestHciHal> hal = nullptr;
std::unique_ptr<HciLayer> hci = nullptr;
TestModuleRegistry fake_registry_;
};
diff --git a/system/gd/hci/hci_layer_unittest.cc b/system/gd/hci/hci_layer_unittest.cc
index 068fd95..8ab6854 100644
--- a/system/gd/hci/hci_layer_unittest.cc
+++ b/system/gd/hci/hci_layer_unittest.cc
@@ -85,12 +85,9 @@
class HciLayerTest : public ::testing::Test {
protected:
void SetUp() override {
- hal_ = new hal::TestHciHal();
- fake_registry_.InjectTestModule(&hal::HciHal::Factory, hal_);
- fake_registry_.Start<hal::HciHal>(&fake_registry_.GetTestThread(),
- fake_registry_.GetTestHandler());
+ hal_ = std::make_unique<hal::TestHciHal>();
hci_handler_ = fake_registry_.GetTestHandler();
- hci_ = std::make_unique<HciLayer>(hci_handler_, hal_);
+ hci_ = std::make_unique<HciLayer>(hci_handler_, hal_.get());
::testing::FLAGS_gtest_death_test_style = "threadsafe";
sync_handler();
}
@@ -98,7 +95,7 @@
void TearDown() override {
fake_registry_.SynchronizeHandler(hci_handler_, std::chrono::milliseconds(20));
hci_.reset();
- fake_registry_.StopAll();
+ hal_.reset();
}
void FakeTimerAdvance(uint64_t ms) {
@@ -122,7 +119,7 @@
"assert failed: fake_registry_.GetTestThread().GetReactor()->WaitForIdle(2s)");
}
- hal::TestHciHal* hal_ = nullptr;
+ std::unique_ptr<hal::TestHciHal> hal_ = nullptr;
std::unique_ptr<HciLayer> hci_ = nullptr;
os::Handler* hci_handler_ = nullptr;
TestModuleRegistry fake_registry_;
diff --git a/system/gd/hci/le_advertising_manager_impl_test.cc b/system/gd/hci/le_advertising_manager_impl_test.cc
index 38cbe15..21878eb 100644
--- a/system/gd/hci/le_advertising_manager_impl_test.cc
+++ b/system/gd/hci/le_advertising_manager_impl_test.cc
@@ -34,6 +34,7 @@
#include "hci/hci_layer_fake.h"
#include "hci/le_address_manager.h"
#include "hci/le_on_advertising_set_terminated_interface.h"
+#include "module.h"
#include "os/thread.h"
#include "packet/raw_builder.h"
diff --git a/system/gd/lpp/lpp_offload_manager.cc b/system/gd/lpp/lpp_offload_manager.cc
index 4518cc9..1615fd1 100644
--- a/system/gd/lpp/lpp_offload_manager.cc
+++ b/system/gd/lpp/lpp_offload_manager.cc
@@ -26,24 +26,13 @@
namespace bluetooth::lpp {
-const ModuleFactory LppOffloadManager::Factory =
- ModuleFactory([]() { return new LppOffloadManager(); });
-
struct LppOffloadManager::impl {
- ~impl() {}
-
- void start(os::Handler* handler, hal::SocketHal* socket_hal) {
+ impl(os::Handler* handler, hal::SocketHal* socket_hal)
+ : handler_(handler), socket_hal_(socket_hal) {
log::info("");
- handler_ = handler;
- socket_hal_ = socket_hal;
socket_capabilities_ = socket_hal_->GetSocketCapabilities();
}
- void stop() {
- log::info("");
- socket_capabilities_ = {};
- }
-
bool register_socket_hal_callbacks(hal::SocketHalCallback* callbacks) {
log::info("");
return socket_hal_->RegisterCallback(callbacks);
@@ -69,18 +58,12 @@
hal::SocketCapabilities socket_capabilities_;
};
-LppOffloadManager::LppOffloadManager() { pimpl_ = std::make_unique<impl>(); }
+LppOffloadManager::LppOffloadManager(os::Handler* handler, hal::SocketHal* socket_hal) {
+ pimpl_ = std::make_unique<impl>(handler, socket_hal);
+}
LppOffloadManager::~LppOffloadManager() = default;
-void LppOffloadManager::ListDependencies(ModuleList* list) const { list->add<hal::SocketHal>(); }
-
-void LppOffloadManager::Start() { pimpl_->start(GetHandler(), GetDependency<hal::SocketHal>()); }
-
-void LppOffloadManager::Stop() { pimpl_->stop(); }
-
-std::string LppOffloadManager::ToString() const { return "Low Power Processor Offload Manager"; }
-
bool LppOffloadManager::RegisterSocketHalCallback(hal::SocketHalCallback* callbacks) {
return pimpl_->register_socket_hal_callbacks(callbacks);
}
@@ -94,7 +77,7 @@
}
void LppOffloadManager::SocketClosed(uint64_t socket_id) {
- CallOn(pimpl_.get(), &impl::socket_closed, socket_id);
+ pimpl_->handler_->CallOn(pimpl_.get(), &impl::socket_closed, socket_id);
}
} // namespace bluetooth::lpp
diff --git a/system/gd/lpp/lpp_offload_manager.h b/system/gd/lpp/lpp_offload_manager.h
index c8b90a69..8a410e2 100644
--- a/system/gd/lpp/lpp_offload_manager.h
+++ b/system/gd/lpp/lpp_offload_manager.h
@@ -18,16 +18,15 @@
#include <bluetooth/log.h>
#include <memory>
-#include <string>
#include "lpp_offload_interface.h"
-#include "module.h"
namespace bluetooth::lpp {
-class LppOffloadManager : public bluetooth::Module, public LppOffloadInterface {
+/* Low Power Processor Offload Manager*/
+class LppOffloadManager : public LppOffloadInterface {
public:
- LppOffloadManager();
+ LppOffloadManager(os::Handler* handler, hal::SocketHal* socket_hal);
LppOffloadManager(const LppOffloadManager&) = delete;
@@ -43,17 +42,6 @@
void SocketClosed(uint64_t socket_id) override;
- static const ModuleFactory Factory;
-
-protected:
- void ListDependencies(ModuleList* list) const override;
-
- void Start() override;
-
- void Stop() override;
-
- std::string ToString() const override;
-
private:
struct impl;
std::unique_ptr<impl> pimpl_;
diff --git a/system/main/shim/entry.cc b/system/main/shim/entry.cc
index e85c031..93299af 100644
--- a/system/main/shim/entry.cc
+++ b/system/main/shim/entry.cc
@@ -57,7 +57,7 @@
hal::SnoopLogger* GetSnoopLogger() { return Stack::GetInstance()->GetSnoopLogger(); }
lpp::LppOffloadInterface* GetLppOffloadManager() {
- return Stack::GetInstance()->GetInstance<lpp::LppOffloadManager>();
+ return Stack::GetInstance()->GetLppOffloadInterface();
}
storage::StorageModule* GetStorage() { return Stack::GetInstance()->GetStorage(); }
diff --git a/system/main/shim/stack.cc b/system/main/shim/stack.cc
index e9173b1..32bacdb 100644
--- a/system/main/shim/stack.cc
+++ b/system/main/shim/stack.cc
@@ -29,7 +29,8 @@
#include <string>
#include "common/strings.h"
-#include "hal/hci_hal.h"
+#include "hal/hci_hal_impl.h"
+#include "hal/link_clocker.h"
#include "hal/ranging_hal_impl.h"
#include "hal/snoop_logger.h"
#include "hci/acl_manager/acl_scheduler.h"
@@ -68,6 +69,9 @@
Acl* acl_ = nullptr;
std::shared_ptr<storage::StorageModule> storage_ = nullptr;
std::shared_ptr<hal::SnoopLogger> snoop_logger_ = nullptr;
+ std::unique_ptr<lpp::LppOffloadManager> lpp_offload_manager_ = nullptr;
+ std::unique_ptr<hal::LinkClocker> link_clocker_ = nullptr;
+ std::unique_ptr<hal::HciHal> hci_hal_ = nullptr;
std::unique_ptr<hal::RangingHal> ranging_hal_ = nullptr;
std::unique_ptr<hci::HciLayer> hci_layer_ = nullptr;
std::unique_ptr<hci::Controller> controller_ = nullptr;
@@ -108,11 +112,10 @@
#if TARGET_FLOSS
modules.add<sysprops::SyspropsModule>();
#else
- if (com::android::bluetooth::flags::socket_settings_api()) { // Added with aosp/3286716
- modules.add<lpp::LppOffloadManager>();
+ if (com::android::bluetooth::flags::socket_settings_api()) {
+ modules.add<hal::SocketHal>();
}
#endif
- modules.add<hal::HciHal>();
management_thread_ = new Thread("management_thread", Thread::Priority::NORMAL);
management_handler_ = new Handler(management_thread_);
@@ -142,8 +145,7 @@
log::info("Successfully toggled Gd stack");
// Make sure the leaf modules are started
- log::assert_that(GetInstance<hal::HciHal>() != nullptr,
- "assert failed: GetInstance<hal::HciHal>() != nullptr");
+ log::assert_that(pimpl_->hci_hal_ != nullptr, "assert failed pimpl_->hci_hal_ != nullptr");
pimpl_->acl_ = new Acl(stack_handler_, GetAclInterface());
@@ -227,6 +229,12 @@
return pimpl_->snoop_logger_.get();
}
+lpp::LppOffloadInterface* Stack::GetLppOffloadInterface() const {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ log::assert_that(is_running_, "assert failed: is_running_");
+ return pimpl_->lpp_offload_manager_.get();
+}
+
hci::HciInterface* Stack::GetHciLayer() const {
std::lock_guard<std::recursive_mutex> lock(mutex_);
log::assert_that(is_running_, "assert failed: is_running_");
@@ -303,13 +311,27 @@
pimpl_->snoop_logger_->Start();
registry_.Start(modules, stack_thread_, stack_handler_);
- auto hci_hal = static_cast<hal::HciHal*>(registry_.Get(&hal::HciHal::Factory));
+#ifndef TARGET_FLOSS
+ if (com::android::bluetooth::flags::socket_settings_api()) { // Added with aosp/3286716
+ auto socket_hal = static_cast<hal::SocketHal*>(registry_.Get(&hal::SocketHal::Factory));
+ log::info("Starting LppOffloadManager");
+ pimpl_->lpp_offload_manager_ =
+ std::make_unique<lpp::LppOffloadManager>(stack_handler_, socket_hal);
+ }
+#endif
+
+ log::info("Starting LinkClocker");
+ pimpl_->link_clocker_ = std::make_unique<hal::LinkClocker>();
+
+ log::info("Starting HciHal");
+ pimpl_->hci_hal_ = std::make_unique<hal::HciHalImpl>(stack_handler_, pimpl_->link_clocker_.get(),
+ pimpl_->snoop_logger_.get());
log::info("Starting RangingHal");
pimpl_->ranging_hal_ = std::make_unique<hal::RangingHalImpl>();
log::info("Starting HciLayer");
- pimpl_->hci_layer_ = std::make_unique<hci::HciLayer>(stack_handler_, hci_hal);
+ pimpl_->hci_layer_ = std::make_unique<hci::HciLayer>(stack_handler_, pimpl_->hci_hal_.get());
log::info("Starting Controller");
pimpl_->controller_ =
@@ -329,7 +351,7 @@
log::info("Starting MsftExtensionManager");
pimpl_->msft_extension_manager_ = std::make_unique<hci::MsftExtensionManager>(
- stack_handler_, hci_hal, pimpl_->hci_layer_.get());
+ stack_handler_, pimpl_->hci_hal_.get(), pimpl_->hci_layer_.get());
log::info("Starting LeScanningManagerImpl");
pimpl_->le_scanning_manager_ = std::make_unique<hci::LeScanningManagerImpl>(
@@ -380,6 +402,17 @@
log::info("Stopping RangingHal");
pimpl_->ranging_hal_.reset();
+ log::info("Stopping HciHal");
+ pimpl_->hci_hal_.reset();
+
+ log::info("Stopping LinkClocker");
+ pimpl_->link_clocker_.reset();
+
+ if (pimpl_->lpp_offload_manager_) {
+ log::info("Stopping LppOffloadManager");
+ pimpl_->lpp_offload_manager_.reset();
+ }
+
registry_.StopAll();
pimpl_->snoop_logger_->Stop();
diff --git a/system/main/shim/stack.h b/system/main/shim/stack.h
index 492e991..7721e40 100644
--- a/system/main/shim/stack.h
+++ b/system/main/shim/stack.h
@@ -25,6 +25,7 @@
#include "hci/le_advertising_manager.h"
#include "hci/le_scanning_manager.h"
#include "hci/remote_name_request.h"
+#include "lpp/lpp_offload_interface.h"
#include "module.h"
#include "os/handler.h"
#include "os/thread.h"
@@ -78,6 +79,7 @@
virtual Acl* GetAcl() const;
virtual storage::StorageModule* GetStorage() const;
virtual hal::SnoopLogger* GetSnoopLogger() const;
+ virtual lpp::LppOffloadInterface* GetLppOffloadInterface() const;
virtual hci::HciInterface* GetHciLayer() const;
virtual hci::Controller* GetController() const;
virtual hci::RemoteNameRequestModule* GetRemoteNameRequest() const;
diff --git a/system/main/test/main_shim_test.cc b/system/main/test/main_shim_test.cc
index b604c49..29d7584 100644
--- a/system/main/test/main_shim_test.cc
+++ b/system/main/test/main_shim_test.cc
@@ -311,10 +311,6 @@
} // namespace testing
} // namespace shim
-namespace hal {
-const ModuleFactory HciHal::Factory = ModuleFactory([]() { return nullptr; });
-} // namespace hal
-
} // namespace bluetooth
class MainShimTest : public testing::Test {
diff --git a/system/osi/src/alarm.cc b/system/osi/src/alarm.cc
index 6aaf435..f12c287 100644
--- a/system/osi/src/alarm.cc
+++ b/system/osi/src/alarm.cc
@@ -23,6 +23,7 @@
#include <android_bluetooth_sysprop.h>
#include <base/cancelable_callback.h>
#include <bluetooth/log.h>
+#include <com_android_bluetooth_flags.h>
#include <fcntl.h>
#include <hardware/bluetooth.h>
#include <malloc.h>
@@ -244,6 +245,9 @@
{
std::lock_guard<std::mutex> lock(alarms_mutex);
local_mutex_ref = alarm->callback_mutex;
+ if (com::android::bluetooth::flags::set_ptr_null_after_free()) {
+ log::assert_that(local_mutex_ref != nullptr, "assert failed: local_mutex_ref != nullptr");
+ }
alarm_cancel_internal(alarm);
}
diff --git a/system/osi/test/fuzzers/alarm/Android.bp b/system/osi/test/fuzzers/alarm/Android.bp
index 3af1096..88d93f2 100644
--- a/system/osi/test/fuzzers/alarm/Android.bp
+++ b/system/osi/test/fuzzers/alarm/Android.bp
@@ -22,6 +22,8 @@
"libstatssocket",
],
static_libs: [
+ "bluetooth_flags_c_lib",
+ "libaconfig_storage_read_api_cc",
"libbluetooth_log",
"libbt-common",
"libchrome",
diff --git a/system/stack/Android.bp b/system/stack/Android.bp
index 2538e09..fd303a2 100644
--- a/system/stack/Android.bp
+++ b/system/stack/Android.bp
@@ -324,8 +324,15 @@
},
}
-cc_fuzz {
- name: "sdp-fuzzer",
+filegroup {
+ name: "SdpFuzzerSources",
+ srcs: [
+ "fuzzers/sdp_fuzzer.cc",
+ ],
+}
+
+cc_defaults {
+ name: "sdp_fuzzer_default",
defaults: [
"btstack_fuzzer_default",
"fluoride_defaults",
@@ -335,6 +342,7 @@
],
srcs: [
":LegacyStackSdp",
+ ":SdpFuzzerSources",
":TestCommonMockFunctions",
":TestFakeOsi",
":TestMockBtif",
@@ -342,7 +350,6 @@
":TestMockMainShim",
":TestMockStackBtm",
":TestMockStackL2cap",
- "fuzzers/sdp_fuzzer.cc",
],
static_libs: [
"bluetooth_flags_c_lib",
@@ -357,6 +364,14 @@
],
}
+cc_fuzz {
+ name: "sdp-fuzzer",
+ team: "trendy_team_bluetooth",
+ defaults: [
+ "sdp_fuzzer_default",
+ ],
+}
+
filegroup {
name: "RfcommFuzzerSources",
srcs: [
@@ -424,8 +439,18 @@
],
}
-cc_fuzz {
- name: "gatt-fuzzer",
+filegroup {
+ name: "GattFuzzerSources",
+ srcs: [
+ "ais/*.cc",
+ "eatt/*.cc",
+ "fuzzers/gatt_fuzzer.cc",
+ "gatt/*.cc",
+ ],
+}
+
+cc_defaults {
+ name: "gatt_fuzzer_default",
defaults: [
"btstack_fuzzer_default",
"fluoride_defaults",
@@ -433,10 +458,12 @@
include_dirs: [
"external/flatbuffers/include",
"external/rust/android-crates-io/crates/quiche/deps/boringssl/src/include",
+ "packages/modules/Bluetooth/system/stack",
"packages/modules/Bluetooth/system/stack/btm",
],
srcs: [
":BluetoothPacketSources",
+ ":GattFuzzerSources",
":TestCommonMockFunctions",
":TestCommonStackConfig",
":TestFakeOsi",
@@ -453,10 +480,6 @@
":TestMockStackHcic",
":TestMockStackL2cap",
":TestMockStackSdp",
- "ais/*.cc",
- "eatt/*.cc",
- "fuzzers/gatt_fuzzer.cc",
- "gatt/*.cc",
],
shared_libs: [
"libaconfig_storage_read_api_cc",
@@ -478,6 +501,14 @@
}
cc_fuzz {
+ name: "gatt-fuzzer",
+ team: "trendy_team_bluetooth",
+ defaults: [
+ "gatt_fuzzer_default",
+ ],
+}
+
+cc_fuzz {
name: "smp-fuzzer",
defaults: [
"btstack_fuzzer_default",
diff --git a/system/stack/fuzzers/test/Android.bp b/system/stack/fuzzers/test/Android.bp
index 45540e6..26bbbe4 100644
--- a/system/stack/fuzzers/test/Android.bp
+++ b/system/stack/fuzzers/test/Android.bp
@@ -27,13 +27,12 @@
android: {
sanitize: {
hwaddress: true,
- all_undefined: true,
},
test_config_template: "FuzzerValidationTestTemplate.xml",
},
host: {
sanitize: {
- all_undefined: true,
+ address: true,
},
test_config_template: "FuzzerValidationHostTestTemplate.xml",
},
@@ -45,6 +44,16 @@
srcs: ["data/rfcomm_corpus.zip"],
}
+filegroup {
+ name: "sdp-fuzzer-corpus",
+ srcs: ["data/sdp_corpus.zip"],
+}
+
+filegroup {
+ name: "gatt-fuzzer-corpus",
+ srcs: ["data/gatt_corpus.zip"],
+}
+
cc_test {
name: "rfcomm-fuzzer-validation-test",
defaults: [
@@ -56,3 +65,27 @@
"rfcomm_fuzzer_validation_test.cc",
],
}
+
+cc_test {
+ name: "sdp-fuzzer-validation-test",
+ defaults: [
+ "fuzzer_validation_test_default",
+ "sdp_fuzzer_default",
+ ],
+ data: [":sdp-fuzzer-corpus"],
+ srcs: [
+ "sdp_fuzzer_validation_test.cc",
+ ],
+}
+
+cc_test {
+ name: "gatt-fuzzer-validation-test",
+ defaults: [
+ "fuzzer_validation_test_default",
+ "gatt_fuzzer_default",
+ ],
+ data: [":gatt-fuzzer-corpus"],
+ srcs: [
+ "gatt_fuzzer_validation_test.cc",
+ ],
+}
diff --git a/system/stack/fuzzers/test/data/gatt_corpus.zip b/system/stack/fuzzers/test/data/gatt_corpus.zip
new file mode 100644
index 0000000..322626f
--- /dev/null
+++ b/system/stack/fuzzers/test/data/gatt_corpus.zip
Binary files differ
diff --git a/system/stack/fuzzers/test/data/sdp_corpus.zip b/system/stack/fuzzers/test/data/sdp_corpus.zip
new file mode 100644
index 0000000..6267d74
--- /dev/null
+++ b/system/stack/fuzzers/test/data/sdp_corpus.zip
Binary files differ
diff --git a/system/stack/fuzzers/test/fuzzer_validation_test.cc b/system/stack/fuzzers/test/fuzzer_validation_test.cc
index 621498b..4687aaf 100644
--- a/system/stack/fuzzers/test/fuzzer_validation_test.cc
+++ b/system/stack/fuzzers/test/fuzzer_validation_test.cc
@@ -38,6 +38,11 @@
// Allow referencing of fuzzer entrance function as-is.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
+// TODO: b/280300628 for fixing memory leaks. Until it's fixed leak
+// detection needs to be turned off to unblock fuzzing.
+// NOLINTNEXTLINE(bugprone-reserved-identifier)
+extern "C" const char *__asan_default_options() { return "detect_leaks=0"; }
+
void runFuzzerOnCorpusAndExitProcess() {
for (const auto &corpus_entry : fs::directory_iterator("./data/corpus")) {
if (!corpus_entry.is_regular_file()) {
@@ -52,6 +57,7 @@
corpus.read(data, size);
corpus.close();
LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t *>(data), size);
+ delete[] data;
}
exit(0);
}
diff --git a/system/stack/fuzzers/test/gatt_fuzzer_validation_test.cc b/system/stack/fuzzers/test/gatt_fuzzer_validation_test.cc
new file mode 100644
index 0000000..5d58e82
--- /dev/null
+++ b/system/stack/fuzzers/test/gatt_fuzzer_validation_test.cc
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2025 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include "fuzzer_validation_test.h"
+
+using fuzzer_validation_test::runValidationTest;
+using fuzzer_validation_test::TestEnvironment;
+using testing::InitGoogleTest;
+
+// Write own main function to allow for plugging in the test environment, which runs only once.
+int main(int argc, char** argv) {
+ InitGoogleTest(&argc, argv);
+ TestEnvironment* env = new TestEnvironment("gatt_corpus");
+ AddGlobalTestEnvironment(env);
+ return RUN_ALL_TESTS();
+}
+
+TEST(GattFuzzerValidationTest, DoesNotCrashOnCorpus) { runValidationTest(); }
diff --git a/system/stack/fuzzers/test/sdp_fuzzer_validation_test.cc b/system/stack/fuzzers/test/sdp_fuzzer_validation_test.cc
new file mode 100644
index 0000000..99f7c43
--- /dev/null
+++ b/system/stack/fuzzers/test/sdp_fuzzer_validation_test.cc
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2025 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include "fuzzer_validation_test.h"
+
+using fuzzer_validation_test::runValidationTest;
+using fuzzer_validation_test::TestEnvironment;
+using testing::InitGoogleTest;
+
+// Write own main function to allow for plugging in the test environment, which runs only once.
+int main(int argc, char** argv) {
+ InitGoogleTest(&argc, argv);
+ TestEnvironment* env = new TestEnvironment("sdp_corpus");
+ AddGlobalTestEnvironment(env);
+ return RUN_ALL_TESTS();
+}
+
+TEST(SdpFuzzerValidationTest, DoesNotCrashOnCorpus) { runValidationTest(); }