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