| /* |
| * Copyright (C) 2021 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.android.server.uwb; |
| |
| import android.util.SparseArray; |
| |
| import com.android.server.uwb.UwbSessionManager.UwbSession; |
| import com.android.server.uwb.data.UwbRangingData; |
| import com.android.server.uwb.data.UwbTwoWayMeasurement; |
| import com.android.server.uwb.data.UwbUciConstants; |
| import com.android.server.uwb.proto.UwbStatsLog; |
| |
| import com.google.uwb.support.base.Params; |
| import com.google.uwb.support.ccc.CccOpenRangingParams; |
| import com.google.uwb.support.fira.FiraOpenSessionParams; |
| import com.google.uwb.support.fira.FiraParams; |
| |
| import java.io.FileDescriptor; |
| import java.io.PrintWriter; |
| import java.util.ArrayDeque; |
| import java.util.Calendar; |
| import java.util.Deque; |
| |
| /** |
| * A class to collect and report UWB metrics. |
| */ |
| public class UwbMetrics { |
| private static final String TAG = "UwbMetrics"; |
| |
| private static final int MAX_RANGING_SESSIONS = 128; |
| private static final int MAX_RANGING_REPORTS = 1024; |
| public static final int INVALID_DISTANCE = 0xFFFF; |
| private static final int ONE_SECOND_IN_MS = 1000; |
| private static final int TEN_SECOND_IN_MS = 10 * 1000; |
| private static final int ONE_MIN_IN_MS = 60 * 1000; |
| private static final int TEN_MIN_IN_MS = 600 * 1000; |
| private static final int ONE_HOUR_IN_MS = 3600 * 1000; |
| private final UwbInjector mUwbInjector; |
| private final Deque<RangingSessionStats> mRangingSessionList = new ArrayDeque<>(); |
| private final SparseArray<RangingSessionStats> mOpenedSessionMap = new SparseArray<>(); |
| private final Deque<RangingReportEvent> mRangingReportList = new ArrayDeque<>(); |
| private int mNumApps = 0; |
| private long mLastRangingDataLogTimeMs; |
| private final Object mLock = new Object(); |
| |
| /** |
| * The class storing the stats of a ranging session. |
| */ |
| public class RangingSessionStats { |
| private int mSessionId; |
| private int mChannel = 9; |
| private long mStartTimeWallClockMs; |
| private long mStartTimeSinceBootMs; |
| private int mInitLatencyMs; |
| private int mInitStatus; |
| private int mRangingStatus; |
| private int mActiveDuration; |
| private int mRangingCount; |
| private int mValidRangingCount; |
| private boolean mHasValidRangingSinceStart; |
| private int mStartCount; |
| private int mStartFailureCount; |
| private int mStartNoValidReportCount; |
| private int mStsType = UwbStatsLog.UWB_SESSION_INITIATED__STS__UNKNOWN_STS; |
| private boolean mIsInitiator; |
| private boolean mIsController; |
| private boolean mIsDiscoveredByFramework = false; |
| private boolean mIsOutOfBand = true; |
| |
| RangingSessionStats(int sessionId) { |
| mSessionId = sessionId; |
| mStartTimeWallClockMs = mUwbInjector.getWallClockMillis(); |
| } |
| |
| /** |
| * Parse UWB profile parameters |
| */ |
| public void parseParams(Params params) { |
| if (params instanceof FiraOpenSessionParams) { |
| parseFiraParams((FiraOpenSessionParams) params); |
| } else if (params instanceof CccOpenRangingParams) { |
| parseCccParams((CccOpenRangingParams) params); |
| } |
| } |
| |
| private void parseFiraParams(FiraOpenSessionParams params) { |
| if (params.getStsConfig() == FiraParams.STS_CONFIG_STATIC) { |
| mStsType = UwbStatsLog.UWB_SESSION_INITIATED__STS__STATIC; |
| } else if (params.getStsConfig() == FiraParams.STS_CONFIG_DYNAMIC) { |
| mStsType = UwbStatsLog.UWB_SESSION_INITIATED__STS__DYNAMIC; |
| } else { |
| mStsType = UwbStatsLog.UWB_SESSION_INITIATED__STS__PROVISIONED; |
| } |
| |
| mIsInitiator = params.getDeviceRole() == FiraParams.RANGING_DEVICE_ROLE_INITIATOR; |
| mIsController = params.getDeviceType() == FiraParams.RANGING_DEVICE_TYPE_CONTROLLER; |
| mChannel = params.getChannelNumber(); |
| } |
| |
| private void parseCccParams(CccOpenRangingParams params) { |
| mChannel = params.getChannel(); |
| } |
| |
| private void convertInitStatus(int status) { |
| mInitStatus = UwbStatsLog.UWB_SESSION_INITIATED__STATUS__GENERAL_FAILURE; |
| switch (status) { |
| case UwbUciConstants.STATUS_CODE_OK: |
| mInitStatus = UwbStatsLog.UWB_SESSION_INITIATED__STATUS__SUCCESS; |
| break; |
| case UwbUciConstants.STATUS_CODE_ERROR_MAX_SESSIONS_EXCEEDED: |
| mInitStatus = UwbStatsLog.UWB_SESSION_INITIATED__STATUS__SESSION_EXCEEDED; |
| break; |
| case UwbUciConstants.STATUS_CODE_ERROR_SESSION_DUPLICATE: |
| mInitStatus = UwbStatsLog.UWB_SESSION_INITIATED__STATUS__SESSION_DUPLICATE; |
| break; |
| case UwbUciConstants.STATUS_CODE_INVALID_PARAM: |
| case UwbUciConstants.STATUS_CODE_INVALID_RANGE: |
| case UwbUciConstants.STATUS_CODE_INVALID_MESSAGE_SIZE: |
| mInitStatus = UwbStatsLog.UWB_SESSION_INITIATED__STATUS__BAD_PARAMS; |
| break; |
| } |
| } |
| |
| private void convertRangingStatus(int status) { |
| mRangingStatus = UwbStatsLog.UWB_START_RANGING__STATUS__RANGING_GENERAL_FAILURE; |
| switch (status) { |
| case UwbUciConstants.STATUS_CODE_OK: |
| case UwbUciConstants.STATUS_CODE_OK_NEGATIVE_DISTANCE_REPORT: |
| mRangingStatus = UwbStatsLog.UWB_START_RANGING__STATUS__RANGING_SUCCESS; |
| break; |
| case UwbUciConstants.STATUS_CODE_RANGING_TX_FAILED: |
| mRangingStatus = UwbStatsLog.UWB_START_RANGING__STATUS__TX_FAILED; |
| break; |
| case UwbUciConstants.STATUS_CODE_RANGING_RX_PHY_DEC_FAILED: |
| mRangingStatus = UwbStatsLog.UWB_START_RANGING__STATUS__RX_PHY_DEC_FAILED; |
| break; |
| case UwbUciConstants.STATUS_CODE_RANGING_RX_PHY_TOA_FAILED: |
| mRangingStatus = UwbStatsLog.UWB_START_RANGING__STATUS__RX_PHY_TOA_FAILED; |
| break; |
| case UwbUciConstants.STATUS_CODE_RANGING_RX_PHY_STS_FAILED: |
| mRangingStatus = UwbStatsLog.UWB_START_RANGING__STATUS__RX_PHY_STS_FAILED; |
| break; |
| case UwbUciConstants.STATUS_CODE_RANGING_RX_MAC_DEC_FAILED: |
| mRangingStatus = UwbStatsLog.UWB_START_RANGING__STATUS__RX_MAC_DEC_FAILED; |
| break; |
| case UwbUciConstants.STATUS_CODE_RANGING_RX_MAC_IE_DEC_FAILED: |
| mRangingStatus = UwbStatsLog.UWB_START_RANGING__STATUS__RX_MAC_IE_DEC_FAILED; |
| break; |
| case UwbUciConstants.STATUS_CODE_RANGING_RX_MAC_IE_MISSING: |
| mRangingStatus = UwbStatsLog.UWB_START_RANGING__STATUS__RX_MAC_IE_MISSING; |
| break; |
| case UwbUciConstants.STATUS_CODE_INVALID_PARAM: |
| case UwbUciConstants.STATUS_CODE_INVALID_RANGE: |
| case UwbUciConstants.STATUS_CODE_INVALID_MESSAGE_SIZE: |
| mRangingStatus = UwbStatsLog.UWB_START_RANGING__STATUS__RANGING_BAD_PARAMS; |
| break; |
| } |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| sb.append("rangingStartTime="); |
| Calendar c = Calendar.getInstance(); |
| synchronized (mLock) { |
| c.setTimeInMillis(mStartTimeWallClockMs); |
| sb.append(mStartTimeWallClockMs == 0 ? " <null>" : |
| String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); |
| sb.append(", sessionId=").append(mSessionId); |
| sb.append(", initLatencyMs=").append(mInitLatencyMs); |
| sb.append(", activeDurationMs=").append(mActiveDuration); |
| sb.append(", rangingCount=").append(mRangingCount); |
| sb.append(", validRangingCount=").append(mValidRangingCount); |
| sb.append(", startCount").append(mStartCount); |
| sb.append(", startFailureCount").append(mStartFailureCount); |
| sb.append(", startNoValidReportCount").append(mStartNoValidReportCount); |
| sb.append(", initStatus=").append(mInitStatus); |
| sb.append(", channel=").append(mChannel); |
| sb.append(", initiator=").append(mIsInitiator); |
| sb.append(", controller=").append(mIsController); |
| sb.append(", discoveredByFramework=").append(mIsDiscoveredByFramework); |
| return sb.toString(); |
| } |
| } |
| } |
| |
| private class RangingReportEvent { |
| private int mSessionId; |
| private int mNlos; |
| private int mDistanceCm; |
| private int mAzimuthDegree; |
| private int mAzimuthFom; |
| private int mElevationDegree; |
| private int mElevationFom; |
| private int mRssiDbm; |
| private long mWallClockMillis; |
| |
| RangingReportEvent(int sessionId, int nlos, int distanceCm, |
| int azimuthDegree, int azimuthFom, |
| int elevationDegree, int elevationFom, int rssiDbm) { |
| mSessionId = sessionId; |
| mWallClockMillis = mUwbInjector.getWallClockMillis(); |
| mNlos = nlos; |
| mDistanceCm = distanceCm; |
| mAzimuthDegree = azimuthDegree; |
| mAzimuthFom = azimuthFom; |
| mElevationDegree = elevationDegree; |
| mElevationFom = elevationFom; |
| mRssiDbm = rssiDbm; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| sb.append("time="); |
| Calendar c = Calendar.getInstance(); |
| synchronized (mLock) { |
| c.setTimeInMillis(mWallClockMillis); |
| sb.append(mWallClockMillis == 0 ? " <null>" : |
| String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); |
| sb.append(", sessionId=").append(mSessionId); |
| sb.append(", Nlos=").append(mNlos); |
| sb.append(", DistanceCm=").append(mDistanceCm); |
| sb.append(", AzimuthDegree=").append(mAzimuthDegree); |
| sb.append(", AzimuthFom=").append(mAzimuthFom); |
| sb.append(", ElevationDegree=").append(mElevationDegree); |
| sb.append(", ElevationFom=").append(mElevationFom); |
| sb.append(", RssiDbm=").append(mRssiDbm); |
| return sb.toString(); |
| } |
| } |
| } |
| |
| public UwbMetrics(UwbInjector uwbInjector) { |
| mUwbInjector = uwbInjector; |
| } |
| |
| /** |
| * Log the ranging session initialization event |
| */ |
| public void logRangingInitEvent(UwbSession uwbSession, int status) { |
| synchronized (mLock) { |
| // If past maximum events, start removing the oldest |
| while (mRangingSessionList.size() >= MAX_RANGING_SESSIONS) { |
| mRangingSessionList.removeFirst(); |
| } |
| RangingSessionStats session = new RangingSessionStats(uwbSession.getSessionId()); |
| session.parseParams(uwbSession.getParams()); |
| session.convertInitStatus(status); |
| mRangingSessionList.add(session); |
| mOpenedSessionMap.put(uwbSession.getSessionId(), session); |
| UwbStatsLog.write(UwbStatsLog.UWB_SESSION_INITED, uwbSession.getProfileType(), |
| session.mStsType, session.mIsInitiator, |
| session.mIsController, session.mIsDiscoveredByFramework, session.mIsOutOfBand, |
| session.mChannel, session.mInitStatus, |
| session.mInitLatencyMs, session.mInitLatencyMs / 20); |
| } |
| } |
| |
| /** |
| * Log the ranging session start event |
| */ |
| public void longRangingStartEvent(UwbSession uwbSession, int status) { |
| synchronized (mLock) { |
| RangingSessionStats session = mOpenedSessionMap.get(uwbSession.getSessionId()); |
| if (session == null) { |
| return; |
| } |
| session.mStartCount++; |
| session.convertRangingStatus(status); |
| UwbStatsLog.write(UwbStatsLog.UWB_RANGING_START, uwbSession.getProfileType(), |
| session.mStsType, session.mIsInitiator, |
| session.mIsController, session.mIsDiscoveredByFramework, session.mIsOutOfBand, |
| session.mRangingStatus); |
| if (status != UwbUciConstants.STATUS_CODE_OK) { |
| session.mStartFailureCount++; |
| session.mStartTimeSinceBootMs = 0; |
| session.mHasValidRangingSinceStart = false; |
| return; |
| } |
| session.mStartTimeSinceBootMs = mUwbInjector.getElapsedSinceBootMillis(); |
| } |
| } |
| |
| /** |
| * Log the ranging session stop event |
| */ |
| public void longRangingStopEvent(UwbSession uwbSession) { |
| synchronized (mLock) { |
| RangingSessionStats session = mOpenedSessionMap.get(uwbSession.getSessionId()); |
| if (session == null) { |
| return; |
| } |
| if (session.mStartTimeSinceBootMs == 0) { |
| return; |
| } |
| if (!session.mHasValidRangingSinceStart) { |
| session.mStartNoValidReportCount++; |
| } |
| session.mHasValidRangingSinceStart = false; |
| session.mActiveDuration += (int) (mUwbInjector.getElapsedSinceBootMillis() |
| - session.mStartTimeSinceBootMs); |
| session.mStartTimeSinceBootMs = 0; |
| } |
| } |
| |
| /** |
| * Log the ranging session close event |
| */ |
| public void logRangingCloseEvent(UwbSession uwbSession, int status) { |
| synchronized (mLock) { |
| RangingSessionStats session = mOpenedSessionMap.get(uwbSession.getSessionId()); |
| if (session == null) { |
| return; |
| } |
| if (status != UwbUciConstants.STATUS_CODE_OK) { |
| return; |
| } |
| // Ranging may close without stop event |
| if (session.mStartTimeSinceBootMs != 0) { |
| session.mActiveDuration += (int) (mUwbInjector.getElapsedSinceBootMillis() |
| - session.mStartTimeSinceBootMs); |
| if (!session.mHasValidRangingSinceStart) { |
| session.mStartNoValidReportCount++; |
| } |
| session.mStartTimeSinceBootMs = 0; |
| session.mHasValidRangingSinceStart = false; |
| } |
| |
| UwbStatsLog.write(UwbStatsLog.UWB_SESSION_CLOSED, uwbSession.getProfileType(), |
| session.mStsType, session.mIsInitiator, |
| session.mIsController, session.mIsDiscoveredByFramework, session.mIsOutOfBand, |
| session.mActiveDuration, getDurationBucket(session.mActiveDuration), |
| session.mRangingCount, session.mValidRangingCount, |
| getCountBucket(session.mRangingCount), |
| getCountBucket(session.mValidRangingCount), |
| session.mStartCount, |
| session.mStartFailureCount, |
| session.mStartNoValidReportCount); |
| mOpenedSessionMap.delete(uwbSession.getSessionId()); |
| } |
| } |
| |
| private int getDurationBucket(int durationMs) { |
| if (durationMs <= ONE_SECOND_IN_MS) { |
| return UwbStatsLog.UWB_SESSION_CLOSED__DURATION_BUCKET__WITHIN_ONE_SEC; |
| } else if (durationMs <= TEN_SECOND_IN_MS) { |
| return UwbStatsLog.UWB_SESSION_CLOSED__DURATION_BUCKET__ONE_TO_TEN_SEC; |
| } else if (durationMs <= ONE_MIN_IN_MS) { |
| return UwbStatsLog.UWB_SESSION_CLOSED__DURATION_BUCKET__TEN_SEC_TO_ONE_MIN; |
| } else if (durationMs <= TEN_MIN_IN_MS) { |
| return UwbStatsLog.UWB_SESSION_CLOSED__DURATION_BUCKET__ONE_TO_TEN_MIN; |
| } else if (durationMs <= ONE_HOUR_IN_MS) { |
| return UwbStatsLog.UWB_SESSION_CLOSED__DURATION_BUCKET__TEN_MIN_TO_ONE_HOUR; |
| } else { |
| return UwbStatsLog.UWB_SESSION_CLOSED__DURATION_BUCKET__MORE_THAN_ONE_HOUR; |
| } |
| } |
| |
| private int getCountBucket(int count) { |
| if (count <= 0) { |
| return UwbStatsLog.UWB_SESSION_CLOSED__RANGING_COUNT_BUCKET__ZERO; |
| } else if (count <= 5) { |
| return UwbStatsLog.UWB_SESSION_CLOSED__RANGING_COUNT_BUCKET__ONE_TO_FIVE; |
| } else if (count <= 20) { |
| return UwbStatsLog.UWB_SESSION_CLOSED__RANGING_COUNT_BUCKET__FIVE_TO_TWENTY; |
| } else if (count <= 100) { |
| return UwbStatsLog.UWB_SESSION_CLOSED__RANGING_COUNT_BUCKET__TWENTY_TO_ONE_HUNDRED; |
| } else if (count <= 500) { |
| return UwbStatsLog |
| .UWB_SESSION_CLOSED__RANGING_COUNT_BUCKET__ONE_HUNDRED_TO_FIVE_HUNDRED; |
| } else { |
| return UwbStatsLog.UWB_SESSION_CLOSED__RANGING_COUNT_BUCKET__MORE_THAN_FIVE_HUNDRED; |
| } |
| } |
| |
| /** |
| * Log the usage of API from a new App |
| */ |
| public void logNewAppUsage() { |
| synchronized (mLock) { |
| mNumApps++; |
| } |
| } |
| |
| /** |
| * Log the ranging measurement result |
| */ |
| public void logRangingResult(int profileType, UwbRangingData rangingData) { |
| synchronized (mLock) { |
| if (rangingData.getRangingMeasuresType() |
| != UwbUciConstants.RANGING_MEASUREMENT_TYPE_TWO_WAY |
| || rangingData.getNoOfRangingMeasures() < 1) { |
| return; |
| } |
| |
| UwbTwoWayMeasurement[] uwbTwoWayMeasurement = rangingData.getRangingTwoWayMeasures(); |
| UwbTwoWayMeasurement measurement = uwbTwoWayMeasurement[0]; |
| |
| int sessionId = (int) rangingData.getSessionId(); |
| RangingSessionStats session = mOpenedSessionMap.get(sessionId); |
| if (session != null) { |
| session.mRangingCount++; |
| } |
| |
| if (!measurement.isStatusCodeOk()) { |
| return; |
| } |
| |
| if (session != null) { |
| session.mValidRangingCount++; |
| if (!session.mHasValidRangingSinceStart) { |
| session.mHasValidRangingSinceStart = true; |
| writeFirstValidRangingResultSinceStart(profileType, session); |
| } |
| } |
| int distanceCm = measurement.getDistance(); |
| int azimuthDegree = (int) measurement.getAoaAzimuth(); |
| int azimuthFom = measurement.getAoaAzimuthFom(); |
| int elevationDegree = (int) measurement.getAoaElevation(); |
| int elevationFom = measurement.getAoaElevationFom(); |
| int nlos = getNlos(measurement); |
| int rssiDbm = measurement.getRssi(); |
| |
| while (mRangingReportList.size() >= MAX_RANGING_REPORTS) { |
| mRangingReportList.removeFirst(); |
| } |
| RangingReportEvent report = new RangingReportEvent(sessionId, nlos, distanceCm, |
| azimuthDegree, azimuthFom, elevationDegree, elevationFom, rssiDbm); |
| mRangingReportList.add(report); |
| |
| long currTimeMs = mUwbInjector.getElapsedSinceBootMillis(); |
| if ((currTimeMs - mLastRangingDataLogTimeMs) < mUwbInjector.getDeviceConfigFacade() |
| .getRangingResultLogIntervalMs()) { |
| return; |
| } |
| mLastRangingDataLogTimeMs = currTimeMs; |
| |
| boolean isDistanceValid = distanceCm != INVALID_DISTANCE; |
| boolean isAzimuthValid = azimuthFom > 0; |
| boolean isElevationValid = elevationFom > 0; |
| int distance50Cm = isDistanceValid ? distanceCm / 50 : 0; |
| int azimuth10Degree = isAzimuthValid ? azimuthDegree / 10 : 0; |
| int elevation10Degree = isElevationValid ? elevationDegree / 10 : 0; |
| UwbStatsLog.write(UwbStatsLog.UWB_RANGING_MEASUREMENT_RECEIVED, profileType, nlos, |
| isDistanceValid, distanceCm, distance50Cm, rssiDbm, |
| isAzimuthValid, azimuthDegree, azimuth10Degree, azimuthFom, |
| isElevationValid, elevationDegree, elevation10Degree, elevationFom); |
| } |
| } |
| |
| private void writeFirstValidRangingResultSinceStart(int profileType, |
| RangingSessionStats session) { |
| int latencyMs = (int) (mUwbInjector.getElapsedSinceBootMillis() |
| - session.mStartTimeSinceBootMs); |
| UwbStatsLog.write(UwbStatsLog.UWB_FIRST_RANGING_RECEIVED, |
| profileType, latencyMs, latencyMs / 200); |
| } |
| |
| private int getNlos(UwbTwoWayMeasurement measurement) { |
| int nlos = measurement.getNLoS(); |
| if (nlos == 0) { |
| return UwbStatsLog.UWB_RANGING_MEASUREMENT_RECEIVED__NLOS__LOS; |
| } else if (nlos == 1) { |
| return UwbStatsLog.UWB_RANGING_MEASUREMENT_RECEIVED__NLOS__NLOS; |
| } else { |
| return UwbStatsLog.UWB_RANGING_MEASUREMENT_RECEIVED__NLOS__NLOS_UNKNOWN; |
| } |
| } |
| |
| private int mNumDeviceInitSuccess = 0; |
| private int mNumDeviceInitFailure = 0; |
| private int mNumDeviceStatusError = 0; |
| private int mNumUciGenericError = 0; |
| |
| /** |
| * Increment the count of device initialization success |
| */ |
| public synchronized void incrementDeviceInitSuccessCount() { |
| mNumDeviceInitSuccess++; |
| } |
| |
| /** |
| * Increment the count of device initialization failure |
| */ |
| public synchronized void incrementDeviceInitFailureCount() { |
| mNumDeviceInitFailure++; |
| UwbStatsLog.write(UwbStatsLog.UWB_DEVICE_ERROR_REPORTED, |
| UwbStatsLog.UWB_DEVICE_ERROR_REPORTED__TYPE__INIT_ERROR); |
| } |
| |
| /** |
| * Increment the count of device status error |
| */ |
| public synchronized void incrementDeviceStatusErrorCount() { |
| mNumDeviceStatusError++; |
| UwbStatsLog.write(UwbStatsLog.UWB_DEVICE_ERROR_REPORTED, |
| UwbStatsLog.UWB_DEVICE_ERROR_REPORTED__TYPE__DEVICE_STATUS_ERROR); |
| } |
| |
| /** |
| * Increment the count of UCI generic error which will trigger UCI command retry |
| */ |
| public synchronized void incrementUciGenericErrorCount() { |
| mNumUciGenericError++; |
| UwbStatsLog.write(UwbStatsLog.UWB_DEVICE_ERROR_REPORTED, |
| UwbStatsLog.UWB_DEVICE_ERROR_REPORTED__TYPE__UCI_GENERIC_ERROR); |
| } |
| |
| /** |
| * Dump the UWB logs |
| */ |
| public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { |
| synchronized (mLock) { |
| pw.println("---- Dump of UwbMetrics ----"); |
| pw.println("---- mRangingSessionList ----"); |
| for (RangingSessionStats stats: mRangingSessionList) { |
| pw.println(stats.toString()); |
| } |
| pw.println("---- mOpenedSessionMap ----"); |
| for (int i = 0; i < mOpenedSessionMap.size(); i++) { |
| pw.println(mOpenedSessionMap.valueAt(i).toString()); |
| } |
| pw.println("---- mRangingReportList ----"); |
| for (RangingReportEvent event: mRangingReportList) { |
| pw.println(event.toString()); |
| } |
| pw.println("mNumApps=" + mNumApps); |
| pw.println("---- Device operation success/error count ----"); |
| pw.println("mNumDeviceInitSuccess = " + mNumDeviceInitSuccess); |
| pw.println("mNumDeviceInitFailure = " + mNumDeviceInitFailure); |
| pw.println("mNumDeviceStatusError = " + mNumDeviceStatusError); |
| pw.println("mNumUciGenericError = " + mNumUciGenericError); |
| } |
| } |
| } |