diff options
31 files changed, 526 insertions, 163 deletions
@@ -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/OWNERS_automotive b/OWNERS_automotive index 15f209f6c7..20c7ac685b 100644 --- a/OWNERS_automotive +++ b/OWNERS_automotive @@ -1,3 +1,3 @@ # Project owners +cmanton@google.com salsavage@google.com -samdaria@google.com 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 d02b6aacb3..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. diff --git a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java index c75097f226..2185ff7741 100644 --- a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +++ b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java @@ -594,6 +594,41 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac } /** + * Update the LE Audio active device following a change of (dual mode compatible) active device + * in a classic audio profile such as A2DP or HFP. + * + * @param previousActiveDevice previous active device of the classic profile + * @param nextActiveDevice current active device of the classic profile + */ + private void updateLeAudioActiveDeviceIfDualMode( + @Nullable BluetoothDevice previousActiveDevice, + @Nullable BluetoothDevice nextActiveDevice) { + if (!Utils.isDualModeAudioEnabled()) { + return; + } + + if (nextActiveDevice != null) { + boolean isDualModeDevice = + mAdapterService.isAllSupportedClassicAudioProfilesActive(nextActiveDevice); + if (isDualModeDevice) { + // If the active device for a classic audio profile is changed + // to a dual mode compatible device, then also update the + // active device for LE Audio. + setLeAudioActiveDevice(nextActiveDevice); + } + } else { + boolean wasDualModeDevice = + mAdapterService.isAllSupportedClassicAudioProfilesActive(previousActiveDevice); + if (wasDualModeDevice) { + // If the active device for a classic audio profile was a + // dual mode compatible device, then also update the + // active device for LE Audio. + setLeAudioActiveDevice(null, true); + } + } + } + + /** * Handles the active device logic for when the A2DP active device changes. Does the following: * 1. Clear the active hearing aid. 2. If dual mode is enabled and all supported classic audio * profiles are enabled, makes this device active for LE Audio. If not, clear the LE Audio @@ -614,26 +649,9 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac if (device != null) { setHearingAidActiveDevice(null, true); } - - if (Utils.isDualModeAudioEnabled()) { - if (device != null) { - boolean isDualModeDevice = - mAdapterService.isAllSupportedClassicAudioProfilesActive(device); - if (isDualModeDevice) { - setLeAudioActiveDevice(device); - } - } else { - boolean wasDualModeDevice = - mAdapterService.isAllSupportedClassicAudioProfilesActive( - mA2dpActiveDevice); - if (wasDualModeDevice) { - // remove LE audio active device when it was actived as dual mode device - // before - setLeAudioActiveDevice(null, true); - } - } - } + updateLeAudioActiveDeviceIfDualMode(mA2dpActiveDevice, device); } + // Just assign locally the new value mA2dpActiveDevice = device; @@ -696,29 +714,9 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac setHearingAidActiveDevice(null, true); } - if (Utils.isDualModeAudioEnabled()) { - if (device != null) { - boolean isDualModeDevice = - mAdapterService.isAllSupportedClassicAudioProfilesActive(device); - if (isDualModeDevice) { - setLeAudioActiveDevice(device); - } - } else { - boolean wasDualModeDevice = - mAdapterService.isAllSupportedClassicAudioProfilesActive( - mA2dpActiveDevice); - if (wasDualModeDevice) { - // remove LE audio active device when it was actived as dual mode device - // before - setLeAudioActiveDevice(null, true); - } - - Log.d(TAG, "HFP active device is null. Try to fallback to le audio device"); - synchronized (mLock) { - setFallbackDeviceActiveLocked(null); - } - } - } else { + updateLeAudioActiveDeviceIfDualMode(mHfpActiveDevice, device); + + if (!Utils.isDualModeAudioEnabled() || device == null) { Log.d(TAG, "HFP active device is null. Try to fallback to le audio device"); synchronized (mLock) { setFallbackDeviceActiveLocked(null); 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/MetricsLogger.java b/android/app/src/com/android/bluetooth/btservice/MetricsLogger.java index 0cb930d3fd..95a6f03094 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; @@ -72,7 +75,6 @@ import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.BtRestrictedStatsLog; import com.android.bluetooth.Utils; import com.android.bluetooth.bass_client.BassConstants; -import com.android.modules.utils.build.SdkLevel; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Ascii; @@ -340,18 +342,11 @@ public class MetricsLogger { BluetoothDevice device = connIntent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); int state = connIntent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); int metricId = mAdapterService.getMetricId(device); - boolean includeMedicalDevices = false; - byte[] remoteDeviceInfoBytes = getRemoteDeviceInfoProto(device, includeMedicalDevices); if (state == BluetoothProfile.STATE_CONNECTING) { String deviceName = mRemoteDevices.getName(device); BluetoothStatsLog.write( BluetoothStatsLog.BLUETOOTH_DEVICE_NAME_REPORTED, metricId, deviceName); - BluetoothStatsLog.write( - BluetoothStatsLog.REMOTE_DEVICE_INFORMATION_WITH_METRIC_ID, - metricId, - remoteDeviceInfoBytes); - - logAllowlistedDeviceNameHash(metricId, deviceName, true); + logAllowlistedDeviceNameHash(metricId, deviceName); } BluetoothStatsLog.write( BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, @@ -602,7 +597,7 @@ public class MetricsLogger { return Integer.parseInt(device.getAddress().replace(":", "").substring(0, 6), 16); } - private List<String> getWordBreakdownList(String deviceName) { + protected List<String> getWordBreakdownList(String deviceName) { if (deviceName == null) { return Collections.emptyList(); } @@ -631,7 +626,7 @@ public class MetricsLogger { } @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) - private void uploadRestrictedBluetothDeviceName(List<String> wordBreakdownList) { + protected void uploadRestrictedBluetothDeviceName(List<String> wordBreakdownList) { for (String word : wordBreakdownList) { BtRestrictedStatsLog.write(RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED, word); } @@ -756,17 +751,10 @@ public class MetricsLogger { return getSha256String(matchedString); } - protected String logAllowlistedDeviceNameHash( - int metricId, String deviceName, boolean logRestrictedNames) { + protected String logAllowlistedDeviceNameHash(int metricId, String deviceName) { List<String> wordBreakdownList = getWordBreakdownList(deviceName); boolean includeMedicalDevices = false; String matchedString = getMatchedString(wordBreakdownList, includeMedicalDevices); - if (logRestrictedNames) { - // Log the restricted bluetooth device name - if (SdkLevel.isAtLeastU()) { - uploadRestrictedBluetothDeviceName(wordBreakdownList); - } - } if (!matchedString.isEmpty()) { statslogBluetoothDeviceNames(metricId, matchedString); } @@ -782,7 +770,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; } @@ -902,6 +890,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, diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java index aa8395e54b..a1e964ebc2 100644 --- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java +++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java @@ -50,6 +50,7 @@ import com.android.bluetooth.bas.BatteryService; import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hfp.HeadsetHalConstants; import com.android.internal.annotations.VisibleForTesting; +import com.android.modules.utils.build.SdkLevel; import java.nio.charset.StandardCharsets; import java.util.ArrayDeque; @@ -946,6 +947,12 @@ public class RemoteDevices { break; } deviceProperties.setName(newName); + List<String> wordBreakdownList = + MetricsLogger.getInstance().getWordBreakdownList(newName); + if (SdkLevel.isAtLeastU()) { + MetricsLogger.getInstance() + .uploadRestrictedBluetothDeviceName(wordBreakdownList); + } intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, bdDevice); intent.putExtra(BluetoothDevice.EXTRA_NAME, deviceProperties.getName()); @@ -1295,6 +1302,13 @@ public class RemoteDevices { getBluetoothClass(device), metricId); + byte[] remoteDeviceInfoBytes = MetricsLogger.getInstance().getRemoteDeviceInfoProto(device); + + BluetoothStatsLog.write( + BluetoothStatsLog.REMOTE_DEVICE_INFORMATION_WITH_METRIC_ID, + metricId, + remoteDeviceInfoBytes); + if (intent == null) { Log.e(TAG, "aclStateChangeCallback intent is null. BondState: " + getBondState(device)); return; 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 018fccff17..dba15c5d1a 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 @@ -246,7 +246,7 @@ public class MetricsLoggerTest { Assert.assertEquals( deviceName, sha256, - mTestableMetricsLogger.logAllowlistedDeviceNameHash(1, deviceName, true)); + mTestableMetricsLogger.logAllowlistedDeviceNameHash(1, deviceName)); } } @@ -294,7 +294,7 @@ public class MetricsLoggerTest { @Test public void uploadEmptyDeviceName() { initTestingBloomfilter(); - Assert.assertEquals("", mTestableMetricsLogger.logAllowlistedDeviceNameHash(1, "", true)); + Assert.assertEquals("", mTestableMetricsLogger.logAllowlistedDeviceNameHash(1, "")); } private void initTestingBloomfilter() { diff --git a/flags/a2dp.aconfig b/flags/a2dp.aconfig index 0b8a749af1..aed2692cdd 100644 --- a/flags/a2dp.aconfig +++ b/flags/a2dp.aconfig @@ -167,3 +167,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "avdt_handle_suspend_cfm_bad_state" + namespace: "bluetooth" + description: "Close connection on AVDTP Suspend Confirmation with BAD STATE error" + bug: "377830155" + metadata { + purpose: PURPOSE_BUGFIX + } +}
\ No newline at end of file diff --git a/flags/gap.aconfig b/flags/gap.aconfig index 56283aaf81..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 { 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..896e4e5ff9 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; @@ -71,18 +68,18 @@ public final class DistanceMeasurementParams implements Parcelable { */ @SystemApi public static final int REPORT_FREQUENCY_HIGH = 2; - private static final int REPORT_DURATION_DEFAULT = 60; - private static final int REPORT_DURATION_MAX = 3600; + private static final int REPORT_DURATION_MAX = Integer.MAX_VALUE; + private static final int REPORT_DURATION_DEFAULT = REPORT_DURATION_MAX; - private BluetoothDevice mDevice = null; - private int mDuration; - private int mFrequency; - private int mMethodId; - private ChannelSoundingParams mChannelSoundingParams = null; + private final BluetoothDevice mDevice; + private final int mDuration; + private final int mFrequency; + private final int mMethodId; + private final ChannelSoundingParams mChannelSoundingParams; /** @hide */ public DistanceMeasurementParams( - BluetoothDevice device, + @NonNull BluetoothDevice device, int duration, int frequency, int methodId, @@ -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; |