summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/app/src/com/android/bluetooth/ObexAppParameters.java10
-rw-r--r--android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java16
-rw-r--r--android/app/src/com/android/bluetooth/btservice/RemoteDevices.java30
-rw-r--r--android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java6
-rw-r--r--android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java4
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java75
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java85
-rw-r--r--android/app/src/com/android/bluetooth/mapclient/MnsObexServer.java12
-rw-r--r--android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessage.java7
-rw-r--r--android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java2
-rw-r--r--android/app/src/com/android/bluetooth/mapclient/obex/RequestSetMessageStatus.java8
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java23
-rw-r--r--android/app/src/com/android/bluetooth/opp/Constants.java38
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java34
-rw-r--r--android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java18
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java4
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java86
-rw-r--r--flags/bta_dm.aconfig10
-rw-r--r--offload/hal/Android.bp16
-rw-r--r--offload/hal/include/hal/ffi.h111
-rw-r--r--offload/hal/service.rs18
-rw-r--r--system/bta/has/has_client_test.cc2
-rw-r--r--system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc4
-rw-r--r--system/bta/le_audio/broadcaster/broadcaster_test.cc3
-rw-r--r--system/bta/le_audio/broadcaster/state_machine.cc27
-rw-r--r--system/bta/le_audio/broadcaster/state_machine_test.cc56
-rw-r--r--system/bta/le_audio/client.cc2
-rw-r--r--system/bta/le_audio/device_groups.cc9
-rw-r--r--system/bta/le_audio/device_groups.h1
-rw-r--r--system/bta/le_audio/devices.h3
-rw-r--r--system/bta/le_audio/devices_test.cc1
-rw-r--r--system/bta/le_audio/le_audio_client_test.cc10
-rw-r--r--system/bta/le_audio/mock_state_machine.h4
-rw-r--r--system/bta/le_audio/state_machine.cc118
-rw-r--r--system/bta/le_audio/state_machine.h4
-rw-r--r--system/bta/le_audio/state_machine_test.cc67
-rw-r--r--system/bta/vc/devices_test.cc11
-rw-r--r--system/bta/vc/vc_test.cc2
-rw-r--r--system/gd/hal/hci_hal_android.cc8
-rw-r--r--system/gd/hal/hci_hal_host.cc8
-rw-r--r--system/gd/hal/hci_hal_host_rootcanal.cc5
-rw-r--r--system/gd/hal/snoop_logger.cc75
-rw-r--r--system/gd/hal/snoop_logger.h20
-rw-r--r--system/gd/hal/snoop_logger_socket_thread.cc2
-rw-r--r--system/gd/hal/snoop_logger_socket_thread.h2
-rw-r--r--system/gd/hal/snoop_logger_test.cc691
-rw-r--r--system/gd/hci/distance_measurement_manager.cc114
-rw-r--r--system/main/shim/entry.cc2
-rw-r--r--system/main/shim/stack.cc13
-rw-r--r--system/main/shim/stack.h5
-rw-r--r--system/stack/test/fuzzers/Android.bp47
-rw-r--r--system/stack/test/fuzzers/a2dp/Android.bp17
-rw-r--r--system/stack/test/fuzzers/a2dp/codec/Android.bp45
-rw-r--r--system/stack/test/fuzzers/avrc/Android.bp17
-rw-r--r--system/stack/test/fuzzers/sdp/Android.bp17
55 files changed, 1065 insertions, 960 deletions
diff --git a/android/app/src/com/android/bluetooth/ObexAppParameters.java b/android/app/src/com/android/bluetooth/ObexAppParameters.java
index 80a3645cda..bb5942497d 100644
--- a/android/app/src/com/android/bluetooth/ObexAppParameters.java
+++ b/android/app/src/com/android/bluetooth/ObexAppParameters.java
@@ -18,7 +18,6 @@ package com.android.bluetooth;
import com.android.obex.HeaderSet;
-import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
@@ -58,14 +57,7 @@ public final class ObexAppParameters {
}
public static ObexAppParameters fromHeaderSet(HeaderSet headerset) {
- try {
- byte[] raw = (byte[]) headerset.getHeader(HeaderSet.APPLICATION_PARAMETER);
- return new ObexAppParameters(raw);
- } catch (IOException e) {
- // won't happen
- }
-
- return null;
+ return new ObexAppParameters((byte[]) headerset.getHeader(HeaderSet.APPLICATION_PARAMETER));
}
public byte[] getHeader() {
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java
index 3ab495fdb0..9df35f9388 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java
@@ -88,17 +88,11 @@ public class AvrcpBipObexServer extends ServerRequestHandler {
@Override
public int onConnect(final HeaderSet request, HeaderSet reply) {
debug("onConnect");
- try {
- byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
- debug("onConnect - uuid=" + Arrays.toString(uuid));
- if (!Arrays.equals(uuid, BLUETOOTH_UUID_AVRCP_COVER_ART)) {
- warn("onConnect - uuid didn't match. Not Acceptable");
- return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
- }
- // ...
- } catch (IOException e) {
- warn("onConnect - Something bad happened");
- return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+ byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
+ debug("onConnect - uuid=" + Arrays.toString(uuid));
+ if (!Arrays.equals(uuid, BLUETOOTH_UUID_AVRCP_COVER_ART)) {
+ warn("onConnect - uuid didn't match. Not Acceptable");
+ return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
}
reply.setHeader(HeaderSet.WHO, BLUETOOTH_UUID_AVRCP_COVER_ART);
diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
index a4cb97f295..843137e8da 100644
--- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -1558,6 +1558,19 @@ public class RemoteDevices {
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ // Log transition to key missing state, if the key missing count is 0 which indicates
+ // that the device is bonded until now.
+ if (mAdapterService.getDatabase().getKeyMissingCount(bluetoothDevice) == 0) {
+ MetricsLogger.getInstance()
+ .logBluetoothEvent(
+ bluetoothDevice,
+ BluetoothStatsLog
+ .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__TRANSITION,
+ BluetoothStatsLog
+ .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__BOND_BONDED_TO_ACTION_KEY_MISSING,
+ 0);
+ }
+
// Bond loss detected, add to the count.
mAdapterService.getDatabase().updateKeyMissingCount(bluetoothDevice, true);
@@ -1635,8 +1648,21 @@ public class RemoteDevices {
algorithm = BluetoothDevice.ENCRYPTION_ALGORITHM_E0;
}
- // Successful bond detected, reset the count.
- mAdapterService.getDatabase().updateKeyMissingCount(bluetoothDevice, false);
+ // Log transition to encryption change state (bonded), if the key missing count is > 0
+ // which indicates that the device is in key missing state.
+ if (mAdapterService.getDatabase().getKeyMissingCount(bluetoothDevice) > 0) {
+ MetricsLogger.getInstance()
+ .logBluetoothEvent(
+ bluetoothDevice,
+ BluetoothStatsLog
+ .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__TRANSITION,
+ BluetoothStatsLog
+ .BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__ACTION_KEY_MISSING_TO_ENCRYPTION_CHANGE,
+ 0);
+
+ // Successful bond detected, reset the count.
+ mAdapterService.getDatabase().updateKeyMissingCount(bluetoothDevice, false);
+ }
}
Intent intent =
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java b/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java
index d6490110f7..8c55d02adb 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java
@@ -1620,6 +1620,12 @@ public class DatabaseManager {
}
}
+ /**
+ * Get the key missing count.
+ *
+ * @param device the BluetoothDevice to get the key missing count for.
+ * @return the key missing count, or -1 if the device is not bonded.
+ */
public int getKeyMissingCount(BluetoothDevice device) {
synchronized (mMetadataCache) {
String address = device.getAddress();
diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java
index 04c6f7fff8..833ae3f542 100644
--- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java
+++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java
@@ -50,8 +50,8 @@ public class DistanceMeasurementManager {
private static final int RSSI_MEDIUM_FREQUENCY_INTERVAL_MS = 1000;
private static final int RSSI_HIGH_FREQUENCY_INTERVAL_MS = 500;
private static final int CS_LOW_FREQUENCY_INTERVAL_MS = 5000;
- private static final int CS_MEDIUM_FREQUENCY_INTERVAL_MS = 3000;
- private static final int CS_HIGH_FREQUENCY_INTERVAL_MS = 200;
+ private static final int CS_MEDIUM_FREQUENCY_INTERVAL_MS = 200;
+ private static final int CS_HIGH_FREQUENCY_INTERVAL_MS = 100;
// sync with system/gd/hic/DistanceMeasurementManager
private static final int INVALID_AZIMUTH_ANGLE_DEGREE = -1;
diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java b/android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java
index b5614ea927..ad191ac02e 100644
--- a/android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java
+++ b/android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java
@@ -22,6 +22,8 @@ import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.TransportBlockFilter;
import android.os.ParcelUuid;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
@@ -30,23 +32,22 @@ import java.util.UUID;
/** Helper class used to manage advertisement package filters. */
/* package */ class ScanFilterQueue {
- public static final int TYPE_DEVICE_ADDRESS = 0;
- public static final int TYPE_SERVICE_DATA_CHANGED = 1;
- public static final int TYPE_SERVICE_UUID = 2;
- public static final int TYPE_SOLICIT_UUID = 3;
- public static final int TYPE_LOCAL_NAME = 4;
- public static final int TYPE_MANUFACTURER_DATA = 5;
- public static final int TYPE_SERVICE_DATA = 6;
- public static final int TYPE_TRANSPORT_DISCOVERY_DATA = 7;
- public static final int TYPE_ADVERTISING_DATA_TYPE = 8;
+ @VisibleForTesting static final int TYPE_DEVICE_ADDRESS = 0;
+ @VisibleForTesting static final int TYPE_SERVICE_DATA_CHANGED = 1;
+ @VisibleForTesting static final int TYPE_SERVICE_UUID = 2;
+ @VisibleForTesting static final int TYPE_SOLICIT_UUID = 3;
+ @VisibleForTesting static final int TYPE_LOCAL_NAME = 4;
+ @VisibleForTesting static final int TYPE_MANUFACTURER_DATA = 5;
+ @VisibleForTesting static final int TYPE_SERVICE_DATA = 6;
+ @VisibleForTesting static final int TYPE_TRANSPORT_DISCOVERY_DATA = 7;
+ @VisibleForTesting static final int TYPE_ADVERTISING_DATA_TYPE = 8;
+
+ private static final int TYPE_INVALID = 0x00; // Meta data type for Transport Block Filter
+ private static final int TYPE_WIFI_NAN_HASH = 0x01; // WIFI NAN HASH type
// Max length is 31 - 3(flags) - 2 (one byte for length and one byte for type).
private static final int MAX_LEN_PER_FIELD = 26;
- // Meta data type for Transport Block Filter
- public static final int TYPE_INVALID = 0x00;
- public static final int TYPE_WIFI_NAN_HASH = 0x01; // WIFI NAN HASH type
-
static class Entry {
public byte type;
public String address;
@@ -67,8 +68,9 @@ import java.util.UUID;
public byte[] meta_data;
}
- private Set<Entry> mEntries = new HashSet<Entry>();
+ private final Set<Entry> mEntries = new HashSet<>();
+ @VisibleForTesting
void addDeviceAddress(String address, byte type, byte[] irk) {
Entry entry = new Entry();
entry.type = TYPE_DEVICE_ADDRESS;
@@ -78,20 +80,12 @@ import java.util.UUID;
mEntries.add(entry);
}
- void addServiceChanged() {
- Entry entry = new Entry();
- entry.type = TYPE_SERVICE_DATA_CHANGED;
- mEntries.add(entry);
- }
-
+ @VisibleForTesting
void addUuid(UUID uuid) {
- Entry entry = new Entry();
- entry.type = TYPE_SERVICE_UUID;
- entry.uuid = uuid;
- entry.uuid_mask = new UUID(0, 0);
- mEntries.add(entry);
+ addUuid(uuid, new UUID(0, 0));
}
+ @VisibleForTesting
void addUuid(UUID uuid, UUID uuidMask) {
Entry entry = new Entry();
entry.type = TYPE_SERVICE_UUID;
@@ -100,14 +94,12 @@ import java.util.UUID;
mEntries.add(entry);
}
+ @VisibleForTesting
void addSolicitUuid(UUID uuid) {
- Entry entry = new Entry();
- entry.type = TYPE_SOLICIT_UUID;
- entry.uuid = uuid;
- entry.uuid_mask = new UUID(0, 0);
- mEntries.add(entry);
+ addSolicitUuid(uuid, new UUID(0, 0));
}
+ @VisibleForTesting
void addSolicitUuid(UUID uuid, UUID uuidMask) {
Entry entry = new Entry();
entry.type = TYPE_SOLICIT_UUID;
@@ -116,6 +108,7 @@ import java.util.UUID;
mEntries.add(entry);
}
+ @VisibleForTesting
void addName(String name) {
Entry entry = new Entry();
entry.type = TYPE_LOCAL_NAME;
@@ -123,17 +116,15 @@ import java.util.UUID;
mEntries.add(entry);
}
+ @VisibleForTesting
void addManufacturerData(int company, byte[] data) {
- Entry entry = new Entry();
- entry.type = TYPE_MANUFACTURER_DATA;
- entry.company = company;
- entry.company_mask = 0xFFFF;
- entry.data = data;
- entry.data_mask = new byte[data.length];
- Arrays.fill(entry.data_mask, (byte) 0xFF);
- mEntries.add(entry);
+ int companyMask = 0xFFFF;
+ byte[] dataMask = new byte[data.length];
+ Arrays.fill(dataMask, (byte) 0xFF);
+ addManufacturerData(company, companyMask, data, dataMask);
}
+ @VisibleForTesting
void addManufacturerData(int company, int companyMask, byte[] data, byte[] dataMask) {
Entry entry = new Entry();
entry.type = TYPE_MANUFACTURER_DATA;
@@ -144,6 +135,7 @@ import java.util.UUID;
mEntries.add(entry);
}
+ @VisibleForTesting
void addServiceData(byte[] data, byte[] dataMask) {
Entry entry = new Entry();
entry.type = TYPE_SERVICE_DATA;
@@ -152,6 +144,7 @@ import java.util.UUID;
mEntries.add(entry);
}
+ @VisibleForTesting
void addTransportDiscoveryData(
int orgId,
int tdsFlags,
@@ -172,6 +165,7 @@ import java.util.UUID;
mEntries.add(entry);
}
+ @VisibleForTesting
void addAdvertisingDataType(int adType, byte[] data, byte[] dataMask) {
Entry entry = new Entry();
entry.type = TYPE_ADVERTISING_DATA_TYPE;
@@ -181,6 +175,7 @@ import java.util.UUID;
mEntries.add(entry);
}
+ @VisibleForTesting
Entry pop() {
if (mEntries.isEmpty()) {
return null;
@@ -191,7 +186,7 @@ import java.util.UUID;
return entry;
}
- /** Compute feature selection based on the filters presented. */
+ // Compute feature selection based on the filters presented.
int getFeatureSelection() {
int selection = 0;
for (Entry entry : mEntries) {
@@ -204,7 +199,7 @@ import java.util.UUID;
return mEntries.toArray(new ScanFilterQueue.Entry[mEntries.size()]);
}
- /** Add ScanFilter to scan filter queue. */
+ // Add ScanFilter to scan filter queue.
void addScanFilter(ScanFilter filter) {
if (filter == null) {
return;
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java b/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java
index 77430eb319..f5a43dcf3d 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java
@@ -331,69 +331,46 @@ public class BluetoothMapObexServer extends ServerRequestHandler {
// always assume version 1.0 to start with
mMessageVersion = BluetoothMapUtils.MAP_V10_STR;
notifyUpdateWakeLock();
- Long threadedMailKey = null;
- try {
- byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
- threadedMailKey = (Long) request.getHeader(THREADED_MAIL_HEADER_ID);
- if (uuid == null) {
- return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
- }
- Log.d(TAG, "onConnect(): uuid=" + Arrays.toString(uuid));
+ byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
+ Long threadedMailKey = (Long) request.getHeader(THREADED_MAIL_HEADER_ID);
+ if (uuid == null) {
+ return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+ }
+ Log.d(TAG, "onConnect(): uuid=" + Arrays.toString(uuid));
- if (uuid.length != UUID_LENGTH) {
- Log.w(TAG, "Wrong UUID length");
+ if (uuid.length != UUID_LENGTH) {
+ Log.w(TAG, "Wrong UUID length");
+ ContentProfileErrorReportUtils.report(
+ BluetoothProfile.MAP,
+ BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER,
+ BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN,
+ 0);
+ return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+ }
+ for (int i = 0; i < UUID_LENGTH; i++) {
+ if (uuid[i] != MAP_TARGET[i]) {
+ Log.w(TAG, "Wrong UUID");
ContentProfileErrorReportUtils.report(
BluetoothProfile.MAP,
BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER,
BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN,
- 0);
+ 1);
return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
}
- for (int i = 0; i < UUID_LENGTH; i++) {
- if (uuid[i] != MAP_TARGET[i]) {
- Log.w(TAG, "Wrong UUID");
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER,
- BluetoothStatsLog
- .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN,
- 1);
- return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
- }
- }
- reply.setHeader(HeaderSet.WHO, uuid);
- } catch (IOException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 2);
- Log.e(TAG, "Exception during onConnect:", e);
- return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
}
+ reply.setHeader(HeaderSet.WHO, uuid);
- try {
- byte[] remote = (byte[]) request.getHeader(HeaderSet.WHO);
- if (remote != null) {
- Log.d(TAG, "onConnect(): remote=" + Arrays.toString(remote));
- reply.setHeader(HeaderSet.TARGET, remote);
- }
- if (threadedMailKey != null && threadedMailKey.longValue() == THREAD_MAIL_KEY) {
- /* If the client provides the correct key we enable threaded e-mail support
- * and reply to the client that we support the requested feature.
- * This is currently an Android only feature. */
- mThreadIdSupport = true;
- reply.setHeader(THREADED_MAIL_HEADER_ID, THREAD_MAIL_KEY);
- }
- } catch (IOException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.MAP,
- BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 3);
- Log.e(TAG, "Exception during onConnect:", e);
- mThreadIdSupport = false;
- return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+ byte[] remote = (byte[]) request.getHeader(HeaderSet.WHO);
+ if (remote != null) {
+ Log.d(TAG, "onConnect(): remote=" + Arrays.toString(remote));
+ reply.setHeader(HeaderSet.TARGET, remote);
+ }
+ if (threadedMailKey != null && threadedMailKey.longValue() == THREAD_MAIL_KEY) {
+ /* If the client provides the correct key we enable threaded e-mail support
+ * and reply to the client that we support the requested feature.
+ * This is currently an Android only feature. */
+ mThreadIdSupport = true;
+ reply.setHeader(THREADED_MAIL_HEADER_ID, THREAD_MAIL_KEY);
}
if ((mRemoteFeatureMask & BluetoothMapUtils.MAP_FEATURE_MESSAGE_LISTING_FORMAT_V11_BIT)
diff --git a/android/app/src/com/android/bluetooth/mapclient/MnsObexServer.java b/android/app/src/com/android/bluetooth/mapclient/MnsObexServer.java
index e72cca015c..69e0baaae4 100644
--- a/android/app/src/com/android/bluetooth/mapclient/MnsObexServer.java
+++ b/android/app/src/com/android/bluetooth/mapclient/MnsObexServer.java
@@ -66,15 +66,9 @@ class MnsObexServer extends ServerRequestHandler {
public int onConnect(final HeaderSet request, HeaderSet reply) {
Log.v(TAG, "onConnect");
- try {
- byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
- if (!Arrays.equals(uuid, MNS_TARGET)) {
- return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
- }
- } catch (IOException e) {
- // this should never happen since getHeader won't throw exception it
- // declares to throw
- return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+ byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
+ if (!Arrays.equals(uuid, MNS_TARGET)) {
+ return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
}
reply.setHeader(HeaderSet.WHO, MNS_TARGET);
diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessage.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessage.java
index 5d425d0864..9cae8b30da 100644
--- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessage.java
+++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessage.java
@@ -99,12 +99,7 @@ class RequestGetMessage extends Request {
}
public String getHandle() {
- try {
- return (String) mHeaderSet.getHeader(HeaderSet.NAME);
- } catch (IOException e) {
- Log.e(TAG, "Unexpected exception while reading handle!", e);
- return null;
- }
+ return (String) mHeaderSet.getHeader(HeaderSet.NAME);
}
@Override
diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java
index de8f7edaa1..b115c77795 100644
--- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java
+++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java
@@ -65,8 +65,6 @@ public class RequestPushMessage extends Request {
}
} catch (NumberFormatException e) {
mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
- } catch (IOException e) {
- mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
}
}
diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetMessageStatus.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetMessageStatus.java
index 73c7193b21..01af11c80e 100644
--- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetMessageStatus.java
+++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestSetMessageStatus.java
@@ -16,7 +16,6 @@
package com.android.bluetooth.mapclient;
-import android.util.Log;
import com.android.bluetooth.ObexAppParameters;
import com.android.obex.ClientSession;
@@ -61,12 +60,7 @@ final class RequestSetMessageStatus extends Request {
}
public String getHandle() {
- try {
- return (String) mHeaderSet.getHeader(HeaderSet.NAME);
- } catch (IOException e) {
- Log.e(TAG, "Unexpected exception while reading handle!", e);
- return null;
- }
+ return (String) mHeaderSet.getHeader(HeaderSet.NAME);
}
@Override
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java
index 17a7bdae36..4a3c69baa8 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java
@@ -620,24 +620,13 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler
Log.d(TAG, "onConnect");
Constants.logHeader(request);
- Long objectCount = null;
- try {
- byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
- Log.v(TAG, "onConnect(): uuid =" + Arrays.toString(uuid));
- if (uuid != null) {
- return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
- }
-
- objectCount = (Long) request.getHeader(HeaderSet.COUNT);
- } catch (IOException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.OPP,
- BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 14);
- Log.e(TAG, e.toString());
- return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+ byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
+ Log.v(TAG, "onConnect(): uuid =" + Arrays.toString(uuid));
+ if (uuid != null) {
+ return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
}
+
+ Long objectCount = (Long) request.getHeader(HeaderSet.COUNT);
String destination;
if (mTransport instanceof BluetoothObexTransport) {
destination = ((BluetoothObexTransport) mTransport).getRemoteAddress();
diff --git a/android/app/src/com/android/bluetooth/opp/Constants.java b/android/app/src/com/android/bluetooth/opp/Constants.java
index 490c7e14c8..7ef50429ea 100644
--- a/android/app/src/com/android/bluetooth/opp/Constants.java
+++ b/android/app/src/com/android/bluetooth/opp/Constants.java
@@ -35,8 +35,6 @@ package com.android.bluetooth.opp;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProtoEnums;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
@@ -44,11 +42,8 @@ import android.net.Uri;
import android.util.Log;
import com.android.bluetooth.BluetoothMethodProxy;
-import com.android.bluetooth.BluetoothStatsLog;
-import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils;
import com.android.obex.HeaderSet;
-import java.io.IOException;
import java.util.regex.Pattern;
/** Bluetooth OPP internal constant definitions */
@@ -278,26 +273,17 @@ public class Constants {
static void logHeader(HeaderSet hs) {
Log.v(TAG, "Dumping HeaderSet " + hs.toString());
- try {
- Log.v(TAG, "COUNT : " + hs.getHeader(HeaderSet.COUNT));
- Log.v(TAG, "NAME : " + hs.getHeader(HeaderSet.NAME));
- Log.v(TAG, "TYPE : " + hs.getHeader(HeaderSet.TYPE));
- Log.v(TAG, "LENGTH : " + hs.getHeader(HeaderSet.LENGTH));
- Log.v(TAG, "TIME_ISO_8601 : " + hs.getHeader(HeaderSet.TIME_ISO_8601));
- Log.v(TAG, "TIME_4_BYTE : " + hs.getHeader(HeaderSet.TIME_4_BYTE));
- Log.v(TAG, "DESCRIPTION : " + hs.getHeader(HeaderSet.DESCRIPTION));
- Log.v(TAG, "TARGET : " + hs.getHeader(HeaderSet.TARGET));
- Log.v(TAG, "HTTP : " + hs.getHeader(HeaderSet.HTTP));
- Log.v(TAG, "WHO : " + hs.getHeader(HeaderSet.WHO));
- Log.v(TAG, "OBJECT_CLASS : " + hs.getHeader(HeaderSet.OBJECT_CLASS));
- Log.v(TAG, "APPLICATION_PARAMETER : " + hs.getHeader(HeaderSet.APPLICATION_PARAMETER));
- } catch (IOException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.OPP,
- BluetoothProtoEnums.BLUETOOTH_OPP_CONSTANTS,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 0);
- Log.e(TAG, "dump HeaderSet error " + e);
- }
+ Log.v(TAG, "COUNT : " + hs.getHeader(HeaderSet.COUNT));
+ Log.v(TAG, "NAME : " + hs.getHeader(HeaderSet.NAME));
+ Log.v(TAG, "TYPE : " + hs.getHeader(HeaderSet.TYPE));
+ Log.v(TAG, "LENGTH : " + hs.getHeader(HeaderSet.LENGTH));
+ Log.v(TAG, "TIME_ISO_8601 : " + hs.getHeader(HeaderSet.TIME_ISO_8601));
+ Log.v(TAG, "TIME_4_BYTE : " + hs.getHeader(HeaderSet.TIME_4_BYTE));
+ Log.v(TAG, "DESCRIPTION : " + hs.getHeader(HeaderSet.DESCRIPTION));
+ Log.v(TAG, "TARGET : " + hs.getHeader(HeaderSet.TARGET));
+ Log.v(TAG, "HTTP : " + hs.getHeader(HeaderSet.HTTP));
+ Log.v(TAG, "WHO : " + hs.getHeader(HeaderSet.WHO));
+ Log.v(TAG, "OBJECT_CLASS : " + hs.getHeader(HeaderSet.OBJECT_CLASS));
+ Log.v(TAG, "APPLICATION_PARAMETER : " + hs.getHeader(HeaderSet.APPLICATION_PARAMETER));
}
}
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java
index c755e1b67c..56cfedeb3f 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java
@@ -1738,28 +1738,18 @@ public class BluetoothPbapObexServer extends ServerRequestHandler {
public static final void logHeader(HeaderSet hs) {
Log.v(TAG, "Dumping HeaderSet " + hs.toString());
- try {
-
- Log.v(TAG, "COUNT : " + hs.getHeader(HeaderSet.COUNT));
- Log.v(TAG, "NAME : " + hs.getHeader(HeaderSet.NAME));
- Log.v(TAG, "TYPE : " + hs.getHeader(HeaderSet.TYPE));
- Log.v(TAG, "LENGTH : " + hs.getHeader(HeaderSet.LENGTH));
- Log.v(TAG, "TIME_ISO_8601 : " + hs.getHeader(HeaderSet.TIME_ISO_8601));
- Log.v(TAG, "TIME_4_BYTE : " + hs.getHeader(HeaderSet.TIME_4_BYTE));
- Log.v(TAG, "DESCRIPTION : " + hs.getHeader(HeaderSet.DESCRIPTION));
- Log.v(TAG, "TARGET : " + hs.getHeader(HeaderSet.TARGET));
- Log.v(TAG, "HTTP : " + hs.getHeader(HeaderSet.HTTP));
- Log.v(TAG, "WHO : " + hs.getHeader(HeaderSet.WHO));
- Log.v(TAG, "OBJECT_CLASS : " + hs.getHeader(HeaderSet.OBJECT_CLASS));
- Log.v(TAG, "APPLICATION_PARAMETER : " + hs.getHeader(HeaderSet.APPLICATION_PARAMETER));
- } catch (IOException e) {
- ContentProfileErrorReportUtils.report(
- BluetoothProfile.PBAP,
- BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER,
- BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION,
- 33);
- Log.e(TAG, "dump HeaderSet error " + e);
- }
+ Log.v(TAG, "COUNT : " + hs.getHeader(HeaderSet.COUNT));
+ Log.v(TAG, "NAME : " + hs.getHeader(HeaderSet.NAME));
+ Log.v(TAG, "TYPE : " + hs.getHeader(HeaderSet.TYPE));
+ Log.v(TAG, "LENGTH : " + hs.getHeader(HeaderSet.LENGTH));
+ Log.v(TAG, "TIME_ISO_8601 : " + hs.getHeader(HeaderSet.TIME_ISO_8601));
+ Log.v(TAG, "TIME_4_BYTE : " + hs.getHeader(HeaderSet.TIME_4_BYTE));
+ Log.v(TAG, "DESCRIPTION : " + hs.getHeader(HeaderSet.DESCRIPTION));
+ Log.v(TAG, "TARGET : " + hs.getHeader(HeaderSet.TARGET));
+ Log.v(TAG, "HTTP : " + hs.getHeader(HeaderSet.HTTP));
+ Log.v(TAG, "WHO : " + hs.getHeader(HeaderSet.WHO));
+ Log.v(TAG, "OBJECT_CLASS : " + hs.getHeader(HeaderSet.OBJECT_CLASS));
+ Log.v(TAG, "APPLICATION_PARAMETER : " + hs.getHeader(HeaderSet.APPLICATION_PARAMETER));
}
@VisibleForTesting
diff --git a/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java b/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java
index 06820a1955..43ec2bb3a5 100644
--- a/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java
+++ b/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java
@@ -57,10 +57,17 @@ import com.android.obex.ServerSession;
import java.io.IOException;
-/**
- * Bluetooth PBAP StateMachine (New connection socket) WAITING FOR AUTH | | (request permission from
- * Settings UI) | (Accept) / \ (Reject) / \ v v CONNECTED -----> FINISHED (OBEX Server done)
- */
+// Bluetooth PBAP StateMachine
+// (New connection socket)
+// WAITING FOR AUTH
+// |
+// | (request permission from Settings UI)
+// |
+// (Accept) / \ (Reject)
+// / \
+// v v
+// CONNECTED -----> FINISHED
+// (OBEX Server done)
// Next tag value for ContentProfileErrorReportUtils.report(): 3
@VisibleForTesting(visibility = Visibility.PACKAGE)
public class PbapStateMachine extends StateMachine {
@@ -382,8 +389,7 @@ public class PbapStateMachine extends StateMachine {
Log.v(TAG, "Pbap Service startObexServerSession");
// acquire the wakeLock before start Obex transaction thread
- mServiceHandler.sendMessage(
- mServiceHandler.obtainMessage(BluetoothPbapService.MSG_ACQUIRE_WAKE_LOCK));
+ mServiceHandler.sendEmptyMessage(BluetoothPbapService.MSG_ACQUIRE_WAKE_LOCK);
mPbapServer =
new BluetoothPbapObexServer(mServiceHandler, mService, PbapStateMachine.this);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java
index 3359c2b48a..15dc16bbf3 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java
@@ -54,8 +54,6 @@ public class ScanFilterQueueTest {
byte[] irk = new byte[] {0x02};
queue.addDeviceAddress(address, type, irk);
- queue.addServiceChanged();
-
UUID uuid = UUID.randomUUID();
queue.addUuid(uuid);
@@ -87,7 +85,7 @@ public class ScanFilterQueueTest {
queue.addAdvertisingDataType(adType, adData, adDataMask);
ScanFilterQueue.Entry[] entries = queue.toArray();
- int entriesLength = 10;
+ int entriesLength = 9;
assertThat(entries.length).isEqualTo(entriesLength);
for (ScanFilterQueue.Entry entry : entries) {
diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java
index e8ef9baedc..607bf253d4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/PbapStateMachineTest.java
@@ -25,103 +25,103 @@ import static com.android.bluetooth.TestUtils.getTestDevice;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.doReturn;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
-import android.os.HandlerThread;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
-import org.junit.After;
+import com.android.bluetooth.TestLooper;
+
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import java.io.IOException;
+import java.io.InputStream;
+
@MediumTest
@RunWith(AndroidJUnit4.class)
public class PbapStateMachineTest {
@Rule public final MockitoRule mMockitoRule = new MockitoRule();
@Mock private BluetoothPbapService mBluetoothPbapService;
+ @Mock private BluetoothSocket mSocket;
+ @Mock private InputStream mInputStream;
private static final int TEST_NOTIFICATION_ID = 1000000;
private final BluetoothDevice mDevice = getTestDevice(36);
- private HandlerThread mHandlerThread;
- private PbapStateMachine mPbapStateMachine;
private Handler mHandler;
- private BluetoothSocket mSocket;
+ private TestLooper mLooper;
+ private PbapStateMachine mStateMachine;
@Before
- public void setUp() {
- mHandlerThread = new HandlerThread("PbapTestHandlerThread");
- mHandlerThread.start();
- mHandler = new Handler(mHandlerThread.getLooper());
+ public void setUp() throws IOException {
+ doReturn(mInputStream).when(mSocket).getInputStream();
+ doReturn(mInputStream).when(mSocket).getInputStream();
+
+ mLooper = new TestLooper();
+ mHandler = new Handler(mLooper.getLooper());
- mPbapStateMachine =
+ mStateMachine =
PbapStateMachine.make(
mBluetoothPbapService,
- mHandlerThread.getLooper(),
+ mLooper.getLooper(),
mDevice,
mSocket,
mHandler,
TEST_NOTIFICATION_ID);
}
- @After
- public void tearDown() throws InterruptedException {
- mHandlerThread.quitSafely();
- mHandlerThread.join();
- }
-
/** Test that initial state is WaitingForAuth */
@Test
- public void testInitialState() {
- assertThat(mPbapStateMachine.getConnectionState()).isEqualTo(STATE_CONNECTING);
- assertThat(mPbapStateMachine.getCurrentState())
+ public void initialState_isConnecting() {
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_CONNECTING);
+ assertThat(mStateMachine.getCurrentState())
.isInstanceOf(PbapStateMachine.WaitingForAuth.class);
}
/** Test state transition from WaitingForAuth to Finished when the user rejected */
- @Ignore("Class BluetoothSocket is final and cannot be mocked. b/71512958: re-enable it.")
@Test
public void testStateTransition_WaitingForAuthToFinished() {
- mPbapStateMachine.sendMessage(PbapStateMachine.REJECTED);
- assertThat(mPbapStateMachine.getConnectionState()).isEqualTo(STATE_DISCONNECTED);
- assertThat(mPbapStateMachine.getCurrentState())
- .isInstanceOf(PbapStateMachine.Finished.class);
+ sendAndDispatchMessage(PbapStateMachine.REJECTED);
+
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_DISCONNECTED);
+ assertThat(mStateMachine.getCurrentState()).isInstanceOf(PbapStateMachine.Finished.class);
}
/** Test state transition from WaitingForAuth to Finished when the user rejected */
- @Ignore("Class BluetoothSocket is final and cannot be mocked. b/71512958: re-enable it.")
@Test
public void testStateTransition_WaitingForAuthToConnected() {
- mPbapStateMachine.sendMessage(PbapStateMachine.AUTHORIZED);
- assertThat(mPbapStateMachine.getConnectionState()).isEqualTo(STATE_CONNECTED);
- assertThat(mPbapStateMachine.getCurrentState())
- .isInstanceOf(PbapStateMachine.Connected.class);
+ sendAndDispatchMessage(PbapStateMachine.AUTHORIZED);
+
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_CONNECTED);
+ assertThat(mStateMachine.getCurrentState()).isInstanceOf(PbapStateMachine.Connected.class);
}
/** Test state transition from Connected to Finished when the OBEX server is done */
- @Ignore("Class BluetoothSocket is final and cannot be mocked. b/71512958: re-enable it.")
@Test
public void testStateTransition_ConnectedToFinished() {
- mPbapStateMachine.sendMessage(PbapStateMachine.AUTHORIZED);
- assertThat(mPbapStateMachine.getConnectionState()).isEqualTo(STATE_CONNECTED);
- assertThat(mPbapStateMachine.getCurrentState())
- .isInstanceOf(PbapStateMachine.Connected.class);
-
- // PBAP OBEX transport is done.
- mPbapStateMachine.sendMessage(PbapStateMachine.DISCONNECT);
- assertThat(mPbapStateMachine.getConnectionState()).isEqualTo(STATE_DISCONNECTED);
- assertThat(mPbapStateMachine.getCurrentState())
- .isInstanceOf(PbapStateMachine.Finished.class);
+ sendAndDispatchMessage(PbapStateMachine.AUTHORIZED);
+
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_CONNECTED);
+ assertThat(mStateMachine.getCurrentState()).isInstanceOf(PbapStateMachine.Connected.class);
+
+ sendAndDispatchMessage(PbapStateMachine.DISCONNECT);
+
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_DISCONNECTED);
+ assertThat(mStateMachine.getCurrentState()).isInstanceOf(PbapStateMachine.Finished.class);
+ }
+
+ private void sendAndDispatchMessage(int what) {
+ mStateMachine.sendMessage(what);
+ mLooper.dispatchAll();
}
}
diff --git a/flags/bta_dm.aconfig b/flags/bta_dm.aconfig
index 0e424d440c..19e8418785 100644
--- a/flags/bta_dm.aconfig
+++ b/flags/bta_dm.aconfig
@@ -27,3 +27,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "bta_dm_disc_close_proper_conn_id"
+ namespace: "bluetooth"
+ description: "Make sure proper connection is closed when timeout happens"
+ bug: "399687217"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/offload/hal/Android.bp b/offload/hal/Android.bp
index 87058f085f..8937b611ef 100644
--- a/offload/hal/Android.bp
+++ b/offload/hal/Android.bp
@@ -16,30 +16,20 @@ package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
-rust_library {
+rust_ffi {
name: "libbluetooth_offload_hal",
- vendor_available: true,
crate_name: "bluetooth_offload_hal",
crate_root: "lib.rs",
edition: "2021",
+ vendor_available: true,
rustlibs: [
"android.hardware.bluetooth-V1-rust",
"libbinder_rs",
"libbluetooth_offload_hci",
+ "libbluetooth_offload_leaudio_hci",
"liblog_rust",
"liblogger",
],
- visibility: [
- "//hardware/interfaces/bluetooth:__subpackages__",
- "//packages/modules/Bluetooth/offload:__subpackages__",
- "//vendor:__subpackages__",
- ],
-}
-
-cc_library_headers {
- name: "libbluetooth_offload_hal_headers",
- vendor_available: true,
- host_supported: true,
export_include_dirs: [
"include",
],
diff --git a/offload/hal/include/hal/ffi.h b/offload/hal/include/hal/ffi.h
index f4d9b5ff4d..49fa20b3c4 100644
--- a/offload/hal/include/hal/ffi.h
+++ b/offload/hal/include/hal/ffi.h
@@ -14,10 +14,13 @@
* limitations under the License.
*/
-extern "C" {
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+namespace aidl::android::hardware::bluetooth::hal {
-#include <stddef.h>
-#include <stdint.h>
+extern "C" {
/**
* Callabcks from C to Rust
@@ -26,17 +29,17 @@ extern "C" {
* `hal_interface.close()` call.
*/
-enum HalStatus {
- STATUS_SUCCESS,
- STATUS_ALREADY_INITIALIZED,
- STATUS_UNABLE_TO_OPEN_INTERFACE,
- STATUS_HARDWARE_INITIALIZATION_ERROR,
- STATUS_UNKNOWN,
+enum Status {
+ SUCCESS,
+ ALREADY_INITIALIZED,
+ UNABLE_TO_OPEN_INTERFACE,
+ HARDWARE_INITIALIZATION_ERROR,
+ UNKNOWN,
};
-struct hal_callbacks {
+struct CCallbacks {
void *handle;
- void (*initialization_complete)(const void *handle, enum HalStatus);
+ void (*initialization_complete)(const void *handle, Status);
void (*event_received)(const void *handle, const uint8_t *data, size_t len);
void (*acl_received)(const void *handle, const uint8_t *data, size_t len);
void (*sco_received)(const void *handle, const uint8_t *data, size_t len);
@@ -50,9 +53,9 @@ struct hal_callbacks {
* Locking over `handle` is not necessary.
*/
-struct hal_interface {
+struct CInterface {
void *handle;
- void (*initialize)(void *handle, const struct hal_callbacks *);
+ void (*initialize)(void *handle, const CCallbacks *);
void (*close)(void *handle);
void (*send_command)(void *handle, const uint8_t *data, size_t len);
void (*send_acl)(void *handle, const uint8_t *data, size_t len);
@@ -60,4 +63,86 @@ struct hal_interface {
void (*send_iso)(void *handle, const uint8_t *data, size_t len);
void (*client_died)(void *handle);
};
+
+/**
+ * Add binder service
+ */
+
+void __add_bluetooth_hci_service(CInterface intf);
+
+} // extern "C"
+
+class IBluetoothHciCallbacks {
+public:
+ IBluetoothHciCallbacks(const CCallbacks *callbacks) : callbacks_(*callbacks) {}
+
+ void initializationComplete(Status status) {
+ callbacks_.initialization_complete(callbacks_.handle, status);
+ }
+
+ void hciEventReceived(std::vector<uint8_t> data) {
+ callbacks_.event_received(callbacks_.handle, data.data(), data.size());
+ }
+
+ void aclDataReceived(std::vector<uint8_t> data) {
+ callbacks_.acl_received(callbacks_.handle, data.data(), data.size());
+ }
+
+ void scoDataReceived(std::vector<uint8_t> data) {
+ callbacks_.sco_received(callbacks_.handle, data.data(), data.size());
+ }
+
+ void isoDataReceived(std::vector<uint8_t> data) {
+ callbacks_.iso_received(callbacks_.handle, data.data(), data.size());
+ }
+
+private:
+ CCallbacks callbacks_;
+};
+
+class IBluetoothHci {
+public:
+ virtual ~IBluetoothHci() = default;
+ virtual void initialize(const std::shared_ptr<IBluetoothHciCallbacks> &callbacks);
+ virtual void close();
+ virtual void sendHciCommand(const std::vector<uint8_t> &data);
+ virtual void sendAclData(const std::vector<uint8_t> &data);
+ virtual void sendScoData(const std::vector<uint8_t> &data);
+ virtual void sendIsoData(const std::vector<uint8_t> &data);
+ virtual void clientDied();
+};
+
+static inline void IBluetoothHci_addService(IBluetoothHci *hci) {
+ __add_bluetooth_hci_service((CInterface){
+ .handle = hci,
+ .initialize =
+ [](void *instance, const CCallbacks *callbacks) {
+ static_cast<IBluetoothHci *>(instance)->initialize(
+ std::make_shared<IBluetoothHciCallbacks>(callbacks));
+ },
+ .close = [](void *instance) { static_cast<IBluetoothHci *>(instance)->close(); },
+ .send_command =
+ [](void *instance, const uint8_t *data, size_t len) {
+ static_cast<IBluetoothHci *>(instance)->sendHciCommand(
+ std::vector<uint8_t>(data, data + len));
+ },
+ .send_acl =
+ [](void *instance, const uint8_t *data, size_t len) {
+ static_cast<IBluetoothHci *>(instance)->sendAclData(
+ std::vector<uint8_t>(data, data + len));
+ },
+ .send_sco =
+ [](void *instance, const uint8_t *data, size_t len) {
+ static_cast<IBluetoothHci *>(instance)->sendScoData(
+ std::vector<uint8_t>(data, data + len));
+ },
+ .send_iso =
+ [](void *instance, const uint8_t *data, size_t len) {
+ static_cast<IBluetoothHci *>(instance)->sendIsoData(
+ std::vector<uint8_t>(data, data + len));
+ },
+ .client_died =
+ [](void *instance) { static_cast<IBluetoothHci *>(instance)->clientDied(); }});
}
+
+} // namespace aidl::android::hardware::bluetooth::hal
diff --git a/offload/hal/service.rs b/offload/hal/service.rs
index a72eea9200..2b171d2e9c 100644
--- a/offload/hal/service.rs
+++ b/offload/hal/service.rs
@@ -13,11 +13,14 @@
// limitations under the License.
use crate::ffi::{CInterface, CStatus, Callbacks, DataCallbacks, Ffi};
-use android_hardware_bluetooth::aidl::android::hardware::bluetooth::IBluetoothHci::IBluetoothHci;
+use android_hardware_bluetooth::aidl::android::hardware::bluetooth::IBluetoothHci::{
+ BnBluetoothHci, BpBluetoothHci, IBluetoothHci,
+};
use android_hardware_bluetooth::aidl::android::hardware::bluetooth::IBluetoothHciCallbacks::IBluetoothHciCallbacks;
use android_hardware_bluetooth::aidl::android::hardware::bluetooth::Status::Status;
use binder::{DeathRecipient, ExceptionCode, IBinder, Interface, Result as BinderResult, Strong};
use bluetooth_offload_hci::{Module, ModuleBuilder};
+use bluetooth_offload_leaudio_hci::LeAudioModuleBuilder;
use std::sync::{Arc, RwLock};
/// Service Implementation of AIDL interface `hardware/interface/bluetoot/aidl`,
@@ -236,3 +239,16 @@ impl From<CStatus> for Status {
}
}
}
+
+#[no_mangle]
+pub extern "C" fn __add_bluetooth_hci_service(cintf: CInterface) {
+ binder::add_service(
+ &format!("{}/default", BpBluetoothHci::get_descriptor()),
+ BnBluetoothHci::new_binder(
+ HciHalProxy::new(vec![Box::new(LeAudioModuleBuilder {})], cintf),
+ binder::BinderFeatures::default(),
+ )
+ .as_binder(),
+ )
+ .expect("Failed to register service");
+}
diff --git a/system/bta/has/has_client_test.cc b/system/bta/has/has_client_test.cc
index 9b02f00027..1f68488f84 100644
--- a/system/bta/has/has_client_test.cc
+++ b/system/bta/has/has_client_test.cc
@@ -1127,11 +1127,11 @@ protected:
class HasClientTest : public HasClientTestBase {
void SetUp(void) override {
+ com::android::bluetooth::flags::provider_->reset_flags();
HasClientTestBase::SetUp();
TestAppRegister();
}
void TearDown(void) override {
- com::android::bluetooth::flags::provider_->reset_flags();
TestAppUnregister();
HasClientTestBase::TearDown();
}
diff --git a/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc b/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc
index 8618670c0e..606ddc69d9 100644
--- a/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc
+++ b/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc
@@ -230,6 +230,8 @@ public:
class LeAudioClientAudioTest : public ::testing::Test {
protected:
void SetUp(void) override {
+ com::android::bluetooth::flags::provider_->reset_flags();
+
init_message_loop_thread();
bluetooth::audio::le_audio::interface_mock = &mock_client_interface_;
bluetooth::audio::le_audio::sink_mock = &mock_hal_interface_audio_sink_;
@@ -279,8 +281,6 @@ protected:
}
void TearDown(void) override {
- com::android::bluetooth::flags::provider_->reset_flags();
-
/* We have to call Cleanup to tidy up some static variables.
* If on the HAL end Source is running it means we are running the Sink
* on our end, and vice versa.
diff --git a/system/bta/le_audio/broadcaster/broadcaster_test.cc b/system/bta/le_audio/broadcaster/broadcaster_test.cc
index 28bfcfb24c..a211a810ad 100644
--- a/system/bta/le_audio/broadcaster/broadcaster_test.cc
+++ b/system/bta/le_audio/broadcaster/broadcaster_test.cc
@@ -251,6 +251,8 @@ public:
class BroadcasterTest : public Test {
protected:
void SetUp() override {
+ com::android::bluetooth::flags::provider_->reset_flags();
+
test::mock::osi_alarm::alarm_free.body = [](alarm_t* alarm) {
if (alarm) {
delete alarm;
@@ -348,7 +350,6 @@ protected:
}
void TearDown() override {
- com::android::bluetooth::flags::provider_->reset_flags();
// Message loop cleanup should wait for all the 'till now' scheduled calls
// so it should be called right at the very begginning of teardown.
cleanup_message_loop_thread();
diff --git a/system/bta/le_audio/broadcaster/state_machine.cc b/system/bta/le_audio/broadcaster/state_machine.cc
index da03674a86..65b16086ff 100644
--- a/system/bta/le_audio/broadcaster/state_machine.cc
+++ b/system/bta/le_audio/broadcaster/state_machine.cc
@@ -281,7 +281,10 @@ private:
DisableAnnouncement();
},
/* in ENABLING state */
- [](const void*) { /* Do nothing */ },
+ [this](const void*) {
+ SetState(State::STOPPING);
+ callbacks_->OnStateMachineEvent(GetBroadcastId(), GetState());
+ },
/* in DISABLING state */
[](const void*) { /* Do nothing */ },
/* in STOPPING state */
@@ -456,6 +459,13 @@ private:
handle_it = std::next(handle_it);
if (handle_it == active_config_->connection_handles.end()) {
+ if (GetState() == BroadcastStateMachine::State::STOPPING) {
+ // All ISO setup completed, but we're in stopping state, we need to tear down all ISO
+ log::warn("ISO setup in stopping state. Tearing down ISO data path.");
+ // Remain in STOPPING, BIG will be terminated in OnRemoveIsoDataPath
+ TriggerIsoDatapathTeardown(active_config_->connection_handles[0]);
+ return;
+ }
/* It was the last BIS to set up - change state to streaming */
SetState(State::STREAMING);
callbacks_->OnStateMachineEvent(GetBroadcastId(), GetState(), nullptr);
@@ -563,8 +573,9 @@ private:
.connection_handles = evt->conn_handles,
};
- if (GetState() == BroadcastStateMachine::State::DISABLING) {
- log::info("Terminating BIG due to stream suspending, big_id={}", evt->big_id);
+ if (GetState() == BroadcastStateMachine::State::DISABLING ||
+ GetState() == BroadcastStateMachine::State::STOPPING) {
+ log::info("Terminating BIG in state={}, big_id={}", ToString(GetState()), evt->big_id);
TerminateBig();
} else {
callbacks_->OnBigCreated(evt->conn_handles);
@@ -578,7 +589,8 @@ private:
case HCI_BLE_TERM_BIG_CPL_EVT: {
auto* evt = static_cast<big_terminate_cmpl_evt*>(data);
- log::info("BIG terminate BIG cmpl, reason={} big_id={}", evt->reason, evt->big_id);
+ log::info("BIG terminate BIG cmpl in state={}, reason={} big_id={}", ToString(GetState()),
+ evt->reason, evt->big_id);
if (evt->big_id != GetAdvertisingSid()) {
log::error("State={} Event={}, unknown adv.sid={}", ToString(GetState()), event,
@@ -589,8 +601,11 @@ private:
active_config_ = std::nullopt;
bool disabling = GetState() == BroadcastStateMachine::State::DISABLING;
- /* Go back to configured if BIG is inactive (we are still announcing) */
- SetState(State::CONFIGURED);
+ /* Go back to configured if BIG is inactive (we are still announcing) and state is not
+ * stopping*/
+ if (GetState() != BroadcastStateMachine::State::STOPPING) {
+ SetState(State::CONFIGURED);
+ }
/* Check if we got this HCI event due to STOP or SUSPEND message. */
if (disabling) {
diff --git a/system/bta/le_audio/broadcaster/state_machine_test.cc b/system/bta/le_audio/broadcaster/state_machine_test.cc
index 70a74ea510..7011d6fdbb 100644
--- a/system/bta/le_audio/broadcaster/state_machine_test.cc
+++ b/system/bta/le_audio/broadcaster/state_machine_test.cc
@@ -28,7 +28,6 @@
#include "broadcast_configuration_provider.h"
#include "btm_iso_api.h"
#include "stack/include/btm_ble_api_types.h"
-#include "state_machine.h"
#include "test/common/mock_functions.h"
#include "test/mock/mock_main_shim_le_advertising_manager.h"
#include "test/mock/mock_stack_btm_iso.h"
@@ -674,6 +673,61 @@ TEST_F(StateMachineTest, ProcessMessageSuspendWhenConfiguredLateBigCreateComplet
ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
}
+TEST_F(StateMachineTest, ProcessMessageStopWhenEnablingLateBigCreateCompleteEvent) {
+ EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
+
+ auto broadcast_id =
+ InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
+ ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
+
+ /* Hold start process on BIG create */
+ EXPECT_CALL(*mock_iso_manager_, CreateBig(_, _)).WillOnce(Return());
+ broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
+
+ ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::ENABLING);
+ EXPECT_CALL(*(sm_callbacks_.get()),
+ OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::STOPPING, _))
+ .Times(1);
+ broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::STOP);
+ ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPING);
+
+ /* Inject late BIG create complete event */
+ big_create_cmpl_evt evt;
+ evt.big_id = broadcasts_[broadcast_id]->GetAdvertisingSid();
+ EXPECT_CALL(*mock_iso_manager_, TerminateBig(_, _)).WillOnce(Return());
+ broadcasts_[broadcast_id]->HandleHciEvent(HCI_BLE_CREATE_BIG_CPL_EVT, &evt);
+
+ // There shall be no change in state
+ ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPING);
+}
+
+TEST_F(StateMachineTest, ProcessMessageStopWhenEnablingLateIsoSetupEvent) {
+ EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
+
+ auto broadcast_id =
+ InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
+ ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
+
+ /* Hold start process on Setup Iso Data Path BIG create */
+ EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).WillOnce(Return());
+ broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
+
+ ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::ENABLING);
+
+ EXPECT_CALL(*(sm_callbacks_.get()),
+ OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::STOPPING, _))
+ .Times(1);
+ EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).WillOnce(Return());
+ broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::STOP);
+ ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPING);
+
+ std::optional<BigConfig> const& big_cfg = broadcasts_[broadcast_id]->GetBigConfig();
+ broadcasts_[broadcast_id]->OnSetupIsoDataPath(0, big_cfg->connection_handles[0]);
+
+ // There shall be no change in state
+ ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPING);
+}
+
TEST_F(StateMachineTest, ProcessMessageSuspendWhenConfiguredLateIsoDataPathSetUp) {
EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
diff --git a/system/bta/le_audio/client.cc b/system/bta/le_audio/client.cc
index 16114df846..9a81a828cb 100644
--- a/system/bta/le_audio/client.cc
+++ b/system/bta/le_audio/client.cc
@@ -2434,7 +2434,7 @@ public:
supp_audio_contexts.source.value());
}
} else if (hdl == leAudioDevice->ctp_hdls_.val_hdl) {
- groupStateMachine_->ProcessGattCtpNotification(group, value, len);
+ groupStateMachine_->ProcessGattCtpNotification(group, leAudioDevice, value, len);
} else if (hdl == leAudioDevice->tmap_role_hdl_) {
bluetooth::le_audio::client_parser::tmap::ParseTmapRole(leAudioDevice->tmap_role_, len,
value);
diff --git a/system/bta/le_audio/device_groups.cc b/system/bta/le_audio/device_groups.cc
index 733f9e71ec..5272c873de 100644
--- a/system/bta/le_audio/device_groups.cc
+++ b/system/bta/le_audio/device_groups.cc
@@ -41,6 +41,7 @@
#include "btm_ble_api_types.h"
#include "btm_iso_api.h"
#include "btm_iso_api_types.h"
+#include "client_parser.h"
#include "com_android_bluetooth_flags.h"
#include "common/strings.h"
#include "gatt_api.h"
@@ -457,6 +458,14 @@ LeAudioDevice* LeAudioDeviceGroup::GetNextActiveDevice(LeAudioDevice* leAudioDev
return (iter == leAudioDevices_.end()) ? nullptr : (iter->lock()).get();
}
+int LeAudioDeviceGroup::GetNumOfActiveDevices(void) const {
+ int result = 0;
+ for (auto dev = GetFirstActiveDevice(); dev; dev = GetNextActiveDevice(dev)) {
+ result++;
+ }
+ return result;
+}
+
LeAudioDevice* LeAudioDeviceGroup::GetFirstActiveDeviceByCisAndDataPathState(
CisState cis_state, DataPathState data_path_state) const {
auto iter = std::find_if(
diff --git a/system/bta/le_audio/device_groups.h b/system/bta/le_audio/device_groups.h
index 421eacf28b..51b2f205d5 100644
--- a/system/bta/le_audio/device_groups.h
+++ b/system/bta/le_audio/device_groups.h
@@ -177,6 +177,7 @@ public:
LeAudioDevice* GetNextActiveDeviceByCisAndDataPathState(
LeAudioDevice* leAudioDevice, types::CisState cis_state,
types::DataPathState data_path_state) const;
+ int GetNumOfActiveDevices(void) const;
bool IsDeviceInTheGroup(LeAudioDevice* leAudioDevice) const;
bool HaveAllActiveDevicesAsesTheSameState(types::AseState state) const;
bool HaveAnyActiveDeviceInStreamingState() const;
diff --git a/system/bta/le_audio/devices.h b/system/bta/le_audio/devices.h
index ed1f7621c1..c934681ef2 100644
--- a/system/bta/le_audio/devices.h
+++ b/system/bta/le_audio/devices.h
@@ -113,6 +113,8 @@ public:
alarm_t* link_quality_timer;
uint16_t link_quality_timer_data;
+ uint8_t last_ase_ctp_command_sent;
+
LeAudioDevice(const RawAddress& address, DeviceConnectState state,
int group_id = bluetooth::groups::kGroupUnknown)
: address_(address),
@@ -133,6 +135,7 @@ public:
acl_asymmetric_(false),
acl_phy_update_done_(false),
link_quality_timer(nullptr),
+ last_ase_ctp_command_sent(0x00),
dsa_({{DsaMode::DISABLED},
types::DataPathState::IDLE,
LE_AUDIO_INVALID_CIS_HANDLE,
diff --git a/system/bta/le_audio/devices_test.cc b/system/bta/le_audio/devices_test.cc
index 9abeb6c82e..9d668391e5 100644
--- a/system/bta/le_audio/devices_test.cc
+++ b/system/bta/le_audio/devices_test.cc
@@ -101,6 +101,7 @@ class LeAudioDevicesTest : public Test {
protected:
void SetUp() override {
__android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
+ com::android::bluetooth::flags::provider_->reset_flags();
devices_ = new LeAudioDevices();
bluetooth::manager::SetMockBtmInterface(&btm_interface);
bluetooth::storage::SetMockBtifStorageInterface(&mock_btif_storage_);
diff --git a/system/bta/le_audio/le_audio_client_test.cc b/system/bta/le_audio/le_audio_client_test.cc
index 42c7f9d634..cbb2d5a7ef 100644
--- a/system/bta/le_audio/le_audio_client_test.cc
+++ b/system/bta/le_audio/le_audio_client_test.cc
@@ -1516,6 +1516,8 @@ protected:
void SetUp() override {
__android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
+ com::android::bluetooth::flags::provider_->reset_flags();
+
init_message_loop_thread();
reset_mock_function_count_map();
ON_CALL(controller_, SupportsBleConnectedIsochronousStreamCentral).WillByDefault(Return(true));
@@ -1599,7 +1601,9 @@ protected:
}
void TearDown() override {
- com::android::bluetooth::flags::provider_->reset_flags();
+ // WARNING: Message loop cleanup should wait for all the 'till now' scheduled calls
+ // so it should be called right at the very begginning of teardown.
+ cleanup_message_loop_thread();
if (is_audio_unicast_source_acquired) {
if (unicast_source_hal_cb_ != nullptr) {
@@ -1615,10 +1619,6 @@ protected:
EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
}
- // Message loop cleanup should wait for all the 'till now' scheduled calls
- // so it should be called right at the very begginning of teardown.
- cleanup_message_loop_thread();
-
// This is required since Stop() and Cleanup() may trigger some callbacks or
// drop unique pointers to mocks we have raw pointer for and we want to
// verify them all.
diff --git a/system/bta/le_audio/mock_state_machine.h b/system/bta/le_audio/mock_state_machine.h
index bee2ea6599..ea3326f5f6 100644
--- a/system/bta/le_audio/mock_state_machine.h
+++ b/system/bta/le_audio/mock_state_machine.h
@@ -50,9 +50,9 @@ public:
bluetooth::le_audio::LeAudioDevice* leAudioDevice,
bluetooth::le_audio::LeAudioDeviceGroup* group),
(override));
-
MOCK_METHOD((void), ProcessGattCtpNotification,
- (bluetooth::le_audio::LeAudioDeviceGroup * group, uint8_t* value, uint16_t len),
+ (bluetooth::le_audio::LeAudioDeviceGroup * group,
+ bluetooth::le_audio::LeAudioDevice* leAudioDevice, uint8_t* value, uint16_t len),
(override));
MOCK_METHOD((void), ProcessHciNotifOnCigCreate,
(bluetooth::le_audio::LeAudioDeviceGroup * group, uint8_t status, uint8_t cig_id,
diff --git a/system/bta/le_audio/state_machine.cc b/system/bta/le_audio/state_machine.cc
index 1c991e624e..a2803c729c 100644
--- a/system/bta/le_audio/state_machine.cc
+++ b/system/bta/le_audio/state_machine.cc
@@ -394,7 +394,8 @@ public:
}
}
- void ProcessGattCtpNotification(LeAudioDeviceGroup* group, uint8_t* value, uint16_t len) {
+ void ProcessGattCtpNotification(LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice,
+ uint8_t* value, uint16_t len) {
auto ntf = std::make_unique<struct bluetooth::le_audio::client_parser::ascs::ctp_ntf>();
bool valid_notification = ParseAseCtpNotification(*ntf, len, value);
@@ -415,10 +416,13 @@ public:
*/
auto target_state = group->GetTargetState();
+ auto current_state = group->GetState();
auto in_transition = group->IsInTransition();
if (!in_transition || target_state != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
- log::debug("Not interested in ctp result for group {} inTransition: {} , targetState: {}",
- group->group_id_, in_transition, ToString(target_state));
+ log::debug(
+ "Not interested in ctp result for group {} inTransition: {} , targetState: {}, "
+ "currentState: {}",
+ group->group_id_, in_transition, ToString(target_state), ToString(current_state));
return;
}
@@ -429,24 +433,59 @@ public:
}
for (auto& entry : ntf->entries) {
+ // release ASEs on device which did not accept control point command
if (entry.response_code !=
bluetooth::le_audio::client_parser::ascs::kCtpResponseCodeSuccess) {
- /* Gracefully stop the stream */
- log::error(
- "Stopping stream due to control point error for ase: {}, error: "
- "0x{:02x}, reason: 0x{:02x}",
- entry.ase_id, entry.response_code, entry.reason);
+ if (ntf->op == bluetooth::le_audio::client_parser::ascs::kCtpOpcodeRelease) {
+ log::warn(
+ "Release failed for {}, ase: {}, last_ase_ctp_command_sent: {:#x}, error: {:#x}, "
+ "reason: {:#x}, let "
+ "watchdog to fire",
+ leAudioDevice->address_, entry.ase_id, leAudioDevice->last_ase_ctp_command_sent,
+ entry.response_code, entry.reason);
+ return;
+ }
- notifyLeAudioHealth(
- group,
- bluetooth::le_audio::LeAudioHealthGroupStatType::STREAM_CREATE_SIGNALING_FAILED);
- StopStream(group);
+ auto release_sent_to_remote = PrepareAndSendRelease(leAudioDevice);
+ auto active_devices = group->GetNumOfActiveDevices();
+
+ int releasing_devices = 0;
+ for (auto dev = group->GetFirstActiveDevice(); dev; dev = group->GetNextActiveDevice(dev)) {
+ if (dev->last_ase_ctp_command_sent ==
+ bluetooth::le_audio::client_parser::ascs::kCtpOpcodeRelease) {
+ releasing_devices++;
+ }
+ }
+
+ log::error(
+ "Releasing ASE due to control point error for {}, ase: {}, opcode: {:#x}, "
+ "last_ase_ctp_command_sent: {:#x}, error: "
+ "{:#x}, reason: {:#x}. release_sent_to_remote: {}, active_devices: {}, "
+ "releasing_devices: {}",
+ leAudioDevice->address_, entry.ase_id, ntf->op,
+ leAudioDevice->last_ase_ctp_command_sent, entry.response_code, entry.reason,
+ release_sent_to_remote, active_devices, releasing_devices);
+
+ // If there is no active devices it means, the whole set got released
+ if (releasing_devices == 0 && active_devices == 0) {
+ /* No remote communication expected */
+ ClearGroup(group, true);
+ notifyLeAudioHealth(
+ group,
+ bluetooth::le_audio::LeAudioHealthGroupStatType::STREAM_CREATE_SIGNALING_FAILED);
+ } else if (active_devices != 0 && releasing_devices == active_devices) {
+ group->SetTargetState(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
+ state_machine_callbacks_->StatusReportCb(group->group_id_, GroupStreamStatus::RELEASING);
+ notifyLeAudioHealth(
+ group,
+ bluetooth::le_audio::LeAudioHealthGroupStatType::STREAM_CREATE_SIGNALING_FAILED);
+ }
return;
}
}
- log::debug("Ctp result OK for group {} inTransition: {} , targetState: {}", group->group_id_,
- in_transition, ToString(target_state));
+ log::debug("Ctp result OK for group {} inTransition: {} , targetState: {}, currentState: {}",
+ group->group_id_, in_transition, ToString(target_state), ToString(current_state));
}
void ProcessGattNotifEvent(uint8_t* value, uint16_t len, struct ase* ase,
@@ -1280,6 +1319,9 @@ public:
/* We should send Receiver Stop Ready when acting as a source */
if (ases_pair.source && ases_pair.source->state == AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING) {
+ leAudioDevice->last_ase_ctp_command_sent =
+ bluetooth::le_audio::client_parser::ascs::kCtpOpcodeReceiverStopReady;
+
std::vector<uint8_t> ids = {ases_pair.source->id};
std::vector<uint8_t> value;
@@ -1936,6 +1978,9 @@ private:
extra_stream << +conf.codec_id.coding_format << "," << +conf.target_latency << ";;";
}
+ leAudioDevice->last_ase_ctp_command_sent =
+ bluetooth::le_audio::client_parser::ascs::kCtpOpcodeCodecConfiguration;
+
std::vector<uint8_t> value;
log::info("{} -> ", leAudioDevice->address_);
bluetooth::le_audio::client_parser::ascs::PrepareAseCtpCodecConfig(confs, value);
@@ -2453,6 +2498,9 @@ private:
<< ";;";
} while ((ase = leAudioDevice->GetNextActiveAse(ase)));
+ leAudioDevice->last_ase_ctp_command_sent =
+ bluetooth::le_audio::client_parser::ascs::kCtpOpcodeEnable;
+
bluetooth::le_audio::client_parser::ascs::PrepareAseCtpEnable(confs, value);
WriteToControlPoint(leAudioDevice, value);
@@ -2494,10 +2542,12 @@ private:
msg_stream << "ASE_ID " << +ase->id << ", ";
} while ((ase = leAudioDevice->GetNextActiveAse(ase)));
+ leAudioDevice->last_ase_ctp_command_sent =
+ bluetooth::le_audio::client_parser::ascs::kCtpOpcodeDisable;
+
log::info("group_id: {}, {}", leAudioDevice->group_id_, leAudioDevice->address_);
std::vector<uint8_t> value;
bluetooth::le_audio::client_parser::ascs::PrepareAseCtpDisable(ids, value);
-
WriteToControlPoint(leAudioDevice, value);
log_history_->AddLogHistory(kLogControlPointCmd, leAudioDevice->group_id_,
@@ -2514,14 +2564,19 @@ private:
return GroupStreamStatus::IDLE;
}
+ bool releasing = false;
for (; leAudioDevice; leAudioDevice = group->GetNextActiveDevice(leAudioDevice)) {
- PrepareAndSendRelease(leAudioDevice);
+ releasing |= PrepareAndSendRelease(leAudioDevice);
}
- return GroupStreamStatus::RELEASING;
+ if (releasing) {
+ return GroupStreamStatus::RELEASING;
+ }
+
+ return GroupStreamStatus::IDLE;
}
- void PrepareAndSendRelease(LeAudioDevice* leAudioDevice) {
+ bool PrepareAndSendRelease(LeAudioDevice* leAudioDevice) {
ase* ase = leAudioDevice->GetFirstActiveAse();
log::assert_that(ase, "shouldn't be called without an active ASE");
@@ -2532,10 +2587,23 @@ private:
do {
log::debug("device: {}, ase_id: {}, cis_id: {}, ase state: {}", leAudioDevice->address_,
ase->id, ase->cis_id, ToString(ase->state));
- ids.push_back(ase->id);
- stream << "ASE_ID " << +ase->id << ",";
+ if (ase->state != AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) {
+ ids.push_back(ase->id);
+ stream << "ASE_ID " << +ase->id << ",";
+ } else {
+ log::info("{}, ase: {} already in idle. Deactivate it", leAudioDevice->address_, ase->id);
+ ase->active = false;
+ }
} while ((ase = leAudioDevice->GetNextActiveAse(ase)));
+ if (ids.empty()) {
+ log::info("Nothing to send to {}", leAudioDevice->address_);
+ return false;
+ }
+
+ leAudioDevice->last_ase_ctp_command_sent =
+ bluetooth::le_audio::client_parser::ascs::kCtpOpcodeRelease;
+
std::vector<uint8_t> value;
bluetooth::le_audio::client_parser::ascs::PrepareAseCtpRelease(ids, value);
WriteToControlPoint(leAudioDevice, value);
@@ -2543,6 +2611,7 @@ private:
log::info("group_id: {}, {}", leAudioDevice->group_id_, leAudioDevice->address_);
log_history_->AddLogHistory(kLogControlPointCmd, leAudioDevice->group_id_,
leAudioDevice->address_, stream.str());
+ return true;
}
void PrepareAndSendConfigQos(LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice) {
@@ -2634,6 +2703,9 @@ private:
return;
}
+ leAudioDevice->last_ase_ctp_command_sent =
+ bluetooth::le_audio::client_parser::ascs::kCtpOpcodeQosConfiguration;
+
std::vector<uint8_t> value;
bluetooth::le_audio::client_parser::ascs::PrepareAseCtpConfigQos(confs, value);
WriteToControlPoint(leAudioDevice, value);
@@ -2710,6 +2782,9 @@ private:
}
if (confs.size() != 0) {
+ leAudioDevice->last_ase_ctp_command_sent =
+ bluetooth::le_audio::client_parser::ascs::kCtpOpcodeUpdateMetadata;
+
std::vector<uint8_t> value;
bluetooth::le_audio::client_parser::ascs::PrepareAseCtpUpdateMetadata(confs, value);
WriteToControlPoint(leAudioDevice, value);
@@ -2736,6 +2811,9 @@ private:
} while ((ase = leAudioDevice->GetNextActiveAse(ase)));
if (ids.size() > 0) {
+ leAudioDevice->last_ase_ctp_command_sent =
+ bluetooth::le_audio::client_parser::ascs::kCtpOpcodeReceiverStartReady;
+
bluetooth::le_audio::client_parser::ascs::PrepareAseCtpAudioReceiverStartReady(ids, value);
WriteToControlPoint(leAudioDevice, value);
diff --git a/system/bta/le_audio/state_machine.h b/system/bta/le_audio/state_machine.h
index 19b50e68c9..be6f80e8da 100644
--- a/system/bta/le_audio/state_machine.h
+++ b/system/bta/le_audio/state_machine.h
@@ -60,8 +60,8 @@ public:
types::BidirectionalPair<std::vector<uint8_t>> ccid_lists = {.sink = {}, .source = {}},
bool configure_qos = false) = 0;
virtual void StopStream(LeAudioDeviceGroup* group) = 0;
- virtual void ProcessGattCtpNotification(LeAudioDeviceGroup* group, uint8_t* value,
- uint16_t len) = 0;
+ virtual void ProcessGattCtpNotification(LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice,
+ uint8_t* value, uint16_t len) = 0;
virtual void ProcessGattNotifEvent(uint8_t* value, uint16_t len, struct types::ase* ase,
LeAudioDevice* leAudioDevice, LeAudioDeviceGroup* group) = 0;
diff --git a/system/bta/le_audio/state_machine_test.cc b/system/bta/le_audio/state_machine_test.cc
index e6f2c2f47c..77f4ce0e26 100644
--- a/system/bta/le_audio/state_machine_test.cc
+++ b/system/bta/le_audio/state_machine_test.cc
@@ -242,6 +242,8 @@ protected:
/* Keep ASE in releasing state */
bool stay_in_releasing_state_;
+ /* Do not response immediately on Release CTP for the devices in the list*/
+ std::vector<RawAddress> block_releasing_state_device_list_;
/* Use for single test to simulate late ASE notifications */
bool stop_inject_configured_ase_after_first_ase_configured_;
@@ -251,6 +253,8 @@ protected:
virtual void SetUp() override {
__android_log_set_minimum_priority(ANDROID_LOG_DEBUG);
+ com::android::bluetooth::flags::provider_->reset_flags();
+
reset_mock_function_count_map();
bluetooth::manager::SetMockBtmInterface(&btm_interface);
gatt::SetMockBtaGattInterface(&gatt_interface);
@@ -264,6 +268,7 @@ protected:
do_not_send_cis_establish_event_ = false;
do_not_send_cis_disconnected_event_ = false;
stay_in_releasing_state_ = false;
+ block_releasing_state_device_list_.clear();
stop_inject_configured_ase_after_first_ase_configured_ = false;
cis_status_.clear();
@@ -607,8 +612,6 @@ protected:
}
void TearDown() override {
- com::android::bluetooth::flags::provider_->reset_flags();
-
/* Clear the alarm on tear down in case test case ends when the
* alarm is scheduled
*/
@@ -1402,8 +1405,8 @@ protected:
UINT8_TO_STREAM(p, reason);
}
- LeAudioGroupStateMachine::Get()->ProcessGattCtpNotification(group, notif_value.data(),
- notif_value.size());
+ LeAudioGroupStateMachine::Get()->ProcessGattCtpNotification(
+ group, leAudioDevice, notif_value.data(), notif_value.size());
}
void PrepareCtpNotificationError(LeAudioDeviceGroup* group, uint8_t opcode, uint8_t response_code,
@@ -1643,6 +1646,12 @@ protected:
ASSERT_NE(it, device->ases_.end());
const auto ase = &(*it);
+ auto iter = std::find(block_releasing_state_device_list_.begin(),
+ block_releasing_state_device_list_.end(), device->address_);
+ if (iter != block_releasing_state_device_list_.end()) {
+ continue;
+ }
+
InjectAseStateNotification(ase, device, group, ascs::kAseStateReleasing, nullptr);
if (stay_in_releasing_state_) {
@@ -2094,11 +2103,15 @@ TEST_F(StateMachineTest, testConfigureQosFailed) {
group, client_parser::ascs::kCtpOpcodeQosConfiguration,
client_parser::ascs::kCtpResponseCodeInvalidConfigurationParameterValue,
client_parser::ascs::kCtpResponsePhy);
+
PrepareReleaseHandler(group);
auto* leAudioDevice = group->GetFirstDevice();
auto expected_devices_written = 0;
while (leAudioDevice) {
+ // We will inject state after manually for test porpuse
+ block_releasing_state_device_list_.push_back(leAudioDevice->address_);
+
EXPECT_CALL(gatt_queue,
WriteCharacteristic(leAudioDevice->conn_id_, leAudioDevice->ctp_hdls_.val_hdl, _,
GATT_WRITE_NO_RSP, _, _))
@@ -2123,9 +2136,13 @@ TEST_F(StateMachineTest, testConfigureQosFailed) {
{.sink = types::AudioContexts(context_type),
.source = types::AudioContexts(context_type)}));
+ InjectReleaseAndIdleStateForAGroup(group);
+
// Check if group has transitioned to a proper state
ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
- ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
+
+ // During error only one cancel will happen when all devices will go down to IDLE
+ ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
}
@@ -2203,7 +2220,10 @@ TEST_F(StateMachineTest, testStreamCreationError) {
client_parser::ascs::kCtpResponseNoReason);
PrepareReleaseHandler(group);
- auto* leAudioDevice = group->GetFirstDevice();
+ auto leAudioDevice = group->GetFirstDevice();
+
+ /* To avoid the loop. Will Inject release later. */
+ block_releasing_state_device_list_.push_back(leAudioDevice->address_);
/*
* 1 - Configure ASE
@@ -2237,9 +2257,11 @@ TEST_F(StateMachineTest, testStreamCreationError) {
{.sink = types::AudioContexts(context_type),
.source = types::AudioContexts(context_type)}));
+ InjectReleaseAndIdleStateForAGroup(group);
+
// Check if group has transitioned to a proper state
ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
- ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
+ ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
}
TEST_F(StateMachineTest, testStreamSingle) {
@@ -2990,7 +3012,8 @@ TEST_F(StateMachineTest, remoteRejectsEnable) {
InjectInitialIdleNotification(group);
- auto* leAudioDevice = group->GetFirstDevice();
+ auto leAudioDevice = group->GetFirstDevice();
+ block_releasing_state_device_list_.push_back(leAudioDevice->address_);
/* First device Control Point actions
* Codec Config
@@ -3002,17 +3025,20 @@ TEST_F(StateMachineTest, remoteRejectsEnable) {
WriteCharacteristic(leAudioDevice->conn_id_, leAudioDevice->ctp_hdls_.val_hdl, _,
GATT_WRITE_NO_RSP, _, _))
.Times(4);
+
leAudioDevice = group->GetNextDevice(leAudioDevice);
+ block_releasing_state_device_list_.push_back(leAudioDevice->address_);
/* Second device Control Point actions
* Codec Config
* QoS Config
+ * Enable
* Release
*/
EXPECT_CALL(gatt_queue,
WriteCharacteristic(leAudioDevice->conn_id_, leAudioDevice->ctp_hdls_.val_hdl, _,
GATT_WRITE_NO_RSP, _, _))
- .Times(3);
+ .Times(4);
// Start the configuration and stream Media content
ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
@@ -3020,9 +3046,11 @@ TEST_F(StateMachineTest, remoteRejectsEnable) {
{.sink = types::AudioContexts(context_type),
.source = types::AudioContexts(context_type)}));
+ InjectReleaseAndIdleStateForAGroup(group);
+
// Check if group has transitioned to a proper state
ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
- ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
+ ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
}
TEST_F(StateMachineTest, testStreamMultiple) {
@@ -5753,7 +5781,7 @@ TEST_F(StateMachineTest, testReleaseStreamWithLateAttachToStream_CodecConfigStat
* 3. Reconnect
* 4. Trigger attach the stream
* 6. StopStream while getting to Codec Configured State on attaching device
- * 7. Check that Attaching device will also go to IDLE
+ * 7. Check that Attaching device will not get Release CMD
*/
ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
@@ -5831,11 +5859,12 @@ TEST_F(StateMachineTest, testReleaseStreamWithLateAttachToStream_CodecConfigStat
/*
* 1. Codec Configure for attaching device
- * 2. Release for both devices
+ * 2. Release for streaming device only as the attaching one is still not in Codec Configured
+ * state.
*/
EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_, lastDevice->ctp_hdls_.val_hdl,
_, GATT_WRITE_NO_RSP, _, _))
- .Times(2);
+ .Times(1);
EXPECT_CALL(gatt_queue, WriteCharacteristic(firstDevice->conn_id_, firstDevice->ctp_hdls_.val_hdl,
_, GATT_WRITE_NO_RSP, _, _))
@@ -9518,12 +9547,12 @@ TEST_F(StateMachineTest, testStopStreamBeforeCodecConfigureIsArrived) {
/*
* 1 - Configure ASE
- * 2 - Release ASE
+ * 2 - Release ASE (we are not Release in such a case)
*/
EXPECT_CALL(gatt_queue,
WriteCharacteristic(leAudioDevice->conn_id_, leAudioDevice->ctp_hdls_.val_hdl, _,
GATT_WRITE_NO_RSP, _, _))
- .Times(2);
+ .Times(1);
EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(0);
EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
@@ -9534,9 +9563,11 @@ TEST_F(StateMachineTest, testStopStreamBeforeCodecConfigureIsArrived) {
InjectInitialIdleNotification(group);
- // Validate GroupStreamStatus
+ // Validate GroupStreamStatus and we should just received IDLE state as There is no Release CMD
+ // sent to the remote
EXPECT_CALL(mock_callbacks_,
- StatusReportCb(leaudio_group_id, bluetooth::le_audio::GroupStreamStatus::RELEASING));
+ StatusReportCb(leaudio_group_id, bluetooth::le_audio::GroupStreamStatus::RELEASING))
+ .Times(0);
EXPECT_CALL(mock_callbacks_,
StatusReportCb(leaudio_group_id, bluetooth::le_audio::GroupStreamStatus::IDLE));
@@ -9556,7 +9587,7 @@ TEST_F(StateMachineTest, testStopStreamBeforeCodecConfigureIsArrived) {
// Check if group has transitioned to a proper state
ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
- ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
+ ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
}
TEST_F(StateMachineTest, testAutonomousReleaseFromEnablingState) {
diff --git a/system/bta/vc/devices_test.cc b/system/bta/vc/devices_test.cc
index 80c860e04e..6ad0cacf1a 100644
--- a/system/bta/vc/devices_test.cc
+++ b/system/bta/vc/devices_test.cc
@@ -56,16 +56,16 @@ static RawAddress GetTestAddress(int index) {
class VolumeControlDevicesTest : public ::testing::Test {
protected:
void SetUp() override {
- com::android::bluetooth::flags::provider_->leaudio_add_aics_support(true);
__android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
+ com::android::bluetooth::flags::provider_->reset_flags();
+
+ com::android::bluetooth::flags::provider_->leaudio_add_aics_support(true);
devices_ = new VolumeControlDevices();
gatt::SetMockBtaGattInterface(&gatt_interface);
gatt::SetMockBtaGattQueue(&gatt_queue);
}
void TearDown() override {
- com::android::bluetooth::flags::provider_->reset_flags();
-
gatt::SetMockBtaGattQueue(nullptr);
gatt::SetMockBtaGattInterface(nullptr);
delete devices_;
@@ -219,8 +219,10 @@ TEST_F(VolumeControlDevicesTest, test_control_point_skip_not_connected) {
class VolumeControlDeviceTest : public ::testing::Test {
protected:
void SetUp() override {
- com::android::bluetooth::flags::provider_->leaudio_add_aics_support(true);
__android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
+ com::android::bluetooth::flags::provider_->reset_flags();
+
+ com::android::bluetooth::flags::provider_->leaudio_add_aics_support(true);
device = new VolumeControlDevice(GetTestAddress(1), true);
gatt::SetMockBtaGattInterface(&gatt_interface);
gatt::SetMockBtaGattQueue(&gatt_queue);
@@ -259,7 +261,6 @@ protected:
}
void TearDown() override {
- com::android::bluetooth::flags::provider_->reset_flags();
bluetooth::manager::SetMockBtmInterface(nullptr);
gatt::SetMockBtaGattQueue(nullptr);
gatt::SetMockBtaGattInterface(nullptr);
diff --git a/system/bta/vc/vc_test.cc b/system/bta/vc/vc_test.cc
index c52dc9f2a6..b52a9c4405 100644
--- a/system/bta/vc/vc_test.cc
+++ b/system/bta/vc/vc_test.cc
@@ -435,6 +435,7 @@ protected:
void SetUp(void) override {
__android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
+ com::android::bluetooth::flags::provider_->reset_flags();
com::android::bluetooth::flags::provider_->leaudio_add_aics_support(true);
@@ -540,7 +541,6 @@ protected:
}
void TearDown(void) override {
- com::android::bluetooth::flags::provider_->reset_flags();
services_map.clear();
gatt::SetMockBtaGattQueue(nullptr);
gatt::SetMockBtaGattInterface(nullptr);
diff --git a/system/gd/hal/hci_hal_android.cc b/system/gd/hal/hci_hal_android.cc
index 20d9e29e3d..8f1246d064 100644
--- a/system/gd/hal/hci_hal_android.cc
+++ b/system/gd/hal/hci_hal_android.cc
@@ -27,6 +27,7 @@
#include "hal/hci_hal.h"
#include "hal/link_clocker.h"
#include "hal/snoop_logger.h"
+#include "main/shim/entry.h"
namespace bluetooth::hal {
@@ -167,10 +168,7 @@ public:
}
protected:
- void ListDependencies(ModuleList* list) const override {
- list->add<LinkClocker>();
- list->add<SnoopLogger>();
- }
+ void ListDependencies(ModuleList* list) const override { list->add<LinkClocker>(); }
void Start() override {
common::StopWatch stop_watch(__func__);
@@ -178,7 +176,7 @@ protected:
"Start can't be called more than once before Stop is called.");
link_clocker_ = GetDependency<LinkClocker>();
- btsnoop_logger_ = GetDependency<SnoopLogger>();
+ btsnoop_logger_ = shim::GetSnoopLogger();
backend_ = HciBackend::CreateAidl();
if (!backend_) {
diff --git a/system/gd/hal/hci_hal_host.cc b/system/gd/hal/hci_hal_host.cc
index 65c1671c8d..970a2ae48c 100644
--- a/system/gd/hal/hci_hal_host.cc
+++ b/system/gd/hal/hci_hal_host.cc
@@ -35,6 +35,7 @@
#include "hal/hci_hal.h"
#include "hal/link_clocker.h"
#include "hal/snoop_logger.h"
+#include "main/shim/entry.h"
#include "metrics/counter_metrics.h"
#include "os/mgmt.h"
#include "os/reactor.h"
@@ -326,10 +327,7 @@ public:
}
protected:
- void ListDependencies(ModuleList* list) const {
- list->add<LinkClocker>();
- list->add<SnoopLogger>();
- }
+ void ListDependencies(ModuleList* list) const { list->add<LinkClocker>(); }
void Start() override {
std::lock_guard<std::mutex> lock(api_mutex_);
@@ -350,7 +348,7 @@ protected:
hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
os::Reactor::REACT_ON_READ_ONLY);
link_clocker_ = GetDependency<LinkClocker>();
- btsnoop_logger_ = GetDependency<SnoopLogger>();
+ btsnoop_logger_ = shim::GetSnoopLogger();
log::info("HAL opened successfully");
}
diff --git a/system/gd/hal/hci_hal_host_rootcanal.cc b/system/gd/hal/hci_hal_host_rootcanal.cc
index f4866a5115..612372a962 100644
--- a/system/gd/hal/hci_hal_host_rootcanal.cc
+++ b/system/gd/hal/hci_hal_host_rootcanal.cc
@@ -30,6 +30,7 @@
#include "hal/hci_hal.h"
#include "hal/hci_hal_host.h"
#include "hal/snoop_logger.h"
+#include "main/shim/entry.h"
#include "metrics/counter_metrics.h"
#include "os/reactor.h"
#include "os/thread.h"
@@ -163,7 +164,7 @@ public:
}
protected:
- void ListDependencies(ModuleList* list) const { list->add<SnoopLogger>(); }
+ void ListDependencies(ModuleList* /*list*/) const {}
void Start() override {
std::lock_guard<std::mutex> lock(api_mutex_);
@@ -175,7 +176,7 @@ protected:
common::Bind(&HciHalHost::send_packet_ready, common::Unretained(this)));
hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_,
os::Reactor::REACT_ON_READ_ONLY);
- btsnoop_logger_ = GetDependency<SnoopLogger>();
+ btsnoop_logger_ = shim::GetSnoopLogger();
log::info("HAL opened successfully");
}
diff --git a/system/gd/hal/snoop_logger.cc b/system/gd/hal/snoop_logger.cc
index 53f5509a0b..f5e0242dfd 100644
--- a/system/gd/hal/snoop_logger.cc
+++ b/system/gd/hal/snoop_logger.cc
@@ -51,6 +51,29 @@ using bluetooth::os::fake_timer::fake_timerfd_get_clock;
namespace bluetooth {
namespace hal {
+static std::string GetBtSnoopMode() {
+ // Default mode is FILTERED on userdebug/eng build, DISABLED on user build.
+ // In userdebug/eng build, it can also be overwritten by modifying the global setting
+ std::string btsnoop_mode = SnoopLogger::kBtSnoopLogModeDisabled;
+ if (os::GetSystemPropertyBool(SnoopLogger::kIsDebuggableProperty, false)) {
+ btsnoop_mode = os::GetSystemProperty(SnoopLogger::kBtSnoopDefaultLogModeProperty)
+ .value_or(SnoopLogger::kBtSnoopLogModeFiltered);
+ }
+
+ btsnoop_mode = os::GetSystemProperty(SnoopLogger::kBtSnoopLogModeProperty).value_or(btsnoop_mode);
+
+ // Only allow a subset of values:
+ if (!(btsnoop_mode == SnoopLogger::kBtSnoopLogModeDisabled ||
+ btsnoop_mode == SnoopLogger::kBtSnoopLogModeFull ||
+ btsnoop_mode == SnoopLogger::kBtSnoopLogModeFiltered ||
+ btsnoop_mode == SnoopLogger::kBtSnoopLogModeKernel)) {
+ log::warn("{}: Invalid btsnoop value, default back to disabled", btsnoop_mode);
+ return SnoopLogger::kBtSnoopLogModeDisabled;
+ }
+
+ return btsnoop_mode;
+}
+
// Adds L2CAP channel to acceptlist.
void FilterTracker::AddL2capCid(uint16_t local_cid, uint16_t remote_cid) {
l2c_local_cid.insert(local_cid);
@@ -492,13 +515,22 @@ const size_t SnoopLogger::PACKET_TYPE_LENGTH = 1;
const size_t SnoopLogger::MAX_HCI_ACL_LEN = 14;
const uint32_t SnoopLogger::L2CAP_HEADER_SIZE = 8;
-SnoopLogger::SnoopLogger(std::string snoop_log_path, std::string snooz_log_path,
- size_t max_packets_per_file, size_t max_packets_per_buffer,
- const std::string& btsnoop_mode, bool qualcomm_debug_log_enabled,
+SnoopLogger::SnoopLogger(os::Handler* handler)
+ : SnoopLogger(handler, os::ParameterProvider::SnoopLogFilePath(),
+ os::ParameterProvider::SnoozLogFilePath(), GetMaxPacketsPerFile(),
+ GetMaxPacketsPerBuffer(), GetBtSnoopMode(), IsQualcommDebugLogEnabled(),
+ kBtSnoozLogLifeTime, kBtSnoozLogDeleteRepeatingAlarmInterval,
+ IsBtSnoopLogPersisted()) {}
+
+SnoopLogger::SnoopLogger(os::Handler* handler, std::string snoop_log_path,
+ std::string snooz_log_path, size_t max_packets_per_file,
+ size_t max_packets_per_buffer, const std::string& btsnoop_mode,
+ bool qualcomm_debug_log_enabled,
const std::chrono::milliseconds snooz_log_life_time,
const std::chrono::milliseconds snooz_log_delete_alarm_interval,
bool snoop_log_persists)
- : btsnoop_mode_(btsnoop_mode),
+ : Module(handler),
+ btsnoop_mode_(btsnoop_mode),
snoop_log_path_(std::move(snoop_log_path)),
snooz_log_path_(std::move(snooz_log_path)),
max_packets_per_file_(max_packets_per_file),
@@ -1292,10 +1324,6 @@ void SnoopLogger::DumpSnoozLogToFile() {
}
}
-void SnoopLogger::ListDependencies(ModuleList* /* list */) const {
- // We have no dependencies
-}
-
void SnoopLogger::Start() {
std::lock_guard<std::recursive_mutex> lock(file_mutex_);
if (btsnoop_mode_ != kBtSnoopLogModeDisabled && btsnoop_mode_ != kBtSnoopLogModeKernel) {
@@ -1385,29 +1413,6 @@ size_t SnoopLogger::GetMaxPacketsPerBuffer() {
std::string SnoopLogger::GetCurrentSnoopMode() { return btsnoop_mode_; }
-static std::string GetBtSnoopMode() {
- // Default mode is FILTERED on userdebug/eng build, DISABLED on user build.
- // In userdebug/eng build, it can also be overwritten by modifying the global setting
- std::string btsnoop_mode = SnoopLogger::kBtSnoopLogModeDisabled;
- if (os::GetSystemPropertyBool(SnoopLogger::kIsDebuggableProperty, false)) {
- btsnoop_mode = os::GetSystemProperty(SnoopLogger::kBtSnoopDefaultLogModeProperty)
- .value_or(SnoopLogger::kBtSnoopLogModeFiltered);
- }
-
- btsnoop_mode = os::GetSystemProperty(SnoopLogger::kBtSnoopLogModeProperty).value_or(btsnoop_mode);
-
- // Only allow a subset of values:
- if (!(btsnoop_mode == SnoopLogger::kBtSnoopLogModeDisabled ||
- btsnoop_mode == SnoopLogger::kBtSnoopLogModeFull ||
- btsnoop_mode == SnoopLogger::kBtSnoopLogModeFiltered ||
- btsnoop_mode == SnoopLogger::kBtSnoopLogModeKernel)) {
- log::warn("{}: Invalid btsnoop value, default back to disabled", btsnoop_mode);
- return SnoopLogger::kBtSnoopLogModeDisabled;
- }
-
- return btsnoop_mode;
-}
-
void SnoopLogger::RegisterSocket(SnoopLoggerSocketInterface* socket) {
std::lock_guard<std::recursive_mutex> lock(file_mutex_);
socket_ = socket;
@@ -1430,14 +1435,6 @@ bool SnoopLogger::IsQualcommDebugLogEnabled() {
return qualcomm_debug_log_enabled;
}
-const ModuleFactory SnoopLogger::Factory = ModuleFactory([]() {
- return new SnoopLogger(os::ParameterProvider::SnoopLogFilePath(),
- os::ParameterProvider::SnoozLogFilePath(), GetMaxPacketsPerFile(),
- GetMaxPacketsPerBuffer(), GetBtSnoopMode(), IsQualcommDebugLogEnabled(),
- kBtSnoozLogLifeTime, kBtSnoozLogDeleteRepeatingAlarmInterval,
- IsBtSnoopLogPersisted());
-});
-
#ifdef __ANDROID__
void SnoopLogger::LogTracePoint(uint64_t timestamp_us, const HciPacket& packet, Direction direction,
PacketType type) {
diff --git a/system/gd/hal/snoop_logger.h b/system/gd/hal/snoop_logger.h
index c1546d6ed4..d13113c9af 100644
--- a/system/gd/hal/snoop_logger.h
+++ b/system/gd/hal/snoop_logger.h
@@ -194,6 +194,8 @@ public:
uint16_t remote_cid;
};
+ SnoopLogger(os::Handler* handler);
+
// Returns the maximum number of packets per file
// Changes to this value is only effective after restarting Bluetooth
static size_t GetMaxPacketsPerFile();
@@ -224,6 +226,8 @@ public:
OUTGOING,
};
+ void Start() override;
+ void Stop() override;
void Capture(const HciPacket& packet, Direction direction, PacketType type);
// Set a L2CAP channel as acceptlisted, allowing packets with that L2CAP CID
@@ -268,6 +272,8 @@ public:
// Dump the contents of the snooz buffer to a file.
void DumpSnoozLogToFile();
+ SnoopLoggerSocketThread const* GetSocketThread() { return snoop_logger_socket_thread_.get(); }
+
protected:
// Packet type length
static const size_t PACKET_TYPE_LENGTH;
@@ -277,16 +283,16 @@ protected:
// Max packet data size when headersfiltered option enabled
static const size_t MAX_HCI_ACL_LEN;
- void ListDependencies(ModuleList* list) const override;
- void Start() override;
- void Stop() override;
+ void ListDependencies(ModuleList* /*list*/) const override {}
std::string ToString() const override { return std::string("SnoopLogger"); }
- SnoopLogger(std::string snoop_log_path, std::string snooz_log_path, size_t max_packets_per_file,
- size_t max_packets_per_buffer, const std::string& btsnoop_mode,
- bool qualcomm_debug_log_enabled, const std::chrono::milliseconds snooz_log_life_time,
+ SnoopLogger(os::Handler* handler, std::string snoop_log_path, std::string snooz_log_path,
+ size_t max_packets_per_file, size_t max_packets_per_buffer,
+ const std::string& btsnoop_mode, bool qualcomm_debug_log_enabled,
+ const std::chrono::milliseconds snooz_log_life_time,
const std::chrono::milliseconds snooz_log_delete_alarm_interval,
bool snoop_log_persists);
+
void CloseCurrentSnoopLogFile();
void OpenNextSnoopLogFile();
// Enable filters according to their sysprops
@@ -341,6 +347,8 @@ private:
SnoopLoggerSocketInterface* socket_;
SyscallWrapperImpl syscall_if;
bool snoop_log_persists = false;
+
+ friend class SnoopLoggerTest;
};
} // namespace hal
diff --git a/system/gd/hal/snoop_logger_socket_thread.cc b/system/gd/hal/snoop_logger_socket_thread.cc
index b2829626cf..efe3c5f546 100644
--- a/system/gd/hal/snoop_logger_socket_thread.cc
+++ b/system/gd/hal/snoop_logger_socket_thread.cc
@@ -72,7 +72,7 @@ void SnoopLoggerSocketThread::Write(const void* data, size_t length) {
bool SnoopLoggerSocketThread::ThreadIsRunning() const { return listen_thread_running_; }
-SnoopLoggerSocket* SnoopLoggerSocketThread::GetSocket() { return socket_.get(); }
+SnoopLoggerSocket* SnoopLoggerSocketThread::GetSocket() const { return socket_.get(); }
void SnoopLoggerSocketThread::Run(std::promise<bool> thread_started) {
log::debug("");
diff --git a/system/gd/hal/snoop_logger_socket_thread.h b/system/gd/hal/snoop_logger_socket_thread.h
index bdf62b720d..f508ff9e9b 100644
--- a/system/gd/hal/snoop_logger_socket_thread.h
+++ b/system/gd/hal/snoop_logger_socket_thread.h
@@ -42,7 +42,7 @@ public:
void Write(const void* data, size_t length) override;
bool ThreadIsRunning() const;
- SnoopLoggerSocket* GetSocket();
+ SnoopLoggerSocket* GetSocket() const;
private:
void Run(std::promise<bool> thread_started);
diff --git a/system/gd/hal/snoop_logger_test.cc b/system/gd/hal/snoop_logger_test.cc
index 4681f82f30..de42db5c06 100644
--- a/system/gd/hal/snoop_logger_test.cc
+++ b/system/gd/hal/snoop_logger_test.cc
@@ -34,37 +34,33 @@
#include "os/system_properties.h"
#include "os/utils.h"
-namespace testing {
+namespace bluetooth::hal {
-using bluetooth::hal::SnoopLoggerCommon;
-using bluetooth::hal::SnoopLoggerSocket;
-using bluetooth::hal::SnoopLoggerSocketInterface;
-using bluetooth::hal::SnoopLoggerSocketThread;
-using bluetooth::hal::SyscallWrapperImpl;
-using bluetooth::os::fake_timer::fake_timerfd_advance;
-using bluetooth::os::fake_timer::fake_timerfd_reset;
-using namespace bluetooth;
+using os::fake_timer::fake_timerfd_advance;
+using os::fake_timer::fake_timerfd_reset;
+using namespace std::chrono_literals;
namespace {
-std::vector<uint8_t> kInformationRequest = {
+static const std::vector<uint8_t> kInformationRequest = {
0xfe, 0x2e, 0x0a, 0x00, 0x06, 0x00, 0x01, 0x00, 0x0a, 0x02, 0x02, 0x00, 0x02, 0x00,
};
-std::vector<uint8_t> kSdpConnectionRequest = {0x08, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x02, 0x0c, 0x04, 0x00, 0x01, 0x00, 0x44, 0x00};
+static const std::vector<uint8_t> kSdpConnectionRequest = {0x08, 0x20, 0x0c, 0x00, 0x08, 0x00,
+ 0x01, 0x00, 0x02, 0x0c, 0x04, 0x00,
+ 0x01, 0x00, 0x44, 0x00};
-std::vector<uint8_t> kAvdtpSuspend = {0x02, 0x02, 0x00, 0x07, 0x00, 0x03,
- 0x00, 0x8d, 0x00, 0x90, 0x09, 0x04};
+static const std::vector<uint8_t> kAvdtpSuspend = {0x02, 0x02, 0x00, 0x07, 0x00, 0x03,
+ 0x00, 0x8d, 0x00, 0x90, 0x09, 0x04};
-std::vector<uint8_t> kHfpAtNrec0 = {0x02, 0x02, 0x20, 0x13, 0x00, 0x0f, 0x00, 0x41,
- 0x00, 0x09, 0xff, 0x15, 0x01, 0x41, 0x54, 0x2b,
- 0x4e, 0x52, 0x45, 0x43, 0x3d, 0x30, 0x0d, 0x5c};
+static const std::vector<uint8_t> kHfpAtNrec0 = {0x02, 0x02, 0x20, 0x13, 0x00, 0x0f, 0x00, 0x41,
+ 0x00, 0x09, 0xff, 0x15, 0x01, 0x41, 0x54, 0x2b,
+ 0x4e, 0x52, 0x45, 0x43, 0x3d, 0x30, 0x0d, 0x5c};
-std::vector<uint8_t> kQualcommConnectionRequest = {0xdc, 0x2e, 0x54, 0x00, 0x50, 0x00, 0xff,
- 0x00, 0x00, 0x0a, 0x0f, 0x09, 0x01, 0x00,
- 0x5c, 0x93, 0x01, 0x00, 0x42, 0x00};
+static const std::vector<uint8_t> kQualcommConnectionRequest = {
+ 0xdc, 0x2e, 0x54, 0x00, 0x50, 0x00, 0xff, 0x00, 0x00, 0x0a,
+ 0x0f, 0x09, 0x01, 0x00, 0x5c, 0x93, 0x01, 0x00, 0x42, 0x00};
-std::vector<uint8_t> kA2dpMediaPacket = {
+static const std::vector<uint8_t> kA2dpMediaPacket = {
0x0b, 0x20, 0x3a, 0x00, 0x36, 0x00, 0x40, 0xa0, 0x80, 0xe0, 0x07, 0x7f, 0x00,
0x1e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x47, 0xfc, 0x00, 0x00, 0xb0, 0x90,
0x80, 0x03, 0x00, 0x20, 0x21, 0x11, 0x45, 0x00, 0x14, 0x50, 0x01, 0x46, 0xf0,
@@ -72,7 +68,7 @@ std::vector<uint8_t> kA2dpMediaPacket = {
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e,
};
-std::vector<bluetooth::hal::HciPacket> kTestData = {
+static const std::vector<bluetooth::hal::HciPacket> kTestData = {
{0x02, 0x20, 0x11, 0x00, 0x0d, 0x00, 0x41, 0x00, 0x9d, 0xef, 0x35,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x40, 0x00, 0x9f, 0xff, 0x3f,
@@ -104,35 +100,16 @@ std::vector<bluetooth::hal::HciPacket> kTestData = {
} // namespace
-using bluetooth::TestModuleRegistry;
-using bluetooth::hal::SnoopLogger;
-using namespace std::chrono_literals;
-
-// Expose protected constructor for test
-class TestSnoopLoggerModule : public SnoopLogger {
+class SnoopLoggerTest : public testing::Test {
public:
- TestSnoopLoggerModule(std::string snoop_log_path, std::string snooz_log_path,
- size_t max_packets_per_file, const std::string& btsnoop_mode,
- bool qualcomm_debug_log_enabled, bool snoop_log_persists)
- : SnoopLogger(std::move(snoop_log_path), std::move(snooz_log_path), max_packets_per_file,
- SnoopLogger::GetMaxPacketsPerBuffer(), btsnoop_mode, qualcomm_debug_log_enabled,
- 20ms, 5ms, snoop_log_persists) {}
-
- std::string ToString() const override { return std::string("TestSnoopLoggerModule"); }
-
- SnoopLoggerSocketThread* GetSocketThread() { return snoop_logger_socket_thread_.get(); }
-
- static uint32_t GetL2capHeaderSize() { return L2CAP_HEADER_SIZE; }
-
- static size_t GetMaxFilteredSize() { return MAX_HCI_ACL_LEN - PACKET_TYPE_LENGTH; }
-};
-
-class SnoopLoggerModuleTest : public Test {
-public:
- TestModuleRegistry* test_registry;
+ os::Thread* thread_;
+ os::Handler* handler_;
protected:
void SetUp() override {
+ thread_ = new os::Thread("test_thread", bluetooth::os::Thread::Priority::NORMAL);
+ handler_ = new os::Handler(thread_);
+
const testing::TestInfo* const test_info =
testing::UnitTest::GetInstance()->current_test_info();
@@ -144,28 +121,30 @@ protected:
temp_snoop_log_last_ = temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log.last");
temp_snooz_log_ = temp_dir_ / (std::string(test_info->name()) + "_btsnooz_hci.log");
temp_snooz_log_last_ = temp_dir_ / (std::string(test_info->name()) + "_btsnooz_hci.log.last");
- temp_snoop_log_filtered =
+ temp_snoop_log_filtered_ =
temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log.filtered");
- temp_snoop_log_filtered_last =
+ temp_snoop_log_filtered_last_ =
temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log.filtered.last");
DeleteSnoopLogFiles();
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
- ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_filtered));
- ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_filtered_last));
+ ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_filtered_));
+ ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_filtered_last_));
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_last_));
-
- test_registry = new TestModuleRegistry();
}
void TearDown() override {
+ handler_->Clear();
+ handler_->WaitUntilStopped(200ms);
+ thread_->Stop();
+ delete handler_;
+ delete thread_;
+
com::android::bluetooth::flags::provider_->reset_flags();
DeleteSnoopLogFiles();
fake_timerfd_reset();
- test_registry->StopAll();
- delete test_registry;
const testing::TestInfo* const test_info =
testing::UnitTest::GetInstance()->current_test_info();
@@ -173,14 +152,25 @@ protected:
test_info->test_suite_name());
}
+ static uint32_t GetL2capHeaderSize() { return SnoopLogger::L2CAP_HEADER_SIZE; }
+ static size_t GetMaxFilteredSize() {
+ return SnoopLogger::MAX_HCI_ACL_LEN - SnoopLogger::PACKET_TYPE_LENGTH;
+ }
+
+ SnoopLogger* NewSnoopLogger(size_t max_packets_per_file, const std::string& btsnoop_mode,
+ bool qualcomm_debug_log_enabled, bool snoop_log_persists) {
+ return new SnoopLogger(handler_, temp_snoop_log_.string(), temp_snooz_log_.string(),
+ max_packets_per_file, SnoopLogger::GetMaxPacketsPerBuffer(),
+ btsnoop_mode, qualcomm_debug_log_enabled, 20ms, 5ms, snoop_log_persists);
+ }
+
std::filesystem::path temp_snoop_log_;
std::filesystem::path temp_snoop_log_last_;
std::filesystem::path temp_snooz_log_;
std::filesystem::path temp_snooz_log_last_;
- std::filesystem::path temp_snoop_log_filtered;
- std::filesystem::path temp_snoop_log_filtered_last;
+ std::filesystem::path temp_snoop_log_filtered_;
+ std::filesystem::path temp_snoop_log_filtered_last_;
-private:
void DeleteSnoopLogFiles() {
if (std::filesystem::exists(temp_snoop_log_)) {
ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_));
@@ -188,11 +178,11 @@ private:
if (std::filesystem::exists(temp_snoop_log_last_)) {
ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_last_));
}
- if (std::filesystem::exists(temp_snoop_log_filtered)) {
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ if (std::filesystem::exists(temp_snoop_log_filtered_)) {
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
- if (std::filesystem::exists(temp_snoop_log_filtered_last)) {
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_last));
+ if (std::filesystem::exists(temp_snoop_log_filtered_last_)) {
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_last_));
}
if (std::filesystem::exists(temp_snooz_log_)) {
ASSERT_TRUE(std::filesystem::remove(temp_snooz_log_));
@@ -203,13 +193,11 @@ private:
}
};
-TEST_F(SnoopLoggerModuleTest, empty_snoop_log_test) {
+TEST_F(SnoopLoggerTest, empty_snoop_log_test) {
// Actual test
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFull, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
- test_registry->StopAll();
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFull, false, false);
+ snoop_logger->Start();
+ snoop_logger->Stop();
// Verify states after test
ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_));
@@ -217,13 +205,11 @@ TEST_F(SnoopLoggerModuleTest, empty_snoop_log_test) {
ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_), sizeof(SnoopLoggerCommon::FileHeaderType));
}
-TEST_F(SnoopLoggerModuleTest, disable_snoop_log_test) {
+TEST_F(SnoopLoggerTest, disable_snoop_log_test) {
// Actual test
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
- test_registry->StopAll();
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, false, false);
+ snoop_logger->Start();
+ snoop_logger->Stop();
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
@@ -231,17 +217,13 @@ TEST_F(SnoopLoggerModuleTest, disable_snoop_log_test) {
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
-TEST_F(SnoopLoggerModuleTest, capture_one_packet_test) {
+TEST_F(SnoopLoggerTest, capture_one_packet_test) {
// Actual test
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFull, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
-
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFull, false, false);
+ snoop_logger->Start();
snoop_logger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::CMD);
-
- test_registry->StopAll();
+ snoop_logger->Stop();
// Verify states after test
ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_));
@@ -251,13 +233,10 @@ TEST_F(SnoopLoggerModuleTest, capture_one_packet_test) {
kInformationRequest.size());
}
-TEST_F(SnoopLoggerModuleTest, capture_hci_cmd_btsnooz_test) {
+TEST_F(SnoopLoggerTest, capture_hci_cmd_btsnooz_test) {
// Actual test
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
-
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, false, false);
+ snoop_logger->Start();
snoop_logger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::CMD);
snoop_logger->DumpSnoozLogToFile();
@@ -266,8 +245,7 @@ TEST_F(SnoopLoggerModuleTest, capture_hci_cmd_btsnooz_test) {
ASSERT_EQ(std::filesystem::file_size(temp_snooz_log_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) +
kInformationRequest.size());
-
- test_registry->StopAll();
+ snoop_logger->Stop();
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
@@ -275,13 +253,10 @@ TEST_F(SnoopLoggerModuleTest, capture_hci_cmd_btsnooz_test) {
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
-TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) {
+TEST_F(SnoopLoggerTest, capture_l2cap_signal_packet_btsnooz_test) {
// Actual test
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
-
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, false, false);
+ snoop_logger->Start();
snoop_logger->Capture(kSdpConnectionRequest, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::ACL);
snoop_logger->DumpSnoozLogToFile();
@@ -291,7 +266,7 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) {
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) +
kSdpConnectionRequest.size());
- test_registry->StopAll();
+ snoop_logger->Stop();
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
@@ -299,13 +274,10 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) {
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
-TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) {
+TEST_F(SnoopLoggerTest, capture_l2cap_short_data_packet_btsnooz_test) {
// Actual test
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
-
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, false, false);
+ snoop_logger->Start();
snoop_logger->Capture(kAvdtpSuspend, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::ACL);
snoop_logger->DumpSnoozLogToFile();
@@ -315,7 +287,7 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) {
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) +
kAvdtpSuspend.size());
- test_registry->StopAll();
+ snoop_logger->Stop();
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
@@ -323,13 +295,10 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) {
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
-TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) {
+TEST_F(SnoopLoggerTest, capture_l2cap_long_data_packet_btsnooz_test) {
// Actual test
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
-
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, false, false);
+ snoop_logger->Start();
snoop_logger->Capture(kHfpAtNrec0, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::ACL);
snoop_logger->DumpSnoozLogToFile();
@@ -338,7 +307,7 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) {
ASSERT_EQ(std::filesystem::file_size(temp_snooz_log_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14);
- test_registry->StopAll();
+ snoop_logger->Stop();
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
@@ -346,13 +315,10 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) {
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
-TEST_F(SnoopLoggerModuleTest, snoop_log_persists) {
+TEST_F(SnoopLoggerTest, snoop_log_persists) {
// Actual test
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, false, true);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
-
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, false, true);
+ snoop_logger->Start();
snoop_logger->Capture(kHfpAtNrec0, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::ACL);
snoop_logger->DumpSnoozLogToFile();
@@ -361,7 +327,7 @@ TEST_F(SnoopLoggerModuleTest, snoop_log_persists) {
ASSERT_EQ(std::filesystem::file_size(temp_snooz_log_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14);
- test_registry->StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
}
@@ -374,44 +340,39 @@ static void sync_handler(bluetooth::os::Handler* handler) {
ASSERT_EQ(future_status, std::future_status::ready);
}
-TEST_F(SnoopLoggerModuleTest, delete_old_snooz_log_files) {
+TEST_F(SnoopLoggerTest, delete_old_snooz_log_files) {
// Actual test
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, false, false);
+ snoop_logger->Start();
std::filesystem::create_directories(temp_snooz_log_.parent_path());
os::WriteToFile(temp_snooz_log_.string(), "");
- auto* handler = test_registry->GetTestModuleHandler(&SnoopLogger::Factory);
ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
- handler->Post(bluetooth::common::BindOnce(fake_timerfd_advance, 10));
+ handler_->Post(bluetooth::common::BindOnce(fake_timerfd_advance, 10));
ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
- handler->Post(bluetooth::common::BindOnce(fake_timerfd_advance, 15));
- sync_handler(handler);
- handler->Post(bluetooth::common::BindOnce(
+ handler_->Post(bluetooth::common::BindOnce(fake_timerfd_advance, 15));
+ sync_handler(handler_);
+ handler_->Post(bluetooth::common::BindOnce(
[](std::filesystem::path path) {
log::info("path: {}", path.string());
ASSERT_FALSE(std::filesystem::exists(path));
},
temp_snooz_log_));
- sync_handler(handler);
+ sync_handler(handler_);
- test_registry->StopAll();
+ snoop_logger->Stop();
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
-TEST_F(SnoopLoggerModuleTest, rotate_file_at_new_session_test) {
+TEST_F(SnoopLoggerTest, rotate_file_at_new_session_test) {
// Start once
{
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFull, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFull, false, false);
+ snoop_logger->Start();
snoop_logger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::CMD);
- test_registry->StopAll();
+ snoop_logger->Stop();
}
// Verify states after test
@@ -423,15 +384,13 @@ TEST_F(SnoopLoggerModuleTest, rotate_file_at_new_session_test) {
// Start again
{
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFull, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFull, false, false);
+ snoop_logger->Start();
snoop_logger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::CMD);
snoop_logger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::CMD);
- test_registry->StopAll();
+ snoop_logger->Stop();
}
// Verify states after test
@@ -445,19 +404,17 @@ TEST_F(SnoopLoggerModuleTest, rotate_file_at_new_session_test) {
kInformationRequest.size());
}
-TEST_F(SnoopLoggerModuleTest, rotate_file_after_full_test) {
+TEST_F(SnoopLoggerTest, rotate_file_after_full_test) {
// Actual test
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFull, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFull, false, false);
+ snoop_logger->Start();
for (int i = 0; i < 11; i++) {
snoop_logger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::CMD);
}
- test_registry->StopAll();
+ snoop_logger->Stop();
// Verify states after test
ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_));
@@ -470,11 +427,9 @@ TEST_F(SnoopLoggerModuleTest, rotate_file_after_full_test) {
(sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()) * 10);
}
-TEST_F(SnoopLoggerModuleTest, qualcomm_debug_log_test) {
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, true, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+TEST_F(SnoopLoggerTest, qualcomm_debug_log_test) {
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, true, false);
+ snoop_logger->Start();
snoop_logger->Capture(kQualcommConnectionRequest, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::ACL);
snoop_logger->DumpSnoozLogToFile();
@@ -484,7 +439,7 @@ TEST_F(SnoopLoggerModuleTest, qualcomm_debug_log_test) {
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) +
kQualcommConnectionRequest.size());
- test_registry->StopAll();
+ snoop_logger->Stop();
// Verify states after test
ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
@@ -492,12 +447,10 @@ TEST_F(SnoopLoggerModuleTest, qualcomm_debug_log_test) {
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
-TEST_F(SnoopLoggerModuleTest, qualcomm_debug_log_regression_test) {
+TEST_F(SnoopLoggerTest, qualcomm_debug_log_regression_test) {
{
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, true, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, true, false);
+ snoop_logger->Start();
snoop_logger->Capture(kHfpAtNrec0, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::ACL);
snoop_logger->DumpSnoozLogToFile();
@@ -506,7 +459,7 @@ TEST_F(SnoopLoggerModuleTest, qualcomm_debug_log_regression_test) {
ASSERT_EQ(
std::filesystem::file_size(temp_snooz_log_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14);
- test_registry->StopAll();
+ snoop_logger->Stop();
}
// Verify states after test
@@ -515,10 +468,8 @@ TEST_F(SnoopLoggerModuleTest, qualcomm_debug_log_regression_test) {
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
{
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, false, false);
+ snoop_logger->Start();
snoop_logger->Capture(kQualcommConnectionRequest, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::ACL);
snoop_logger->DumpSnoozLogToFile();
@@ -527,7 +478,7 @@ TEST_F(SnoopLoggerModuleTest, qualcomm_debug_log_regression_test) {
ASSERT_EQ(
std::filesystem::file_size(temp_snooz_log_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14);
- test_registry->StopAll();
+ snoop_logger->Stop();
}
// Verify states after test
@@ -536,7 +487,7 @@ TEST_F(SnoopLoggerModuleTest, qualcomm_debug_log_regression_test) {
ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
-TEST_F(SnoopLoggerModuleTest, filter_tracker_test) {
+TEST_F(SnoopLoggerTest, filter_tracker_test) {
std::unordered_map<uint16_t, bluetooth::hal::FilterTracker> filter_list;
uint16_t handle = 1;
uint16_t local_cid = 0x40;
@@ -564,7 +515,7 @@ TEST_F(SnoopLoggerModuleTest, filter_tracker_test) {
ASSERT_FALSE(filter_list[handle].IsAcceptlistedDlci(dlci));
}
-TEST_F(SnoopLoggerModuleTest, a2dp_packets_filtered_test) {
+TEST_F(SnoopLoggerTest, a2dp_packets_filtered_test) {
// Actual test
uint16_t conn_handle = 0x000b;
uint16_t local_cid = 0x0001;
@@ -576,12 +527,8 @@ TEST_F(SnoopLoggerModuleTest, a2dp_packets_filtered_test) {
bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty);
ASSERT_TRUE(filter_a2dp_property && filter_a2dp_property.value() == "true");
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
-
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ snoop_logger->Start();
// Simulate A2dp Media channel setup
snoop_logger->AddA2dpMediaChannel(conn_handle, local_cid, remote_cid);
@@ -589,22 +536,22 @@ TEST_F(SnoopLoggerModuleTest, a2dp_packets_filtered_test) {
snoop_logger->Capture(kA2dpMediaPacket, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::ACL);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty,
"false"));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Should filter packet
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType));
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, a2dp_packets_filtered_negative_test) {
+TEST_F(SnoopLoggerTest, a2dp_packets_filtered_negative_test) {
// Actual test
uint16_t conn_handle = 0x000b;
uint16_t local_cid = 0x0001;
@@ -616,12 +563,9 @@ TEST_F(SnoopLoggerModuleTest, a2dp_packets_filtered_negative_test) {
bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty);
ASSERT_TRUE(filter_a2dp_property && filter_a2dp_property.value() == "true");
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ snoop_logger->Start();
// Simulate A2dp Media channel setup
snoop_logger->AddA2dpMediaChannel(conn_handle, local_cid, remote_cid);
@@ -630,35 +574,32 @@ TEST_F(SnoopLoggerModuleTest, a2dp_packets_filtered_negative_test) {
snoop_logger->Capture(kA2dpMediaPacket, SnoopLogger::Direction::OUTGOING,
SnoopLogger::PacketType::ACL);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty,
"false"));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Should not filter
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) +
kA2dpMediaPacket.size());
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, headers_filtered_test) {
+TEST_F(SnoopLoggerTest, headers_filtered_test) {
ASSERT_TRUE(
bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterHeadersProperty, "true"));
auto filter_headers_property =
bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterHeadersProperty);
ASSERT_TRUE(filter_headers_property && filter_headers_property.value() == "true");
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ snoop_logger->Start();
std::vector<uint8_t> kAclPacket = {
0x0b, 0x20, 0x18, 0x00, 0x14, 0x00, 0x44, 0x00, 0x1b, 0x2f, 0x21, 0x41, 0x54, 0x2b,
@@ -667,28 +608,27 @@ TEST_F(SnoopLoggerModuleTest, headers_filtered_test) {
snoop_logger->Capture(kAclPacket, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(
bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterHeadersProperty, "false"));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
log::info("const size: {}", (int)(sizeof(SnoopLoggerCommon::FileHeaderType) +
sizeof(SnoopLogger::PacketHeaderType)));
// Packet should be filtered
- const size_t file_size = (size_t)std::filesystem::file_size(temp_snoop_log_filtered);
+ const size_t file_size = (size_t)std::filesystem::file_size(temp_snoop_log_filtered_);
const size_t expected_file_size = sizeof(SnoopLoggerCommon::FileHeaderType) +
- sizeof(SnoopLogger::PacketHeaderType) +
- TestSnoopLoggerModule::GetMaxFilteredSize();
+ sizeof(SnoopLogger::PacketHeaderType) + GetMaxFilteredSize();
ASSERT_EQ(file_size, expected_file_size);
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_sabme_ua_test) {
+TEST_F(SnoopLoggerTest, rfcomm_channel_filtered_sabme_ua_test) {
// Actual test
uint16_t conn_handle = 0x000b;
uint16_t local_cid = 0x0044;
@@ -701,12 +641,9 @@ TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_sabme_ua_test) {
ASSERT_TRUE(filter_rfcomm_property);
ASSERT_EQ("true", filter_rfcomm_property.value());
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ snoop_logger->Start();
// Simulate Rfcomm channel
snoop_logger->AddRfcommL2capChannel(conn_handle, local_cid, remote_cid);
@@ -723,24 +660,24 @@ TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_sabme_ua_test) {
SnoopLogger::PacketType::ACL);
snoop_logger->Capture(kRfcommUa, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL);
snoop_logger->ClearL2capAcceptlist(conn_handle, local_cid, remote_cid);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty,
"false"));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Packets should not be filtered because because they are SAMBE and UA events.
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType) + 2 * sizeof(SnoopLogger::PacketHeaderType) +
kRfcommSabme.size() + kRfcommUa.size());
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_acceptlisted_dlci_test) {
+TEST_F(SnoopLoggerTest, rfcomm_channel_filtered_acceptlisted_dlci_test) {
// Actual test
uint16_t conn_handle = 0x000b;
uint16_t local_cid = 0x0041;
@@ -755,12 +692,9 @@ TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_acceptlisted_dlci_test) {
ASSERT_TRUE(filter_rfcomm_property);
ASSERT_EQ("true", filter_rfcomm_property.value());
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ snoop_logger->Start();
// Simulate Rfcomm channel
snoop_logger->AddRfcommL2capChannel(conn_handle, local_cid, remote_cid);
@@ -774,24 +708,24 @@ TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_acceptlisted_dlci_test) {
snoop_logger->Capture(kRfcommDlci, SnoopLogger::Direction::INCOMING,
SnoopLogger::PacketType::ACL);
snoop_logger->ClearL2capAcceptlist(conn_handle, local_cid, remote_cid);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty,
"false"));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Packet should not be filtered because DLCI acceptlisted
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) +
kRfcommDlci.size());
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_not_acceptlisted_dlci_test) {
+TEST_F(SnoopLoggerTest, rfcomm_channel_filtered_not_acceptlisted_dlci_test) {
// Actual test
uint16_t conn_handle = 0x000b;
uint16_t local_cid = 0x0041;
@@ -806,12 +740,9 @@ TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_not_acceptlisted_dlci_test
ASSERT_TRUE(filter_rfcomm_property);
ASSERT_EQ("true", filter_rfcomm_property.value());
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ snoop_logger->Start();
// Simulate Rfcomm channel
snoop_logger->AddRfcommL2capChannel(conn_handle, local_cid, remote_cid);
@@ -825,24 +756,24 @@ TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_not_acceptlisted_dlci_test
SnoopLogger::PacketType::ACL);
snoop_logger->ClearL2capAcceptlist(conn_handle, local_cid, remote_cid);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty,
"false"));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Packet should be filtered because DLCI not acceptlisted
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) +
- TestSnoopLoggerModule::GetL2capHeaderSize());
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ GetL2capHeaderSize());
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_not_acceptlisted_l2cap_channel_test) {
+TEST_F(SnoopLoggerTest, rfcomm_channel_filtered_not_acceptlisted_l2cap_channel_test) {
// Actual test
uint16_t conn_handle = 0x000b;
uint16_t local_cid = 0x0041;
@@ -855,12 +786,9 @@ TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_not_acceptlisted_l2cap_cha
ASSERT_TRUE(filter_rfcomm_property);
ASSERT_EQ("true", filter_rfcomm_property.value());
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ snoop_logger->Start();
std::vector<uint8_t> kRfcommL2capChannel = {
0x0b, 0x20, 0x12, 0x00, 0x0e, 0x00, 0x41, 0x00, 0x00, 0xef, 0x15,
@@ -871,24 +799,24 @@ TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_not_acceptlisted_l2cap_cha
SnoopLogger::PacketType::ACL);
snoop_logger->ClearL2capAcceptlist(conn_handle, local_cid, remote_cid);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty,
"false"));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Packet should be filtered because L2CAP channel not acceptlisted
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) +
- TestSnoopLoggerModule::GetL2capHeaderSize());
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ GetL2capHeaderSize());
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_acceptlisted_l2cap_channel_test) {
+TEST_F(SnoopLoggerTest, rfcomm_channel_filtered_acceptlisted_l2cap_channel_test) {
// Actual test
uint16_t conn_handle = 0x000b;
uint16_t local_cid = 0x0041;
@@ -901,13 +829,9 @@ TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_acceptlisted_l2cap_channel
ASSERT_TRUE(filter_rfcomm_property);
ASSERT_EQ("true", filter_rfcomm_property.value());
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
-
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ snoop_logger->Start();
snoop_logger->AcceptlistL2capChannel(conn_handle, local_cid, remote_cid);
std::vector<uint8_t> kRfcommL2capChannel = {
@@ -919,24 +843,24 @@ TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_acceptlisted_l2cap_channel
SnoopLogger::PacketType::ACL);
snoop_logger->ClearL2capAcceptlist(conn_handle, local_cid, remote_cid);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty,
"false"));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Packet should not be filtered because L2CAP channel acceptlisted
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) +
kRfcommL2capChannel.size());
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, profiles_filtered_hfp_hf_test) {
+TEST_F(SnoopLoggerTest, profiles_filtered_hfp_hf_test) {
// Actual test
uint16_t conn_handle = 0x000b;
uint16_t local_cid = 0x0043;
@@ -966,13 +890,9 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_hfp_hf_test) {
(filterMapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeMagic) !=
std::string::npos));
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
-
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ snoop_logger->Start();
snoop_logger->SetL2capChannelOpen(conn_handle, local_cid, remote_cid, psm, false);
snoop_logger->SetRfcommPortOpen(conn_handle, local_cid, dlci, profile_uuid_hfp_hf, flow);
@@ -988,9 +908,9 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_hfp_hf_test) {
snoop_logger->SetL2capChannelClose(conn_handle, local_cid, remote_cid);
snoop_logger->SetRfcommPortClose(conn_handle, local_cid, dlci, profile_uuid_hfp_hf);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty,
SnoopLogger::kBtSnoopLogFilterProfileModeDisabled));
@@ -999,16 +919,16 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_hfp_hf_test) {
SnoopLogger::kBtSnoopLogFilterProfileModeDisabled));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Packet should be filtered
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) +
HEADER_SIZE + strlen(clcc_pattern.c_str()));
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_magic_test) {
+TEST_F(SnoopLoggerTest, profiles_filtered_pbap_magic_test) {
// Actual test
constexpr uint16_t PROFILE_PSM_PBAP = 0x1025;
constexpr uint16_t PROFILE_UUID_PBAP = 0x112f;
@@ -1039,13 +959,9 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_magic_test) {
(filterMapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeMagic) !=
std::string::npos));
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 15,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
-
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(15, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ snoop_logger->Start();
snoop_logger->SetL2capChannelOpen(conn_handle, local_cid, remote_cid, psm, false);
snoop_logger->SetRfcommPortOpen(conn_handle, local_cid, dlci, profile_uuid_pbap, flow);
@@ -1057,9 +973,9 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_magic_test) {
snoop_logger->SetL2capChannelClose(conn_handle, local_cid, remote_cid);
snoop_logger->SetRfcommPortClose(conn_handle, local_cid, dlci, profile_uuid_pbap);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty,
SnoopLogger::kBtSnoopLogFilterProfileModeDisabled));
@@ -1068,18 +984,18 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_magic_test) {
SnoopLogger::kBtSnoopLogFilterProfileModeDisabled));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Packets should be filtered
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType) +
(int)kTestData.size() * (sizeof(SnoopLogger::PacketHeaderType) + HEADER_SIZE +
strlen(magic_string.c_str())));
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_header_test) {
+TEST_F(SnoopLoggerTest, profiles_filtered_pbap_header_test) {
// Actual test
constexpr uint16_t PROFILE_PSM_PBAP = 0x1025;
constexpr uint16_t PROFILE_UUID_PBAP = 0x112f;
@@ -1109,13 +1025,9 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_header_test) {
(filterMapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeHeader) !=
std::string::npos));
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 15,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
-
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(15, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ snoop_logger->Start();
snoop_logger->SetL2capChannelOpen(conn_handle, local_cid, remote_cid, psm, false);
snoop_logger->SetRfcommPortOpen(conn_handle, local_cid, dlci, profile_uuid_pbap, flow);
@@ -1127,9 +1039,9 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_header_test) {
snoop_logger->SetL2capChannelClose(conn_handle, local_cid, remote_cid);
snoop_logger->SetRfcommPortClose(conn_handle, local_cid, dlci, profile_uuid_pbap);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty,
SnoopLogger::kBtSnoopLogFilterProfileModeDisabled));
@@ -1138,17 +1050,17 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_header_test) {
SnoopLogger::kBtSnoopLogFilterProfileModeDisabled));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Packets should be filtered
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType) +
(int)kTestData.size() * (sizeof(SnoopLogger::PacketHeaderType) + HEADER_SIZE));
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
-TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_fullfilter_test) {
+TEST_F(SnoopLoggerTest, profiles_filtered_pbap_fullfilter_test) {
// Actual test
constexpr uint16_t PROFILE_PSM_PBAP = 0x1025;
constexpr uint16_t PROFILE_UUID_PBAP = 0x112f;
@@ -1178,13 +1090,9 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_fullfilter_test) {
(filterMapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeFullfillter) !=
std::string::npos));
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 15,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
-
- TestModuleRegistry test_registry;
- test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(15, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ snoop_logger->Start();
snoop_logger->SetL2capChannelOpen(conn_handle, local_cid, remote_cid, psm, false);
snoop_logger->SetRfcommPortOpen(conn_handle, local_cid, dlci, profile_uuid_pbap, flow);
@@ -1196,9 +1104,9 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_fullfilter_test) {
snoop_logger->SetL2capChannelClose(conn_handle, local_cid, remote_cid);
snoop_logger->SetRfcommPortClose(conn_handle, local_cid, dlci, profile_uuid_pbap);
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
- test_registry.StopAll();
+ snoop_logger->Stop();
ASSERT_TRUE(bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty,
SnoopLogger::kBtSnoopLogFilterProfileModeDisabled));
@@ -1207,22 +1115,20 @@ TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_fullfilter_test) {
SnoopLogger::kBtSnoopLogFilterProfileModeDisabled));
// Verify states after test
- ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
// Packets should be filtered
- ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered),
+ ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_filtered_),
sizeof(SnoopLoggerCommon::FileHeaderType));
- ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered));
+ ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_));
}
static constexpr int INVALID_FD = -1;
-TEST_F(SnoopLoggerModuleTest, socket_disabled_connect_fail_test) {
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, true, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+TEST_F(SnoopLoggerTest, socket_disabled_connect_fail_test) {
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, true, false);
+ snoop_logger->Start();
// // Create a TCP socket file descriptor
int socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
@@ -1239,15 +1145,14 @@ TEST_F(SnoopLoggerModuleTest, socket_disabled_connect_fail_test) {
RUN_NO_INTR(ret = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr)));
ASSERT_NE(0, ret);
- test_registry->StopAll();
+ snoop_logger->Stop();
close(socket_fd);
}
-TEST_F(SnoopLoggerModuleTest, default_socket_enabled_capture_recv_test) {
+TEST_F(SnoopLoggerTest, default_socket_enabled_capture_recv_test) {
int ret;
- auto* snoop_logger = new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(),
- 10, SnoopLogger::kBtSnoopLogModeFull, true, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFull, true, false);
+ snoop_logger->Start();
// // Create a TCP socket file descriptor
int socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
@@ -1285,14 +1190,13 @@ TEST_F(SnoopLoggerModuleTest, default_socket_enabled_capture_recv_test) {
ASSERT_EQ(bytes_read, static_cast<int>(kHfpAtNrec0.size()));
ASSERT_EQ(0, std::memcmp(recv_buf3, kHfpAtNrec0.data(), kHfpAtNrec0.size()));
- test_registry->StopAll();
+ snoop_logger->Stop();
close(socket_fd);
}
-TEST_F(SnoopLoggerModuleTest, custom_socket_register_enabled_capture_recv_test) {
- auto* snoop_logger = new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(),
- 10, SnoopLogger::kBtSnoopLogModeFull, true, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+TEST_F(SnoopLoggerTest, custom_socket_register_enabled_capture_recv_test) {
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFull, true, false);
+ snoop_logger->Start();
int new_port = 8873;
SyscallWrapperImpl syscall_if;
@@ -1342,15 +1246,13 @@ TEST_F(SnoopLoggerModuleTest, custom_socket_register_enabled_capture_recv_test)
ASSERT_EQ(bytes_read, static_cast<int>(kHfpAtNrec0.size()));
ASSERT_EQ(0, std::memcmp(recv_buf3, kHfpAtNrec0.data(), kHfpAtNrec0.size()));
- test_registry->StopAll();
+ snoop_logger->Stop();
close(socket_fd);
}
-TEST_F(SnoopLoggerModuleTest, custom_socket_interface_register_logging_disabled_test) {
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeDisabled, true, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+TEST_F(SnoopLoggerTest, custom_socket_interface_register_logging_disabled_test) {
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeDisabled, true, false);
+ snoop_logger->Start();
class SnoopLoggerSocketMock : public SnoopLoggerSocketInterface {
public:
@@ -1367,13 +1269,12 @@ TEST_F(SnoopLoggerModuleTest, custom_socket_interface_register_logging_disabled_
ASSERT_FALSE(mock.write_called);
- test_registry->StopAll();
+ snoop_logger->Stop();
}
-TEST_F(SnoopLoggerModuleTest, custom_socket_interface_register_logging_enabled_test) {
- auto* snoop_logger = new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(),
- 10, SnoopLogger::kBtSnoopLogModeFull, true, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+TEST_F(SnoopLoggerTest, custom_socket_interface_register_logging_enabled_test) {
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFull, true, false);
+ snoop_logger->Start();
class SnoopLoggerSocketMock : public SnoopLoggerSocketInterface {
public:
@@ -1390,10 +1291,10 @@ TEST_F(SnoopLoggerModuleTest, custom_socket_interface_register_logging_enabled_t
ASSERT_TRUE(mock.write_called);
- test_registry->StopAll();
+ snoop_logger->Stop();
}
-TEST_F(SnoopLoggerModuleTest, custom_socket_profiles_filtered_hfp_hf_test) {
+TEST_F(SnoopLoggerTest, custom_socket_profiles_filtered_hfp_hf_test) {
uint16_t conn_handle = 0x000b;
uint16_t local_cid = 0x0043;
uint16_t remote_cid = 0x3040;
@@ -1439,11 +1340,9 @@ TEST_F(SnoopLoggerModuleTest, custom_socket_profiles_filtered_hfp_hf_test) {
(filterMapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeMagic) !=
std::string::npos));
- auto* snoop_logger =
- new TestSnoopLoggerModule(temp_snoop_log_.string(), temp_snooz_log_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ snoop_logger->Start();
int new_port = 8873;
SyscallWrapperImpl syscall_if;
@@ -1504,95 +1403,75 @@ TEST_F(SnoopLoggerModuleTest, custom_socket_profiles_filtered_hfp_hf_test) {
bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty,
SnoopLogger::kBtSnoopLogFilterProfileModeDisabled));
- test_registry->StopAll();
+ snoop_logger->Stop();
close(socket_fd);
}
#ifdef __ANDROID__
-TEST_F(SnoopLoggerModuleTest, recreate_log_directory_when_enabled_test) {
+TEST_F(SnoopLoggerTest, recreate_log_directory_when_enabled_test) {
com::android::bluetooth::flags::provider_->snoop_logger_recreate_logs_directory(true);
- // Actual test
const testing::TestInfo* const test_info = testing::UnitTest::GetInstance()->current_test_info();
- const std::filesystem::path os_btsnoop_file_path_ = os::ParameterProvider::SnoopLogFilePath();
- std::filesystem::path temp_dir_path_ = os_btsnoop_file_path_.parent_path();
-
- const std::filesystem::path temp_log_btsnoop_file_ =
- temp_dir_path_ / (std::string(test_info->name()) + "_btsnoop_hci.log");
- const std::filesystem::path temp_log_btsnooz_file_ =
- temp_dir_path_ / (std::string(test_info->name()) + "_btsnooz_hci.log");
+ const std::filesystem::path file_path = os::ParameterProvider::SnoopLogFilePath();
+ const std::filesystem::path temp_dir_ = file_path.parent_path();
- if (std::filesystem::exists(temp_dir_path_)) {
- std::filesystem::remove_all(temp_dir_path_);
- }
+ // Override the paths used for the test. The feature tested here relies on the actual
+ // snoop path on Android to work.
+ temp_snoop_log_ = temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log");
+ temp_snoop_log_last_ = temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log.last");
+ temp_snooz_log_ = temp_dir_ / (std::string(test_info->name()) + "_btsnooz_hci.log");
+ temp_snooz_log_last_ = temp_dir_ / (std::string(test_info->name()) + "_btsnooz_hci.log.last");
+ temp_snoop_log_filtered_ =
+ temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log.filtered");
+ temp_snoop_log_filtered_last_ =
+ temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log.filtered.last");
+ DeleteSnoopLogFiles();
+ std::filesystem::remove_all(temp_dir_);
- ASSERT_FALSE(std::filesystem::exists(temp_dir_path_));
+ ASSERT_FALSE(std::filesystem::exists(temp_dir_));
- auto* snoop_logger = new TestSnoopLoggerModule(temp_log_btsnoop_file_.string(),
- temp_log_btsnooz_file_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFull, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFull, false, false);
+ snoop_logger->Start();
- ASSERT_TRUE(std::filesystem::exists(temp_dir_path_));
+ ASSERT_TRUE(std::filesystem::exists(temp_dir_));
- test_registry->StopAll();
+ snoop_logger->Stop();
- // btsnoop file should exist
- ASSERT_TRUE(std::filesystem::exists(temp_log_btsnoop_file_));
- // btsnooz file should be removed as snoop_log_persists is false
- ASSERT_FALSE(std::filesystem::exists(temp_log_btsnooz_file_));
- // remove temp_dir_path_ contents after test
- if (std::filesystem::exists(temp_dir_path_)) {
- for (const auto& entry : std::filesystem::directory_iterator(temp_dir_path_)) {
- std::filesystem::remove_all(entry.path());
- }
- }
- ASSERT_TRUE(std::filesystem::exists(temp_dir_path_));
+ // btsnoop file should exist, but btsnooz should be removed as snoop_log_persist is false.
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_));
+ ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
}
-TEST_F(SnoopLoggerModuleTest, recreate_log_directory_when_filtered_test) {
+TEST_F(SnoopLoggerTest, recreate_log_directory_when_filtered_test) {
com::android::bluetooth::flags::provider_->snoop_logger_recreate_logs_directory(true);
- // Actual test
const testing::TestInfo* const test_info = testing::UnitTest::GetInstance()->current_test_info();
- const std::filesystem::path os_btsnoop_file_path_ = os::ParameterProvider::SnoopLogFilePath();
- std::filesystem::path temp_dir_path_ = os_btsnoop_file_path_.parent_path();
+ const std::filesystem::path file_path = os::ParameterProvider::SnoopLogFilePath();
+ const std::filesystem::path temp_dir_ = file_path.parent_path();
- const std::filesystem::path temp_log_btsnoop_file_ =
- temp_dir_path_ / (std::string(test_info->name()) + "_btsnoop_hci.log");
- const std::filesystem::path temp_log_btsnooz_file_ =
- temp_dir_path_ / (std::string(test_info->name()) + "_btsnooz_hci.log");
+ // Override the paths used for the test. The feature tested here relies on the actual
+ // snoop path on Android to work.
+ temp_snoop_log_ = temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log");
+ temp_snoop_log_last_ = temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log.last");
+ temp_snooz_log_ = temp_dir_ / (std::string(test_info->name()) + "_btsnooz_hci.log");
+ temp_snooz_log_last_ = temp_dir_ / (std::string(test_info->name()) + "_btsnooz_hci.log.last");
+ temp_snoop_log_filtered_ =
+ temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log.filtered");
+ temp_snoop_log_filtered_last_ =
+ temp_dir_ / (std::string(test_info->name()) + "_btsnoop_hci.log.filtered.last");
+ DeleteSnoopLogFiles();
+ std::filesystem::remove_all(temp_dir_);
- if (std::filesystem::exists(temp_dir_path_)) {
- std::filesystem::remove_all(temp_dir_path_);
- }
-
- ASSERT_FALSE(std::filesystem::exists(temp_dir_path_));
-
- auto* snoop_logger = new TestSnoopLoggerModule(
- temp_log_btsnoop_file_.string(), temp_log_btsnooz_file_.string(), 10,
- SnoopLogger::kBtSnoopLogModeFiltered, false, false);
- test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger);
+ ASSERT_FALSE(std::filesystem::exists(temp_dir_));
- ASSERT_TRUE(std::filesystem::exists(temp_dir_path_));
+ auto* snoop_logger = NewSnoopLogger(10, SnoopLogger::kBtSnoopLogModeFiltered, false, false);
+ snoop_logger->Start();
- test_registry->StopAll();
+ ASSERT_TRUE(std::filesystem::exists(temp_dir_));
- const std::filesystem::path temp_log_btsnoop_filtered_file_ =
- temp_dir_path_ / (std::string(test_info->name()) + "_btsnoop_hci.log.filtered");
- const std::filesystem::path temp_log_btsnooz_filtered_file_ =
- temp_dir_path_ / (std::string(test_info->name()) + "_btsnooz_hci.log.filtered");
+ snoop_logger->Stop();
- // btsnoop file should exist
- ASSERT_TRUE(std::filesystem::exists(temp_log_btsnoop_filtered_file_));
- // btsnooz file should be removed as snoop_log_persists is false
- ASSERT_FALSE(std::filesystem::exists(temp_log_btsnooz_filtered_file_));
- // remove temp_dir_path_ contents after test
- if (std::filesystem::exists(temp_dir_path_)) {
- for (const auto& entry : std::filesystem::directory_iterator(temp_dir_path_)) {
- std::filesystem::remove_all(entry.path());
- }
- }
- ASSERT_TRUE(std::filesystem::exists(temp_dir_path_));
+ // btsnoop file should exist.
+ ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered_));
}
#endif // __ANDROID__
-} // namespace testing
+} // namespace bluetooth::hal
diff --git a/system/gd/hci/distance_measurement_manager.cc b/system/gd/hci/distance_measurement_manager.cc
index 885f0b3bf1..5e144db7fe 100644
--- a/system/gd/hci/distance_measurement_manager.cc
+++ b/system/gd/hci/distance_measurement_manager.cc
@@ -86,6 +86,7 @@ static constexpr uint16_t kDefaultRasMtu = 247; // Section 3.1.2 of RAP 1.0
static constexpr uint8_t kAttHeaderSize = 5; // Section 3.2.2.1 of RAS 1.0
static constexpr uint8_t kRasSegmentHeaderSize = 1;
static constexpr uint16_t kEnableSecurityTimeoutMs = 10000; // 10s
+static constexpr uint16_t kProcedureScheduleGuardMs = 1000; // 1s
struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
struct CsProcedureData {
@@ -187,6 +188,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
Address address;
hci::Role local_hci_role = hci::Role::CENTRAL;
uint16_t procedure_counter = 0;
+ uint16_t procedure_counting_after_enable = 0;
CsRole role = CsRole::INITIATOR;
bool local_start = false; // If the CS was started by the local device.
// TODO: clean up, replace the measurement_ongoing with STOPPED
@@ -212,7 +214,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
uint16_t interval_ms = kDefaultIntervalMs;
uint16_t max_procedure_count = 1;
bool waiting_for_start_callback = false;
- std::unique_ptr<os::RepeatingAlarm> repeating_alarm = nullptr;
+ std::unique_ptr<os::Alarm> procedure_schedule_guard_alarm = nullptr;
// RAS data
RangingHeader ranging_header_;
PacketViewForRecombination segment_data_;
@@ -389,7 +391,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
}
bool init_cs_requester_tracker(const Address& cs_remote_address, uint16_t connection_handle,
- hci::Role local_hci_role, uint16_t interval,
+ hci::Role local_hci_role, uint16_t interval_ms,
bool* has_updated_procedure_params) {
*has_updated_procedure_params = false;
auto it = cs_requester_trackers_.find(connection_handle);
@@ -415,24 +417,22 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
}
}
// make sure the repeating_alarm is initialized.
- if (it->second.repeating_alarm == nullptr) {
- it->second.repeating_alarm = std::make_unique<os::RepeatingAlarm>(handler_);
+ if (it->second.procedure_schedule_guard_alarm == nullptr) {
+ it->second.procedure_schedule_guard_alarm = std::make_unique<os::Alarm>(handler_);
}
it->second.state = CsTrackerState::INIT;
- // If the interval is less than 1 second, update it to 1 second and increase the
- // max_procedure_count
- uint16_t max_procedure_count = 1;
- if (interval < 1000) {
- max_procedure_count = 1000 / interval;
- interval = 1000;
- }
- if (max_procedure_count != it->second.max_procedure_count) {
- log::info("Update interval to 1s and max_procedure_count to {}", max_procedure_count);
+
+ if (interval_ms != it->second.interval_ms) {
+ log::info("Update interval to {}", interval_ms);
+ uint16_t max_procedure_count = 1;
+ if (interval_ms < 1000) {
+ max_procedure_count = 5;
+ }
it->second.max_procedure_count = max_procedure_count;
*has_updated_procedure_params = true;
}
- it->second.interval_ms = interval;
+ it->second.interval_ms = interval_ms;
it->second.local_start = true;
it->second.measurement_ongoing = true;
it->second.waiting_for_start_callback = true;
@@ -465,19 +465,14 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
cs_requester_trackers_[connection_handle].requesting_config_id);
return;
}
- log::info("enable cs procedure regularly with interval: {} ms",
- cs_requester_trackers_[connection_handle].interval_ms);
- cs_requester_trackers_[connection_handle].repeating_alarm->Cancel();
+
+ cs_requester_trackers_[connection_handle].procedure_schedule_guard_alarm->Cancel();
if (has_updated_procedure_params) {
send_le_cs_set_procedure_parameters(
connection_handle, cs_requester_trackers_[connection_handle].used_config_id,
cs_requester_trackers_[connection_handle].remote_num_antennas_supported_);
} else {
send_le_cs_procedure_enable(connection_handle, Enable::ENABLED);
- cs_requester_trackers_[connection_handle].repeating_alarm->Schedule(
- common::Bind(&impl::send_le_cs_procedure_enable, common::Unretained(this),
- connection_handle, Enable::ENABLED),
- std::chrono::milliseconds(cs_requester_trackers_[connection_handle].interval_ms));
}
}
@@ -505,7 +500,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (it == cs_requester_trackers_.end()) {
log::warn("Can't find CS tracker for {}", address);
} else if (it->second.measurement_ongoing) {
- it->second.repeating_alarm->Cancel();
+ it->second.procedure_schedule_guard_alarm->Cancel();
send_le_cs_procedure_enable(connection_handle, Enable::DISABLED);
// does not depend on the 'disable' command result.
reset_tracker_on_stopped(it->second);
@@ -568,9 +563,9 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
log::info("address:{}", address);
for (auto it = cs_requester_trackers_.begin(); it != cs_requester_trackers_.end();) {
if (it->second.address == address) {
- if (it->second.repeating_alarm != nullptr) {
- it->second.repeating_alarm->Cancel();
- it->second.repeating_alarm.reset();
+ if (it->second.procedure_schedule_guard_alarm != nullptr) {
+ it->second.procedure_schedule_guard_alarm->Cancel();
+ it->second.procedure_schedule_guard_alarm.reset();
}
DistanceMeasurementErrorCode reason = REASON_NO_LE_CONNECTION;
if (ras_disconnect_reason == ras::RasDisconnectReason::SERVER_NOT_AVAILABLE) {
@@ -820,9 +815,21 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
(preferred_peer_antenna_value >> 2) & 0x01;
preferred_peer_antenna.use_fourth_ordered_antenna_element_ =
(preferred_peer_antenna_value >> 3) & 0x01;
+
+ // only change the min_procedure_interval, leave the flexibility to the controller
+ uint16_t min_procedure_interval = kMinProcedureInterval;
+ if (cs_requester_trackers_[connection_handle].max_procedure_count != 1 &&
+ cs_requester_trackers_[connection_handle].interval_ms > 100) {
+ // TODO(b/398253048): keep the burst mode for 'HIGH' for now. allow app to disable it.
+ uint16_t measurement_interval_ms = cs_requester_trackers_[connection_handle].interval_ms;
+ min_procedure_interval = static_cast<uint16_t>(
+ std::round((double)measurement_interval_ms /
+ cs_requester_trackers_[connection_handle].conn_interval_));
+ }
+ log::debug("procedure params: min_int = {}", min_procedure_interval);
hci_layer_->EnqueueCommand(
LeCsSetProcedureParametersBuilder::Create(
- connection_handle, config_id, kMaxProcedureLen, kMinProcedureInterval,
+ connection_handle, config_id, kMaxProcedureLen, min_procedure_interval,
kMaxProcedureInterval,
cs_requester_trackers_[connection_handle].max_procedure_count, kMinSubeventLen,
kMaxSubeventLen, tone_antenna_config_selection, CsPhy::LE_1M_PHY, kTxPwrDelta,
@@ -845,8 +852,8 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (it->second.measurement_ongoing) {
distance_measurement_callbacks_->OnDistanceMeasurementStopped(it->second.address, errorCode,
METHOD_CS);
- it->second.repeating_alarm->Cancel();
- it->second.repeating_alarm.reset();
+ it->second.procedure_schedule_guard_alarm->Cancel();
+ it->second.procedure_schedule_guard_alarm.reset();
}
reset_tracker_on_stopped(it->second);
// the cs_tracker should be kept until the connection is disconnected
@@ -863,11 +870,12 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (enable == Enable::ENABLED) {
if (it->second.state == CsTrackerState::STOPPED) {
log::error("safe guard, error state, no local measurement request.");
- if (it->second.repeating_alarm) {
- it->second.repeating_alarm->Cancel();
+ if (it->second.procedure_schedule_guard_alarm) {
+ it->second.procedure_schedule_guard_alarm->Cancel();
}
return;
}
+
it->second.state = CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED;
} else { // Enable::DISABLE
if (it->second.state != CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED &&
@@ -1166,13 +1174,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
}
if (it->second.measurement_ongoing) {
- log::info("enable cs procedure regularly with interval: {} ms", it->second.interval_ms);
- it->second.repeating_alarm->Cancel();
send_le_cs_procedure_enable(connection_handle, Enable::ENABLED);
- it->second.repeating_alarm->Schedule(
- common::Bind(&impl::send_le_cs_procedure_enable, common::Unretained(this),
- connection_handle, Enable::ENABLED),
- std::chrono::milliseconds(it->second.interval_ms));
}
}
@@ -1280,6 +1282,24 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
live_tracker->selected_tx_power = event_view.GetSelectedTxPower();
live_tracker->n_procedure_count = event_view.GetProcedureCount();
live_tracker->retry_counter_for_cs_enable = 0;
+ live_tracker->procedure_counting_after_enable = 0;
+ if (live_tracker->local_start) {
+ uint32_t schedule_interval = live_tracker->interval_ms;
+ if (live_tracker->n_procedure_count > 1) {
+ schedule_interval = live_tracker->n_procedure_count * event_view.GetProcedureInterval() *
+ live_tracker->conn_interval_ +
+ kProcedureScheduleGuardMs;
+ log::debug("guard interval is {} ms", schedule_interval);
+ }
+ if (live_tracker->n_procedure_count >= 1) {
+ live_tracker->procedure_schedule_guard_alarm->Cancel();
+ log::info("schedule next procedure enable after {} ms", schedule_interval);
+ cs_requester_trackers_[connection_handle].procedure_schedule_guard_alarm->Schedule(
+ common::Bind(&impl::send_le_cs_procedure_enable, common::Unretained(this),
+ connection_handle, Enable::ENABLED),
+ std::chrono::milliseconds(schedule_interval));
+ }
+ }
if (live_tracker->local_start && live_tracker->waiting_for_start_callback) {
live_tracker->waiting_for_start_callback = false;
@@ -1352,7 +1372,8 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
subevent_abort_reason = cs_event_result.GetSubeventAbortReason();
result_data_structures = cs_event_result.GetResultDataStructures();
- procedure_data = init_cs_procedure_data(live_tracker, cs_event_result.GetProcedureCounter(),
+ procedure_data = init_cs_procedure_data(connection_handle, live_tracker,
+ cs_event_result.GetProcedureCounter(),
cs_event_result.GetNumAntennaPaths());
if (live_tracker->role == CsRole::INITIATOR) {
procedure_data->frequency_compensation.push_back(
@@ -1530,7 +1551,9 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
log::warn("can't find tracker for 0x{:04x}", connection_handle);
return;
}
- if (cs_requester_trackers_[connection_handle].state != CsTrackerState::STARTED) {
+ if (cs_requester_trackers_[connection_handle].state != CsTrackerState::STARTED &&
+ cs_requester_trackers_[connection_handle].state !=
+ CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED) {
log::warn("The measurement for {} is stopped, ignore the remote data.", connection_handle);
return;
}
@@ -1583,7 +1606,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
}
auto& tracker = cs_requester_trackers_[connection_handle];
if (tracker.measurement_ongoing && tracker.local_start) {
- cs_requester_trackers_[connection_handle].repeating_alarm->Cancel();
+ cs_requester_trackers_[connection_handle].procedure_schedule_guard_alarm->Cancel();
send_le_cs_procedure_enable(connection_handle, Enable::DISABLED);
distance_measurement_callbacks_->OnDistanceMeasurementStopped(
tracker.address, REASON_INTERNAL_ERROR, METHOD_CS);
@@ -1984,11 +2007,10 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
connection_handle);
}
- CsProcedureData* init_cs_procedure_data(CsTracker* live_tracker, uint16_t procedure_counter,
- uint8_t num_antenna_paths) {
+ CsProcedureData* init_cs_procedure_data(uint16_t connection_handle, CsTracker* live_tracker,
+ uint16_t procedure_counter, uint8_t num_antenna_paths) {
// Update procedure count
live_tracker->procedure_counter = procedure_counter;
-
std::vector<CsProcedureData>& data_list = live_tracker->procedure_data_list;
for (auto& data : data_list) {
if (data.counter == procedure_counter) {
@@ -1997,6 +2019,14 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
return &data;
}
}
+ live_tracker->procedure_counting_after_enable += 1;
+ if (live_tracker->local_start && live_tracker->procedure_counting_after_enable > 0 &&
+ live_tracker->n_procedure_count > 1 &&
+ live_tracker->procedure_counting_after_enable == live_tracker->n_procedure_count) {
+ log::debug("enable procedure after finishing the last procedure");
+ send_le_cs_procedure_enable(connection_handle, Enable::ENABLED);
+ }
+
log::info("Create data for procedure_counter: {}", procedure_counter);
data_list.emplace_back(procedure_counter, num_antenna_paths, live_tracker->used_config_id,
live_tracker->selected_tx_power);
diff --git a/system/main/shim/entry.cc b/system/main/shim/entry.cc
index ace58f79e4..4937187328 100644
--- a/system/main/shim/entry.cc
+++ b/system/main/shim/entry.cc
@@ -60,7 +60,7 @@ hci::DistanceMeasurementManager* GetDistanceMeasurementManager() {
return Stack::GetInstance()->GetInstance<hci::DistanceMeasurementManager>();
}
-hal::SnoopLogger* GetSnoopLogger() { return Stack::GetInstance()->GetInstance<hal::SnoopLogger>(); }
+hal::SnoopLogger* GetSnoopLogger() { return Stack::GetInstance()->GetSnoopLogger(); }
lpp::LppOffloadInterface* GetLppOffloadManager() {
return Stack::GetInstance()->GetInstance<lpp::LppOffloadManager>();
diff --git a/system/main/shim/stack.cc b/system/main/shim/stack.cc
index ef9fd0d5d4..c570a5f542 100644
--- a/system/main/shim/stack.cc
+++ b/system/main/shim/stack.cc
@@ -69,6 +69,7 @@ struct Stack::impl {
Acl* acl_ = nullptr;
metrics::CounterMetrics* counter_metrics_ = nullptr;
storage::StorageModule* storage_ = nullptr;
+ hal::SnoopLogger* snoop_logger_ = nullptr;
};
Stack::Stack() { pimpl_ = std::make_shared<Stack::impl>(); }
@@ -90,6 +91,7 @@ void Stack::StartEverything() {
pimpl_->counter_metrics_ = new metrics::CounterMetrics(new Handler(stack_thread_));
pimpl_->storage_ = new storage::StorageModule(new Handler(stack_thread_));
+ pimpl_->snoop_logger_ = new hal::SnoopLogger(new Handler(stack_thread_));
#if TARGET_FLOSS
modules.add<sysprops::SyspropsModule>();
@@ -116,11 +118,12 @@ void Stack::StartEverything() {
WakelockManager::Get().Acquire();
}
+ is_running_ = true;
+
std::promise<void> promise;
auto future = promise.get_future();
management_handler_->Post(common::BindOnce(&Stack::handle_start_up, common::Unretained(this),
&modules, std::move(promise)));
- is_running_ = true;
auto init_status = future.wait_for(
std::chrono::milliseconds(get_gd_stack_timeout_ms(/* is_start = */ true)));
@@ -223,6 +226,12 @@ storage::StorageModule* Stack::GetStorage() const {
return pimpl_->storage_;
}
+hal::SnoopLogger* Stack::GetSnoopLogger() const {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ log::assert_that(is_running_, "assert failed: is_running_");
+ return pimpl_->snoop_logger_;
+}
+
os::Handler* Stack::GetHandler() {
std::lock_guard<std::recursive_mutex> lock(mutex_);
log::assert_that(is_running_, "assert failed: is_running_");
@@ -249,12 +258,14 @@ void Stack::Dump(int fd, std::promise<void> promise) const {
void Stack::handle_start_up(ModuleList* modules, std::promise<void> promise) {
pimpl_->counter_metrics_->Start();
pimpl_->storage_->Start();
+ pimpl_->snoop_logger_->Start();
registry_.Start(modules, stack_thread_);
promise.set_value();
}
void Stack::handle_shut_down(std::promise<void> promise) {
registry_.StopAll();
+ pimpl_->snoop_logger_->Stop();
pimpl_->storage_->Stop();
pimpl_->counter_metrics_->Stop();
promise.set_value();
diff --git a/system/main/shim/stack.h b/system/main/shim/stack.h
index 2fbdfca43c..8307e00a23 100644
--- a/system/main/shim/stack.h
+++ b/system/main/shim/stack.h
@@ -26,6 +26,10 @@
// The shim layer implementation on the Gd stack side.
namespace bluetooth {
+namespace hal {
+class SnoopLogger;
+}
+
namespace storage {
class StorageModule;
}
@@ -68,6 +72,7 @@ public:
virtual Acl* GetAcl() const;
virtual metrics::CounterMetrics* GetCounterMetrics() const;
virtual storage::StorageModule* GetStorage() const;
+ virtual hal::SnoopLogger* GetSnoopLogger() const;
os::Handler* GetHandler();
diff --git a/system/stack/test/fuzzers/Android.bp b/system/stack/test/fuzzers/Android.bp
index 91bc857f8f..192a3ed6e2 100644
--- a/system/stack/test/fuzzers/Android.bp
+++ b/system/stack/test/fuzzers/Android.bp
@@ -8,7 +8,7 @@ package {
}
cc_defaults {
- name: "libbt-stack_fuzz_defaults",
+ name: "bluetooth_fuzz_stack_defaults",
defaults: [
"fluoride_defaults",
"latest_android_hardware_audio_common_ndk_static",
@@ -20,9 +20,11 @@ cc_defaults {
"-Wno-missing-prototypes",
],
include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd/",
- "packages/modules/Bluetooth/system/include/",
+ "packages/modules/Bluetooth/system",
+ "packages/modules/Bluetooth/system/bta/include",
+ "packages/modules/Bluetooth/system/bta/sys",
+ "packages/modules/Bluetooth/system/gd",
+ "packages/modules/Bluetooth/system/include",
"packages/modules/Bluetooth/system/stack/include",
"packages/modules/Bluetooth/system/stack/test",
],
@@ -59,6 +61,7 @@ cc_defaults {
"libbte",
"libbtif",
"libbtif-core",
+ "libchrome",
"libcom.android.sysprop.bluetooth.wrapped",
"libexpresslog",
"libflags_rust_cpp_bridge",
@@ -97,3 +100,39 @@ cc_defaults {
},
},
}
+
+cc_fuzz {
+ name: "bluetooth_fuzz_stack_a2dp",
+ defaults: ["bluetooth_fuzz_stack_defaults"],
+ srcs: ["a2dp/fuzz_a2dp.cc"],
+}
+
+cc_fuzz {
+ name: "bluetooth_fuzz_stack_a2dp_codec",
+ defaults: ["bluetooth_fuzz_stack_defaults"],
+ srcs: ["a2dp/codec/fuzz_a2dp_codec.cc"],
+}
+
+cc_fuzz {
+ name: "bluetooth_fuzz_stack_a2dp_codec_info",
+ defaults: ["bluetooth_fuzz_stack_defaults"],
+ srcs: ["a2dp/codec/fuzz_a2dp_codec_info.cc"],
+}
+
+cc_fuzz {
+ name: "bluetooth_fuzz_stack_a2dp_codec_config",
+ defaults: ["bluetooth_fuzz_stack_defaults"],
+ srcs: ["a2dp/codec/fuzz_a2dp_codec_config.cc"],
+}
+
+cc_fuzz {
+ name: "bluetooth_fuzz_stack_avrc",
+ defaults: ["bluetooth_fuzz_stack_defaults"],
+ srcs: ["avrc/fuzz_avrc.cc"],
+}
+
+cc_fuzz {
+ name: "bluetooth_fuzz_stack_sdp",
+ defaults: ["bluetooth_fuzz_stack_defaults"],
+ srcs: ["sdp/fuzz_sdp.cc"],
+}
diff --git a/system/stack/test/fuzzers/a2dp/Android.bp b/system/stack/test/fuzzers/a2dp/Android.bp
deleted file mode 100644
index 65b56b4895..0000000000
--- a/system/stack/test/fuzzers/a2dp/Android.bp
+++ /dev/null
@@ -1,17 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_fuzz {
- name: "a2dp_fuzz",
- static_libs: ["libchrome"],
- defaults: ["libbt-stack_fuzz_defaults"],
- srcs: [
- "fuzz_a2dp.cc",
- ],
-}
diff --git a/system/stack/test/fuzzers/a2dp/codec/Android.bp b/system/stack/test/fuzzers/a2dp/codec/Android.bp
deleted file mode 100644
index 7c7825db3d..0000000000
--- a/system/stack/test/fuzzers/a2dp/codec/Android.bp
+++ /dev/null
@@ -1,45 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_defaults {
- name: "libbt-stack_fuzz_codec_defaults",
- defaults: ["libbt-stack_fuzz_defaults"],
- include_dirs: [
- "packages/modules/Bluetooth/system/bta/include/", // For tBT_A2DP_OFFLOAD
- "packages/modules/Bluetooth/system/bta/sys/", // For tBT_A2DP_OFFLOAD
- "packages/modules/Bluetooth/system/gd",
- ],
-}
-
-cc_fuzz {
- name: "a2dp_codec_fuzz",
- static_libs: ["libchrome"],
- defaults: ["libbt-stack_fuzz_codec_defaults"],
- srcs: [
- "fuzz_a2dp_codec.cc",
- ],
-}
-
-cc_fuzz {
- name: "a2dp_codec_info_fuzz",
- static_libs: ["libchrome"],
- defaults: ["libbt-stack_fuzz_codec_defaults"],
- srcs: [
- "fuzz_a2dp_codec_info.cc",
- ],
-}
-
-cc_fuzz {
- name: "a2dp_codec_cfg_fuzz",
- static_libs: ["libchrome"],
- defaults: ["libbt-stack_fuzz_codec_defaults"],
- srcs: [
- "fuzz_a2dp_codec_config.cc",
- ],
-}
diff --git a/system/stack/test/fuzzers/avrc/Android.bp b/system/stack/test/fuzzers/avrc/Android.bp
deleted file mode 100644
index d9e2696657..0000000000
--- a/system/stack/test/fuzzers/avrc/Android.bp
+++ /dev/null
@@ -1,17 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_fuzz {
- name: "avrc_fuzz",
- defaults: ["libbt-stack_fuzz_defaults"],
- srcs: [
- "fuzz_avrc.cc",
- ],
- static_libs: ["libchrome"],
-}
diff --git a/system/stack/test/fuzzers/sdp/Android.bp b/system/stack/test/fuzzers/sdp/Android.bp
deleted file mode 100644
index bc5aaa702b..0000000000
--- a/system/stack/test/fuzzers/sdp/Android.bp
+++ /dev/null
@@ -1,17 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_fuzz {
- name: "sdp_fuzz",
- static_libs: ["libchrome"],
- defaults: ["libbt-stack_fuzz_defaults"],
- srcs: [
- "fuzz_sdp.cc",
- ],
-}