• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.bluetooth.cts;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assert.assertThrows;
22 
23 import android.bluetooth.BluetoothClass;
24 import android.bluetooth.BluetoothQualityReport;
25 import android.bluetooth.BluetoothQualityReport.BqrCommon;
26 import android.bluetooth.BluetoothQualityReport.BqrConnectFail;
27 import android.bluetooth.BluetoothQualityReport.BqrEnergyMonitor;
28 import android.bluetooth.BluetoothQualityReport.BqrRfStats;
29 import android.bluetooth.BluetoothQualityReport.BqrVsA2dpChoppy;
30 import android.bluetooth.BluetoothQualityReport.BqrVsLsto;
31 import android.bluetooth.BluetoothQualityReport.BqrVsScoChoppy;
32 import android.os.Parcel;
33 import android.platform.test.annotations.RequiresFlagsEnabled;
34 import android.platform.test.flag.junit.CheckFlagsRule;
35 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
36 import android.util.Log;
37 
38 import androidx.test.ext.junit.runners.AndroidJUnit4;
39 
40 import com.android.bluetooth.flags.Flags;
41 
42 import com.google.common.truth.Expect;
43 
44 import org.junit.Rule;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 
48 import java.nio.ByteBuffer;
49 import java.nio.ByteOrder;
50 
51 @RunWith(AndroidJUnit4.class)
52 public final class BluetoothQualityReportTest {
53     private static final String TAG = BluetoothQualityReportTest.class.getSimpleName();
54 
55     @Rule public final Expect expect = Expect.create();
56 
57     @Rule
58     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
59 
60     private static String mRemoteAddress = "01:02:03:04:05:06";
61     private static String mDefaultAddress = "00:00:00:00:00:00";
62     private static String mRemoteName = "DeviceName";
63     private static String mDefaultName = "";
64     private static int mLmpVer = 0;
65     private static int mLmpSubVer = 1;
66     private static int mManufacturerId = 3;
67     private static int mRemoteCoD = 4;
68 
assertBqrCommon(BQRParameters bqrp, BluetoothQualityReport bqr)69     private void assertBqrCommon(BQRParameters bqrp, BluetoothQualityReport bqr) {
70         // BQR Common
71         BqrCommon bqrCommon = bqr.getBqrCommon();
72         assertThat(bqrCommon).isNotNull();
73         assertThat(bqr.getQualityReportId()).isEqualTo(bqrp.getQualityReportId());
74         if ((bqr.getQualityReportId() == BluetoothQualityReport.QUALITY_REPORT_ID_ENERGY_MONITOR)
75                 || (bqr.getQualityReportId()
76                         == BluetoothQualityReport.QUALITY_REPORT_ID_RF_STATS)) {
77             return;
78         }
79         assertThat(bqrCommon.getPacketType()).isEqualTo(bqrp.mPacketType);
80         assertThat(BqrCommon.packetTypeToString(bqrCommon.getPacketType())).isEqualTo("TYPE_NULL");
81         assertThat(bqrCommon.getConnectionHandle()).isEqualTo(bqrp.mConnectionHandle);
82         assertThat(BqrCommon.connectionRoleToString(bqrCommon.getConnectionRole()))
83                 .isEqualTo(bqrp.mConnectionRoleCentral);
84         assertThat(bqrCommon.getConnectionRole()).isEqualTo(bqrp.mConnectionRole);
85         assertThat(bqrCommon.getTxPowerLevel()).isEqualTo(bqrp.mTxPowerLevel);
86         assertThat(bqrCommon.getRssi()).isEqualTo(bqrp.mRssi);
87         assertThat(bqrCommon.getSnr()).isEqualTo(bqrp.mSnr);
88         assertThat(bqrCommon.getUnusedAfhChannelCount()).isEqualTo(bqrp.mUnusedAfhChannelCount);
89         assertThat(bqrCommon.getAfhSelectUnidealChannelCount())
90                 .isEqualTo(bqrp.mAfhSelectUnidealChannelCount);
91         assertThat(bqrCommon.getLsto()).isEqualTo(bqrp.mLsto);
92         assertThat(bqrCommon.getPiconetClock()).isEqualTo(bqrp.mPiconetClock);
93         assertThat(bqrCommon.getRetransmissionCount()).isEqualTo(bqrp.mRetransmissionCount);
94         assertThat(bqrCommon.getNoRxCount()).isEqualTo(bqrp.mNoRxCount);
95         assertThat(bqrCommon.getNakCount()).isEqualTo(bqrp.mNakCount);
96         assertThat(bqrCommon.getLastTxAckTimestamp()).isEqualTo(bqrp.mLastTxAckTimestamp);
97         assertThat(bqrCommon.getFlowOffCount()).isEqualTo(bqrp.mFlowOffCount);
98         assertThat(bqrCommon.getLastFlowOnTimestamp()).isEqualTo(bqrp.mLastFlowOnTimestamp);
99         assertThat(bqrCommon.getOverflowCount()).isEqualTo(bqrp.mOverflowCount);
100         assertThat(bqrCommon.getUnderflowCount()).isEqualTo(bqrp.mUnderflowCount);
101         assertThat(bqrCommon.getCalFailedItemCount()).isEqualTo(bqrp.mCalFailedItemCount);
102     }
103 
assertBqrV6Common(BQRParameters bqrp, BluetoothQualityReport bqr)104     private void assertBqrV6Common(BQRParameters bqrp, BluetoothQualityReport bqr) {
105         // BQR Common
106         BqrCommon bqrCommon = bqr.getBqrCommon();
107         expect.that(bqrCommon).isNotNull();
108         expect.that(bqr.getQualityReportId()).isEqualTo(bqrp.getQualityReportId());
109         if ((bqr.getQualityReportId() == BluetoothQualityReport.QUALITY_REPORT_ID_ENERGY_MONITOR)
110                 || (bqr.getQualityReportId()
111                         == BluetoothQualityReport.QUALITY_REPORT_ID_RF_STATS)) {
112             return;
113         }
114         expect.that(bqrCommon.getPacketType()).isEqualTo(bqrp.mPacketType);
115         expect.that(BqrCommon.packetTypeToString(bqrCommon.getPacketType())).isEqualTo("TYPE_NULL");
116         expect.that(bqrCommon.getConnectionHandle()).isEqualTo(bqrp.mConnectionHandle);
117         expect.that(BqrCommon.connectionRoleToString(bqrCommon.getConnectionRole()))
118                 .isEqualTo(bqrp.mConnectionRoleCentral);
119         expect.that(bqrCommon.getConnectionRole()).isEqualTo(bqrp.mConnectionRole);
120         expect.that(bqrCommon.getTxPowerLevel()).isEqualTo(bqrp.mTxPowerLevel);
121         expect.that(bqrCommon.getRssi()).isEqualTo(bqrp.mRssi);
122         expect.that(bqrCommon.getSnr()).isEqualTo(bqrp.mSnr);
123         expect.that(bqrCommon.getUnusedAfhChannelCount()).isEqualTo(bqrp.mUnusedAfhChannelCount);
124         expect.that(bqrCommon.getAfhSelectUnidealChannelCount())
125                 .isEqualTo(bqrp.mAfhSelectUnidealChannelCount);
126         expect.that(bqrCommon.getLsto()).isEqualTo(bqrp.mLsto);
127         expect.that(bqrCommon.getPiconetClock()).isEqualTo(bqrp.mPiconetClock);
128         expect.that(bqrCommon.getRetransmissionCount()).isEqualTo(bqrp.mRetransmissionCount);
129         expect.that(bqrCommon.getNoRxCount()).isEqualTo(bqrp.mNoRxCount);
130         expect.that(bqrCommon.getNakCount()).isEqualTo(bqrp.mNakCount);
131         expect.that(bqrCommon.getLastTxAckTimestamp()).isEqualTo(bqrp.mLastTxAckTimestamp);
132         expect.that(bqrCommon.getFlowOffCount()).isEqualTo(bqrp.mFlowOffCount);
133         expect.that(bqrCommon.getLastFlowOnTimestamp()).isEqualTo(bqrp.mLastFlowOnTimestamp);
134         expect.that(bqrCommon.getOverflowCount()).isEqualTo(bqrp.mOverflowCount);
135         expect.that(bqrCommon.getUnderflowCount()).isEqualTo(bqrp.mUnderflowCount);
136         expect.that(bqrCommon.getCalFailedItemCount()).isEqualTo(bqrp.mCalFailedItemCount);
137 
138         expect.that(bqrCommon.getTxTotalPackets()).isEqualTo(bqrp.mTxTotalPackets);
139         expect.that(bqrCommon.getTxUnackPackets()).isEqualTo(bqrp.mTxUnackPackets);
140         expect.that(bqrCommon.getTxFlushPackets()).isEqualTo(bqrp.mTxFlushPackets);
141         expect.that(bqrCommon.getTxLastSubeventPackets()).isEqualTo(bqrp.mTxLastSubeventPackets);
142         expect.that(bqrCommon.getCrcErrorPackets()).isEqualTo(bqrp.mCrcErrorPackets);
143         expect.that(bqrCommon.getRxDupPackets()).isEqualTo(bqrp.mRxDupPackets);
144         expect.that(bqrCommon.getRxUnRecvPackets()).isEqualTo(bqrp.mRxUnRecvPackets);
145         expect.that(bqrCommon.getCoexInfoMask()).isEqualTo(bqrp.mCoexInfoMask);
146         expect.that(bqrCommon.getCoexInfoMask()).isEqualTo(bqrp.mCoexInfoMask);
147     }
148 
assertBqrApproachLsto(BQRParameters bqrp, BluetoothQualityReport bqr)149     private void assertBqrApproachLsto(BQRParameters bqrp, BluetoothQualityReport bqr) {
150         // BQR VS LSTO
151         BqrVsLsto bqrVsLsto = (BqrVsLsto) bqr.getBqrEvent();
152         assertThat(bqrVsLsto).isNotNull();
153         assertThat(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
154                 .isEqualTo("Approaching LSTO");
155         assertThat(bqrVsLsto.getConnState()).isEqualTo(bqrp.mConnState & 0xFF);
156         assertThat(BqrVsLsto.connStateToString(bqrVsLsto.getConnState()))
157                 .isEqualTo("CONN_UNPARK_ACTIVE");
158         assertThat(bqrVsLsto.getBasebandStats()).isEqualTo(bqrp.mBasebandStats);
159         assertThat(bqrVsLsto.getSlotsUsed()).isEqualTo(bqrp.mSlotsUsed);
160         assertThat(bqrVsLsto.getCxmDenials()).isEqualTo(bqrp.mCxmDenials);
161         assertThat(bqrVsLsto.getTxSkipped()).isEqualTo(bqrp.mTxSkipped);
162         assertThat(bqrVsLsto.getRfLoss()).isEqualTo(bqrp.mRfLoss);
163         assertThat(bqrVsLsto.getNativeClock()).isEqualTo(bqrp.mNativeClock);
164         assertThat(bqrVsLsto.getLastTxAckTimestamp()).isEqualTo(bqrp.mLastTxAckTimestampLsto);
165         assertThat(bqrVsLsto.describeContents()).isEqualTo(0);
166     }
167 
assertBqrA2dpChoppy(BQRParameters bqrp, BluetoothQualityReport bqr)168     private void assertBqrA2dpChoppy(BQRParameters bqrp, BluetoothQualityReport bqr) {
169         // BQR VS A2DP Choppy
170         BqrVsA2dpChoppy bqrVsA2dpChoppy = (BqrVsA2dpChoppy) bqr.getBqrEvent();
171         assertThat(bqrVsA2dpChoppy).isNotNull();
172         assertThat(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
173                 .isEqualTo("A2DP choppy");
174         assertThat(bqrVsA2dpChoppy.getArrivalTime()).isEqualTo(bqrp.mArrivalTime);
175         assertThat(bqrVsA2dpChoppy.getScheduleTime()).isEqualTo(bqrp.mScheduleTime);
176         assertThat(bqrVsA2dpChoppy.getGlitchCount()).isEqualTo(bqrp.mGlitchCountA2dp);
177         assertThat(bqrVsA2dpChoppy.getTxCxmDenials()).isEqualTo(bqrp.mTxCxmDenialsA2dp);
178         assertThat(bqrVsA2dpChoppy.getRxCxmDenials()).isEqualTo(bqrp.mRxCxmDenialsA2dp);
179         assertThat(bqrVsA2dpChoppy.getAclTxQueueLength()).isEqualTo(bqrp.mAclTxQueueLength);
180         assertThat(bqrVsA2dpChoppy.getLinkQuality()).isEqualTo(bqrp.mLinkQuality);
181         assertThat(BqrVsA2dpChoppy.linkQualityToString(bqrVsA2dpChoppy.getLinkQuality()))
182                 .isEqualTo("MEDIUM");
183         assertThat(bqrVsA2dpChoppy.describeContents()).isEqualTo(0);
184     }
185 
assertBqrScoChoppy(BQRParameters bqrp, BluetoothQualityReport bqr)186     private void assertBqrScoChoppy(BQRParameters bqrp, BluetoothQualityReport bqr) {
187         // BQR VS SCO Choppy
188         BqrVsScoChoppy bqrVsScoChoppy = (BqrVsScoChoppy) bqr.getBqrEvent();
189         assertThat(bqrVsScoChoppy).isNotNull();
190         assertThat(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
191                 .isEqualTo("SCO choppy");
192         assertThat(bqrVsScoChoppy.getGlitchCount()).isEqualTo(bqrp.mGlitchCountSco);
193         assertThat(bqrVsScoChoppy.getIntervalEsco()).isEqualTo(bqrp.mIntervalEsco);
194         assertThat(bqrVsScoChoppy.getWindowEsco()).isEqualTo(bqrp.mWindowEsco);
195         assertThat(bqrVsScoChoppy.getAirFormat()).isEqualTo(bqrp.mAirFormat);
196         assertThat(BqrVsScoChoppy.airFormatToString(bqrVsScoChoppy.getAirFormat()))
197                 .isEqualTo("CVSD");
198         assertThat(bqrVsScoChoppy.getInstanceCount()).isEqualTo(bqrp.mInstanceCount);
199         assertThat(bqrVsScoChoppy.getTxCxmDenials()).isEqualTo(bqrp.mTxCxmDenialsSco);
200         assertThat(bqrVsScoChoppy.getRxCxmDenials()).isEqualTo(bqrp.mRxCxmDenialsSco);
201         assertThat(bqrVsScoChoppy.getTxAbortCount()).isEqualTo(bqrp.mTxAbortCount);
202         assertThat(bqrVsScoChoppy.getLateDispatch()).isEqualTo(bqrp.mLateDispatch);
203         assertThat(bqrVsScoChoppy.getMicIntrMiss()).isEqualTo(bqrp.mMicIntrMiss);
204         assertThat(bqrVsScoChoppy.getLpaIntrMiss()).isEqualTo(bqrp.mLpaIntrMiss);
205         assertThat(bqrVsScoChoppy.getSprIntrMiss()).isEqualTo(bqrp.mSprIntrMiss);
206         assertThat(bqrVsScoChoppy.getPlcFillCount()).isEqualTo(bqrp.mPlcFillCount);
207         assertThat(bqrVsScoChoppy.getPlcDiscardCount()).isEqualTo(bqrp.mPlcDiscardCount);
208         assertThat(bqrVsScoChoppy.getMissedInstanceCount()).isEqualTo(bqrp.mMissedInstanceCount);
209         assertThat(bqrVsScoChoppy.getTxRetransmitSlotCount())
210                 .isEqualTo(bqrp.mTxRetransmitSlotCount);
211         assertThat(bqrVsScoChoppy.getRxRetransmitSlotCount())
212                 .isEqualTo(bqrp.mRxRetransmitSlotCount);
213         assertThat(bqrVsScoChoppy.getGoodRxFrameCount()).isEqualTo(bqrp.mGoodRxFrameCount);
214         assertThat(bqrVsScoChoppy.describeContents()).isEqualTo(0);
215     }
216 
assertBqrEnergyMonitor(BQRParameters bqrp, BluetoothQualityReport bqr)217     private void assertBqrEnergyMonitor(BQRParameters bqrp, BluetoothQualityReport bqr) {
218         BqrEnergyMonitor bqrEnergyMonitor = (BqrEnergyMonitor) bqr.getBqrEvent();
219         expect.that(bqrEnergyMonitor).isNotNull();
220         expect.that(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
221                 .isEqualTo("Energy Monitor");
222         expect.that(bqrp.mAvgCurrentConsume)
223                 .isEqualTo(bqrEnergyMonitor.getAverageCurrentConsumptionMicroamps());
224         expect.that(bqrp.mIdleTotalTime).isEqualTo(bqrEnergyMonitor.getIdleStateTotalTimeMillis());
225         expect.that(bqrp.mIdleStateEnterCount).isEqualTo(bqrEnergyMonitor.getIdleStateEnterCount());
226         expect.that(bqrp.mActiveTotalTime)
227                 .isEqualTo(bqrEnergyMonitor.getActiveStateTotalTimeMillis());
228         expect.that(bqrp.mActiveStateEnterCount)
229                 .isEqualTo(bqrEnergyMonitor.getActiveStateEnterCount());
230         expect.that(bqrp.mBredrTxTotalTime).isEqualTo(bqrEnergyMonitor.getBredrTxTotalTimeMillis());
231         expect.that(bqrp.mBredrTxStateEnterCount)
232                 .isEqualTo(bqrEnergyMonitor.getBredrTxStateEnterCount());
233         expect.that(bqrp.mBredrTxAvgPowerLevel)
234                 .isEqualTo(bqrEnergyMonitor.getBredrAverageTxPowerLeveldBm());
235         expect.that(bqrp.mBredrRxTotalTime).isEqualTo(bqrEnergyMonitor.getBredrRxTotalTimeMillis());
236         expect.that(bqrp.mBredrRxStateEnterCount)
237                 .isEqualTo(bqrEnergyMonitor.getBredrRxStateEnterCount());
238         expect.that(bqrp.mLeTxTotalTime).isEqualTo(bqrEnergyMonitor.getLeTsTotalTimeMillis());
239         expect.that(bqrp.mLeTxStateEnterCount).isEqualTo(bqrEnergyMonitor.getLeTxStateEnterCount());
240         expect.that(bqrp.mLeTxAvgPowerLevel)
241                 .isEqualTo(bqrEnergyMonitor.getLeAverageTxPowerLeveldBm());
242         expect.that(bqrp.mLeRxTotalTime).isEqualTo(bqrEnergyMonitor.getLeRxTotalTimeMillis());
243         expect.that(bqrp.mLeRxStateEnterCount).isEqualTo(bqrEnergyMonitor.getLeRxStateEnterCount());
244         expect.that(bqrp.mReportTotalTime)
245                 .isEqualTo(bqrEnergyMonitor.getPowerDataTotalTimeMillis());
246         expect.that(bqrp.mRxActiveOneChainTime)
247                 .isEqualTo(bqrEnergyMonitor.getRxSingleChainActiveDurationMillis());
248         expect.that(bqrp.mRxActiveTwoChainTime)
249                 .isEqualTo(bqrEnergyMonitor.getRxDualChainActiveDurationMillis());
250         expect.that(bqrp.mTxiPaActiveOneChainTime)
251                 .isEqualTo(bqrEnergyMonitor.getTxInternalPaSingleChainActiveDurationMillis());
252         expect.that(bqrp.mTxiPaActiveTwoChainTime)
253                 .isEqualTo(bqrEnergyMonitor.getTxInternalPaDualChainActiveDurationMillis());
254         expect.that(bqrp.mTxePaActiveOneChainTime)
255                 .isEqualTo(bqrEnergyMonitor.getTxExternalPaSingleChainActiveDurationMillis());
256         expect.that(bqrp.mTxePaActiveTwoChainTime)
257                 .isEqualTo(bqrEnergyMonitor.getTxExternalPaDualChainActiveDurationMillis());
258         expect.that(bqrEnergyMonitor.describeContents()).isEqualTo(0);
259     }
260 
assertBqrConnectFail(BQRParameters bqrp, BluetoothQualityReport bqr)261     private void assertBqrConnectFail(BQRParameters bqrp, BluetoothQualityReport bqr) {
262         // BQR VS Connect Fail
263         BqrConnectFail bqrConnectFail = (BqrConnectFail) bqr.getBqrEvent();
264         assertThat(bqrConnectFail).isNotNull();
265         assertThat(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
266                 .isEqualTo("Connect fail");
267         assertThat(bqrConnectFail.getFailReason()).isEqualTo(bqrp.mFailReason);
268         assertThat(bqrConnectFail.describeContents()).isEqualTo(0);
269     }
270 
assertBqrRfStats(BQRParameters bqrp, BluetoothQualityReport bqr)271     private void assertBqrRfStats(BQRParameters bqrp, BluetoothQualityReport bqr) {
272         BqrRfStats bqrRfStats = (BqrRfStats) bqr.getBqrEvent();
273         expect.that(bqrRfStats).isNotNull();
274         expect.that(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
275                 .isEqualTo("RF Stats");
276         expect.that(bqrp.mExtensionInfo).isEqualTo(bqrRfStats.getExtensionInfo());
277         expect.that(bqrp.mReportTimePeriod).isEqualTo(bqrRfStats.getPerformanceDurationMillis());
278         expect.that(bqrp.mTxPoweriPaBf)
279                 .isEqualTo(bqrRfStats.getTxPowerInternalPaBeamformingCount());
280         expect.that(bqrp.mTxPowerePaBf)
281                 .isEqualTo(bqrRfStats.getTxPowerExternalPaBeamformingCount());
282         expect.that(bqrp.mTxPoweriPaDiv).isEqualTo(bqrRfStats.getTxPowerInternalPaDiversityCount());
283         expect.that(bqrp.mTxPowerePaDiv).isEqualTo(bqrRfStats.getTxPowerExternalPaDiversityCount());
284         expect.that(bqrp.mRssiChainOver50)
285                 .isEqualTo(bqrRfStats.getPacketsWithRssiAboveMinus50dBm());
286         expect.that(bqrp.mRssiChain50To55).isEqualTo(bqrRfStats.getPacketsWithRssi50To55dBm());
287         expect.that(bqrp.mRssiChain55To60).isEqualTo(bqrRfStats.getPacketsWithRssi55To60dBm());
288         expect.that(bqrp.mRssiChain60To65).isEqualTo(bqrRfStats.getPacketsWithRssi60To65dBm());
289         expect.that(bqrp.mRssiChain65To70).isEqualTo(bqrRfStats.getPacketsWithRssi65To70dBm());
290         expect.that(bqrp.mRssiChain70To75).isEqualTo(bqrRfStats.getPacketsWithRssi70To75dBm());
291         expect.that(bqrp.mRssiChain75To80).isEqualTo(bqrRfStats.getPacketsWithRssi75To80dBm());
292         expect.that(bqrp.mRssiChain80To85).isEqualTo(bqrRfStats.getPacketsWithRssi80To85dBm());
293         expect.that(bqrp.mRssiChain85To90).isEqualTo(bqrRfStats.getPacketsWithRssi85To90dBm());
294         expect.that(bqrp.mRssiChainUnder90)
295                 .isEqualTo(bqrRfStats.getPacketsWithRssiBelowMinus90dBm());
296         expect.that(bqrp.mRssiDeltaUnder2).isEqualTo(bqrRfStats.getPacketsWithRssiDeltaBelow2dBm());
297         expect.that(bqrp.mRssiDelta2To5).isEqualTo(bqrRfStats.getPacketsWithRssiDelta2To5dBm());
298         expect.that(bqrp.mRssiDelta5To8).isEqualTo(bqrRfStats.getPacketsWithRssiDelta5To8dBm());
299         expect.that(bqrp.mRssiDelta8To11).isEqualTo(bqrRfStats.getPacketsWithRssiDelta8To11dBm());
300         expect.that(bqrp.mRssiDeltaOver11)
301                 .isEqualTo(bqrRfStats.getPacketsWithRssiDeltaAbove11dBm());
302         expect.that(bqrRfStats.describeContents()).isEqualTo(0);
303     }
304 
getBluetoothClassHelper(int remoteCoD)305     private static BluetoothClass getBluetoothClassHelper(int remoteCoD) {
306         Parcel p = Parcel.obtain();
307         p.writeInt(remoteCoD);
308         p.setDataPosition(0);
309         BluetoothClass bluetoothClass = BluetoothClass.CREATOR.createFromParcel(p);
310         p.recycle();
311         return bluetoothClass;
312     }
313 
initBqrCommon( BQRParameters bqrp, String remoteAddr, int lmpVer, int lmpSubVer, int manufacturerId, String remoteName, int remoteCoD)314     private BluetoothQualityReport initBqrCommon(
315             BQRParameters bqrp,
316             String remoteAddr,
317             int lmpVer,
318             int lmpSubVer,
319             int manufacturerId,
320             String remoteName,
321             int remoteCoD) {
322 
323         BluetoothClass bluetoothClass = getBluetoothClassHelper(remoteCoD);
324 
325         BluetoothQualityReport bqr =
326                 new BluetoothQualityReport.Builder(bqrp.getByteArray())
327                         .setRemoteAddress(remoteAddr)
328                         .setLmpVersion(lmpVer)
329                         .setLmpSubVersion(lmpSubVer)
330                         .setManufacturerId(manufacturerId)
331                         .setRemoteName(remoteName)
332                         .setBluetoothClass(bluetoothClass)
333                         .build();
334 
335         Log.i(TAG, bqr.toString());
336 
337         assertThat(remoteAddr).isEqualTo(bqr.getRemoteAddress());
338         assertThat(bqr.getLmpVersion()).isEqualTo(lmpVer);
339         assertThat(bqr.getLmpSubVersion()).isEqualTo(lmpSubVer);
340         assertThat(bqr.getManufacturerId()).isEqualTo(manufacturerId);
341         assertThat(remoteName).isEqualTo(bqr.getRemoteName());
342         assertThat(bqr.getBluetoothClass()).isEqualTo(bluetoothClass);
343 
344         assertBqrCommon(bqrp, bqr);
345 
346         return bqr;
347     }
348 
349     @Test
bqrMonitor()350     public void bqrMonitor() {
351         BQRParameters bqrp = BQRParameters.getInstance();
352         assertThat(bqrp).isNotNull();
353 
354         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
355         assertThat(bqrp.getQualityReportId())
356                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
357 
358         BluetoothQualityReport bqr =
359                 initBqrCommon(
360                         bqrp,
361                         mRemoteAddress,
362                         mLmpVer,
363                         mLmpSubVer,
364                         mManufacturerId,
365                         mRemoteName,
366                         mRemoteCoD);
367     }
368 
369     @Test
bqrApproachLsto()370     public void bqrApproachLsto() {
371         BQRParameters bqrp = BQRParameters.getInstance();
372         assertThat(bqrp).isNotNull();
373 
374         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO);
375         assertThat(bqrp.getQualityReportId())
376                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO);
377 
378         BluetoothQualityReport bqr =
379                 initBqrCommon(
380                         bqrp,
381                         mRemoteAddress,
382                         mLmpVer,
383                         mLmpSubVer,
384                         mManufacturerId,
385                         mRemoteName,
386                         mRemoteCoD);
387 
388         assertBqrApproachLsto(bqrp, bqr);
389     }
390 
391     @Test
bqrA2dpChoppy()392     public void bqrA2dpChoppy() {
393         BQRParameters bqrp = BQRParameters.getInstance();
394         assertThat(bqrp).isNotNull();
395 
396         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY);
397         assertThat(bqrp.getQualityReportId())
398                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY);
399 
400         BluetoothQualityReport bqr =
401                 initBqrCommon(
402                         bqrp,
403                         mRemoteAddress,
404                         mLmpVer,
405                         mLmpSubVer,
406                         mManufacturerId,
407                         mRemoteName,
408                         mRemoteCoD);
409 
410         assertBqrA2dpChoppy(bqrp, bqr);
411     }
412 
413     @Test
bqrScoChoppy()414     public void bqrScoChoppy() {
415         BQRParameters bqrp = BQRParameters.getInstance();
416         assertThat(bqrp).isNotNull();
417 
418         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY);
419         assertThat(bqrp.getQualityReportId())
420                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY);
421 
422         BluetoothQualityReport bqr =
423                 initBqrCommon(
424                         bqrp,
425                         mRemoteAddress,
426                         mLmpVer,
427                         mLmpSubVer,
428                         mManufacturerId,
429                         mRemoteName,
430                         mRemoteCoD);
431 
432         assertBqrScoChoppy(bqrp, bqr);
433     }
434 
435     @Test
436     @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_BLUETOOTH_QUALITY_REPORT_V6)
bqrEnergyMonitor()437     public void bqrEnergyMonitor() {
438         BQRParameters bqrp = BQRParameters.getInstance();
439         assertThat(bqrp).isNotNull();
440 
441         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_ENERGY_MONITOR);
442         assertThat(bqrp.getQualityReportId())
443                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_ENERGY_MONITOR);
444 
445         BluetoothQualityReport bqr =
446                 initBqrCommon(
447                         bqrp,
448                         mRemoteAddress,
449                         mLmpVer,
450                         mLmpSubVer,
451                         mManufacturerId,
452                         mRemoteName,
453                         mRemoteCoD);
454 
455         assertBqrEnergyMonitor(bqrp, bqr);
456     }
457 
458     @Test
bqrConnectFail()459     public void bqrConnectFail() {
460         BQRParameters bqrp = BQRParameters.getInstance();
461         assertThat(bqrp).isNotNull();
462 
463         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL);
464         assertThat(bqrp.getQualityReportId())
465                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL);
466 
467         BluetoothQualityReport bqr =
468                 initBqrCommon(
469                         bqrp,
470                         mRemoteAddress,
471                         mLmpVer,
472                         mLmpSubVer,
473                         mManufacturerId,
474                         mRemoteName,
475                         mRemoteCoD);
476 
477         assertBqrConnectFail(bqrp, bqr);
478 
479         BqrConnectFail bqrConnectFail = (BqrConnectFail) bqr.getBqrEvent();
480         assertThat(bqrConnectFail).isNotNull();
481 
482         assertThat(BqrConnectFail.connectFailIdToString(BqrConnectFail.CONNECT_FAIL_ID_NO_ERROR))
483                 .isEqualTo("No error");
484         assertThat(
485                         BqrConnectFail.connectFailIdToString(
486                                 BqrConnectFail.CONNECT_FAIL_ID_PAGE_TIMEOUT))
487                 .isEqualTo("Page Timeout");
488         assertThat(
489                         BqrConnectFail.connectFailIdToString(
490                                 BqrConnectFail.CONNECT_FAIL_ID_CONNECTION_TIMEOUT))
491                 .isEqualTo("Connection Timeout");
492         assertThat(
493                         BqrConnectFail.connectFailIdToString(
494                                 BqrConnectFail.CONNECT_FAIL_ID_ACL_ALREADY_EXIST))
495                 .isEqualTo("ACL already exists");
496         assertThat(
497                         BqrConnectFail.connectFailIdToString(
498                                 BqrConnectFail.CONNECT_FAIL_ID_CONTROLLER_BUSY))
499                 .isEqualTo("Controller busy");
500         assertThat(BqrConnectFail.connectFailIdToString(0xFF)).isEqualTo("INVALID");
501     }
502 
503     @Test
504     @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_BLUETOOTH_QUALITY_REPORT_V6)
bqrRfStats()505     public void bqrRfStats() {
506         BQRParameters bqrp = BQRParameters.getInstance();
507         assertThat(bqrp).isNotNull();
508 
509         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_RF_STATS);
510         assertThat(bqrp.getQualityReportId())
511                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_RF_STATS);
512 
513         BluetoothQualityReport bqr =
514                 initBqrCommon(
515                         bqrp,
516                         mRemoteAddress,
517                         mLmpVer,
518                         mLmpSubVer,
519                         mManufacturerId,
520                         mRemoteName,
521                         mRemoteCoD);
522 
523         assertBqrRfStats(bqrp, bqr);
524     }
525 
526     @Test
defaultNameAddress()527     public void defaultNameAddress() {
528         BQRParameters bqrp = BQRParameters.getInstance();
529         assertThat(bqrp).isNotNull();
530 
531         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
532         assertThat(bqrp.getQualityReportId())
533                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
534 
535         BluetoothClass bluetoothClass = getBluetoothClassHelper(mRemoteCoD);
536 
537         BluetoothQualityReport bqr =
538                 new BluetoothQualityReport.Builder(bqrp.getByteArray())
539                         .setRemoteAddress("123456123456")
540                         .setLmpVersion(mLmpVer)
541                         .setLmpSubVersion(mLmpSubVer)
542                         .setManufacturerId(mManufacturerId)
543                         .setBluetoothClass(bluetoothClass)
544                         .build();
545 
546         assertThat(bqr.getRemoteAddress()).isEqualTo(mDefaultAddress);
547         assertThat(bqr.getRemoteName()).isEqualTo(mDefaultName);
548     }
549 
550     @Test
invalidQualityReportId()551     public void invalidQualityReportId() {
552         BQRParameters bqrp = BQRParameters.getInstance();
553         assertThat(bqrp).isNotNull();
554 
555         bqrp.setQualityReportId((byte) 123);
556         assertThat(bqrp.getQualityReportId()).isEqualTo(123);
557 
558         assertThrows(
559                 IllegalArgumentException.class,
560                 () ->
561                         initBqrCommon(
562                                 bqrp,
563                                 mRemoteAddress,
564                                 mLmpVer,
565                                 mLmpSubVer,
566                                 mManufacturerId,
567                                 mRemoteName,
568                                 mRemoteCoD));
569     }
570 
571     @Test
rawDataNull()572     public void rawDataNull() {
573         BluetoothClass bluetoothClass = getBluetoothClassHelper(mRemoteCoD);
574 
575         assertThrows(
576                 NullPointerException.class,
577                 () ->
578                         new BluetoothQualityReport.Builder(null)
579                                 .setRemoteAddress(mRemoteAddress)
580                                 .setLmpVersion(mLmpVer)
581                                 .setLmpSubVersion(mLmpSubVer)
582                                 .setManufacturerId(mManufacturerId)
583                                 .setRemoteName(mRemoteName)
584                                 .setBluetoothClass(bluetoothClass)
585                                 .build());
586     }
587 
588     @Test
invalidRawData()589     public void invalidRawData() {
590         BQRParameters bqrp = BQRParameters.getInstance();
591         assertThat(bqrp).isNotNull();
592 
593         BluetoothClass bluetoothClass = getBluetoothClassHelper(mRemoteCoD);
594 
595         for (int id : BQRParameters.QualityReportId) {
596             bqrp.setQualityReportId((byte) id);
597             assertThat(bqrp.getQualityReportId()).isEqualTo(id);
598 
599             byte[] rawData = {0};
600 
601             switch (id) {
602                 case BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR:
603                     rawData = ByteBuffer.allocate(BQRParameters.mBqrCommonSize - 1).array();
604                     break;
605                 case BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO:
606                     rawData =
607                             ByteBuffer.allocate(
608                                             BQRParameters.mBqrCommonSize
609                                                     + BQRParameters.mBqrVsLstoSize
610                                                     - 1)
611                                     .array();
612                     break;
613                 case BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY:
614                     rawData =
615                             ByteBuffer.allocate(
616                                             BQRParameters.mBqrCommonSize
617                                                     + BQRParameters.mBqrVsA2dpChoppySize
618                                                     - 1)
619                                     .array();
620                     break;
621                 case BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY:
622                     rawData =
623                             ByteBuffer.allocate(
624                                             BQRParameters.mBqrCommonSize
625                                                     + BQRParameters.mBqrVsScoChoppySize
626                                                     - 1)
627                                     .array();
628                     break;
629                 case BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL:
630                     rawData =
631                             ByteBuffer.allocate(
632                                             BQRParameters.mBqrCommonSize
633                                                     + BQRParameters.mBqrVsScoChoppySize
634                                                     - 1)
635                                     .array();
636                     break;
637             }
638 
639             final byte[] data = rawData;
640 
641             assertThrows(
642                     IllegalArgumentException.class,
643                     () ->
644                             new BluetoothQualityReport.Builder(data)
645                                     .setRemoteAddress(mRemoteAddress)
646                                     .setLmpVersion(mLmpVer)
647                                     .setLmpSubVersion(mLmpSubVer)
648                                     .setManufacturerId(mManufacturerId)
649                                     .setRemoteName(mRemoteName)
650                                     .setBluetoothClass(bluetoothClass)
651                                     .build());
652         }
653     }
654 
655     @Test
readWriteBqrParcel()656     public void readWriteBqrParcel() {
657         BQRParameters bqrp = BQRParameters.getInstance();
658         assertThat(bqrp).isNotNull();
659 
660         for (int id : BQRParameters.QualityReportId) {
661             if ((id == BluetoothQualityReport.QUALITY_REPORT_ID_ENERGY_MONITOR)
662                     || (id == BluetoothQualityReport.QUALITY_REPORT_ID_RF_STATS)) {
663                 continue;
664             }
665             bqrp.setQualityReportId((byte) id);
666             assertThat(bqrp.getQualityReportId()).isEqualTo(id);
667 
668             BluetoothQualityReport bqr =
669                     initBqrCommon(
670                             bqrp,
671                             mRemoteAddress,
672                             mLmpVer,
673                             mLmpSubVer,
674                             mManufacturerId,
675                             mRemoteName,
676                             mRemoteCoD);
677 
678             Parcel parcel = Parcel.obtain();
679             bqr.writeToParcel(parcel, 0);
680             parcel.setDataPosition(0);
681 
682             BluetoothQualityReport bqrFromParcel =
683                     BluetoothQualityReport.CREATOR.createFromParcel(parcel);
684 
685             assertBqrCommon(bqrp, bqrFromParcel);
686 
687             switch (id) {
688                 case BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR:
689                     break;
690                 case BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO:
691                     assertBqrApproachLsto(bqrp, bqr);
692                     break;
693                 case BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY:
694                     assertBqrA2dpChoppy(bqrp, bqr);
695                     break;
696                 case BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY:
697                     assertBqrScoChoppy(bqrp, bqr);
698                     break;
699                 case BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL:
700                     assertBqrConnectFail(bqrp, bqr);
701                     break;
702             }
703         }
704     }
705 
706     @Test
707     @RequiresFlagsEnabled(Flags.FLAG_SUPPORT_BLUETOOTH_QUALITY_REPORT_V6)
readWriteBqrParcelV6Flag()708     public void readWriteBqrParcelV6Flag() {
709         BQRParameters bqrp = BQRParameters.getInstance();
710         assertThat(bqrp).isNotNull();
711 
712         for (int id : BQRParameters.QualityReportId) {
713             bqrp.setQualityReportId((byte) id);
714             assertThat(bqrp.getQualityReportId()).isEqualTo(id);
715 
716             BluetoothQualityReport bqr =
717                     initBqrCommon(
718                             bqrp,
719                             mRemoteAddress,
720                             mLmpVer,
721                             mLmpSubVer,
722                             mManufacturerId,
723                             mRemoteName,
724                             mRemoteCoD);
725 
726             Parcel parcel = Parcel.obtain();
727             bqr.writeToParcel(parcel, 0);
728             parcel.setDataPosition(0);
729 
730             BluetoothQualityReport bqrFromParcel =
731                     BluetoothQualityReport.CREATOR.createFromParcel(parcel);
732 
733             assertBqrV6Common(bqrp, bqrFromParcel);
734 
735             switch (id) {
736                 case BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR:
737                     break;
738                 case BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO:
739                     assertBqrApproachLsto(bqrp, bqr);
740                     break;
741                 case BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY:
742                     assertBqrA2dpChoppy(bqrp, bqr);
743                     break;
744                 case BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY:
745                     assertBqrScoChoppy(bqrp, bqr);
746                     break;
747                 case BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL:
748                     assertBqrConnectFail(bqrp, bqr);
749                     break;
750                 case BluetoothQualityReport.QUALITY_REPORT_ID_ENERGY_MONITOR:
751                     assertBqrEnergyMonitor(bqrp, bqr);
752                     break;
753                 case BluetoothQualityReport.QUALITY_REPORT_ID_RF_STATS:
754                     assertBqrRfStats(bqrp, bqr);
755                     break;
756             }
757         }
758     }
759 
760     @Test
readWriteBqrCommonParcel()761     public void readWriteBqrCommonParcel() {
762         BQRParameters bqrp = BQRParameters.getInstance();
763         assertThat(bqrp).isNotNull();
764 
765         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
766         assertThat(bqrp.getQualityReportId())
767                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
768 
769         BluetoothQualityReport bqr =
770                 initBqrCommon(
771                         bqrp,
772                         mRemoteAddress,
773                         mLmpVer,
774                         mLmpSubVer,
775                         mManufacturerId,
776                         mRemoteName,
777                         mRemoteCoD);
778 
779         assertThat(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
780                 .isEqualTo("Quality monitor");
781 
782         Parcel parcel = Parcel.obtain();
783         bqr.getBqrCommon().writeToParcel(parcel, 0);
784         parcel.setDataPosition(0);
785 
786         BqrCommon bqrCommonFromParcel = BqrCommon.CREATOR.createFromParcel(parcel);
787 
788         // BQR Common
789         assertThat(bqrCommonFromParcel).isNotNull();
790         assertThat(bqrCommonFromParcel.getPacketType()).isEqualTo(bqrp.mPacketType);
791         assertThat(BqrCommon.packetTypeToString(bqrCommonFromParcel.getPacketType()))
792                 .isEqualTo("TYPE_NULL");
793         assertThat(bqrCommonFromParcel.getConnectionHandle()).isEqualTo(bqrp.mConnectionHandle);
794         assertThat(BqrCommon.connectionRoleToString(bqrCommonFromParcel.getConnectionRole()))
795                 .isEqualTo(bqrp.mConnectionRoleCentral);
796         assertThat(bqrCommonFromParcel.getTxPowerLevel()).isEqualTo(bqrp.mTxPowerLevel);
797         assertThat(bqrCommonFromParcel.getRssi()).isEqualTo(bqrp.mRssi);
798         assertThat(bqrCommonFromParcel.getSnr()).isEqualTo(bqrp.mSnr);
799         assertThat(bqrCommonFromParcel.getUnusedAfhChannelCount())
800                 .isEqualTo(bqrp.mUnusedAfhChannelCount);
801         assertThat(bqrCommonFromParcel.getAfhSelectUnidealChannelCount())
802                 .isEqualTo(bqrp.mAfhSelectUnidealChannelCount);
803         assertThat(bqrCommonFromParcel.getLsto()).isEqualTo(bqrp.mLsto);
804         assertThat(bqrCommonFromParcel.getPiconetClock()).isEqualTo(bqrp.mPiconetClock);
805         assertThat(bqrCommonFromParcel.getRetransmissionCount())
806                 .isEqualTo(bqrp.mRetransmissionCount);
807         assertThat(bqrCommonFromParcel.getNoRxCount()).isEqualTo(bqrp.mNoRxCount);
808         assertThat(bqrCommonFromParcel.getNakCount()).isEqualTo(bqrp.mNakCount);
809         assertThat(bqrCommonFromParcel.getLastTxAckTimestamp()).isEqualTo(bqrp.mLastTxAckTimestamp);
810         assertThat(bqrCommonFromParcel.getFlowOffCount()).isEqualTo(bqrp.mFlowOffCount);
811         assertThat(bqrCommonFromParcel.getLastFlowOnTimestamp())
812                 .isEqualTo(bqrp.mLastFlowOnTimestamp);
813         assertThat(bqrCommonFromParcel.getOverflowCount()).isEqualTo(bqrp.mOverflowCount);
814         assertThat(bqrCommonFromParcel.getUnderflowCount()).isEqualTo(bqrp.mUnderflowCount);
815     }
816 
817     @Test
readWriteBqrVsApproachLstoParcel()818     public void readWriteBqrVsApproachLstoParcel() {
819         BQRParameters bqrp = BQRParameters.getInstance();
820         assertThat(bqrp).isNotNull();
821 
822         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO);
823         assertThat(bqrp.getQualityReportId())
824                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO);
825 
826         BluetoothQualityReport bqr =
827                 initBqrCommon(
828                         bqrp,
829                         mRemoteAddress,
830                         mLmpVer,
831                         mLmpSubVer,
832                         mManufacturerId,
833                         mRemoteName,
834                         mRemoteCoD);
835 
836         assertThat(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
837                 .isEqualTo("Approaching LSTO");
838 
839         BqrVsLsto bqrVsLsto = (BqrVsLsto) bqr.getBqrEvent();
840         assertThat(bqrVsLsto).isNotNull();
841         Parcel parcel = Parcel.obtain();
842         bqrVsLsto.writeToParcel(parcel, 0);
843         parcel.setDataPosition(0);
844 
845         BqrVsLsto bqrVsLstoFromParcel = BqrVsLsto.CREATOR.createFromParcel(parcel);
846 
847         // BQR VS LSTO
848         assertThat(bqrVsLstoFromParcel).isNotNull();
849         assertThat(bqrVsLstoFromParcel.getConnState()).isEqualTo(bqrp.mConnState & 0xFF);
850         assertThat(BqrVsLsto.connStateToString(bqrVsLstoFromParcel.getConnState()))
851                 .isEqualTo("CONN_UNPARK_ACTIVE");
852         assertThat(bqrVsLstoFromParcel.getBasebandStats()).isEqualTo(bqrp.mBasebandStats);
853         assertThat(bqrVsLstoFromParcel.getSlotsUsed()).isEqualTo(bqrp.mSlotsUsed);
854         assertThat(bqrVsLstoFromParcel.getCxmDenials()).isEqualTo(bqrp.mCxmDenials);
855         assertThat(bqrVsLstoFromParcel.getTxSkipped()).isEqualTo(bqrp.mTxSkipped);
856         assertThat(bqrVsLstoFromParcel.getRfLoss()).isEqualTo(bqrp.mRfLoss);
857         assertThat(bqrVsLstoFromParcel.getNativeClock()).isEqualTo(bqrp.mNativeClock);
858         assertThat(bqrVsLstoFromParcel.getLastTxAckTimestamp())
859                 .isEqualTo(bqrp.mLastTxAckTimestampLsto);
860         assertThat(bqrVsLstoFromParcel.describeContents()).isEqualTo(0);
861     }
862 
863     @Test
readWriteBqrVsA2dpChoppyParcel()864     public void readWriteBqrVsA2dpChoppyParcel() {
865         BQRParameters bqrp = BQRParameters.getInstance();
866         assertThat(bqrp).isNotNull();
867 
868         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY);
869         assertThat(bqrp.getQualityReportId())
870                 .isEqualTo(BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY);
871 
872         BluetoothQualityReport bqr =
873                 initBqrCommon(
874                         bqrp,
875                         mRemoteAddress,
876                         mLmpVer,
877                         mLmpSubVer,
878                         mManufacturerId,
879                         mRemoteName,
880                         mRemoteCoD);
881 
882         assertThat(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
883                 .isEqualTo("A2DP choppy");
884 
885         BqrVsA2dpChoppy bqrVsA2dpChoppy = (BqrVsA2dpChoppy) bqr.getBqrEvent();
886         assertThat(bqrVsA2dpChoppy).isNotNull();
887         Parcel parcel = Parcel.obtain();
888         bqrVsA2dpChoppy.writeToParcel(parcel, 0);
889         parcel.setDataPosition(0);
890 
891         BqrVsA2dpChoppy bqrVsA2dpChoppyFromParcel =
892                 BqrVsA2dpChoppy.CREATOR.createFromParcel(parcel);
893 
894         // BQR VS A2DP Choppy
895         assertThat(bqrVsA2dpChoppyFromParcel).isNotNull();
896         assertThat(bqrVsA2dpChoppyFromParcel.getArrivalTime()).isEqualTo(bqrp.mArrivalTime);
897         assertThat(bqrVsA2dpChoppyFromParcel.getScheduleTime()).isEqualTo(bqrp.mScheduleTime);
898         assertThat(bqrVsA2dpChoppyFromParcel.getGlitchCount()).isEqualTo(bqrp.mGlitchCountA2dp);
899         assertThat(bqrVsA2dpChoppyFromParcel.getTxCxmDenials()).isEqualTo(bqrp.mTxCxmDenialsA2dp);
900         assertThat(bqrVsA2dpChoppyFromParcel.getRxCxmDenials()).isEqualTo(bqrp.mRxCxmDenialsA2dp);
901         assertThat(bqrVsA2dpChoppyFromParcel.getAclTxQueueLength())
902                 .isEqualTo(bqrp.mAclTxQueueLength);
903         assertThat(bqrVsA2dpChoppyFromParcel.getLinkQuality()).isEqualTo(bqrp.mLinkQuality);
904         assertThat(BqrVsA2dpChoppy.linkQualityToString(bqrVsA2dpChoppyFromParcel.getLinkQuality()))
905                 .isEqualTo("MEDIUM");
906         assertThat(bqrVsA2dpChoppyFromParcel.describeContents()).isEqualTo(0);
907     }
908 
909     @Test
readWriteBqrVsScoChoppyParcel()910     public void readWriteBqrVsScoChoppyParcel() {
911         BQRParameters bqrp = BQRParameters.getInstance();
912         assertThat(bqrp).isNotNull();
913 
914         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY);
915         assertThat(BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY)
916                 .isEqualTo(bqrp.getQualityReportId());
917 
918         BluetoothQualityReport bqr =
919                 initBqrCommon(
920                         bqrp,
921                         mRemoteAddress,
922                         mLmpVer,
923                         mLmpSubVer,
924                         mManufacturerId,
925                         mRemoteName,
926                         mRemoteCoD);
927 
928         assertThat(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
929                 .isEqualTo("SCO choppy");
930 
931         BqrVsScoChoppy bqrVsScoChoppy = (BqrVsScoChoppy) bqr.getBqrEvent();
932         assertThat(bqrVsScoChoppy).isNotNull();
933         Parcel parcel = Parcel.obtain();
934         bqrVsScoChoppy.writeToParcel(parcel, 0);
935         parcel.setDataPosition(0);
936 
937         BqrVsScoChoppy bqrVsScoChoppyFromParcel = BqrVsScoChoppy.CREATOR.createFromParcel(parcel);
938 
939         // BQR VS SCO Choppy
940         assertThat(bqrVsScoChoppyFromParcel).isNotNull();
941         assertThat(bqrVsScoChoppyFromParcel.getGlitchCount()).isEqualTo(bqrp.mGlitchCountSco);
942         assertThat(bqrVsScoChoppyFromParcel.getIntervalEsco()).isEqualTo(bqrp.mIntervalEsco);
943         assertThat(bqrVsScoChoppyFromParcel.getWindowEsco()).isEqualTo(bqrp.mWindowEsco);
944         assertThat(bqrVsScoChoppyFromParcel.getAirFormat()).isEqualTo(bqrp.mAirFormat);
945         assertThat(BqrVsScoChoppy.airFormatToString(bqrVsScoChoppyFromParcel.getAirFormat()))
946                 .isEqualTo("CVSD");
947         assertThat(bqrVsScoChoppyFromParcel.getInstanceCount()).isEqualTo(bqrp.mInstanceCount);
948         assertThat(bqrVsScoChoppyFromParcel.getTxCxmDenials()).isEqualTo(bqrp.mTxCxmDenialsSco);
949         assertThat(bqrVsScoChoppyFromParcel.getRxCxmDenials()).isEqualTo(bqrp.mRxCxmDenialsSco);
950         assertThat(bqrVsScoChoppyFromParcel.getTxAbortCount()).isEqualTo(bqrp.mTxAbortCount);
951         assertThat(bqrVsScoChoppyFromParcel.getLateDispatch()).isEqualTo(bqrp.mLateDispatch);
952         assertThat(bqrVsScoChoppyFromParcel.getMicIntrMiss()).isEqualTo(bqrp.mMicIntrMiss);
953         assertThat(bqrVsScoChoppyFromParcel.getLpaIntrMiss()).isEqualTo(bqrp.mLpaIntrMiss);
954         assertThat(bqrVsScoChoppyFromParcel.getSprIntrMiss()).isEqualTo(bqrp.mSprIntrMiss);
955         assertThat(bqrVsScoChoppyFromParcel.getPlcFillCount()).isEqualTo(bqrp.mPlcFillCount);
956         assertThat(bqrVsScoChoppyFromParcel.getPlcDiscardCount()).isEqualTo(bqrp.mPlcDiscardCount);
957 
958         assertThat(bqrVsScoChoppyFromParcel.getMissedInstanceCount())
959                 .isEqualTo(bqrp.mMissedInstanceCount);
960         assertThat(bqrVsScoChoppyFromParcel.getTxRetransmitSlotCount())
961                 .isEqualTo(bqrp.mTxRetransmitSlotCount);
962         assertThat(bqrVsScoChoppyFromParcel.getRxRetransmitSlotCount())
963                 .isEqualTo(bqrp.mRxRetransmitSlotCount);
964         assertThat(bqrVsScoChoppyFromParcel.getGoodRxFrameCount())
965                 .isEqualTo(bqrp.mGoodRxFrameCount);
966         assertThat(bqrVsScoChoppyFromParcel.describeContents()).isEqualTo(0);
967     }
968 
969     @Test
readWriteBqrConnectFailParcel()970     public void readWriteBqrConnectFailParcel() {
971         BQRParameters bqrp = BQRParameters.getInstance();
972         assertThat(bqrp).isNotNull();
973 
974         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL);
975         assertThat(BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL)
976                 .isEqualTo(bqrp.getQualityReportId());
977 
978         BluetoothQualityReport bqr =
979                 initBqrCommon(
980                         bqrp,
981                         mRemoteAddress,
982                         mLmpVer,
983                         mLmpSubVer,
984                         mManufacturerId,
985                         mRemoteName,
986                         mRemoteCoD);
987 
988         assertThat(BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()))
989                 .isEqualTo("Connect fail");
990 
991         BqrConnectFail bqrConnectFail = (BqrConnectFail) bqr.getBqrEvent();
992         assertThat(bqrConnectFail).isNotNull();
993         Parcel parcel = Parcel.obtain();
994         bqrConnectFail.writeToParcel(parcel, 0);
995         parcel.setDataPosition(0);
996 
997         BqrConnectFail bqrConnFailFromParcel = BqrConnectFail.CREATOR.createFromParcel(parcel);
998 
999         // BQR VS Connect Fail
1000         assertThat(bqrConnFailFromParcel).isNotNull();
1001         assertThat(bqrConnFailFromParcel.getFailReason()).isEqualTo(bqrp.mFailReason);
1002         assertThat(bqrConnFailFromParcel.describeContents()).isEqualTo(0);
1003     }
1004 
1005     /**
1006      * Get the test object of BluetoothQualityReport based on given Quality Report Id.
1007      *
1008      * @param qualityReportId Quality Report Id
1009      * @return Bluetooth Quality Report object
1010      */
getBqr(int qualityReportId)1011     public static BluetoothQualityReport getBqr(int qualityReportId) {
1012         BQRParameters bqrp = BQRParameters.getInstance();
1013         assertThat(bqrp).isNotNull();
1014 
1015         bqrp.setQualityReportId((byte) qualityReportId);
1016         assertThat(bqrp.getQualityReportId()).isEqualTo(qualityReportId);
1017         BluetoothClass bluetoothClass = getBluetoothClassHelper(mRemoteCoD);
1018 
1019         BluetoothQualityReport bqr =
1020                 new BluetoothQualityReport.Builder(bqrp.getByteArray())
1021                         .setRemoteAddress(mRemoteAddress)
1022                         .setLmpVersion(mLmpVer)
1023                         .setLmpSubVersion(mLmpSubVer)
1024                         .setManufacturerId(mManufacturerId)
1025                         .setRemoteName(mRemoteName)
1026                         .setBluetoothClass(bluetoothClass)
1027                         .build();
1028         return bqr;
1029     }
1030 
1031     private static final class BQRParameters {
1032         private static BQRParameters INSTANCE;
1033         private static String TAG = "BQRParameters";
1034 
1035         public static int mBqrCommonSize = 85;
1036         public static int mBqrVsLstoSize = 23;
1037         public static int mBqrVsA2dpChoppySize = 16;
1038         public static int mBqrVsScoChoppySize = 33;
1039         public static int mBqrConnectFailSize = 1;
1040         public static int mBqrEnergyMonitorSize = 81;
1041         public static int mBqrRfStatsSize = 82;
1042 
1043         // BQR Common
1044         public byte mQualityReportId = 1;
1045         public byte mPacketType = 2;
1046         public short mConnectionHandle = 3;
1047         public byte mConnectionRole = 0; // Central
1048         public String mConnectionRoleCentral = "Central";
1049         public byte mTxPowerLevel = 5;
1050         public byte mRssi = 6;
1051         public byte mSnr = 7;
1052         public byte mUnusedAfhChannelCount = 8;
1053         public byte mAfhSelectUnidealChannelCount = 9;
1054         public short mLsto = 10;
1055         public int mPiconetClock = 11;
1056         public int mRetransmissionCount = 12;
1057         public int mNoRxCount = 13;
1058         public int mNakCount = 14;
1059         public int mLastTxAckTimestamp = 15;
1060         public int mFlowOffCount = 16;
1061         public int mLastFlowOnTimestamp = 17;
1062         public int mOverflowCount = 18;
1063         public int mUnderflowCount = 19;
1064         public String mAddressStr = "01:02:03:04:05:06";
1065         public byte[] mAddress = {6, 5, 4, 3, 2, 1};
1066         public byte mCalFailedItemCount = 50;
1067 
1068         public int mTxTotalPackets = 20;
1069         public int mTxUnackPackets = 21;
1070         public int mTxFlushPackets = 22;
1071         public int mTxLastSubeventPackets = 23;
1072         public int mCrcErrorPackets = 24;
1073         public int mRxDupPackets = 25;
1074         public int mRxUnRecvPackets = 26;
1075         public short mCoexInfoMask = 1;
1076 
1077         // BQR VS LSTO
1078         public byte mConnState = (byte) 0x89;
1079         public int mBasebandStats = 21;
1080         public int mSlotsUsed = 22;
1081         public short mCxmDenials = 23;
1082         public short mTxSkipped = 24;
1083         public short mRfLoss = 25;
1084         public int mNativeClock = 26;
1085         public int mLastTxAckTimestampLsto = 27;
1086 
1087         // BQR VS A2DP Choppy
1088         public int mArrivalTime = 28;
1089         public int mScheduleTime = 29;
1090         public short mGlitchCountA2dp = 30;
1091         public short mTxCxmDenialsA2dp = 31;
1092         public short mRxCxmDenialsA2dp = 32;
1093         public byte mAclTxQueueLength = 33;
1094         public byte mLinkQuality = 3;
1095 
1096         // BQR VS SCO Choppy
1097         public short mGlitchCountSco = 35;
1098         public byte mIntervalEsco = 36;
1099         public byte mWindowEsco = 37;
1100         public byte mAirFormat = 2;
1101         public short mInstanceCount = 39;
1102         public short mTxCxmDenialsSco = 40;
1103         public short mRxCxmDenialsSco = 41;
1104         public short mTxAbortCount = 42;
1105         public short mLateDispatch = 43;
1106         public short mMicIntrMiss = 44;
1107         public short mLpaIntrMiss = 45;
1108         public short mSprIntrMiss = 46;
1109         public short mPlcFillCount = 47;
1110         public short mPlcDiscardCount = 51;
1111         public short mMissedInstanceCount = 52;
1112         public short mTxRetransmitSlotCount = 53;
1113         public short mRxRetransmitSlotCount = 54;
1114         public short mGoodRxFrameCount = 55;
1115 
1116         // BQR VS Connect Fail
1117         public byte mFailReason = 0x3a;
1118 
1119         // BQR Energy Monitor
1120         public short mAvgCurrentConsume = 56;
1121         public int mIdleTotalTime = 57;
1122         public int mIdleStateEnterCount = 58;
1123         public int mActiveTotalTime = 59;
1124         public int mActiveStateEnterCount = 60;
1125         public int mBredrTxTotalTime = 61;
1126         public int mBredrTxStateEnterCount = 62;
1127         public byte mBredrTxAvgPowerLevel = 63;
1128         public int mBredrRxTotalTime = 64;
1129         public int mBredrRxStateEnterCount = 65;
1130         public int mLeTxTotalTime = 66;
1131         public int mLeTxStateEnterCount = 67;
1132         public byte mLeTxAvgPowerLevel = 68;
1133         public int mLeRxTotalTime = 69;
1134         public int mLeRxStateEnterCount = 70;
1135         public int mReportTotalTime = 71;
1136         public int mRxActiveOneChainTime = 72;
1137         public int mRxActiveTwoChainTime = 73;
1138         public int mTxiPaActiveOneChainTime = 74;
1139         public int mTxiPaActiveTwoChainTime = 75;
1140         public int mTxePaActiveOneChainTime = 76;
1141         public int mTxePaActiveTwoChainTime = 77;
1142 
1143         // BQR Rf Stats
1144         public byte mExtensionInfo = 78;
1145         public int mReportTimePeriod = 79;
1146         public int mTxPoweriPaBf = 80;
1147         public int mTxPowerePaBf = 81;
1148         public int mTxPoweriPaDiv = 82;
1149         public int mTxPowerePaDiv = 83;
1150         public int mRssiChainOver50 = 84;
1151         public int mRssiChain50To55 = 85;
1152         public int mRssiChain55To60 = 86;
1153         public int mRssiChain60To65 = 87;
1154         public int mRssiChain65To70 = 88;
1155         public int mRssiChain70To75 = 89;
1156         public int mRssiChain75To80 = 90;
1157         public int mRssiChain80To85 = 91;
1158         public int mRssiChain85To90 = 92;
1159         public int mRssiChainUnder90 = 93;
1160         public int mRssiDeltaUnder2 = 94;
1161         public int mRssiDelta2To5 = 95;
1162         public int mRssiDelta5To8 = 96;
1163         public int mRssiDelta8To11 = 97;
1164         public int mRssiDeltaOver11 = 98;
1165 
1166         public static int[] QualityReportId = {
1167             BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR,
1168             BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO,
1169             BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY,
1170             BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY,
1171             BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL,
1172             BluetoothQualityReport.QUALITY_REPORT_ID_ENERGY_MONITOR,
1173             BluetoothQualityReport.QUALITY_REPORT_ID_RF_STATS,
1174         };
1175 
BQRParameters()1176         private BQRParameters() {}
1177 
getInstance()1178         public static BQRParameters getInstance() {
1179             if (INSTANCE == null) {
1180                 INSTANCE = new BQRParameters();
1181             }
1182             return INSTANCE;
1183         }
1184 
setQualityReportId(byte id)1185         public void setQualityReportId(byte id) {
1186             mQualityReportId = id;
1187         }
1188 
getQualityReportId()1189         public int getQualityReportId() {
1190             return (int) mQualityReportId;
1191         }
1192 
getByteArray()1193         public byte[] getByteArray() {
1194             ByteBuffer ba;
1195             ByteBuffer addrBuff = ByteBuffer.wrap(mAddress, 0, mAddress.length);
1196 
1197             switch ((int) mQualityReportId) {
1198                 case BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR:
1199                     ba = ByteBuffer.allocate(mBqrCommonSize);
1200                     break;
1201                 case BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO:
1202                     ba = ByteBuffer.allocate(mBqrCommonSize + mBqrVsLstoSize);
1203                     break;
1204                 case BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY:
1205                     ba = ByteBuffer.allocate(mBqrCommonSize + mBqrVsA2dpChoppySize);
1206                     break;
1207                 case BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY:
1208                     ba = ByteBuffer.allocate(mBqrCommonSize + mBqrVsScoChoppySize);
1209                     break;
1210                 case BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL:
1211                     ba = ByteBuffer.allocate(mBqrCommonSize + mBqrConnectFailSize);
1212                     break;
1213                 case BluetoothQualityReport.QUALITY_REPORT_ID_ENERGY_MONITOR:
1214                     ba = ByteBuffer.allocate(1 + mBqrEnergyMonitorSize);
1215                     break;
1216                 case BluetoothQualityReport.QUALITY_REPORT_ID_RF_STATS:
1217                     ba = ByteBuffer.allocate(1 + mBqrRfStatsSize);
1218                     break;
1219                 default:
1220                     ba = ByteBuffer.allocate(mBqrCommonSize);
1221                     break;
1222             }
1223 
1224             ba.order(ByteOrder.LITTLE_ENDIAN);
1225 
1226             ba.put(mQualityReportId);
1227 
1228             if (mQualityReportId
1229                     == (byte) BluetoothQualityReport.QUALITY_REPORT_ID_ENERGY_MONITOR) {
1230                 ba.putShort(mAvgCurrentConsume);
1231                 ba.putInt(mIdleTotalTime);
1232                 ba.putInt(mIdleStateEnterCount);
1233                 ba.putInt(mActiveTotalTime);
1234                 ba.putInt(mActiveStateEnterCount);
1235                 ba.putInt(mBredrTxTotalTime);
1236                 ba.putInt(mBredrTxStateEnterCount);
1237                 ba.put(mBredrTxAvgPowerLevel);
1238                 ba.putInt(mBredrRxTotalTime);
1239                 ba.putInt(mBredrRxStateEnterCount);
1240                 ba.putInt(mLeTxTotalTime);
1241                 ba.putInt(mLeTxStateEnterCount);
1242                 ba.put(mLeTxAvgPowerLevel);
1243                 ba.putInt(mLeRxTotalTime);
1244                 ba.putInt(mLeRxStateEnterCount);
1245                 ba.putInt(mReportTotalTime);
1246                 ba.putInt(mRxActiveOneChainTime);
1247                 ba.putInt(mRxActiveTwoChainTime);
1248                 ba.putInt(mTxiPaActiveOneChainTime);
1249                 ba.putInt(mTxiPaActiveTwoChainTime);
1250                 ba.putInt(mTxePaActiveOneChainTime);
1251                 ba.putInt(mTxePaActiveTwoChainTime);
1252             } else if (mQualityReportId
1253                     == (byte) BluetoothQualityReport.QUALITY_REPORT_ID_RF_STATS) {
1254                 ba.put(mExtensionInfo);
1255                 ba.putInt(mReportTimePeriod);
1256                 ba.putInt(mTxPoweriPaBf);
1257                 ba.putInt(mTxPowerePaBf);
1258                 ba.putInt(mTxPoweriPaDiv);
1259                 ba.putInt(mTxPowerePaDiv);
1260                 ba.putInt(mRssiChainOver50);
1261                 ba.putInt(mRssiChain50To55);
1262                 ba.putInt(mRssiChain55To60);
1263                 ba.putInt(mRssiChain60To65);
1264                 ba.putInt(mRssiChain65To70);
1265                 ba.putInt(mRssiChain70To75);
1266                 ba.putInt(mRssiChain75To80);
1267                 ba.putInt(mRssiChain80To85);
1268                 ba.putInt(mRssiChain85To90);
1269                 ba.putInt(mRssiChainUnder90);
1270                 ba.putInt(mRssiDeltaUnder2);
1271                 ba.putInt(mRssiDelta2To5);
1272                 ba.putInt(mRssiDelta5To8);
1273                 ba.putInt(mRssiDelta8To11);
1274                 ba.putInt(mRssiDeltaOver11);
1275             } else {
1276                 ba.put(mPacketType);
1277                 ba.putShort(mConnectionHandle);
1278                 ba.put(mConnectionRole);
1279                 ba.put(mTxPowerLevel);
1280                 ba.put(mRssi);
1281                 ba.put(mSnr);
1282                 ba.put(mUnusedAfhChannelCount);
1283                 ba.put(mAfhSelectUnidealChannelCount);
1284                 ba.putShort(mLsto);
1285                 ba.putInt(mPiconetClock);
1286                 ba.putInt(mRetransmissionCount);
1287                 ba.putInt(mNoRxCount);
1288                 ba.putInt(mNakCount);
1289                 ba.putInt(mLastTxAckTimestamp);
1290                 ba.putInt(mFlowOffCount);
1291                 ba.putInt(mLastFlowOnTimestamp);
1292                 ba.putInt(mOverflowCount);
1293                 ba.putInt(mUnderflowCount);
1294                 ba.put(addrBuff);
1295                 ba.put(mCalFailedItemCount);
1296                 ba.putInt(mTxTotalPackets);
1297                 ba.putInt(mTxUnackPackets);
1298                 ba.putInt(mTxFlushPackets);
1299                 ba.putInt(mTxLastSubeventPackets);
1300                 ba.putInt(mCrcErrorPackets);
1301                 ba.putInt(mRxDupPackets);
1302                 ba.putInt(mRxUnRecvPackets);
1303                 ba.putShort(mCoexInfoMask);
1304 
1305                 if (mQualityReportId
1306                         == (byte) BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO) {
1307                     ba.put(mConnState);
1308                     ba.putInt(mBasebandStats);
1309                     ba.putInt(mSlotsUsed);
1310                     ba.putShort(mCxmDenials);
1311                     ba.putShort(mTxSkipped);
1312                     ba.putShort(mRfLoss);
1313                     ba.putInt(mNativeClock);
1314                     ba.putInt(mLastTxAckTimestampLsto);
1315                 } else if (mQualityReportId
1316                         == (byte) BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY) {
1317                     ba.putInt(mArrivalTime);
1318                     ba.putInt(mScheduleTime);
1319                     ba.putShort(mGlitchCountA2dp);
1320                     ba.putShort(mTxCxmDenialsA2dp);
1321                     ba.putShort(mRxCxmDenialsA2dp);
1322                     ba.put(mAclTxQueueLength);
1323                     ba.put(mLinkQuality);
1324                 } else if (mQualityReportId
1325                         == (byte) BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY) {
1326                     ba.putShort(mGlitchCountSco);
1327                     ba.put(mIntervalEsco);
1328                     ba.put(mWindowEsco);
1329                     ba.put(mAirFormat);
1330                     ba.putShort(mInstanceCount);
1331                     ba.putShort(mTxCxmDenialsSco);
1332                     ba.putShort(mRxCxmDenialsSco);
1333                     ba.putShort(mTxAbortCount);
1334                     ba.putShort(mLateDispatch);
1335                     ba.putShort(mMicIntrMiss);
1336                     ba.putShort(mLpaIntrMiss);
1337                     ba.putShort(mSprIntrMiss);
1338                     ba.putShort(mPlcFillCount);
1339                     ba.putShort(mPlcDiscardCount);
1340                     ba.putShort(mMissedInstanceCount);
1341                     ba.putShort(mTxRetransmitSlotCount);
1342                     ba.putShort(mRxRetransmitSlotCount);
1343                     ba.putShort(mGoodRxFrameCount);
1344 
1345                 } else if (mQualityReportId
1346                         == (byte) BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL) {
1347                     ba.put(mFailReason);
1348                 }
1349             }
1350             return ba.array();
1351         }
1352     }
1353 }
1354