diff options
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", - ], -} |