Loading android/app/Android.bp +3 −3 Original line number Diff line number Diff line Loading @@ -246,16 +246,16 @@ android_app { "error_prone_annotations", "framework-annotations-lib", "framework-bluetooth-pre-jarjar", "framework-configinfrastructure", "framework-configinfrastructure.stubs.module_lib", "framework-connectivity.stubs.module_lib", "framework-location.stubs.module_lib", "framework-mediaprovider", "framework-mediaprovider.stubs.module_lib", "framework-statsd.stubs.module_lib", "framework-tethering.stubs.module_lib", "unsupportedappusage", // Need to link the class at runtime "framework-bluetooth", "framework-bluetooth.stubs.module_lib", ], static_libs: [ "BluetoothApiShims", Loading android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +207 −3 Original line number Diff line number Diff line Loading @@ -50,13 +50,16 @@ import android.os.Binder; import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; import android.os.SystemClock; import android.provider.DeviceConfig; import android.util.Log; import android.util.Pair; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; Loading @@ -73,6 +76,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Scanner; Loading Loading @@ -131,6 +135,8 @@ public class BassClientStateMachine extends StateMachine { private final ConnectedProcessing mConnectedProcessing = new ConnectedProcessing(); private final List<Pair<ScanResult, Integer>> mSourceSyncRequestsQueue = new ArrayList<Pair<ScanResult, Integer>>(); private final Map<Integer, LeAudioBroadcastSyncStats> mBroadcastSyncStats = new LinkedHashMap<>(); @VisibleForTesting final List<BluetoothGattCharacteristic> mBroadcastCharacteristics = Loading Loading @@ -204,6 +210,94 @@ public class BassClientStateMachine extends StateMachine { } } private static class LeAudioBroadcastSyncStats { private BluetoothDevice mDevice; private boolean mIsLocalBroadcast; private int mBroadcastId; private long mSourceAddTime; private long mSourcePaSyncedTime; private long mSourceBisSyncedTime; private int mSyncStatus; LeAudioBroadcastSyncStats( BluetoothDevice sink, BluetoothLeBroadcastMetadata metadata, boolean isLocalBroadcast, long startTime) { this.mDevice = sink; this.mIsLocalBroadcast = isLocalBroadcast; this.mBroadcastId = metadata.getBroadcastId(); this.mSourceAddTime = startTime; this.mSourcePaSyncedTime = 0; this.mSourceBisSyncedTime = 0; this.mSyncStatus = BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_SYNC_REQUESTED; } public void updatePaSyncedTime(long paSyncedTime) { if (mSourcePaSyncedTime == 0) { mSourcePaSyncedTime = paSyncedTime; } } public void updateBisSyncedTime(long bisSyncedTime) { if (mSourceBisSyncedTime == 0) { mSourceBisSyncedTime = bisSyncedTime; } } public void updateSyncStatus(int status) { if (mSyncStatus != BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_AUDIO_SYNC_SUCCESS) { Log.d( TAG, "logBroadcastSyncMetrics: updating from state: " + mSyncStatus + " to " + status); mSyncStatus = status; } } public void logBroadcastSyncMetrics(long stopTime) { long syncDurationMs = (mSourceBisSyncedTime > 0) ? (stopTime - mSourceBisSyncedTime) : 0; long latencyPaSyncedMs = (mSourcePaSyncedTime > 0) ? (mSourcePaSyncedTime - mSourceAddTime) : 0; long latencyBisSyncedMs = (mSourcePaSyncedTime > 0 && mSourceBisSyncedTime > 0) ? (mSourceBisSyncedTime - mSourcePaSyncedTime) : 0; Log.d( TAG, "logBroadcastSyncMetrics: broadcastId: " + mBroadcastId + ", isLocalBroadcast: " + mIsLocalBroadcast + ", syncDurationMs: " + syncDurationMs + ", latencyPaSyncedMs: " + latencyPaSyncedMs + ", latencyBisSyncedMs: " + latencyBisSyncedMs + ", syncStatus: " + mSyncStatus); MetricsLogger.getInstance() .logLeAudioBroadcastAudioSync( mDevice, mBroadcastId, mIsLocalBroadcast, syncDurationMs, latencyPaSyncedMs, latencyBisSyncedMs, mSyncStatus); } } static BassClientStateMachine make( BluetoothDevice device, BassClientService svc, Loading Loading @@ -259,6 +353,7 @@ public class BassClientStateMachine extends StateMachine { mPendingRemove.clear(); mPeriodicAdvCallbacksMap.clear(); mSourceSyncRequestsQueue.clear(); mBroadcastSyncStats.clear(); } Boolean hasPendingSourceOperation() { Loading Loading @@ -785,6 +880,94 @@ public class BassClientStateMachine extends StateMachine { } } private void processSyncStateChangeStats(BluetoothLeBroadcastReceiveState recvState) { int sourceId = recvState.getSourceId(); BluetoothLeBroadcastMetadata metaData = getCurrentBroadcastMetadata(sourceId); if (metaData == null) { Log.d(TAG, "No metadata for sourceId, skip logging"); return; } int broadcastId = metaData.getBroadcastId(); LeAudioBroadcastSyncStats syncStats = mBroadcastSyncStats.get(broadcastId); if (syncStats == null) { Log.d(TAG, "No stats for sourceId, skip logging"); return; } // Check PA state int paState = recvState.getPaSyncState(); if (paState == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) { syncStats.updatePaSyncedTime(SystemClock.elapsedRealtime()); syncStats.updateSyncStatus( BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_PA_SYNC_SUCCESS); // Continue to check other fields } else if (paState == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_FAILED_TO_SYNCHRONIZE) { syncStats.updateSyncStatus( BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_PA_SYNC_FAILED); // Update the failure state and continue to let sinks retry PA sync } else if (paState == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_NO_PAST) { // NO PAST server will not attempt to PA sync, log the failure logBroadcastSyncStatsWithStatus( broadcastId, BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_PA_SYNC_NO_PAST); return; } // Check Big encrypt state int bigEncryptState = recvState.getBigEncryptionState(); if (bigEncryptState == BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_BAD_CODE) { logBroadcastSyncStatsWithStatus( broadcastId, BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_BIG_DECRYPT_FAILED); return; } // Check Bis state for (int i = 0; i < recvState.getNumSubgroups(); i++) { Long bisState = recvState.getBisSyncState().get(i); if (bisState != BassConstants.BIS_SYNC_FAILED_SYNC_TO_BIG && bisState != BassConstants.BIS_SYNC_NOT_SYNC_TO_BIS) { // Any bis synced, update status and break syncStats.updateBisSyncedTime(SystemClock.elapsedRealtime()); syncStats.updateSyncStatus( BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_AUDIO_SYNC_SUCCESS); break; } else if (bisState == BassConstants.BIS_SYNC_FAILED_SYNC_TO_BIG) { logBroadcastSyncStatsWithStatus( broadcastId, BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_AUDIO_SYNC_FAILED); break; } } } private void logBroadcastSyncStatsWithStatus(int broadcastId, int status) { LeAudioBroadcastSyncStats syncStats = mBroadcastSyncStats.remove(broadcastId); if (syncStats != null) { if (status != BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_UNKNOWN) { syncStats.updateSyncStatus(status); } syncStats.logBroadcastSyncMetrics(SystemClock.elapsedRealtime()); } } private void logAllBroadcastSyncStatsAndCleanup() { for (LeAudioBroadcastSyncStats syncStats : mBroadcastSyncStats.values()) { syncStats.logBroadcastSyncMetrics(SystemClock.elapsedRealtime()); } mBroadcastSyncStats.clear(); } private void checkAndUpdateBroadcastCode(BluetoothLeBroadcastReceiveState recvState) { log("checkAndUpdateBroadcastCode"); // Whenever receive state indicated code requested, assistant should set the broadcast code Loading Loading @@ -985,22 +1168,33 @@ public class BassClientStateMachine extends StateMachine { } checkAndUpdateBroadcastCode(recvState); processPASyncState(recvState); processSyncStateChangeStats(recvState); } else { if (recvState.getSourceDevice() == null || recvState.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) { BluetoothDevice removedDevice = oldRecvState.getSourceDevice(); log("sourceInfo removal " + removedDevice); int prevSourceId = oldRecvState.getSourceId(); if (!Flags.leaudioBroadcastExtractPeriodicScannerFromStateMachine()) { cancelActiveSync( mService.getSyncHandleForBroadcastId(recvState.getBroadcastId())); } setCurrentBroadcastMetadata(oldRecvState.getSourceId(), null); BluetoothLeBroadcastMetadata metaData = getCurrentBroadcastMetadata(prevSourceId); if (metaData != null) { logBroadcastSyncStatsWithStatus( metaData.getBroadcastId(), BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_UNKNOWN); } setCurrentBroadcastMetadata(prevSourceId, null); if (mPendingSourceToSwitch != null) { // Source remove is triggered by switch source request mService.getCallbacks() .notifySourceRemoved( mDevice, oldRecvState.getSourceId(), prevSourceId, BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST); log("Switching to new source"); Message message = obtainMessage(ADD_BCAST_SOURCE); Loading @@ -1010,7 +1204,7 @@ public class BassClientStateMachine extends StateMachine { mService.getCallbacks() .notifySourceRemoved( mDevice, oldRecvState.getSourceId(), prevSourceId, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); } } else { Loading @@ -1027,6 +1221,7 @@ public class BassClientStateMachine extends StateMachine { BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); checkAndUpdateBroadcastCode(recvState); processPASyncState(recvState); processSyncStateChangeStats(recvState); if (isPendingRemove(recvState.getSourceId())) { Message message = obtainMessage(REMOVE_BCAST_SOURCE); Loading Loading @@ -1435,6 +1630,7 @@ public class BassClientStateMachine extends StateMachine { + mDevice + "): " + messageWhatToString(getCurrentMessage().what)); logAllBroadcastSyncStatsAndCleanup(); clearCharsCache(); mNextSourceId = 0; removeDeferredMessages(DISCONNECT); Loading Loading @@ -1993,6 +2189,14 @@ public class BassClientStateMachine extends StateMachine { break; } if (mBluetoothGatt != null && mBroadcastScanControlPoint != null) { mBroadcastSyncStats.put( metaData.getBroadcastId(), new LeAudioBroadcastSyncStats( mDevice, metaData, mService.isLocalBroadcast(metaData), SystemClock.elapsedRealtime())); writeBassControlPoint(addSourceInfo); mPendingOperation = message.what; mPendingMetadata = metaData; Loading android/app/src/com/android/bluetooth/btservice/MetricsLogger.java +50 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.util.proto.ProtoOutputStream; import androidx.annotation.RequiresApi; import com.android.bluetooth.bass_client.BassConstants; import com.android.bluetooth.BluetoothMetricsProto.BluetoothLog; import com.android.bluetooth.BluetoothMetricsProto.BluetoothRemoteDeviceInformation; import com.android.bluetooth.BluetoothMetricsProto.ProfileConnectionStats; Loading Loading @@ -583,4 +584,53 @@ public class MetricsLogger { } return digest.digest(name.getBytes(StandardCharsets.UTF_8)); } /** Logs LE Audio Broadcast audio session. */ public void logLeAudioBroadcastAudioSession( int broadcastId, int[] audioQuality, int groupSize, long sessionDurationMs, long latencySessionConfiguredMs, long latencySessionStreamingMs, int sessionStatus) { if (!mInitialized) { return; } BluetoothStatsLog.write( BluetoothStatsLog.BROADCAST_AUDIO_SESSION_REPORTED, broadcastId, audioQuality.length, audioQuality, groupSize, sessionDurationMs, latencySessionConfiguredMs, latencySessionStreamingMs, sessionStatus); } /** Logs LE Audio Broadcast audio sync. */ public void logLeAudioBroadcastAudioSync( BluetoothDevice device, int broadcastId, boolean isLocalBroadcast, long syncDurationMs, long latencyPaSyncMs, long latencyBisSyncMs, int syncStatus) { if (!mInitialized) { return; } BluetoothStatsLog.write( BluetoothStatsLog.BROADCAST_AUDIO_SYNC_REPORTED, isLocalBroadcast ? broadcastId : BassConstants.INVALID_BROADCAST_ID, isLocalBroadcast, syncDurationMs, latencyPaSyncMs, latencyBisSyncMs, syncStatus, getRemoteDeviceInfoProto(device)); } } Loading
android/app/Android.bp +3 −3 Original line number Diff line number Diff line Loading @@ -246,16 +246,16 @@ android_app { "error_prone_annotations", "framework-annotations-lib", "framework-bluetooth-pre-jarjar", "framework-configinfrastructure", "framework-configinfrastructure.stubs.module_lib", "framework-connectivity.stubs.module_lib", "framework-location.stubs.module_lib", "framework-mediaprovider", "framework-mediaprovider.stubs.module_lib", "framework-statsd.stubs.module_lib", "framework-tethering.stubs.module_lib", "unsupportedappusage", // Need to link the class at runtime "framework-bluetooth", "framework-bluetooth.stubs.module_lib", ], static_libs: [ "BluetoothApiShims", Loading
android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +207 −3 Original line number Diff line number Diff line Loading @@ -50,13 +50,16 @@ import android.os.Binder; import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; import android.os.SystemClock; import android.provider.DeviceConfig; import android.util.Log; import android.util.Pair; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; Loading @@ -73,6 +76,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Scanner; Loading Loading @@ -131,6 +135,8 @@ public class BassClientStateMachine extends StateMachine { private final ConnectedProcessing mConnectedProcessing = new ConnectedProcessing(); private final List<Pair<ScanResult, Integer>> mSourceSyncRequestsQueue = new ArrayList<Pair<ScanResult, Integer>>(); private final Map<Integer, LeAudioBroadcastSyncStats> mBroadcastSyncStats = new LinkedHashMap<>(); @VisibleForTesting final List<BluetoothGattCharacteristic> mBroadcastCharacteristics = Loading Loading @@ -204,6 +210,94 @@ public class BassClientStateMachine extends StateMachine { } } private static class LeAudioBroadcastSyncStats { private BluetoothDevice mDevice; private boolean mIsLocalBroadcast; private int mBroadcastId; private long mSourceAddTime; private long mSourcePaSyncedTime; private long mSourceBisSyncedTime; private int mSyncStatus; LeAudioBroadcastSyncStats( BluetoothDevice sink, BluetoothLeBroadcastMetadata metadata, boolean isLocalBroadcast, long startTime) { this.mDevice = sink; this.mIsLocalBroadcast = isLocalBroadcast; this.mBroadcastId = metadata.getBroadcastId(); this.mSourceAddTime = startTime; this.mSourcePaSyncedTime = 0; this.mSourceBisSyncedTime = 0; this.mSyncStatus = BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_SYNC_REQUESTED; } public void updatePaSyncedTime(long paSyncedTime) { if (mSourcePaSyncedTime == 0) { mSourcePaSyncedTime = paSyncedTime; } } public void updateBisSyncedTime(long bisSyncedTime) { if (mSourceBisSyncedTime == 0) { mSourceBisSyncedTime = bisSyncedTime; } } public void updateSyncStatus(int status) { if (mSyncStatus != BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_AUDIO_SYNC_SUCCESS) { Log.d( TAG, "logBroadcastSyncMetrics: updating from state: " + mSyncStatus + " to " + status); mSyncStatus = status; } } public void logBroadcastSyncMetrics(long stopTime) { long syncDurationMs = (mSourceBisSyncedTime > 0) ? (stopTime - mSourceBisSyncedTime) : 0; long latencyPaSyncedMs = (mSourcePaSyncedTime > 0) ? (mSourcePaSyncedTime - mSourceAddTime) : 0; long latencyBisSyncedMs = (mSourcePaSyncedTime > 0 && mSourceBisSyncedTime > 0) ? (mSourceBisSyncedTime - mSourcePaSyncedTime) : 0; Log.d( TAG, "logBroadcastSyncMetrics: broadcastId: " + mBroadcastId + ", isLocalBroadcast: " + mIsLocalBroadcast + ", syncDurationMs: " + syncDurationMs + ", latencyPaSyncedMs: " + latencyPaSyncedMs + ", latencyBisSyncedMs: " + latencyBisSyncedMs + ", syncStatus: " + mSyncStatus); MetricsLogger.getInstance() .logLeAudioBroadcastAudioSync( mDevice, mBroadcastId, mIsLocalBroadcast, syncDurationMs, latencyPaSyncedMs, latencyBisSyncedMs, mSyncStatus); } } static BassClientStateMachine make( BluetoothDevice device, BassClientService svc, Loading Loading @@ -259,6 +353,7 @@ public class BassClientStateMachine extends StateMachine { mPendingRemove.clear(); mPeriodicAdvCallbacksMap.clear(); mSourceSyncRequestsQueue.clear(); mBroadcastSyncStats.clear(); } Boolean hasPendingSourceOperation() { Loading Loading @@ -785,6 +880,94 @@ public class BassClientStateMachine extends StateMachine { } } private void processSyncStateChangeStats(BluetoothLeBroadcastReceiveState recvState) { int sourceId = recvState.getSourceId(); BluetoothLeBroadcastMetadata metaData = getCurrentBroadcastMetadata(sourceId); if (metaData == null) { Log.d(TAG, "No metadata for sourceId, skip logging"); return; } int broadcastId = metaData.getBroadcastId(); LeAudioBroadcastSyncStats syncStats = mBroadcastSyncStats.get(broadcastId); if (syncStats == null) { Log.d(TAG, "No stats for sourceId, skip logging"); return; } // Check PA state int paState = recvState.getPaSyncState(); if (paState == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) { syncStats.updatePaSyncedTime(SystemClock.elapsedRealtime()); syncStats.updateSyncStatus( BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_PA_SYNC_SUCCESS); // Continue to check other fields } else if (paState == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_FAILED_TO_SYNCHRONIZE) { syncStats.updateSyncStatus( BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_PA_SYNC_FAILED); // Update the failure state and continue to let sinks retry PA sync } else if (paState == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_NO_PAST) { // NO PAST server will not attempt to PA sync, log the failure logBroadcastSyncStatsWithStatus( broadcastId, BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_PA_SYNC_NO_PAST); return; } // Check Big encrypt state int bigEncryptState = recvState.getBigEncryptionState(); if (bigEncryptState == BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_BAD_CODE) { logBroadcastSyncStatsWithStatus( broadcastId, BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_BIG_DECRYPT_FAILED); return; } // Check Bis state for (int i = 0; i < recvState.getNumSubgroups(); i++) { Long bisState = recvState.getBisSyncState().get(i); if (bisState != BassConstants.BIS_SYNC_FAILED_SYNC_TO_BIG && bisState != BassConstants.BIS_SYNC_NOT_SYNC_TO_BIS) { // Any bis synced, update status and break syncStats.updateBisSyncedTime(SystemClock.elapsedRealtime()); syncStats.updateSyncStatus( BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_AUDIO_SYNC_SUCCESS); break; } else if (bisState == BassConstants.BIS_SYNC_FAILED_SYNC_TO_BIG) { logBroadcastSyncStatsWithStatus( broadcastId, BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_AUDIO_SYNC_FAILED); break; } } } private void logBroadcastSyncStatsWithStatus(int broadcastId, int status) { LeAudioBroadcastSyncStats syncStats = mBroadcastSyncStats.remove(broadcastId); if (syncStats != null) { if (status != BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_UNKNOWN) { syncStats.updateSyncStatus(status); } syncStats.logBroadcastSyncMetrics(SystemClock.elapsedRealtime()); } } private void logAllBroadcastSyncStatsAndCleanup() { for (LeAudioBroadcastSyncStats syncStats : mBroadcastSyncStats.values()) { syncStats.logBroadcastSyncMetrics(SystemClock.elapsedRealtime()); } mBroadcastSyncStats.clear(); } private void checkAndUpdateBroadcastCode(BluetoothLeBroadcastReceiveState recvState) { log("checkAndUpdateBroadcastCode"); // Whenever receive state indicated code requested, assistant should set the broadcast code Loading Loading @@ -985,22 +1168,33 @@ public class BassClientStateMachine extends StateMachine { } checkAndUpdateBroadcastCode(recvState); processPASyncState(recvState); processSyncStateChangeStats(recvState); } else { if (recvState.getSourceDevice() == null || recvState.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) { BluetoothDevice removedDevice = oldRecvState.getSourceDevice(); log("sourceInfo removal " + removedDevice); int prevSourceId = oldRecvState.getSourceId(); if (!Flags.leaudioBroadcastExtractPeriodicScannerFromStateMachine()) { cancelActiveSync( mService.getSyncHandleForBroadcastId(recvState.getBroadcastId())); } setCurrentBroadcastMetadata(oldRecvState.getSourceId(), null); BluetoothLeBroadcastMetadata metaData = getCurrentBroadcastMetadata(prevSourceId); if (metaData != null) { logBroadcastSyncStatsWithStatus( metaData.getBroadcastId(), BluetoothStatsLog .BROADCAST_AUDIO_SYNC_REPORTED__SYNC_STATUS__SYNC_STATUS_UNKNOWN); } setCurrentBroadcastMetadata(prevSourceId, null); if (mPendingSourceToSwitch != null) { // Source remove is triggered by switch source request mService.getCallbacks() .notifySourceRemoved( mDevice, oldRecvState.getSourceId(), prevSourceId, BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST); log("Switching to new source"); Message message = obtainMessage(ADD_BCAST_SOURCE); Loading @@ -1010,7 +1204,7 @@ public class BassClientStateMachine extends StateMachine { mService.getCallbacks() .notifySourceRemoved( mDevice, oldRecvState.getSourceId(), prevSourceId, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); } } else { Loading @@ -1027,6 +1221,7 @@ public class BassClientStateMachine extends StateMachine { BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); checkAndUpdateBroadcastCode(recvState); processPASyncState(recvState); processSyncStateChangeStats(recvState); if (isPendingRemove(recvState.getSourceId())) { Message message = obtainMessage(REMOVE_BCAST_SOURCE); Loading Loading @@ -1435,6 +1630,7 @@ public class BassClientStateMachine extends StateMachine { + mDevice + "): " + messageWhatToString(getCurrentMessage().what)); logAllBroadcastSyncStatsAndCleanup(); clearCharsCache(); mNextSourceId = 0; removeDeferredMessages(DISCONNECT); Loading Loading @@ -1993,6 +2189,14 @@ public class BassClientStateMachine extends StateMachine { break; } if (mBluetoothGatt != null && mBroadcastScanControlPoint != null) { mBroadcastSyncStats.put( metaData.getBroadcastId(), new LeAudioBroadcastSyncStats( mDevice, metaData, mService.isLocalBroadcast(metaData), SystemClock.elapsedRealtime())); writeBassControlPoint(addSourceInfo); mPendingOperation = message.what; mPendingMetadata = metaData; Loading
android/app/src/com/android/bluetooth/btservice/MetricsLogger.java +50 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.util.proto.ProtoOutputStream; import androidx.annotation.RequiresApi; import com.android.bluetooth.bass_client.BassConstants; import com.android.bluetooth.BluetoothMetricsProto.BluetoothLog; import com.android.bluetooth.BluetoothMetricsProto.BluetoothRemoteDeviceInformation; import com.android.bluetooth.BluetoothMetricsProto.ProfileConnectionStats; Loading Loading @@ -583,4 +584,53 @@ public class MetricsLogger { } return digest.digest(name.getBytes(StandardCharsets.UTF_8)); } /** Logs LE Audio Broadcast audio session. */ public void logLeAudioBroadcastAudioSession( int broadcastId, int[] audioQuality, int groupSize, long sessionDurationMs, long latencySessionConfiguredMs, long latencySessionStreamingMs, int sessionStatus) { if (!mInitialized) { return; } BluetoothStatsLog.write( BluetoothStatsLog.BROADCAST_AUDIO_SESSION_REPORTED, broadcastId, audioQuality.length, audioQuality, groupSize, sessionDurationMs, latencySessionConfiguredMs, latencySessionStreamingMs, sessionStatus); } /** Logs LE Audio Broadcast audio sync. */ public void logLeAudioBroadcastAudioSync( BluetoothDevice device, int broadcastId, boolean isLocalBroadcast, long syncDurationMs, long latencyPaSyncMs, long latencyBisSyncMs, int syncStatus) { if (!mInitialized) { return; } BluetoothStatsLog.write( BluetoothStatsLog.BROADCAST_AUDIO_SYNC_REPORTED, isLocalBroadcast ? broadcastId : BassConstants.INVALID_BROADCAST_ID, isLocalBroadcast, syncDurationMs, latencyPaSyncMs, latencyBisSyncMs, syncStatus, getRemoteDeviceInfoProto(device)); } }