Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a9ee5cb authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12337246 from 82fe1c5c to 24Q4-release

Change-Id: I523b40474dff0ccff937103375af81f2bd5395b1
parents d909b724 82fe1c5c
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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",
+207 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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 =
@@ -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,
@@ -259,6 +353,7 @@ public class BassClientStateMachine extends StateMachine {
        mPendingRemove.clear();
        mPeriodicAdvCallbacksMap.clear();
        mSourceSyncRequestsQueue.clear();
        mBroadcastSyncStats.clear();
    }

    Boolean hasPendingSourceOperation() {
@@ -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
@@ -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);
@@ -1010,7 +1204,7 @@ public class BassClientStateMachine extends StateMachine {
                        mService.getCallbacks()
                                .notifySourceRemoved(
                                        mDevice,
                                        oldRecvState.getSourceId(),
                                        prevSourceId,
                                        BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
                    }
                } else {
@@ -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);
@@ -1435,6 +1630,7 @@ public class BassClientStateMachine extends StateMachine {
                            + mDevice
                            + "): "
                            + messageWhatToString(getCurrentMessage().what));
            logAllBroadcastSyncStatsAndCleanup();
            clearCharsCache();
            mNextSourceId = 0;
            removeDeferredMessages(DISCONNECT);
@@ -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;
+50 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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));
    }
}
+188 −0

File changed.

Preview size limit exceeded, changes collapsed.

+4 −4
Original line number Diff line number Diff line
@@ -9,10 +9,10 @@ java_defaults {
    min_sdk_version: "Tiramisu",
    target_sdk_version: "current",
    libs: [
        "android.test.base",
        "android.test.mock",
        "android.test.runner",
        "javax.obex",
        "android.test.base.stubs",
        "android.test.mock.stubs",
        "android.test.runner.stubs",
        "javax.obex.stubs",
        "libprotobuf-java-micro",
        "telephony-common",
    ],
Loading