summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--OWNERS1
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassClientService.java268
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java17
-rw-r--r--android/app/src/com/android/bluetooth/btservice/BondStateMachine.java1
-rw-r--r--android/app/src/com/android/bluetooth/btservice/MedicalDeviceBloomfilterGenerator.java76
-rw-r--r--android/app/src/com/android/bluetooth/btservice/MetricsLogger.java137
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java54
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java22
-rw-r--r--flags/gap.aconfig23
-rw-r--r--flags/opp.aconfig9
-rw-r--r--flags/pairing.aconfig10
-rw-r--r--framework/api/system-current.txt44
-rw-r--r--framework/java/android/bluetooth/le/ChannelSoundingParams.java4
-rw-r--r--framework/java/android/bluetooth/le/DistanceMeasurementManager.java5
-rw-r--r--framework/java/android/bluetooth/le/DistanceMeasurementMethod.java1
-rw-r--r--framework/java/android/bluetooth/le/DistanceMeasurementParams.java5
-rw-r--r--framework/java/android/bluetooth/le/DistanceMeasurementResult.java16
-rw-r--r--system/bta/hh/bta_hh_act.cc3
-rw-r--r--system/btif/include/btif_bqr.h126
-rw-r--r--system/btif/src/btif_bqr.cc159
-rw-r--r--system/btif/src/btif_dm.cc11
-rw-r--r--system/btif/src/btif_hh.cc5
-rw-r--r--system/gd/rust/topshim/btav/btav_shim.cc11
-rw-r--r--system/gd/rust/topshim/btav_sink/btav_sink_shim.cc11
-rw-r--r--system/stack/bnep/bnep_api.cc2
-rw-r--r--system/stack/bnep/bnep_main.cc2
-rw-r--r--system/stack/bnep/bnep_utils.cc2
-rw-r--r--system/stack/hid/hidd_conn.cc2
-rw-r--r--system/stack/hid/hidh_conn.cc2
29 files changed, 804 insertions, 225 deletions
diff --git a/OWNERS b/OWNERS
index bb6f4b9579..82367c3a5f 100644
--- a/OWNERS
+++ b/OWNERS
@@ -5,6 +5,7 @@ girardier@google.com #{LAST_RESORT_SUGGESTION}
muhammadfalam@google.com #{LAST_RESORT_SUGGESTION}
siyuanh@google.com #{LAST_RESORT_SUGGESTION}
okamil@google.com #{LAST_RESORT_SUGGESTION}
+wescande@google.com #{LAST_RESORT_SUGGESTION}
# Per-file ownership
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
index 957b02c322..72648cbcfd 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
@@ -1297,9 +1297,9 @@ public class BassClientService extends ProfileService {
return devices;
}
- private boolean isValidBroadcastSourceAddition(
+ private int checkDuplicateSourceAdditionAndGetSourceId(
BluetoothDevice device, BluetoothLeBroadcastMetadata metaData) {
- boolean retval = true;
+ int sourceId = BassConstants.INVALID_SOURCE_ID;
List<BluetoothLeBroadcastReceiveState> currentAllSources = getAllSources(device);
for (int i = 0; i < currentAllSources.size(); i++) {
BluetoothLeBroadcastReceiveState state = currentAllSources.get(i);
@@ -1307,17 +1307,12 @@ public class BassClientService extends ProfileService {
&& metaData.getSourceAddressType() == state.getSourceAddressType()
&& metaData.getSourceAdvertisingSid() == state.getSourceAdvertisingSid()
&& metaData.getBroadcastId() == state.getBroadcastId()) {
- retval = false;
- Log.e(
- TAG,
- "isValidBroadcastSourceAddition: fail for "
- + device
- + " metaData: "
- + metaData);
+ sourceId = state.getSourceId();
+ log("DuplicatedSourceAddition: for " + device + " metaData: " + metaData);
break;
}
}
- return retval;
+ return sourceId;
}
private boolean hasRoomForBroadcastSourceAddition(BluetoothDevice device) {
@@ -1512,45 +1507,77 @@ public class BassClientService extends ProfileService {
}
}
- private int areValidParametersToModifySource(
- BluetoothLeBroadcastMetadata updatedMetadata,
- BassClientStateMachine stateMachine,
- Integer deviceSourceId,
- BluetoothDevice device) {
- if (updatedMetadata == null || stateMachine == null) {
- log(
- "areValidParametersToModifySource: Error bad parameters: sourceId = "
- + deviceSourceId
- + " updatedMetadata = "
- + updatedMetadata);
+ private int validateParametersForSourceOperation(
+ BassClientStateMachine stateMachine, BluetoothDevice device) {
+ if (stateMachine == null) {
+ log("validateParameters: stateMachine is null for device: " + device);
return BluetoothStatusCodes.ERROR_BAD_PARAMETERS;
}
- if (deviceSourceId == BassConstants.INVALID_SOURCE_ID) {
- log("areValidParametersToModifySource: no such sourceId for device: " + device);
- return BluetoothStatusCodes.ERROR_LE_BROADCAST_ASSISTANT_INVALID_SOURCE_ID;
- }
+
if (getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) {
- log("areValidParametersToModifySource: device is not connected");
+ log("validateParameters: device is not connected, device: " + device);
return BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR;
}
- byte[] code = updatedMetadata.getBroadcastCode();
+
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ private int validateParametersForSourceOperation(
+ BassClientStateMachine stateMachine,
+ BluetoothDevice device,
+ BluetoothLeBroadcastMetadata metadata) {
+ int status = validateParametersForSourceOperation(stateMachine, device);
+ if (status != BluetoothStatusCodes.SUCCESS) {
+ return status;
+ }
+
+ if (metadata == null) {
+ log("validateParameters: metadata is null for device: " + device);
+ return BluetoothStatusCodes.ERROR_BAD_PARAMETERS;
+ }
+
+ byte[] code = metadata.getBroadcastCode();
if ((code != null) && (code.length != 0)) {
if ((code.length > 16) || (code.length < 4)) {
log(
- "areValidParametersToModifySource: Invalid broadcast code length: "
+ "validateParameters: Invalid broadcast code length: "
+ code.length
+ ", should be between 4 and 16 octets");
return BluetoothStatusCodes.ERROR_BAD_PARAMETERS;
}
}
- if (stateMachine.hasPendingSourceOperation()) {
- Log.w(
- TAG,
- "modifySource: source operation already pending, device: "
- + device
- + ", broadcastId: "
- + updatedMetadata.getBroadcastId());
- return BluetoothStatusCodes.ERROR_ALREADY_IN_TARGET_STATE;
+
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ private int validateParametersForSourceOperation(
+ BassClientStateMachine stateMachine, BluetoothDevice device, Integer sourceId) {
+ int status = validateParametersForSourceOperation(stateMachine, device);
+ if (status != BluetoothStatusCodes.SUCCESS) {
+ return status;
+ }
+
+ if (sourceId == BassConstants.INVALID_SOURCE_ID) {
+ log("validateParameters: no such sourceId for device: " + device);
+ return BluetoothStatusCodes.ERROR_LE_BROADCAST_ASSISTANT_INVALID_SOURCE_ID;
+ }
+
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ private int validateParametersForSourceOperation(
+ BassClientStateMachine stateMachine,
+ BluetoothDevice device,
+ BluetoothLeBroadcastMetadata metadata,
+ Integer sourceId) {
+ int status = validateParametersForSourceOperation(stateMachine, device, metadata);
+ if (status != BluetoothStatusCodes.SUCCESS) {
+ return status;
+ }
+
+ if (sourceId == BassConstants.INVALID_SOURCE_ID) {
+ log("validateParameters: no such sourceId for device: " + device);
+ return BluetoothStatusCodes.ERROR_LE_BROADCAST_ASSISTANT_INVALID_SOURCE_ID;
}
return BluetoothStatusCodes.SUCCESS;
@@ -2942,16 +2969,10 @@ public class BassClientService extends ProfileService {
byte[] code = sourceMetadata.getBroadcastCode();
for (BluetoothDevice device : devices) {
BassClientStateMachine stateMachine = getOrCreateStateMachine(device);
- if (stateMachine == null) {
- log("addSource: Error bad parameter: no state machine for " + device);
- mCallbacks.notifySourceAddFailed(
- device, sourceMetadata, BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
- continue;
- }
- if (getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) {
- log("addSource: device is not connected");
- mCallbacks.notifySourceAddFailed(
- device, sourceMetadata, BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR);
+ int statusCode =
+ validateParametersForSourceOperation(stateMachine, device, sourceMetadata);
+ if (statusCode != BluetoothStatusCodes.SUCCESS) {
+ mCallbacks.notifySourceAddFailed(device, sourceMetadata, statusCode);
continue;
}
if (stateMachine.hasPendingSourceOperation()) {
@@ -2965,12 +2986,19 @@ public class BassClientService extends ProfileService {
device, sourceMetadata, BluetoothStatusCodes.ERROR_ALREADY_IN_TARGET_STATE);
continue;
}
+ if (leaudioBroadcastResyncHelper()) {
+ int sourceId = checkDuplicateSourceAdditionAndGetSourceId(device, sourceMetadata);
+ if (sourceId != BassConstants.INVALID_SOURCE_ID) {
+ updateSourceToResumeBroadcast(device, sourceId, sourceMetadata);
+ continue;
+ }
+ }
if (!hasRoomForBroadcastSourceAddition(device)) {
log("addSource: device has no room");
- Integer sourceId = getSourceIdToRemove(device);
- if (sourceId != BassConstants.INVALID_SOURCE_ID) {
+ Integer sourceIdToRemove = getSourceIdToRemove(device);
+ if (sourceIdToRemove != BassConstants.INVALID_SOURCE_ID) {
BluetoothLeBroadcastMetadata metaData =
- stateMachine.getCurrentBroadcastMetadata(sourceId);
+ stateMachine.getCurrentBroadcastMetadata(sourceIdToRemove);
if (metaData != null) {
// Add host intentional pause if previous broadcast is different than
// current
@@ -2983,7 +3011,7 @@ public class BassClientService extends ProfileService {
TAG,
"Switch Broadcast Source: "
+ ("device: " + device)
- + (", old SourceId: " + sourceId)
+ + (", old SourceId: " + sourceIdToRemove)
+ (", new broadcastId: " + sourceMetadata.getBroadcastId())
+ (", new broadcastName: "
+ sourceMetadata.getBroadcastName()));
@@ -2993,7 +3021,9 @@ public class BassClientService extends ProfileService {
// mark group op for both remove and add source
// so setSourceGroupManaged will be updated accordingly in callbacks
enqueueSourceGroupOp(
- device, BassClientStateMachine.REMOVE_BCAST_SOURCE, sourceId);
+ device,
+ BassClientStateMachine.REMOVE_BCAST_SOURCE,
+ sourceIdToRemove);
enqueueSourceGroupOp(
device, BassClientStateMachine.ADD_BCAST_SOURCE, sourceMetadata);
}
@@ -3004,7 +3034,7 @@ public class BassClientService extends ProfileService {
Message message =
stateMachine.obtainMessage(BassClientStateMachine.SWITCH_BCAST_SOURCE);
message.obj = sourceMetadata;
- message.arg1 = sourceId;
+ message.arg1 = sourceIdToRemove;
stateMachine.sendMessage(message);
} else {
mCallbacks.notifySourceAddFailed(
@@ -3014,22 +3044,14 @@ public class BassClientService extends ProfileService {
}
continue;
}
- if (!isValidBroadcastSourceAddition(device, sourceMetadata)) {
- log("addSource: not a valid broadcast source addition");
- mCallbacks.notifySourceAddFailed(
- device,
- sourceMetadata,
- BluetoothStatusCodes.ERROR_LE_BROADCAST_ASSISTANT_DUPLICATE_ADDITION);
- continue;
- }
- if ((code != null) && (code.length != 0)) {
- if ((code.length > 16) || (code.length < 4)) {
- log(
- "Invalid broadcast code length: "
- + code.length
- + ", should be between 4 and 16 octets");
+ if (!leaudioBroadcastResyncHelper()) {
+ int sourceId = checkDuplicateSourceAdditionAndGetSourceId(device, sourceMetadata);
+ if (sourceId != BassConstants.INVALID_SOURCE_ID) {
+ log("addSource: not a valid broadcast source addition");
mCallbacks.notifySourceAddFailed(
- device, sourceMetadata, BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
+ device,
+ sourceMetadata,
+ BluetoothStatusCodes.ERROR_LE_BROADCAST_ASSISTANT_DUPLICATE_ADDITION);
continue;
}
}
@@ -3106,14 +3128,24 @@ public class BassClientService extends ProfileService {
BluetoothDevice device = deviceSourceIdPair.getKey();
Integer deviceSourceId = deviceSourceIdPair.getValue();
BassClientStateMachine stateMachine = getOrCreateStateMachine(device);
-
int statusCode =
- areValidParametersToModifySource(
- updatedMetadata, stateMachine, deviceSourceId, device);
+ validateParametersForSourceOperation(
+ stateMachine, device, updatedMetadata, deviceSourceId);
if (statusCode != BluetoothStatusCodes.SUCCESS) {
mCallbacks.notifySourceModifyFailed(device, sourceId, statusCode);
continue;
}
+ if (stateMachine.hasPendingSourceOperation()) {
+ Log.w(
+ TAG,
+ "modifySource: source operation already pending, device: "
+ + device
+ + ", broadcastId: "
+ + updatedMetadata.getBroadcastId());
+ mCallbacks.notifySourceModifyFailed(
+ device, sourceId, BluetoothStatusCodes.ERROR_ALREADY_IN_TARGET_STATE);
+ continue;
+ }
sEventLogger.logd(
TAG,
@@ -3158,32 +3190,17 @@ public class BassClientService extends ProfileService {
Map<BluetoothDevice, Integer> devices = getGroupManagedDeviceSources(sink, sourceId).second;
for (Map.Entry<BluetoothDevice, Integer> deviceSourceIdPair : devices.entrySet()) {
BluetoothDevice device = deviceSourceIdPair.getKey();
- Integer deviceSourceId = deviceSourceIdPair.getValue();
- BassClientStateMachine stateMachine = getOrCreateStateMachine(device);
-
/* Removes metadata for sink device if not paused */
if (!mPausedBroadcastSinks.contains(device)) {
mBroadcastMetadataMap.remove(device);
}
- if (stateMachine == null) {
- log("removeSource: Error bad parameters: device = " + device);
- mCallbacks.notifySourceRemoveFailed(
- device, sourceId, BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
- continue;
- }
- if (deviceSourceId == BassConstants.INVALID_SOURCE_ID) {
- log("removeSource: no such sourceId for device: " + device);
- mCallbacks.notifySourceRemoveFailed(
- device,
- sourceId,
- BluetoothStatusCodes.ERROR_LE_BROADCAST_ASSISTANT_INVALID_SOURCE_ID);
- continue;
- }
- if (getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) {
- log("removeSource: device is not connected");
- mCallbacks.notifySourceRemoveFailed(
- device, sourceId, BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR);
+ Integer deviceSourceId = deviceSourceIdPair.getValue();
+ BassClientStateMachine stateMachine = getOrCreateStateMachine(device);
+ int statusCode =
+ validateParametersForSourceOperation(stateMachine, device, deviceSourceId);
+ if (statusCode != BluetoothStatusCodes.SUCCESS) {
+ mCallbacks.notifySourceRemoveFailed(device, sourceId, statusCode);
continue;
}
@@ -3796,36 +3813,7 @@ public class BassClientService extends ProfileService {
|| activeSyncedSrc.contains(
getSyncHandleForBroadcastId(metadata.getBroadcastId())))) {
int sourceId = receiveState.get().getSourceId();
- int statusCode =
- areValidParametersToModifySource(
- metadata, stateMachine, sourceId, sink);
-
- if (statusCode != BluetoothStatusCodes.SUCCESS) {
- mCallbacks.notifySourceModifyFailed(sink, sourceId, statusCode);
- // remove the device from mPausedBroadcastSinks
- iterator.remove();
- continue;
- }
-
- sEventLogger.logd(
- TAG,
- "Modify Broadcast Source (resume): "
- + ("device: " + sink)
- + (", sourceId: " + sourceId)
- + (", updatedBroadcastId: " + metadata.getBroadcastId())
- + (", updatedBroadcastName: " + metadata.getBroadcastName()));
- Message message =
- stateMachine.obtainMessage(BassClientStateMachine.UPDATE_BCAST_SOURCE);
- message.arg1 = sourceId;
- message.arg2 =
- DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_BLUETOOTH,
- "persist.vendor.service.bt.defNoPAS",
- false)
- ? BassConstants.PA_SYNC_PAST_NOT_AVAILABLE
- : BassConstants.PA_SYNC_PAST_AVAILABLE;
- message.obj = metadata;
- stateMachine.sendMessage(message);
+ updateSourceToResumeBroadcast(sink, sourceId, metadata);
} else {
addSource(sink, metadata, false);
}
@@ -3848,6 +3836,44 @@ public class BassClientService extends ProfileService {
logPausedBroadcastsAndSinks();
}
+ private void updateSourceToResumeBroadcast(
+ BluetoothDevice sink, int sourceId, BluetoothLeBroadcastMetadata metadata) {
+ BassClientStateMachine stateMachine = getOrCreateStateMachine(sink);
+ int statusCode =
+ validateParametersForSourceOperation(stateMachine, sink, metadata, sourceId);
+ if (statusCode != BluetoothStatusCodes.SUCCESS) {
+ return;
+ }
+ if (stateMachine.hasPendingSourceOperation()) {
+ Log.w(
+ TAG,
+ "updateSourceToResumeBroadcast: source operation already pending, device: "
+ + sink
+ + ", broadcastId: "
+ + metadata.getBroadcastId());
+ return;
+ }
+
+ sEventLogger.logd(
+ TAG,
+ "Modify Broadcast Source (resume): "
+ + ("device: " + sink)
+ + (", sourceId: " + sourceId)
+ + (", updatedBroadcastId: " + metadata.getBroadcastId())
+ + (", updatedBroadcastName: " + metadata.getBroadcastName()));
+ Message message = stateMachine.obtainMessage(BassClientStateMachine.UPDATE_BCAST_SOURCE);
+ message.arg1 = sourceId;
+ message.arg2 =
+ DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_BLUETOOTH,
+ "persist.vendor.service.bt.defNoPAS",
+ false)
+ ? BassConstants.PA_SYNC_PAST_NOT_AVAILABLE
+ : BassConstants.PA_SYNC_PAST_AVAILABLE;
+ message.obj = metadata;
+ stateMachine.sendMessage(message);
+ }
+
/** Handle Unicast source stream status change */
public void handleUnicastSourceStreamStatusChange(int status) {
mUnicastSourceStreamStatus = Optional.of(status);
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
index 021b73289b..5954b827b0 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
@@ -1151,6 +1151,7 @@ class BassClientStateMachine extends StateMachine {
log("processBroadcastReceiverState: invalid index: " + recvState.getSourceId());
return;
}
+ int sourceId = recvState.getSourceId();
BluetoothLeBroadcastReceiveState oldRecvState =
mBluetoothLeBroadcastReceiveStates.get(characteristic.getInstanceId());
if (oldRecvState == null) {
@@ -1178,7 +1179,7 @@ class BassClientStateMachine extends StateMachine {
.notifySourceAdded(
mDevice, recvState, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
if (mPendingMetadata != null) {
- setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata);
+ setCurrentBroadcastMetadata(sourceId, mPendingMetadata);
mPendingMetadata = null;
}
checkAndUpdateBroadcastCode(recvState);
@@ -1224,28 +1225,28 @@ class BassClientStateMachine extends StateMachine {
} else {
log("update to an existing recvState");
if (mPendingMetadata != null) {
- setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata);
+ setCurrentBroadcastMetadata(sourceId, mPendingMetadata);
mPendingMetadata = null;
}
removeMessages(CANCEL_PENDING_SOURCE_OPERATION);
mService.getCallbacks()
.notifySourceModified(
mDevice,
- recvState.getSourceId(),
+ sourceId,
BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
checkAndUpdateBroadcastCode(recvState);
processPASyncState(recvState);
processSyncStateChangeStats(recvState);
- if (isPendingRemove(recvState.getSourceId())) {
+ if (isPendingRemove(sourceId) && !isSyncedToTheSource(sourceId)) {
Message message = obtainMessage(REMOVE_BCAST_SOURCE);
- message.arg1 = recvState.getSourceId();
+ message.arg1 = sourceId;
sendMessage(message);
}
}
}
}
- broadcastReceiverState(recvState, recvState.getSourceId());
+ broadcastReceiverState(recvState, sourceId);
}
// Implements callback methods for GATT events that the app cares about.
@@ -1916,7 +1917,7 @@ class BassClientStateMachine extends StateMachine {
res[offset++] = (byte) numSubGroups;
for (int i = 0; i < numSubGroups; i++) {
- int bisIndexValue = existingState.getBisSyncState().get(i).intValue();
+ int bisIndexValue = 0xFFFFFFFF;
if (paSync == BassConstants.PA_SYNC_DO_NOT_SYNC) {
bisIndexValue = 0;
} else if (metaData != null
@@ -1929,6 +1930,8 @@ class BassClientStateMachine extends StateMachine {
if (bisIndexValue == 0) {
bisIndexValue = 0xFFFFFFFF;
}
+ } else if (i < existingState.getBisSyncState().size()) {
+ bisIndexValue = existingState.getBisSyncState().get(i).intValue();
}
log("UPDATE_BCAST_SOURCE: bisIndexValue : " + bisIndexValue);
// BIS_Sync
diff --git a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java
index 6909bc6d49..6d5bb49338 100644
--- a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java
+++ b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java
@@ -545,6 +545,7 @@ final class BondStateMachine extends StateMachine {
if (oldState == newState) {
return;
}
+ MetricsLogger.getInstance().logBondStateMachineEvent(device, newState);
BluetoothStatsLog.write(
BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
mAdapterService.obfuscateAddress(device),
diff --git a/android/app/src/com/android/bluetooth/btservice/MedicalDeviceBloomfilterGenerator.java b/android/app/src/com/android/bluetooth/btservice/MedicalDeviceBloomfilterGenerator.java
new file mode 100644
index 0000000000..06055cfc8f
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/btservice/MedicalDeviceBloomfilterGenerator.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.bluetooth.btservice;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/** Class to generate a medical device bloomfilter */
+public class MedicalDeviceBloomfilterGenerator {
+
+ public static final String BLOOM_FILTER_DEFAULT =
+ "01070000003C01002106584044800850055"
+ + "002308488410020D9A00001138410510000"
+ + "000042004200000000000C2000000040064"
+ + "0120080020110412A500090520210040C40"
+ + "4002601040005004400148414006198A041"
+ + "00890000600400000800210041810600800"
+ + "0142208000721A030000028102448201110"
+ + "0002007120020101448C211490A2B000084"
+ + "C010004004C00C080808200026210608110"
+ + "200011200000015000000212C4400040802"
+ + "00111114840000001002080040186000404"
+ + "81C064400052381109017039900000200C9"
+ + "C0002E6480000101C40000601064001A018"
+ + "40440280A810001000040455A0404617034"
+ + "50000140040D020020C6204100804041600"
+ + "80840002000800804280028000440000122"
+ + "00808409905022000590000110448080400"
+ + "561004210020430092602000040C0090C00"
+ + "C18480020000519C1482100111011120390"
+ + "02C0000228208104800C050440000004040"
+ + "00871400882400140080000005308124900"
+ + "104000040002410508CA349000200000202"
+ + "90200920181890100800110220A20874820"
+ + "0428080054A0005101C0820060090080040"
+ + "6820C480F40081014010201800000018101"
+ + "208914100321008006520002030010800C4"
+ + "1022C000048206002010041220000008021"
+ + "002080314040000100030002008";
+
+ /** Provide byte[] version of a given string */
+ public static byte[] hexStringToByteArray(String s) {
+ int len = s.length();
+ byte[] data = new byte[len / 2];
+ for (int i = 0; i < len; i += 2) {
+ data[i / 2] =
+ (byte)
+ ((Character.digit(s.charAt(i), 16) << 4)
+ + Character.digit(s.charAt(i + 1), 16));
+ }
+ return data;
+ }
+
+ /** Generate bloom filter file given filePath */
+ public static void generateDefaultBloomfilter(String filePath) throws IOException {
+ File outputFile = new File(filePath);
+ outputFile.createNewFile(); // if file already exists will do nothing
+ FileOutputStream fos = new FileOutputStream(filePath);
+ fos.write(hexStringToByteArray(BLOOM_FILTER_DEFAULT));
+ fos.close();
+ }
+}
diff --git a/android/app/src/com/android/bluetooth/btservice/MetricsLogger.java b/android/app/src/com/android/bluetooth/btservice/MetricsLogger.java
index 98040486db..b74220c9ea 100644
--- a/android/app/src/com/android/bluetooth/btservice/MetricsLogger.java
+++ b/android/app/src/com/android/bluetooth/btservice/MetricsLogger.java
@@ -15,6 +15,7 @@
*/
package com.android.bluetooth.btservice;
+import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__BOND;
import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__PROFILE_CONNECTION;
import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__PROFILE_CONNECTION_A2DP;
import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__PROFILE_CONNECTION_A2DP_SINK;
@@ -31,6 +32,8 @@ import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVEN
import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__PROFILE_CONNECTION_PAN;
import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__PROFILE_CONNECTION_PBAP_CLIENT;
import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__PROFILE_CONNECTION_VOLUME_CONTROL;
+import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__STATE_BONDED;
+import static com.android.bluetooth.BluetoothStatsLog.BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__STATE_NONE;
import static com.android.bluetooth.BtRestrictedStatsLog.RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED;
import android.app.AlarmManager;
@@ -96,7 +99,10 @@ public class MetricsLogger {
private static final String TAG = "BluetoothMetricsLogger";
private static final String BLOOMFILTER_PATH = "/data/misc/bluetooth";
private static final String BLOOMFILTER_FILE = "/devices_for_metrics_v3";
+ private static final String MEDICAL_DEVICE_BLOOMFILTER_FILE = "/medical_devices_for_metrics_v1";
public static final String BLOOMFILTER_FULL_PATH = BLOOMFILTER_PATH + BLOOMFILTER_FILE;
+ public static final String MEDICAL_DEVICE_BLOOMFILTER_FULL_PATH =
+ BLOOMFILTER_PATH + MEDICAL_DEVICE_BLOOMFILTER_FILE;
// 6 hours timeout for counter metrics
private static final long BLUETOOTH_COUNTER_METRICS_ACTION_DURATION_MILLIS = 6L * 3600L * 1000L;
@@ -114,6 +120,10 @@ public class MetricsLogger {
private BloomFilter<byte[]> mBloomFilter = null;
protected boolean mBloomFilterInitialized = false;
+ private BloomFilter<byte[]> mMedicalDeviceBloomFilter = null;
+
+ protected boolean mMedicalDeviceBloomFilterInitialized = false;
+
private AlarmManager.OnAlarmListener mOnAlarmListener =
new AlarmManager.OnAlarmListener() {
@Override
@@ -185,10 +195,48 @@ public class MetricsLogger {
return true;
}
+ /** Initialize medical device bloom filter */
+ public boolean initMedicalDeviceBloomFilter(String path) {
+ try {
+ File medicalDeviceFile = new File(path);
+ if (!medicalDeviceFile.exists()) {
+ Log.w(TAG, "MetricsLogger is creating a new medical device Bloomfilter file");
+ MedicalDeviceBloomfilterGenerator.generateDefaultBloomfilter(path);
+ }
+
+ FileInputStream inputStream = new FileInputStream(new File(path));
+ mMedicalDeviceBloomFilter =
+ BloomFilter.readFrom(inputStream, Funnels.byteArrayFunnel());
+ mMedicalDeviceBloomFilterInitialized = true;
+ } catch (IOException e1) {
+ Log.w(TAG, "MetricsLogger can't read the medical device BloomFilter file.");
+ byte[] bloomfilterData =
+ MedicalDeviceBloomfilterGenerator.hexStringToByteArray(
+ MedicalDeviceBloomfilterGenerator.BLOOM_FILTER_DEFAULT);
+ try {
+ mMedicalDeviceBloomFilter =
+ BloomFilter.readFrom(
+ new ByteArrayInputStream(bloomfilterData),
+ Funnels.byteArrayFunnel());
+ mMedicalDeviceBloomFilterInitialized = true;
+ Log.i(TAG, "The medical device bloomfilter is used");
+ return true;
+ } catch (IOException e2) {
+ Log.w(TAG, "The medical device bloomfilter can't be used.");
+ }
+ return false;
+ }
+ return true;
+ }
+
protected void setBloomfilter(BloomFilter bloomfilter) {
mBloomFilter = bloomfilter;
}
+ protected void setMedicalDeviceBloomfilter(BloomFilter bloomfilter) {
+ mMedicalDeviceBloomFilter = bloomfilter;
+ }
+
void init(AdapterService adapterService, RemoteDevices remoteDevices) {
if (mInitialized) {
return;
@@ -203,6 +251,12 @@ public class MetricsLogger {
// We still want to use this class even if the bloomfilter isn't initialized
// so still return true here.
}
+ if (!initMedicalDeviceBloomFilter(MEDICAL_DEVICE_BLOOMFILTER_FULL_PATH)) {
+ Log.w(TAG, "MetricsLogger can't initialize the medical device bloomfilter");
+ // The class is for multiple metrics tasks.
+ // We still want to use this class even if the bloomfilter isn't initialized
+ // so still return true here.
+ }
IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
@@ -289,7 +343,8 @@ public class MetricsLogger {
BluetoothDevice device = connIntent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int state = connIntent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
int metricId = mAdapterService.getMetricId(device);
- byte[] remoteDeviceInfoBytes = getRemoteDeviceInfoProto(device);
+ boolean includeMedicalDevices = false;
+ byte[] remoteDeviceInfoBytes = getRemoteDeviceInfoProto(device, includeMedicalDevices);
if (state == BluetoothProfile.STATE_CONNECTING) {
String deviceName = mRemoteDevices.getName(device);
BluetoothStatsLog.write(
@@ -417,6 +472,7 @@ public class MetricsLogger {
mAdapterService = null;
mInitialized = false;
mBloomFilterInitialized = false;
+ mMedicalDeviceBloomFilterInitialized = false;
}
protected void cancelPendingDrain() {
@@ -446,15 +502,31 @@ public class MetricsLogger {
/**
* Retrieves a byte array containing serialized remote device information for the specified
- * BluetoothDevice. This data can be used for remote device identification and logging.
+ * BluetoothDevice. This data can be used for remote device identification and logging. Does not
+ * include medical remote devices.
*
* @param device The BluetoothDevice for which to retrieve device information.
* @return A byte array containing the serialized remote device information.
*/
public byte[] getRemoteDeviceInfoProto(BluetoothDevice device) {
- if (!mInitialized) {
- return null;
- }
+ return mInitialized ? buildRemoteDeviceInfoProto(device, false) : null;
+ }
+
+ /**
+ * Retrieves a byte array containing serialized remote device information for the specified
+ * BluetoothDevice. This data can be used for remote device identification and logging.
+ *
+ * @param device The BluetoothDevice for which to retrieve device information.
+ * @param includeMedicalDevices Should be true only if logging as de-identified metric,
+ * otherwise false.
+ * @return A byte array containing the serialized remote device information.
+ */
+ public byte[] getRemoteDeviceInfoProto(BluetoothDevice device, boolean includeMedicalDevices) {
+ return mInitialized ? buildRemoteDeviceInfoProto(device, includeMedicalDevices) : null;
+ }
+
+ private byte[] buildRemoteDeviceInfoProto(
+ BluetoothDevice device, boolean includeMedicalDevices) {
ProtoOutputStream proto = new ProtoOutputStream();
// write Allowlisted Device Name Hash
@@ -463,7 +535,8 @@ public class MetricsLogger {
ProtoOutputStream.FIELD_TYPE_STRING,
ProtoOutputStream.FIELD_COUNT_SINGLE,
BluetoothRemoteDeviceInformation.ALLOWLISTED_DEVICE_NAME_HASH_FIELD_NUMBER,
- getAllowlistedDeviceNameHash(mAdapterService.getRemoteName(device)));
+ getAllowlistedDeviceNameHash(
+ mAdapterService.getRemoteName(device), includeMedicalDevices));
// write COD
writeFieldIfNotNull(
@@ -567,7 +640,7 @@ public class MetricsLogger {
}
}
- private String getMatchedString(List<String> wordBreakdownList) {
+ private String getMatchedString(List<String> wordBreakdownList, boolean includeMedicalDevices) {
if (!mBloomFilterInitialized || wordBreakdownList.isEmpty()) {
return "";
}
@@ -579,6 +652,21 @@ public class MetricsLogger {
matchedString = word;
}
}
+
+ return (matchedString.equals("") && includeMedicalDevices)
+ ? getMatchedStringForMedicalDevice(wordBreakdownList)
+ : matchedString;
+ }
+
+ private String getMatchedStringForMedicalDevice(List<String> wordBreakdownList) {
+ String matchedString = "";
+ for (String word : wordBreakdownList) {
+ byte[] sha256 = getSha256(word);
+ if (mMedicalDeviceBloomFilter.mightContain(sha256)
+ && word.length() > matchedString.length()) {
+ matchedString = word;
+ }
+ }
return matchedString;
}
@@ -664,16 +752,18 @@ public class MetricsLogger {
advDurationMs);
}
- protected String getAllowlistedDeviceNameHash(String deviceName) {
+ protected String getAllowlistedDeviceNameHash(
+ String deviceName, boolean includeMedicalDevices) {
List<String> wordBreakdownList = getWordBreakdownList(deviceName);
- String matchedString = getMatchedString(wordBreakdownList);
+ String matchedString = getMatchedString(wordBreakdownList, includeMedicalDevices);
return getSha256String(matchedString);
}
protected String logAllowlistedDeviceNameHash(
int metricId, String deviceName, boolean logRestrictedNames) {
List<String> wordBreakdownList = getWordBreakdownList(deviceName);
- String matchedString = getMatchedString(wordBreakdownList);
+ boolean includeMedicalDevices = false;
+ String matchedString = getMatchedString(wordBreakdownList, includeMedicalDevices);
if (logRestrictedNames) {
// Log the restricted bluetooth device name
if (SdkLevel.isAtLeastU()) {
@@ -695,7 +785,7 @@ public class MetricsLogger {
public void logBluetoothEvent(BluetoothDevice device, int eventType, int state, int uid) {
- if (mAdapterService.getMetricId(device) == 0 || !mInitialized) {
+ if (!mInitialized || mAdapterService.getMetricId(device) == 0) {
return;
}
@@ -705,7 +795,7 @@ public class MetricsLogger {
state,
uid,
mAdapterService.getMetricId(device),
- getRemoteDeviceInfoProto(device));
+ getRemoteDeviceInfoProto(device, false));
}
protected static String getSha256String(String name) {
@@ -815,6 +905,27 @@ public class MetricsLogger {
sessionStatus);
}
+ /** Logs Bond State Machine event */
+ public void logBondStateMachineEvent(BluetoothDevice device, int bondState) {
+ switch (bondState) {
+ case BluetoothDevice.BOND_NONE:
+ logBluetoothEvent(
+ device,
+ BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__BOND,
+ BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__STATE_NONE,
+ 0);
+ break;
+ case BluetoothDevice.BOND_BONDED:
+ logBluetoothEvent(
+ device,
+ BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__EVENT_TYPE__BOND,
+ BLUETOOTH_CROSS_LAYER_EVENT_REPORTED__STATE__STATE_BONDED,
+ 0);
+ break;
+ default:
+ }
+ }
+
/** Logs LE Audio Broadcast audio sync. */
public void logLeAudioBroadcastAudioSync(
BluetoothDevice device,
@@ -836,6 +947,6 @@ public class MetricsLogger {
latencyPaSyncMs,
latencyBisSyncMs,
syncStatus,
- getRemoteDeviceInfoProto(device));
+ getRemoteDeviceInfoProto(device, false));
}
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java
index 696526bb26..685bd05839 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java
@@ -2701,6 +2701,60 @@ public class BassClientStateMachineTest {
assertThat(mBassClientStateMachine.mPendingSourceId).isEqualTo(sourceId);
}
+ @Test
+ public void updateBroadcastSource_pendingSourceToRemove() {
+ prepareInitialReceiveStateForGatt();
+
+ generateBroadcastReceiveStatesAndVerify(
+ mSourceTestDevice,
+ TEST_SOURCE_ID,
+ BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED,
+ BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING,
+ 0x1L);
+
+ BassClientStateMachine.BluetoothGattTestableWrapper btGatt =
+ Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class);
+ mBassClientStateMachine.mBluetoothGatt = btGatt;
+ BluetoothGattCharacteristic scanControlPoint =
+ Mockito.mock(BluetoothGattCharacteristic.class);
+ mBassClientStateMachine.mBroadcastScanControlPoint = scanControlPoint;
+
+ BluetoothLeBroadcastMetadata metadata = createBroadcastMetadata();
+ mBassClientStateMachine.mPendingMetadata = metadata;
+
+ sendMessageAndVerifyTransition(
+ mBassClientStateMachine.obtainMessage(
+ UPDATE_BCAST_SOURCE,
+ TEST_SOURCE_ID,
+ BassConstants.PA_SYNC_DO_NOT_SYNC,
+ metadata),
+ BassClientStateMachine.ConnectedProcessing.class);
+ assertThat(mBassClientStateMachine.mPendingOperation).isEqualTo(UPDATE_BCAST_SOURCE);
+ assertThat(mBassClientStateMachine.mPendingSourceId).isEqualTo(TEST_SOURCE_ID);
+
+ mBassClientStateMachine.mPendingOperation = 0;
+ mBassClientStateMachine.mPendingSourceId = 0;
+ // Verify not removing source when PA is still synced
+ generateBroadcastReceiveStatesAndVerify(
+ mSourceTestDevice,
+ TEST_SOURCE_ID,
+ BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED,
+ BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
+ 0x0L);
+ assertThat(mBassClientStateMachine.mPendingOperation).isEqualTo(0);
+ assertThat(mBassClientStateMachine.mPendingSourceId).isEqualTo(0);
+
+ // Verify removing source when PA is unsynced
+ generateBroadcastReceiveStatesAndVerify(
+ mSourceTestDevice,
+ TEST_SOURCE_ID,
+ BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE,
+ BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
+ 0x0L);
+ assertThat(mBassClientStateMachine.mPendingOperation).isEqualTo(REMOVE_BCAST_SOURCE);
+ assertThat(mBassClientStateMachine.mPendingSourceId).isEqualTo(TEST_SOURCE_ID);
+ }
+
private void initToConnectingState() {
allowConnection(true);
allowConnectGatt(true);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java
index 3f0331f2b8..018fccff17 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/MetricsLoggerTest.java
@@ -270,6 +270,28 @@ public class MetricsLoggerTest {
}
@Test
+ public void testGetAllowlistedDeviceNameHashForMedicalDevice() {
+ String deviceName = "Sam's rphonak hearing aid";
+ String expectMedicalDeviceSha256 = MetricsLogger.getSha256String("rphonakhearingaid");
+
+ String actualMedicalDeviceSha256 =
+ mTestableMetricsLogger.getAllowlistedDeviceNameHash(deviceName, true);
+
+ Assert.assertEquals(expectMedicalDeviceSha256, actualMedicalDeviceSha256);
+ }
+
+ @Test
+ public void testGetAllowlistedDeviceNameHashForMedicalDeviceIdentifiedLogging() {
+ String deviceName = "Sam's rphonak hearing aid";
+ String expectMedicalDeviceSha256 = "";
+
+ String actualMedicalDeviceSha256 =
+ mTestableMetricsLogger.getAllowlistedDeviceNameHash(deviceName, false);
+
+ Assert.assertEquals(expectMedicalDeviceSha256, actualMedicalDeviceSha256);
+ }
+
+ @Test
public void uploadEmptyDeviceName() {
initTestingBloomfilter();
Assert.assertEquals("", mTestableMetricsLogger.logAllowlistedDeviceNameHash(1, "", true));
diff --git a/flags/gap.aconfig b/flags/gap.aconfig
index 2b2b5cdd55..36a83faa6f 100644
--- a/flags/gap.aconfig
+++ b/flags/gap.aconfig
@@ -236,6 +236,19 @@ flag {
namespace: "bluetooth"
description: "Support MSFT HCI extension for LE Scanning. go/bt-msft-aosp-dd"
bug: "365787977"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "le_impl_ack_pause_disarmed"
+ namespace: "bluetooth"
+ description: "Let le_impl AckPause when disarmed to prevent stuck in pausing state"
+ bug: "357024179"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
flag {
@@ -257,3 +270,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "initial_conn_params_p1"
+ namespace: "bluetooth"
+ description: "Use aggressive connection parameters when <2 connections exist. go/initial-connection-parameter-optimization"
+ bug: "378595485"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+} \ No newline at end of file
diff --git a/flags/opp.aconfig b/flags/opp.aconfig
index adc94796d5..6e32ab0b75 100644
--- a/flags/opp.aconfig
+++ b/flags/opp.aconfig
@@ -28,3 +28,12 @@ flag {
}
}
+flag {
+ name: "opp_set_insets_for_edge_to_edge"
+ namespace: "bluetooth"
+ description: "Set proper insets in BluetoothOppTransferHistory to adapt to edge-to-edge."
+ bug: "378813445"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/pairing.aconfig b/flags/pairing.aconfig
index 6662aee382..152f262bcb 100644
--- a/flags/pairing.aconfig
+++ b/flags/pairing.aconfig
@@ -199,4 +199,14 @@ flag {
metadata {
purpose: PURPOSE_BUGFIX
}
+}
+
+flag {
+ name: "prevent_service_connections_on_remove_bond"
+ namespace: "bluetooth"
+ description: "Disable service connections on remove bond"
+ bug: "378736590"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
} \ No newline at end of file
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 5e52c1f8fb..10cb58064b 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -1275,7 +1275,7 @@ package android.bluetooth.le {
method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void startTruncatedScan(java.util.List<android.bluetooth.le.TruncatedFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
}
- @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public final class ChannelSoundingParams implements android.os.Parcelable {
+ public final class ChannelSoundingParams implements android.os.Parcelable {
method public int describeContents();
method public int getCsSecurityLevel();
method public int getLocationType();
@@ -1304,8 +1304,8 @@ package android.bluetooth.le {
}
public final class DistanceMeasurementManager {
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getChannelSoundingMaxSupportedSecurityLevel(@NonNull android.bluetooth.BluetoothDevice);
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getLocalChannelSoundingMaxSupportedSecurityLevel();
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getChannelSoundingMaxSupportedSecurityLevel(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getLocalChannelSoundingMaxSupportedSecurityLevel();
method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.le.DistanceMeasurementMethod> getSupportedMethods();
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.os.CancellationSignal startMeasurementSession(@NonNull android.bluetooth.le.DistanceMeasurementParams, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.le.DistanceMeasurementSession.Callback);
}
@@ -1319,7 +1319,7 @@ package android.bluetooth.le {
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.DistanceMeasurementMethod> CREATOR;
field public static final int DISTANCE_MEASUREMENT_METHOD_AUTO = 0; // 0x0
- field @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public static final int DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING = 2; // 0x2
+ field public static final int DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING = 2; // 0x2
field public static final int DISTANCE_MEASUREMENT_METHOD_RSSI = 1; // 0x1
}
@@ -1332,7 +1332,7 @@ package android.bluetooth.le {
public final class DistanceMeasurementParams implements android.os.Parcelable {
method public int describeContents();
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") @Nullable public android.bluetooth.le.ChannelSoundingParams getChannelSoundingParams();
+ method @Nullable public android.bluetooth.le.ChannelSoundingParams getChannelSoundingParams();
method public static int getDefaultDurationSeconds();
method @NonNull public android.bluetooth.BluetoothDevice getDevice();
method @IntRange(from=0) public int getDurationSeconds();
@@ -1349,7 +1349,7 @@ package android.bluetooth.le {
public static final class DistanceMeasurementParams.Builder {
ctor public DistanceMeasurementParams.Builder(@NonNull android.bluetooth.BluetoothDevice);
method @NonNull public android.bluetooth.le.DistanceMeasurementParams build();
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") @NonNull public android.bluetooth.le.DistanceMeasurementParams.Builder setChannelSoundingParams(@NonNull android.bluetooth.le.ChannelSoundingParams);
+ method @NonNull public android.bluetooth.le.DistanceMeasurementParams.Builder setChannelSoundingParams(@NonNull android.bluetooth.le.ChannelSoundingParams);
method @NonNull public android.bluetooth.le.DistanceMeasurementParams.Builder setDurationSeconds(@IntRange(from=0) int);
method @NonNull public android.bluetooth.le.DistanceMeasurementParams.Builder setFrequency(int);
method @NonNull public android.bluetooth.le.DistanceMeasurementParams.Builder setMethodId(int);
@@ -1359,25 +1359,25 @@ package android.bluetooth.le {
method public int describeContents();
method @FloatRange(from=-90.0, to=90.0) public double getAltitudeAngle();
method @FloatRange(from=0.0, to=360.0) public double getAzimuthAngle();
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel();
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public double getDelaySpreadMeters();
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public int getDetectedAttackLevel();
+ method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel();
+ method public double getDelaySpreadMeters();
+ method public int getDetectedAttackLevel();
method public double getErrorAltitudeAngle();
method public double getErrorAzimuthAngle();
method @FloatRange(from=0.0) public double getErrorMeters();
method @FlaggedApi("com.android.bluetooth.flags.channel_sounding_25q2_apis") public long getMeasurementTimestampNanos();
method public double getResultMeters();
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public double getVelocityMetersPerSecond();
+ method public double getVelocityMetersPerSecond();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.DistanceMeasurementResult> CREATOR;
- field @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public static final int NADM_ATTACK_IS_EXTREMELY_LIKELY = 6; // 0x6
- field @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public static final int NADM_ATTACK_IS_EXTREMELY_UNLIKELY = 0; // 0x0
- field @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public static final int NADM_ATTACK_IS_LIKELY = 4; // 0x4
- field @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public static final int NADM_ATTACK_IS_POSSIBLE = 3; // 0x3
- field @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public static final int NADM_ATTACK_IS_UNLIKELY = 2; // 0x2
- field @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public static final int NADM_ATTACK_IS_VERY_LIKELY = 5; // 0x5
- field @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public static final int NADM_ATTACK_IS_VERY_UNLIKELY = 1; // 0x1
- field @FlaggedApi("com.android.bluetooth.flags.channel_sounding") public static final int NADM_UNKNOWN = 255; // 0xff
+ field public static final int NADM_ATTACK_IS_EXTREMELY_LIKELY = 6; // 0x6
+ field public static final int NADM_ATTACK_IS_EXTREMELY_UNLIKELY = 0; // 0x0
+ field public static final int NADM_ATTACK_IS_LIKELY = 4; // 0x4
+ field public static final int NADM_ATTACK_IS_POSSIBLE = 3; // 0x3
+ field public static final int NADM_ATTACK_IS_UNLIKELY = 2; // 0x2
+ field public static final int NADM_ATTACK_IS_VERY_LIKELY = 5; // 0x5
+ field public static final int NADM_ATTACK_IS_VERY_UNLIKELY = 1; // 0x1
+ field public static final int NADM_UNKNOWN = 255; // 0xff
}
public static final class DistanceMeasurementResult.Builder {
@@ -1385,13 +1385,13 @@ package android.bluetooth.le {
method @NonNull public android.bluetooth.le.DistanceMeasurementResult build();
method @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setAltitudeAngle(@FloatRange(from=-90.0, to=90.0) double);
method @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setAzimuthAngle(@FloatRange(from=0.0, to=360.0) double);
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setConfidenceLevel(@FloatRange(from=0.0, to=1.0) double);
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setDelaySpreadMeters(double);
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setDetectedAttackLevel(int);
+ method @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setConfidenceLevel(@FloatRange(from=0.0, to=1.0) double);
+ method @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setDelaySpreadMeters(double);
+ method @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setDetectedAttackLevel(int);
method @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setErrorAltitudeAngle(@FloatRange(from=0.0, to=180.0) double);
method @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setErrorAzimuthAngle(@FloatRange(from=0.0, to=360.0) double);
method @FlaggedApi("com.android.bluetooth.flags.channel_sounding_25q2_apis") @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setMeasurementTimestampNanos(long);
- method @FlaggedApi("com.android.bluetooth.flags.channel_sounding") @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setVelocityMetersPerSecond(double);
+ method @NonNull public android.bluetooth.le.DistanceMeasurementResult.Builder setVelocityMetersPerSecond(double);
}
public final class DistanceMeasurementSession {
diff --git a/framework/java/android/bluetooth/le/ChannelSoundingParams.java b/framework/java/android/bluetooth/le/ChannelSoundingParams.java
index 7c6baf1cff..ab5b8b4b40 100644
--- a/framework/java/android/bluetooth/le/ChannelSoundingParams.java
+++ b/framework/java/android/bluetooth/le/ChannelSoundingParams.java
@@ -16,15 +16,12 @@
package android.bluetooth.le;
-import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import com.android.bluetooth.flags.Flags;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -35,7 +32,6 @@ import java.lang.annotation.RetentionPolicy;
*
* @hide
*/
-@FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public final class ChannelSoundingParams implements Parcelable {
diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementManager.java b/framework/java/android/bluetooth/le/DistanceMeasurementManager.java
index 75ef152ef6..7a5eb37268 100644
--- a/framework/java/android/bluetooth/le/DistanceMeasurementManager.java
+++ b/framework/java/android/bluetooth/le/DistanceMeasurementManager.java
@@ -19,7 +19,6 @@ package android.bluetooth.le;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
-import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -36,8 +35,6 @@ import android.os.ParcelUuid;
import android.os.RemoteException;
import android.util.Log;
-import com.android.bluetooth.flags.Flags;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -169,7 +166,6 @@ public final class DistanceMeasurementManager {
* when Channel Sounding is not supported or encounters an internal error.
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
@RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
@@ -200,7 +196,6 @@ public final class DistanceMeasurementManager {
* when Channel Sounding is not supported or encounters an internal error.
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
@RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java b/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java
index 12b1a940f1..eb4032057d 100644
--- a/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java
+++ b/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java
@@ -73,7 +73,6 @@ public final class DistanceMeasurementMethod implements Parcelable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public static final int DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING = 2;
diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementParams.java b/framework/java/android/bluetooth/le/DistanceMeasurementParams.java
index f3116ed95a..04b3febe55 100644
--- a/framework/java/android/bluetooth/le/DistanceMeasurementParams.java
+++ b/framework/java/android/bluetooth/le/DistanceMeasurementParams.java
@@ -16,7 +16,6 @@
package android.bluetooth.le;
-import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -27,8 +26,6 @@ import android.bluetooth.le.DistanceMeasurementMethod.DistanceMeasurementMethodI
import android.os.Parcel;
import android.os.Parcelable;
-import com.android.bluetooth.flags.Flags;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
@@ -143,7 +140,6 @@ public final class DistanceMeasurementParams implements Parcelable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public @Nullable ChannelSoundingParams getChannelSoundingParams() {
return mChannelSoundingParams;
@@ -312,7 +308,6 @@ public final class DistanceMeasurementParams implements Parcelable {
* @return the same Builder instance
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public @NonNull Builder setChannelSoundingParams(
@NonNull ChannelSoundingParams channelSoundingParams) {
diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementResult.java b/framework/java/android/bluetooth/le/DistanceMeasurementResult.java
index 9fb3416a85..e69e895fba 100644
--- a/framework/java/android/bluetooth/le/DistanceMeasurementResult.java
+++ b/framework/java/android/bluetooth/le/DistanceMeasurementResult.java
@@ -64,7 +64,6 @@ public final class DistanceMeasurementResult implements Parcelable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public static final int NADM_ATTACK_IS_EXTREMELY_UNLIKELY = 0;
@@ -73,7 +72,6 @@ public final class DistanceMeasurementResult implements Parcelable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public static final int NADM_ATTACK_IS_VERY_UNLIKELY = 1;
@@ -82,7 +80,6 @@ public final class DistanceMeasurementResult implements Parcelable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public static final int NADM_ATTACK_IS_UNLIKELY = 2;
@@ -91,7 +88,6 @@ public final class DistanceMeasurementResult implements Parcelable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public static final int NADM_ATTACK_IS_POSSIBLE = 3;
@@ -100,7 +96,6 @@ public final class DistanceMeasurementResult implements Parcelable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public static final int NADM_ATTACK_IS_LIKELY = 4;
@@ -109,7 +104,6 @@ public final class DistanceMeasurementResult implements Parcelable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public static final int NADM_ATTACK_IS_VERY_LIKELY = 5;
@@ -118,7 +112,6 @@ public final class DistanceMeasurementResult implements Parcelable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public static final int NADM_ATTACK_IS_EXTREMELY_LIKELY = 6;
@@ -127,7 +120,6 @@ public final class DistanceMeasurementResult implements Parcelable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public static final int NADM_UNKNOWN = 0xFF;
@@ -269,7 +261,6 @@ public final class DistanceMeasurementResult implements Parcelable {
* @return delay spread in meters in degrees or Double.NaN if not available
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public double getDelaySpreadMeters() {
return mDelaySpreadMeters;
@@ -282,7 +273,6 @@ public final class DistanceMeasurementResult implements Parcelable {
* @return confidence of estimated distance or Double.NaN if not available
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
@FloatRange(from = 0.0, to = 1.0)
public double getConfidenceLevel() {
@@ -295,7 +285,6 @@ public final class DistanceMeasurementResult implements Parcelable {
* @return Nadm that represents the chance of being attacked for the measurement.
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
@Nadm
public int getDetectedAttackLevel() {
@@ -310,7 +299,6 @@ public final class DistanceMeasurementResult implements Parcelable {
* object in meters/sec.
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
public double getVelocityMetersPerSecond() {
return mVelocityMetersPerSecond;
@@ -532,7 +520,6 @@ public final class DistanceMeasurementResult implements Parcelable {
* @throws IllegalArgumentException if value is invalid
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
@NonNull
public Builder setDelaySpreadMeters(double delaySpreadMeters) {
@@ -551,7 +538,6 @@ public final class DistanceMeasurementResult implements Parcelable {
* @throws IllegalArgumentException if value is invalid
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
@NonNull
public Builder setConfidenceLevel(
@@ -573,7 +559,6 @@ public final class DistanceMeasurementResult implements Parcelable {
* @throws IllegalArgumentException if value is invalid
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
@NonNull
public Builder setDetectedAttackLevel(@Nadm int detectedAttackLevel) {
@@ -601,7 +586,6 @@ public final class DistanceMeasurementResult implements Parcelable {
* @param velocityMetersPerSecond estimated velocity in meters/sec.
* @hide
*/
- @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING)
@SystemApi
@NonNull
public Builder setVelocityMetersPerSecond(double velocityMetersPerSecond) {
diff --git a/system/bta/hh/bta_hh_act.cc b/system/bta/hh/bta_hh_act.cc
index 118a4b72f4..e32500a4ed 100644
--- a/system/bta/hh/bta_hh_act.cc
+++ b/system/bta/hh/bta_hh_act.cc
@@ -978,6 +978,9 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
/* remove from known device list in BTA */
bta_hh_clean_up_kdev(p_cb);
+ } else if (com::android::bluetooth::flags::remove_pending_hid_connection()) {
+ log::warn("Failed to remove device {}", dev_info.link_spec);
+ bta_hh_clean_up_kdev(p_cb);
}
}
break;
diff --git a/system/btif/include/btif_bqr.h b/system/btif/include/btif_bqr.h
index 909335b411..38bfa8badc 100644
--- a/system/btif/include/btif_bqr.h
+++ b/system/btif/include/btif_bqr.h
@@ -200,8 +200,10 @@ enum BqrQualityReportId : uint8_t {
QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY = 0x03,
QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04,
QUALITY_REPORT_ID_ROOT_INFLAMMATION = 0x05,
+ QUALITY_REPORT_ID_ENERGY_MONITOR = 0x06,
QUALITY_REPORT_ID_LE_AUDIO_CHOPPY = 0x07,
QUALITY_REPORT_ID_CONNECT_FAIL = 0x08,
+ QUALITY_REPORT_ID_RF_STATS = 0x09,
QUALITY_REPORT_ID_VENDOR_SPECIFIC_QUALITY = 0x10,
QUALITY_REPORT_ID_LMP_LL_MESSAGE_TRACE = 0x11,
QUALITY_REPORT_ID_BT_SCHEDULING_TRACE = 0x12,
@@ -330,6 +332,112 @@ typedef struct {
const uint8_t* vendor_specific_parameter;
} BqrLinkQualityEvent;
+// Energy Monitor BQR event
+typedef struct {
+ // Quality report ID.
+ uint8_t quality_report_id;
+ // Average current consumption of all activities consumed by the controller (mA)
+ uint16_t avg_current_consume;
+ // Total time in the idle (low power states, sleep) state. (ms)
+ uint32_t idle_total_time;
+ // Indicates how many times the controller enters the idle state.
+ uint32_t idle_state_enter_count;
+ // Total time in the active (inquiring, paging, ACL/SCO/eSCO/BIS/CIS traffic, processing any task)
+ // state. (ms)
+ uint32_t active_total_time;
+ // Indicates how many times the controller enters the active states.
+ uint32_t active_state_enter_count;
+ // Total time in the BR/EDR specific Tx(Transmitting for ACL/SCO/eSCO traffic)state (ms)
+ uint32_t bredr_tx_total_time;
+ // Indicates how many times the controller enters the BR/EDR specific Tx state.
+ uint32_t bredr_tx_state_enter_count;
+ // Average Tx power level of all the BR/EDR link(s) (dBm)
+ uint8_t bredr_tx_avg_power_lv;
+ // Total time in the BR/EDR specific Rx (Receiving from ACL/SCO/eSCO traffic) state. (ms)
+ uint32_t bredr_rx_total_time;
+ // Indicates how many times the controller enters the BR/EDR specific Rx state. (ms)
+ uint32_t bredr_rx_state_enter_count;
+ // Total time in the LE specific Tx (Transmitting for either ACL/BIS/CIS or LE advertising
+ // traffic) state (ms)
+ uint32_t le_tx_total_time;
+ // Indicates how many times the controller enters theLE specific Tx state.
+ uint32_t le_tx_state_enter_count;
+ // Average Tx power level of all the LE link(s) (dBm)
+ uint8_t le_tx_avg_power_lv;
+ // Total time in the LE specific Rx (Receiving from either ACL/BIS/CIS or LE scanning traffic)
+ // state. (ms)
+ uint32_t le_rx_total_time;
+ // Indicates how many times the controller enters the LE specific Rx state
+ uint32_t le_rx_state_enter_count;
+ // The total time duration to collect power related information (ms)
+ uint32_t tm_period;
+ // The time duration of RX active in one chain
+ uint32_t rx_active_one_chain_time;
+ // The time duration of RX active in two chain
+ uint32_t rx_active_two_chain_time;
+ // The time duration of internal TX active in one chain
+ uint32_t tx_ipa_active_one_chain_time;
+ // The time duration of internal TX active in two chain
+ uint32_t tx_ipa_active_two_chain_time;
+ // The time duration of external TX active in one chain
+ uint32_t tx_epa_active_one_chain_time;
+ // The time duration of external TX active in two chain
+ uint32_t tx_epa_active_two_chain_time;
+} __attribute__((__packed__)) BqrEnergyMonitorEvent;
+
+static constexpr uint8_t kEnergyMonitorParamTotalLen = sizeof(BqrEnergyMonitorEvent);
+
+// RF Stats BQR event
+typedef struct {
+ // Quality report ID.
+ uint8_t quality_report_id;
+ // Extension for Further usage = 0x01 for BQRv6
+ uint8_t ext_info;
+ // time period (ms)
+ uint32_t tm_period;
+ // Packet counter of iPA BF
+ uint32_t tx_pw_ipa_bf;
+ // Packet counter of ePA BF
+ uint32_t tx_pw_epa_bf;
+ // Packet counter of iPA Div
+ uint32_t tx_pw_ipa_div;
+ // Packet counter of ePA Div
+ uint32_t tx_pw_epa_div;
+ // Packet counter of RSSI chain > -50 dBm
+ uint32_t rssi_ch_50;
+ // Packet counter of RSSI chain between -50 dBm ~ >-55 dBm
+ uint32_t rssi_ch_50_55;
+ // Packet counter of RSSI chain between -55 dBm ~ >-60 dBm
+ uint32_t rssi_ch_55_60;
+ // Packet counter of RSSI chain between -60 dBm ~ >-65 dBm
+ uint32_t rssi_ch_60_65;
+ // Packet counter of RSSI chain between -65 dBm ~ >-70 dBm
+ uint32_t rssi_ch_65_70;
+ // Packet counter of RSSI chain between -70 dBm ~ >-75 dBm
+ uint32_t rssi_ch_70_75;
+ // Packet counter of RSSI chain between -75 dBm ~ >-80 dBm
+ uint32_t rssi_ch_75_80;
+ // Packet counter of RSSI chain between -80 dBm ~ >-85 dBm
+ uint32_t rssi_ch_80_85;
+ // Packet counter of RSSI chain between -85 dBm ~ >-90 dBm
+ uint32_t rssi_ch_85_90;
+ // Packet counter of RSSI chain < -90 dBm
+ uint32_t rssi_ch_90;
+ // Packet counter of RSSI delta < 2 dBm
+ uint32_t rssi_delta_2_down;
+ // Packet counter of RSSI delta between 2 dBm ~ 5 dBm
+ uint32_t rssi_delta_2_5;
+ // Packet counter of RSSI delta between 5 dBm ~ 8 dB
+ uint32_t rssi_delta_5_8;
+ // Packet counter of RSSI delta between 8 dBm ~ 11 dBm
+ uint32_t rssi_delta_8_11;
+ // Packet counter of RSSI delta > 11 dBm
+ uint32_t rssi_delta_11_up;
+} __attribute__((__packed__)) BqrRFStatsEvent;
+
+// Total length of all parameters of the RF Stats event
+static constexpr uint8_t kRFStatsParamTotalLen = sizeof(BqrRFStatsEvent);
+
// Log dump related BQR event
typedef struct {
// Quality report ID.
@@ -348,6 +456,20 @@ public:
// @param length Total length of all parameters contained in the sub-event.
// @param p_param_buf A pointer to the parameters contained in the sub-event.
void ParseBqrLinkQualityEvt(uint8_t length, const uint8_t* p_param_buf);
+ // Parse the Energy Monitor BQR event.
+ //
+ // @param length Total length of all parameters contained in the sub-event.
+ // @param p_param_buf A pointer to the parameters contained in the sub-event.
+ //
+ // @return true if the event was parsed successfully, false otherwise.
+ bool ParseBqrEnergyMonitorEvt(uint8_t length, const uint8_t* p_param_buf);
+ // Parse the RF Stats BQR event.
+ //
+ // @param length Total length of all parameters contained in the sub-event.
+ // @param p_param_buf A pointer to the parameters contained in the sub-event.
+ //
+ // @return true if the event was parsed successfully, false otherwise.
+ bool ParseBqrRFStatsEvt(uint8_t length, const uint8_t* p_param_buf);
// Write the LMP/LL message trace to the log file.
//
// @param fd The File Descriptor of the log file.
@@ -372,6 +494,10 @@ public:
virtual ~BqrVseSubEvt() = default;
// Link Quality related BQR event
BqrLinkQualityEvent bqr_link_quality_event_ = {};
+ // Energy Monitor BQR event
+ BqrEnergyMonitorEvent bqr_energy_monitor_event_ = {};
+ // RF Stats BQR event
+ BqrRFStatsEvent bqr_rf_stats_event_ = {};
// Log Dump related BQR event
BqrLogDumpEvent bqr_log_dump_event_ = {};
// Local wall clock timestamp of receiving BQR VSE sub-event
diff --git a/system/btif/src/btif_bqr.cc b/system/btif/src/btif_bqr.cc
index 5e7eb73dad..37ce06a935 100644
--- a/system/btif/src/btif_bqr.cc
+++ b/system/btif/src/btif_bqr.cc
@@ -15,6 +15,7 @@
*/
#include <bluetooth/log.h>
+#include <com_android_bluetooth_flags.h>
#include <fcntl.h>
#ifdef __ANDROID__
#include <statslog_bt.h>
@@ -155,6 +156,79 @@ void BqrVseSubEvt::ParseBqrLinkQualityEvt(uint8_t length, const uint8_t* p_param
localtime_r(&now, &tm_timestamp_);
}
+bool BqrVseSubEvt::ParseBqrEnergyMonitorEvt(uint8_t length, const uint8_t* p_param_buf) {
+ if (length < kEnergyMonitorParamTotalLen) {
+ log::fatal(
+ "Parameter total length: {} is abnormal. It shall be not shorter than: "
+ "{}",
+ length, kEnergyMonitorParamTotalLen);
+ return false;
+ }
+
+ STREAM_TO_UINT8(bqr_energy_monitor_event_.quality_report_id, p_param_buf);
+ bqr_link_quality_event_.quality_report_id = bqr_energy_monitor_event_.quality_report_id;
+ STREAM_TO_UINT16(bqr_energy_monitor_event_.avg_current_consume, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.idle_total_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.idle_state_enter_count, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.active_total_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.active_state_enter_count, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.bredr_tx_total_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.bredr_tx_state_enter_count, p_param_buf);
+ STREAM_TO_UINT8(bqr_energy_monitor_event_.bredr_tx_avg_power_lv, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.bredr_rx_total_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.bredr_rx_state_enter_count, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.le_tx_total_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.le_tx_state_enter_count, p_param_buf);
+ STREAM_TO_UINT8(bqr_energy_monitor_event_.le_tx_avg_power_lv, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.le_rx_total_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.le_rx_state_enter_count, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.tm_period, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.rx_active_one_chain_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.rx_active_two_chain_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.tx_ipa_active_one_chain_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.tx_ipa_active_two_chain_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.tx_epa_active_one_chain_time, p_param_buf);
+ STREAM_TO_UINT32(bqr_energy_monitor_event_.tx_epa_active_two_chain_time, p_param_buf);
+ return true;
+}
+
+bool BqrVseSubEvt::ParseBqrRFStatsEvt(uint8_t length, const uint8_t* p_param_buf) {
+ if (length < kRFStatsParamTotalLen) {
+ log::fatal(
+ "Parameter total length: {} is abnormal. It shall be not shorter than: "
+ "{}",
+ length, kRFStatsParamTotalLen);
+ return false;
+ }
+
+ STREAM_TO_UINT8(bqr_rf_stats_event_.quality_report_id, p_param_buf);
+ bqr_link_quality_event_.quality_report_id = bqr_rf_stats_event_.quality_report_id;
+ STREAM_TO_UINT8(bqr_rf_stats_event_.ext_info, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.tm_period, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.tx_pw_ipa_bf, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.tx_pw_epa_bf, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.tx_pw_ipa_div, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.tx_pw_epa_div, p_param_buf);
+
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_50, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_50_55, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_55_60, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_60_65, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_65_70, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_70_75, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_75_80, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_80_85, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_85_90, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_90, p_param_buf);
+
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_delta_2_down, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_delta_2_5, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_delta_5_8, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_delta_8_11, p_param_buf);
+ STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_delta_11_up, p_param_buf);
+ return true;
+}
+
void BqrVseSubEvt::WriteLmpLlTraceLogFile(int fd, uint8_t length, const uint8_t* p_param_buf) {
const auto now = system_clock::to_time_t(system_clock::now());
localtime_r(&now, &tm_timestamp_);
@@ -226,7 +300,19 @@ std::string BqrVseSubEvt::ToString() const {
<< ", CRCError: " << std::to_string(bqr_link_quality_event_.crc_error_packets)
<< ", RxDuplicate: " << std::to_string(bqr_link_quality_event_.rx_duplicate_packets);
}
-
+ if (QUALITY_REPORT_ID_ENERGY_MONITOR == bqr_link_quality_event_.quality_report_id) {
+ ss << ", TotalTime: " << std::to_string(bqr_energy_monitor_event_.tm_period)
+ << ", ActiveTime: " << std::to_string(bqr_energy_monitor_event_.active_total_time)
+ << ", IdleTime: " << std::to_string(bqr_energy_monitor_event_.idle_total_time)
+ << ", AvgCurrent: " << std::to_string(bqr_energy_monitor_event_.avg_current_consume);
+ }
+ if (QUALITY_REPORT_ID_RF_STATS == bqr_link_quality_event_.quality_report_id) {
+ ss << ", TotalTime: " << std::to_string(bqr_rf_stats_event_.tm_period)
+ << ", TxiPABF: " << std::to_string(bqr_rf_stats_event_.tx_pw_ipa_bf)
+ << ", TxePABF: " << std::to_string(bqr_rf_stats_event_.tx_pw_epa_bf)
+ << ", TxiPADiv: " << std::to_string(bqr_rf_stats_event_.tx_pw_ipa_div)
+ << ", TxePADiv: " << std::to_string(bqr_rf_stats_event_.tx_pw_epa_div);
+ }
return ss.str();
}
@@ -248,6 +334,10 @@ static std::string QualityReportIdToString(uint8_t quality_report_id) {
return "LE Audio Choppy";
case QUALITY_REPORT_ID_CONNECT_FAIL:
return "Connect Fail";
+ case QUALITY_REPORT_ID_ENERGY_MONITOR:
+ return "Energy Monitor";
+ case QUALITY_REPORT_ID_RF_STATS:
+ return "RF Stats";
default:
return "Invalid";
}
@@ -589,6 +679,9 @@ static void ConfigureBqrCmpl(uint32_t current_evt_mask) {
}
static void AddLinkQualityEventToQueue(uint8_t length, const uint8_t* p_link_quality_event);
+static void AddEnergyMonitorEventToQueue(uint8_t length, const uint8_t* p_link_quality_event);
+static void AddRFStatsEventToQueue(uint8_t length, const uint8_t* p_link_quality_event);
+static void AddLinkQualityEventToQueue(uint8_t length, const uint8_t* p_link_quality_event);
// Categorize the incoming Bluetooth Quality Report.
//
// @param length Lengths of the quality report sent from the Bluetooth
@@ -631,6 +724,34 @@ static void CategorizeBqrEvent(uint8_t length, const uint8_t* p_bqr_event) {
log::warn("Unexpected ID: 0x{:x}", quality_report_id);
break;
+ case QUALITY_REPORT_ID_ENERGY_MONITOR:
+ if (length < kEnergyMonitorParamTotalLen) {
+ log::fatal(
+ "Parameter total length: {} is abnormal. It shall be not shorter "
+ "than: {}",
+ length, kEnergyMonitorParamTotalLen);
+ return;
+ }
+
+ if (com::android::bluetooth::flags::support_bluetooth_quality_report_v6()) {
+ AddEnergyMonitorEventToQueue(length, p_bqr_event);
+ }
+ break;
+
+ case QUALITY_REPORT_ID_RF_STATS:
+ if (length < kRFStatsParamTotalLen) {
+ log::fatal(
+ "Parameter total length: {} is abnormal. It shall be not shorter "
+ "than: {}",
+ length, kRFStatsParamTotalLen);
+ return;
+ }
+
+ if (com::android::bluetooth::flags::support_bluetooth_quality_report_v6()) {
+ AddRFStatsEventToQueue(length, p_bqr_event);
+ }
+ break;
+
default:
log::warn("Unknown ID: 0x{:x}", quality_report_id);
break;
@@ -705,6 +826,42 @@ static void AddLinkQualityEventToQueue(uint8_t length, const uint8_t* p_link_qua
kpBqrEventQueue.Enqueue(p_bqr_event.release());
}
+static void AddEnergyMonitorEventToQueue(uint8_t length, const uint8_t* p_energy_monitor_event) {
+ std::unique_ptr<BqrVseSubEvt> p_bqr_event = std::make_unique<BqrVseSubEvt>();
+
+ if (!p_bqr_event->ParseBqrEnergyMonitorEvt(length, p_energy_monitor_event)) {
+ log::warn("failed to parse BQR energy monitor event");
+ return;
+ }
+
+ BluetoothQualityReportInterface* bqrItf = getBluetoothQualityReportInterface();
+
+ if (bqrItf == NULL) {
+ log::warn("failed to deliver BQR, bqrItf is NULL");
+ return;
+ }
+
+ bqrItf->bqr_delivery_event(RawAddress::kAny, p_energy_monitor_event, length);
+}
+
+static void AddRFStatsEventToQueue(uint8_t length, const uint8_t* p_rf_stats_event) {
+ std::unique_ptr<BqrVseSubEvt> p_bqr_event = std::make_unique<BqrVseSubEvt>();
+
+ if (!p_bqr_event->ParseBqrRFStatsEvt(length, p_rf_stats_event)) {
+ log::warn("failed to parse BQR RF stats event");
+ return;
+ }
+
+ BluetoothQualityReportInterface* bqrItf = getBluetoothQualityReportInterface();
+
+ if (bqrItf == NULL) {
+ log::warn("failed to deliver BQR, bqrItf is NULL");
+ return;
+ }
+
+ bqrItf->bqr_delivery_event(RawAddress::kAny, p_rf_stats_event, length);
+}
+
static int OpenLmpLlTraceLogFile();
// Dump the LMP/LL message handshaking with the remote device to a log file.
diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc
index 2259ebcb23..70762b7c64 100644
--- a/system/btif/src/btif_dm.cc
+++ b/system/btif/src/btif_dm.cc
@@ -563,18 +563,7 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr,
if (pairing_cb.bond_type == BOND_TYPE_TEMPORARY) {
state = BT_BOND_STATE_NONE;
- } else {
- if (state == BT_BOND_STATE_NONE) {
- bluetooth::os::LogMetricBluetoothEvent(ToGdAddress(bd_addr),
- android::bluetooth::EventType::BOND,
- android::bluetooth::State::STATE_NONE);
- } else if (state == BT_BOND_STATE_BONDED) {
- bluetooth::os::LogMetricBluetoothEvent(ToGdAddress(bd_addr),
- android::bluetooth::EventType::BOND,
- android::bluetooth::State::STATE_BONDED);
- }
}
-
log::info(
"Bond state changed to state={}[0:none, 1:bonding, "
"2:bonded],prev_state={}, sdp_attempts={}",
diff --git a/system/btif/src/btif_hh.cc b/system/btif/src/btif_hh.cc
index e908807275..1a9855ef31 100644
--- a/system/btif/src/btif_hh.cc
+++ b/system/btif/src/btif_hh.cc
@@ -977,6 +977,11 @@ void btif_hh_remove_device(const tAclLinkSpec& link_spec) {
} else {
log::warn("device_num = 0");
}
+
+ if (com::android::bluetooth::flags::remove_pending_hid_connection()) {
+ BTA_HhRemoveDev(p_dev->dev_handle); // Remove the connection, in case it was pending
+ }
+
bta_hh_co_close(p_dev);
p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
diff --git a/system/gd/rust/topshim/btav/btav_shim.cc b/system/gd/rust/topshim/btav/btav_shim.cc
index 3838d03b66..eed0d54190 100644
--- a/system/gd/rust/topshim/btav/btav_shim.cc
+++ b/system/gd/rust/topshim/btav/btav_shim.cc
@@ -239,18 +239,15 @@ static ::rust::Vec<A2dpCodecConfig> to_rust_codec_config_vec(
return rconfigs;
}
-static A2dpError to_rust_error(const btav_error_t& error) {
+static void connection_state_cb(const RawAddress& addr, btav_connection_state_t state,
+ const btav_error_t& error) {
+ // CAUTION: The error_msg field is a reference and could refer to a rvalue on the stack.
+ // DO NOT make this conversion into a helper function.
A2dpError a2dp_error = {
.status = error.status,
.error_code = error.error_code,
.error_msg = error.error_msg.value_or(""),
};
- return a2dp_error;
-}
-
-static void connection_state_cb(const RawAddress& addr, btav_connection_state_t state,
- const btav_error_t& error) {
- A2dpError a2dp_error = to_rust_error(error);
rusty::connection_state_callback(addr, state, a2dp_error);
}
static void audio_state_cb(const RawAddress& addr, btav_audio_state_t state) {
diff --git a/system/gd/rust/topshim/btav_sink/btav_sink_shim.cc b/system/gd/rust/topshim/btav_sink/btav_sink_shim.cc
index 8b38b9b15a..d2999d9a2c 100644
--- a/system/gd/rust/topshim/btav_sink/btav_sink_shim.cc
+++ b/system/gd/rust/topshim/btav_sink/btav_sink_shim.cc
@@ -32,18 +32,15 @@ namespace rust {
namespace internal {
static A2dpSinkIntf* g_a2dp_sink_if;
-static A2dpError to_rust_error(const btav_error_t& error) {
+static void connection_state_cb(const RawAddress& addr, btav_connection_state_t state,
+ const btav_error_t& error) {
+ // CAUTION: The error_msg field is a reference and could refer to a rvalue on the stack.
+ // DO NOT make this conversion into a helper function.
A2dpError a2dp_error = {
.status = error.status,
.error_code = error.error_code,
.error_msg = error.error_msg.value_or(""),
};
- return a2dp_error;
-}
-
-static void connection_state_cb(const RawAddress& addr, btav_connection_state_t state,
- const btav_error_t& error) {
- A2dpError a2dp_error = to_rust_error(error);
rusty::sink_connection_state_callback(addr, state, a2dp_error);
}
static void audio_state_cb(const RawAddress& addr, btav_audio_state_t state) {
diff --git a/system/stack/bnep/bnep_api.cc b/system/stack/bnep/bnep_api.cc
index 25e4ac474d..85fb0bf04d 100644
--- a/system/stack/bnep/bnep_api.cc
+++ b/system/stack/bnep/bnep_api.cc
@@ -30,7 +30,6 @@
#include <cstdint>
#include "bnep_int.h"
-#include "bt_transport.h"
#include "bta/include/bta_sec_api.h"
#include "internal_include/bt_target.h"
#include "osi/include/alarm.h"
@@ -40,6 +39,7 @@
#include "stack/include/bt_psm_types.h"
#include "stack/include/l2cap_interface.h"
#include "types/bluetooth/uuid.h"
+#include "types/bt_transport.h"
#include "types/raw_address.h"
using namespace bluetooth;
diff --git a/system/stack/bnep/bnep_main.cc b/system/stack/bnep/bnep_main.cc
index 1cbea82777..add8bad93d 100644
--- a/system/stack/bnep/bnep_main.cc
+++ b/system/stack/bnep/bnep_main.cc
@@ -29,7 +29,6 @@
#include "bnep_api.h"
#include "bnep_int.h"
-#include "bt_transport.h"
#include "bta/include/bta_sec_api.h"
#include "hci/controller_interface.h"
#include "internal_include/bt_target.h"
@@ -44,6 +43,7 @@
#include "stack/include/bt_psm_types.h"
#include "stack/include/bt_types.h"
#include "stack/include/l2cap_interface.h"
+#include "types/bt_transport.h"
#include "types/raw_address.h"
using namespace bluetooth;
diff --git a/system/stack/bnep/bnep_utils.cc b/system/stack/bnep/bnep_utils.cc
index 1d3bf444bc..921e16992c 100644
--- a/system/stack/bnep/bnep_utils.cc
+++ b/system/stack/bnep/bnep_utils.cc
@@ -30,7 +30,6 @@
#include "bnep_api.h"
#include "bnep_int.h"
-#include "bt_transport.h"
#include "hci/controller_interface.h"
#include "internal_include/bt_target.h"
#include "l2cap_types.h"
@@ -43,6 +42,7 @@
#include "stack/include/bt_types.h"
#include "stack/include/l2cap_interface.h"
#include "types/bluetooth/uuid.h"
+#include "types/bt_transport.h"
#include "types/raw_address.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
diff --git a/system/stack/hid/hidd_conn.cc b/system/stack/hid/hidd_conn.cc
index 99ebe08242..b50516d8a8 100644
--- a/system/stack/hid/hidd_conn.cc
+++ b/system/stack/hid/hidd_conn.cc
@@ -31,7 +31,6 @@
#include <cstdint>
#include <cstring>
-#include "bt_transport.h"
#include "bta/include/bta_sec_api.h"
#include "hid_conn.h"
#include "hidd_api.h"
@@ -45,6 +44,7 @@
#include "stack/include/l2cap_interface.h"
#include "stack/include/l2cdefs.h"
#include "stack/include/stack_metrics_logging.h"
+#include "types/bt_transport.h"
#include "types/raw_address.h"
using namespace bluetooth;
diff --git a/system/stack/hid/hidh_conn.cc b/system/stack/hid/hidh_conn.cc
index ce36edca9d..cc2a480b57 100644
--- a/system/stack/hid/hidh_conn.cc
+++ b/system/stack/hid/hidh_conn.cc
@@ -30,7 +30,6 @@
#include <cstdint>
-#include "bt_transport.h"
#include "bta/include/bta_sec_api.h"
#include "hci_error_code.h"
#include "hid_conn.h"
@@ -50,6 +49,7 @@
#include "stack/include/btm_log_history.h"
#include "stack/include/l2cap_interface.h"
#include "stack/include/stack_metrics_logging.h"
+#include "types/bt_transport.h"
#include "types/raw_address.h"
using namespace bluetooth;