1 /* 2 * Copyright (C) 2019 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.net.wifi; 18 19 import android.annotation.IntDef; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.SystemApi; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.telephony.Annotation.NetworkType; 26 import android.util.Log; 27 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.util.Arrays; 31 import java.util.Collections; 32 import java.util.List; 33 import java.util.NoSuchElementException; 34 35 /** 36 * This class makes a subset of 37 * com.android.server.wifi.nano.WifiMetricsProto.WifiUsabilityStatsEntry parcelable. 38 * 39 * @hide 40 */ 41 @SystemApi 42 public final class WifiUsabilityStatsEntry implements Parcelable { 43 private static final String TAG = "WifiUsabilityStatsEntry"; 44 45 /** {@hide} */ 46 @Retention(RetentionPolicy.SOURCE) 47 @IntDef(prefix = {"PROBE_STATUS_"}, value = { 48 PROBE_STATUS_UNKNOWN, 49 PROBE_STATUS_NO_PROBE, 50 PROBE_STATUS_SUCCESS, 51 PROBE_STATUS_FAILURE}) 52 public @interface ProbeStatus {} 53 54 /** Link probe status is unknown */ 55 public static final int PROBE_STATUS_UNKNOWN = 0; 56 /** Link probe is not triggered */ 57 public static final int PROBE_STATUS_NO_PROBE = 1; 58 /** Link probe is triggered and the result is success */ 59 public static final int PROBE_STATUS_SUCCESS = 2; 60 /** Link probe is triggered and the result is failure */ 61 public static final int PROBE_STATUS_FAILURE = 3; 62 63 /** Absolute milliseconds from device boot when these stats were sampled */ 64 private final long mTimeStampMillis; 65 /** The RSSI (in dBm) at the sample time */ 66 private final int mRssi; 67 /** Link speed at the sample time in Mbps */ 68 private final int mLinkSpeedMbps; 69 /** The total number of tx success counted from the last radio chip reset */ 70 private final long mTotalTxSuccess; 71 /** The total number of MPDU data packet retries counted from the last radio chip reset */ 72 private final long mTotalTxRetries; 73 /** The total number of tx bad counted from the last radio chip reset */ 74 private final long mTotalTxBad; 75 /** The total number of rx success counted from the last radio chip reset */ 76 private final long mTotalRxSuccess; 77 /** The total time the wifi radio is on in ms counted from the last radio chip reset */ 78 private final long mTotalRadioOnTimeMillis; 79 /** The total time the wifi radio is doing tx in ms counted from the last radio chip reset */ 80 private final long mTotalRadioTxTimeMillis; 81 /** The total time the wifi radio is doing rx in ms counted from the last radio chip reset */ 82 private final long mTotalRadioRxTimeMillis; 83 /** The total time spent on all types of scans in ms counted from the last radio chip reset */ 84 private final long mTotalScanTimeMillis; 85 /** The total time spent on nan scans in ms counted from the last radio chip reset */ 86 private final long mTotalNanScanTimeMillis; 87 /** The total time spent on background scans in ms counted from the last radio chip reset */ 88 private final long mTotalBackgroundScanTimeMillis; 89 /** The total time spent on roam scans in ms counted from the last radio chip reset */ 90 private final long mTotalRoamScanTimeMillis; 91 /** The total time spent on pno scans in ms counted from the last radio chip reset */ 92 private final long mTotalPnoScanTimeMillis; 93 /** The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the last radio 94 * chip reset */ 95 private final long mTotalHotspot2ScanTimeMillis; 96 /** The total time CCA is on busy status on the current frequency in ms counted from the last 97 * radio chip reset */ 98 private final long mTotalCcaBusyFreqTimeMillis; 99 /** The total radio on time on the current frequency from the last radio chip reset */ 100 private final long mTotalRadioOnFreqTimeMillis; 101 /** The total number of beacons received from the last radio chip reset */ 102 private final long mTotalBeaconRx; 103 /** The status of link probe since last stats update */ 104 @ProbeStatus private final int mProbeStatusSinceLastUpdate; 105 /** The elapsed time of the most recent link probe since last stats update */ 106 private final int mProbeElapsedTimeSinceLastUpdateMillis; 107 /** The MCS rate of the most recent link probe since last stats update */ 108 private final int mProbeMcsRateSinceLastUpdate; 109 /** Rx link speed at the sample time in Mbps */ 110 private final int mRxLinkSpeedMbps; 111 /** @see #getTimeSliceDutyCycleInPercent() */ 112 private final int mTimeSliceDutyCycleInPercent; 113 114 /** {@hide} */ 115 @Retention(RetentionPolicy.SOURCE) 116 @IntDef(prefix = {"WME_ACCESS_CATEGORY_"}, value = { 117 WME_ACCESS_CATEGORY_BE, 118 WME_ACCESS_CATEGORY_BK, 119 WME_ACCESS_CATEGORY_VI, 120 WME_ACCESS_CATEGORY_VO}) 121 public @interface WmeAccessCategory {} 122 123 /** 124 * Wireless Multimedia Extensions (WME) Best Effort Access Category, IEEE Std 802.11-2020, 125 * Section 9.4.2.28, Table 9-155 126 */ 127 public static final int WME_ACCESS_CATEGORY_BE = 0; 128 /** 129 * Wireless Multimedia Extensions (WME) Background Access Category, IEEE Std 802.11-2020, 130 * Section 9.4.2.28, Table 9-155 131 */ 132 public static final int WME_ACCESS_CATEGORY_BK = 1; 133 /** 134 * Wireless Multimedia Extensions (WME) Video Access Category, IEEE Std 802.11-2020, 135 * Section 9.4.2.28, Table 9-155 136 */ 137 public static final int WME_ACCESS_CATEGORY_VI = 2; 138 /** 139 * Wireless Multimedia Extensions (WME) Voice Access Category, IEEE Std 802.11-2020, 140 * Section 9.4.2.28, Table 9-155 141 */ 142 public static final int WME_ACCESS_CATEGORY_VO = 3; 143 /** Number of WME Access Categories */ 144 public static final int NUM_WME_ACCESS_CATEGORIES = 4; 145 146 /** 147 * Data packet contention time statistics. 148 */ 149 public static final class ContentionTimeStats implements Parcelable { 150 private long mContentionTimeMinMicros; 151 private long mContentionTimeMaxMicros; 152 private long mContentionTimeAvgMicros; 153 private long mContentionNumSamples; 154 155 /** @hide */ ContentionTimeStats()156 public ContentionTimeStats() { 157 } 158 159 /** 160 * Constructor function 161 * @param timeMin The minimum data packet contention time 162 * @param timeMax The maximum data packet contention time 163 * @param timeAvg The average data packet contention time 164 * @param numSamples The number of samples used to get the reported contention time 165 */ ContentionTimeStats(long timeMin, long timeMax, long timeAvg, long numSamples)166 public ContentionTimeStats(long timeMin, long timeMax, long timeAvg, long numSamples) { 167 this.mContentionTimeMinMicros = timeMin; 168 this.mContentionTimeMaxMicros = timeMax; 169 this.mContentionTimeAvgMicros = timeAvg; 170 this.mContentionNumSamples = numSamples; 171 } 172 173 @Override describeContents()174 public int describeContents() { 175 return 0; 176 } 177 178 @Override writeToParcel(@onNull Parcel dest, int flags)179 public void writeToParcel(@NonNull Parcel dest, int flags) { 180 dest.writeLong(mContentionTimeMinMicros); 181 dest.writeLong(mContentionTimeMaxMicros); 182 dest.writeLong(mContentionTimeAvgMicros); 183 dest.writeLong(mContentionNumSamples); 184 } 185 186 /** Implement the Parcelable interface */ 187 public static final @NonNull Creator<ContentionTimeStats> CREATOR = 188 new Creator<ContentionTimeStats>() { 189 public ContentionTimeStats createFromParcel(Parcel in) { 190 ContentionTimeStats stats = new ContentionTimeStats(); 191 stats.mContentionTimeMinMicros = in.readLong(); 192 stats.mContentionTimeMaxMicros = in.readLong(); 193 stats.mContentionTimeAvgMicros = in.readLong(); 194 stats.mContentionNumSamples = in.readLong(); 195 return stats; 196 } 197 public ContentionTimeStats[] newArray(int size) { 198 return new ContentionTimeStats[size]; 199 } 200 }; 201 202 /** Data packet min contention time in microseconds */ getContentionTimeMinMicros()203 public long getContentionTimeMinMicros() { 204 return mContentionTimeMinMicros; 205 } 206 207 /** Data packet max contention time in microseconds */ getContentionTimeMaxMicros()208 public long getContentionTimeMaxMicros() { 209 return mContentionTimeMaxMicros; 210 } 211 212 /** Data packet average contention time in microseconds */ getContentionTimeAvgMicros()213 public long getContentionTimeAvgMicros() { 214 return mContentionTimeAvgMicros; 215 } 216 217 /** 218 * Number of data packets used for deriving the min, the max, and the average 219 * contention time 220 */ getContentionNumSamples()221 public long getContentionNumSamples() { 222 return mContentionNumSamples; 223 } 224 } 225 private final ContentionTimeStats[] mContentionTimeStats; 226 227 /** {@hide} */ 228 @Retention(RetentionPolicy.SOURCE) 229 @IntDef(prefix = {"WIFI_PREAMBLE_"}, value = { 230 WIFI_PREAMBLE_OFDM, 231 WIFI_PREAMBLE_CCK, 232 WIFI_PREAMBLE_HT, 233 WIFI_PREAMBLE_VHT, 234 WIFI_PREAMBLE_HE, 235 WIFI_PREAMBLE_EHT, 236 WIFI_PREAMBLE_INVALID}) 237 public @interface WifiPreambleType {} 238 239 /** Preamble type for 802.11a/g, IEEE Std 802.11-2020, Section 17 */ 240 public static final int WIFI_PREAMBLE_OFDM = 0; 241 /** Preamble type for 802.11b, IEEE Std 802.11-2020, Section 16 */ 242 public static final int WIFI_PREAMBLE_CCK = 1; 243 /** Preamble type for 802.11n, IEEE Std 802.11-2020, Section 19 */ 244 public static final int WIFI_PREAMBLE_HT = 2; 245 /** Preamble type for 802.11ac, IEEE Std 802.11-2020, Section 21 */ 246 public static final int WIFI_PREAMBLE_VHT = 3; 247 /** Preamble type for 802.11ax, IEEE Std 802.11ax-2021, Section 27 */ 248 public static final int WIFI_PREAMBLE_HE = 5; 249 /** Preamble type for 802.11be, IEEE Std 802.11be-2021, Section 36 */ 250 public static final int WIFI_PREAMBLE_EHT = 6; 251 /** Invalid */ 252 public static final int WIFI_PREAMBLE_INVALID = -1; 253 254 /** {@hide} */ 255 @Retention(RetentionPolicy.SOURCE) 256 @IntDef(prefix = {"WIFI_SPATIAL_STREAMS_"}, value = { 257 WIFI_SPATIAL_STREAMS_ONE, 258 WIFI_SPATIAL_STREAMS_TWO, 259 WIFI_SPATIAL_STREAMS_THREE, 260 WIFI_SPATIAL_STREAMS_FOUR, 261 WIFI_SPATIAL_STREAMS_INVALID}) 262 public @interface WifiSpatialStreams {} 263 264 /** Single stream, 1x1 */ 265 public static final int WIFI_SPATIAL_STREAMS_ONE = 1; 266 /** Dual streams, 2x2 */ 267 public static final int WIFI_SPATIAL_STREAMS_TWO = 2; 268 /** Three streams, 3x3 */ 269 public static final int WIFI_SPATIAL_STREAMS_THREE = 3; 270 /** Four streams, 4x4 */ 271 public static final int WIFI_SPATIAL_STREAMS_FOUR = 4; 272 /** Invalid */ 273 public static final int WIFI_SPATIAL_STREAMS_INVALID = -1; 274 275 /** {@hide} */ 276 @Retention(RetentionPolicy.SOURCE) 277 @IntDef(prefix = {"WIFI_BANDWIDTH_"}, value = { 278 WIFI_BANDWIDTH_20_MHZ, 279 WIFI_BANDWIDTH_40_MHZ, 280 WIFI_BANDWIDTH_80_MHZ, 281 WIFI_BANDWIDTH_160_MHZ, 282 WIFI_BANDWIDTH_320_MHZ, 283 WIFI_BANDWIDTH_80P80_MHZ, 284 WIFI_BANDWIDTH_5_MHZ, 285 WIFI_BANDWIDTH_10_MHZ, 286 WIFI_BANDWIDTH_INVALID}) 287 public @interface WifiChannelBandwidth {} 288 289 /** Channel bandwidth: 20MHz */ 290 public static final int WIFI_BANDWIDTH_20_MHZ = 0; 291 /** Channel bandwidth: 40MHz */ 292 public static final int WIFI_BANDWIDTH_40_MHZ = 1; 293 /** Channel bandwidth: 80MHz */ 294 public static final int WIFI_BANDWIDTH_80_MHZ = 2; 295 /** Channel bandwidth: 160MHz */ 296 public static final int WIFI_BANDWIDTH_160_MHZ = 3; 297 /** Channel bandwidth: 80MHz + 80MHz */ 298 public static final int WIFI_BANDWIDTH_80P80_MHZ = 4; 299 /** Channel bandwidth: 5MHz */ 300 public static final int WIFI_BANDWIDTH_5_MHZ = 5; 301 /** Channel bandwidth: 10MHz */ 302 public static final int WIFI_BANDWIDTH_10_MHZ = 6; 303 /** Channel bandwidth: 320MHz */ 304 public static final int WIFI_BANDWIDTH_320_MHZ = 7; 305 /** Invalid */ 306 public static final int WIFI_BANDWIDTH_INVALID = -1; 307 308 /** 309 * Rate information and statistics: packet counters (tx/rx successful packets, retries, lost) 310 * indexed by preamble, bandwidth, number of spatial streams, MCS, and bit rate. 311 */ 312 public static final class RateStats implements Parcelable { 313 @WifiPreambleType private int mPreamble; 314 @WifiSpatialStreams private int mNss; 315 @WifiChannelBandwidth private int mBw; 316 private int mRateMcsIdx; 317 private int mBitRateInKbps; 318 private int mTxMpdu; 319 private int mRxMpdu; 320 private int mMpduLost; 321 private int mRetries; 322 323 /** @hide */ RateStats()324 public RateStats() { 325 } 326 327 /** 328 * Constructor function. 329 * @param preamble Preamble information. 330 * @param nss Number of spatial streams. 331 * @param bw Bandwidth information. 332 * @param rateMcsIdx MCS index. OFDM/CCK rate code would be as per IEEE std in the units of 333 * 0.5Mbps. HT/VHT/HE/EHT: it would be MCS index. 334 * @param bitRateInKbps Bitrate in units of 100 Kbps. 335 * @param txMpdu Number of successfully transmitted data packets (ACK received). 336 * @param rxMpdu Number of received data packets. 337 * @param mpduLost Number of data packet losses (no ACK). 338 * @param retries Number of data packet retries. 339 */ RateStats(@ifiPreambleType int preamble, @WifiSpatialStreams int nss, @WifiChannelBandwidth int bw, int rateMcsIdx, int bitRateInKbps, int txMpdu, int rxMpdu, int mpduLost, int retries)340 public RateStats(@WifiPreambleType int preamble, @WifiSpatialStreams int nss, 341 @WifiChannelBandwidth int bw, int rateMcsIdx, int bitRateInKbps, int txMpdu, 342 int rxMpdu, int mpduLost, int retries) { 343 this.mPreamble = preamble; 344 this.mNss = nss; 345 this.mBw = bw; 346 this.mRateMcsIdx = rateMcsIdx; 347 this.mBitRateInKbps = bitRateInKbps; 348 this.mTxMpdu = txMpdu; 349 this.mRxMpdu = rxMpdu; 350 this.mMpduLost = mpduLost; 351 this.mRetries = retries; 352 } 353 354 @Override describeContents()355 public int describeContents() { 356 return 0; 357 } 358 359 @Override writeToParcel(@onNull Parcel dest, int flags)360 public void writeToParcel(@NonNull Parcel dest, int flags) { 361 dest.writeInt(mPreamble); 362 dest.writeInt(mNss); 363 dest.writeInt(mBw); 364 dest.writeInt(mRateMcsIdx); 365 dest.writeInt(mBitRateInKbps); 366 dest.writeInt(mTxMpdu); 367 dest.writeInt(mRxMpdu); 368 dest.writeInt(mMpduLost); 369 dest.writeInt(mRetries); 370 } 371 372 /** Implement the Parcelable interface */ 373 public static final @NonNull Creator<RateStats> CREATOR = new Creator<RateStats>() { 374 public RateStats createFromParcel(Parcel in) { 375 RateStats stats = new RateStats(); 376 stats.mPreamble = in.readInt(); 377 stats.mNss = in.readInt(); 378 stats.mBw = in.readInt(); 379 stats.mRateMcsIdx = in.readInt(); 380 stats.mBitRateInKbps = in.readInt(); 381 stats.mTxMpdu = in.readInt(); 382 stats.mRxMpdu = in.readInt(); 383 stats.mMpduLost = in.readInt(); 384 stats.mRetries = in.readInt(); 385 return stats; 386 } 387 public RateStats[] newArray(int size) { 388 return new RateStats[size]; 389 } 390 }; 391 392 /** Preamble information, see {@link WifiPreambleType} */ getPreamble()393 @WifiPreambleType public int getPreamble() { 394 return mPreamble; 395 } 396 397 /** Number of spatial streams, see {@link WifiSpatialStreams} */ getNumberOfSpatialStreams()398 @WifiSpatialStreams public int getNumberOfSpatialStreams() { 399 return mNss; 400 } 401 402 /** Bandwidth information, see {@link WifiChannelBandwidth} */ getBandwidthInMhz()403 @WifiChannelBandwidth public int getBandwidthInMhz() { 404 return mBw; 405 } 406 407 /** 408 * MCS index. OFDM/CCK rate code would be as per IEEE std in the units of 0.5Mbps. 409 * HT/VHT/HE/EHT: it would be MCS index 410 */ getRateMcsIdx()411 public int getRateMcsIdx() { 412 return mRateMcsIdx; 413 } 414 415 /** Bitrate in units of a hundred Kbps */ getBitRateInKbps()416 public int getBitRateInKbps() { 417 return mBitRateInKbps; 418 } 419 420 /** Number of successfully transmitted data packets (ACK received) */ getTxMpdu()421 public int getTxMpdu() { 422 return mTxMpdu; 423 } 424 425 /** Number of received data packets */ getRxMpdu()426 public int getRxMpdu() { 427 return mRxMpdu; 428 } 429 430 /** Number of data packet losses (no ACK) */ getMpduLost()431 public int getMpduLost() { 432 return mMpduLost; 433 } 434 435 /** Number of data packet retries */ getRetries()436 public int getRetries() { 437 return mRetries; 438 } 439 } 440 private final RateStats[] mRateStats; 441 442 /** 443 * Wifi link layer radio stats. 444 */ 445 public static final class RadioStats implements Parcelable { 446 private int mRadioId; 447 private long mTotalRadioOnTimeMillis; 448 private long mTotalRadioTxTimeMillis; 449 private long mTotalRadioRxTimeMillis; 450 private long mTotalScanTimeMillis; 451 private long mTotalNanScanTimeMillis; 452 private long mTotalBackgroundScanTimeMillis; 453 private long mTotalRoamScanTimeMillis; 454 private long mTotalPnoScanTimeMillis; 455 private long mTotalHotspot2ScanTimeMillis; 456 457 /** @hide */ RadioStats()458 public RadioStats() { 459 } 460 461 /** 462 * Constructor function 463 * @param radioId Firmware/Hardware implementation specific persistent value for this 464 * device, identifying the radio interface for which the stats are produced. 465 * @param onTime The total time the wifi radio is on in ms counted from the last radio 466 * chip reset 467 * @param txTime The total time the wifi radio is transmitting in ms counted from the last 468 * radio chip reset 469 * @param rxTime The total time the wifi radio is receiving in ms counted from the last 470 * radio chip reset 471 * @param onTimeScan The total time spent on all types of scans in ms counted from the 472 * last radio chip reset 473 * @param onTimeNanScan The total time spent on nan scans in ms counted from the last radio 474 * chip reset 475 * @param onTimeBackgroundScan The total time spent on background scans in ms counted from 476 * the last radio chip reset 477 * @param onTimeRoamScan The total time spent on roam scans in ms counted from the last 478 * radio chip reset 479 * @param onTimePnoScan The total time spent on pno scans in ms counted from the last radio 480 * chip reset 481 * @param onTimeHs20Scan The total time spent on hotspot2.0 scans and GAS exchange in ms 482 * counted from the last radio chip reset 483 */ RadioStats(int radioId, long onTime, long txTime, long rxTime, long onTimeScan, long onTimeNanScan, long onTimeBackgroundScan, long onTimeRoamScan, long onTimePnoScan, long onTimeHs20Scan)484 public RadioStats(int radioId, long onTime, long txTime, long rxTime, long onTimeScan, 485 long onTimeNanScan, long onTimeBackgroundScan, long onTimeRoamScan, 486 long onTimePnoScan, long onTimeHs20Scan) { 487 this.mRadioId = radioId; 488 this.mTotalRadioOnTimeMillis = onTime; 489 this.mTotalRadioTxTimeMillis = txTime; 490 this.mTotalRadioRxTimeMillis = rxTime; 491 this.mTotalScanTimeMillis = onTimeScan; 492 this.mTotalNanScanTimeMillis = onTimeNanScan; 493 this.mTotalBackgroundScanTimeMillis = onTimeBackgroundScan; 494 this.mTotalRoamScanTimeMillis = onTimeRoamScan; 495 this.mTotalPnoScanTimeMillis = onTimePnoScan; 496 this.mTotalHotspot2ScanTimeMillis = onTimeHs20Scan; 497 } 498 499 @Override describeContents()500 public int describeContents() { 501 return 0; 502 } 503 504 @Override writeToParcel(@onNull Parcel dest, int flags)505 public void writeToParcel(@NonNull Parcel dest, int flags) { 506 dest.writeInt(mRadioId); 507 dest.writeLong(mTotalRadioOnTimeMillis); 508 dest.writeLong(mTotalRadioTxTimeMillis); 509 dest.writeLong(mTotalRadioRxTimeMillis); 510 dest.writeLong(mTotalScanTimeMillis); 511 dest.writeLong(mTotalNanScanTimeMillis); 512 dest.writeLong(mTotalBackgroundScanTimeMillis); 513 dest.writeLong(mTotalRoamScanTimeMillis); 514 dest.writeLong(mTotalPnoScanTimeMillis); 515 dest.writeLong(mTotalHotspot2ScanTimeMillis); 516 } 517 518 /** Implement the Parcelable interface */ 519 public static final @NonNull Creator<RadioStats> CREATOR = 520 new Creator<RadioStats>() { 521 public RadioStats createFromParcel(Parcel in) { 522 RadioStats stats = new RadioStats(); 523 stats.mRadioId = in.readInt(); 524 stats.mTotalRadioOnTimeMillis = in.readLong(); 525 stats.mTotalRadioTxTimeMillis = in.readLong(); 526 stats.mTotalRadioRxTimeMillis = in.readLong(); 527 stats.mTotalScanTimeMillis = in.readLong(); 528 stats.mTotalNanScanTimeMillis = in.readLong(); 529 stats.mTotalBackgroundScanTimeMillis = in.readLong(); 530 stats.mTotalRoamScanTimeMillis = in.readLong(); 531 stats.mTotalPnoScanTimeMillis = in.readLong(); 532 stats.mTotalHotspot2ScanTimeMillis = in.readLong(); 533 return stats; 534 } 535 public RadioStats[] newArray(int size) { 536 return new RadioStats[size]; 537 } 538 }; 539 540 /** 541 * Firmware/Hardware implementation specific persistent value for this 542 * device, identifying the radio interface for which the stats are produced. 543 */ getRadioId()544 public long getRadioId() { 545 return mRadioId; 546 } 547 548 /** The total time the wifi radio is on in ms counted from the last radio chip reset */ getTotalRadioOnTimeMillis()549 public long getTotalRadioOnTimeMillis() { 550 return mTotalRadioOnTimeMillis; 551 } 552 553 /** 554 * The total time the wifi radio is transmitting in ms counted from the last radio chip 555 * reset 556 */ getTotalRadioTxTimeMillis()557 public long getTotalRadioTxTimeMillis() { 558 return mTotalRadioTxTimeMillis; 559 } 560 561 /** 562 * The total time the wifi radio is receiving in ms counted from the last radio chip reset 563 */ getTotalRadioRxTimeMillis()564 public long getTotalRadioRxTimeMillis() { 565 return mTotalRadioRxTimeMillis; 566 } 567 568 /** 569 * The total time spent on all types of scans in ms counted from the last radio chip reset 570 */ getTotalScanTimeMillis()571 public long getTotalScanTimeMillis() { 572 return mTotalScanTimeMillis; 573 } 574 575 /** The total time spent on nan scans in ms counted from the last radio chip reset */ getTotalNanScanTimeMillis()576 public long getTotalNanScanTimeMillis() { 577 return mTotalNanScanTimeMillis; 578 } 579 580 /** The total time spent on background scans in ms counted from the last radio chip reset */ getTotalBackgroundScanTimeMillis()581 public long getTotalBackgroundScanTimeMillis() { 582 return mTotalBackgroundScanTimeMillis; 583 } 584 585 /** The total time spent on roam scans in ms counted from the last radio chip reset */ getTotalRoamScanTimeMillis()586 public long getTotalRoamScanTimeMillis() { 587 return mTotalRoamScanTimeMillis; 588 } 589 590 /** The total time spent on pno scans in ms counted from the last radio chip reset */ getTotalPnoScanTimeMillis()591 public long getTotalPnoScanTimeMillis() { 592 return mTotalPnoScanTimeMillis; 593 } 594 595 /** 596 * The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the 597 * last radio chip reset 598 */ getTotalHotspot2ScanTimeMillis()599 public long getTotalHotspot2ScanTimeMillis() { 600 return mTotalHotspot2ScanTimeMillis; 601 } 602 } 603 private final RadioStats[] mRadioStats; 604 private final int mChannelUtilizationRatio; 605 private final boolean mIsThroughputSufficient; 606 private final boolean mIsWifiScoringEnabled; 607 private final boolean mIsCellularDataAvailable; 608 private final @NetworkType int mCellularDataNetworkType; 609 private final int mCellularSignalStrengthDbm; 610 private final int mCellularSignalStrengthDb; 611 private final boolean mIsSameRegisteredCell; 612 613 /** Constructor function {@hide} */ WifiUsabilityStatsEntry(long timeStampMillis, int rssi, int linkSpeedMbps, long totalTxSuccess, long totalTxRetries, long totalTxBad, long totalRxSuccess, long totalRadioOnTimeMillis, long totalRadioTxTimeMillis, long totalRadioRxTimeMillis, long totalScanTimeMillis, long totalNanScanTimeMillis, long totalBackgroundScanTimeMillis, long totalRoamScanTimeMillis, long totalPnoScanTimeMillis, long totalHotspot2ScanTimeMillis, long totalCcaBusyFreqTimeMillis, long totalRadioOnFreqTimeMillis, long totalBeaconRx, @ProbeStatus int probeStatusSinceLastUpdate, int probeElapsedTimeSinceLastUpdateMillis, int probeMcsRateSinceLastUpdate, int rxLinkSpeedMbps, int timeSliceDutyCycleInPercent, ContentionTimeStats[] contentionTimeStats, RateStats[] rateStats, RadioStats[] radiostats, int channelUtilizationRatio, boolean isThroughputSufficient, boolean isWifiScoringEnabled, boolean isCellularDataAvailable, @NetworkType int cellularDataNetworkType, int cellularSignalStrengthDbm, int cellularSignalStrengthDb, boolean isSameRegisteredCell)614 public WifiUsabilityStatsEntry(long timeStampMillis, int rssi, int linkSpeedMbps, 615 long totalTxSuccess, long totalTxRetries, long totalTxBad, long totalRxSuccess, 616 long totalRadioOnTimeMillis, long totalRadioTxTimeMillis, long totalRadioRxTimeMillis, 617 long totalScanTimeMillis, long totalNanScanTimeMillis, 618 long totalBackgroundScanTimeMillis, 619 long totalRoamScanTimeMillis, long totalPnoScanTimeMillis, 620 long totalHotspot2ScanTimeMillis, 621 long totalCcaBusyFreqTimeMillis, long totalRadioOnFreqTimeMillis, long totalBeaconRx, 622 @ProbeStatus int probeStatusSinceLastUpdate, int probeElapsedTimeSinceLastUpdateMillis, 623 int probeMcsRateSinceLastUpdate, int rxLinkSpeedMbps, 624 int timeSliceDutyCycleInPercent, ContentionTimeStats[] contentionTimeStats, 625 RateStats[] rateStats, RadioStats[] radiostats, int channelUtilizationRatio, 626 boolean isThroughputSufficient, boolean isWifiScoringEnabled, 627 boolean isCellularDataAvailable, @NetworkType int cellularDataNetworkType, 628 int cellularSignalStrengthDbm, int cellularSignalStrengthDb, 629 boolean isSameRegisteredCell) { 630 mTimeStampMillis = timeStampMillis; 631 mRssi = rssi; 632 mLinkSpeedMbps = linkSpeedMbps; 633 mTotalTxSuccess = totalTxSuccess; 634 mTotalTxRetries = totalTxRetries; 635 mTotalTxBad = totalTxBad; 636 mTotalRxSuccess = totalRxSuccess; 637 mTotalRadioOnTimeMillis = totalRadioOnTimeMillis; 638 mTotalRadioTxTimeMillis = totalRadioTxTimeMillis; 639 mTotalRadioRxTimeMillis = totalRadioRxTimeMillis; 640 mTotalScanTimeMillis = totalScanTimeMillis; 641 mTotalNanScanTimeMillis = totalNanScanTimeMillis; 642 mTotalBackgroundScanTimeMillis = totalBackgroundScanTimeMillis; 643 mTotalRoamScanTimeMillis = totalRoamScanTimeMillis; 644 mTotalPnoScanTimeMillis = totalPnoScanTimeMillis; 645 mTotalHotspot2ScanTimeMillis = totalHotspot2ScanTimeMillis; 646 mTotalCcaBusyFreqTimeMillis = totalCcaBusyFreqTimeMillis; 647 mTotalRadioOnFreqTimeMillis = totalRadioOnFreqTimeMillis; 648 mTotalBeaconRx = totalBeaconRx; 649 mProbeStatusSinceLastUpdate = probeStatusSinceLastUpdate; 650 mProbeElapsedTimeSinceLastUpdateMillis = probeElapsedTimeSinceLastUpdateMillis; 651 mProbeMcsRateSinceLastUpdate = probeMcsRateSinceLastUpdate; 652 mRxLinkSpeedMbps = rxLinkSpeedMbps; 653 mTimeSliceDutyCycleInPercent = timeSliceDutyCycleInPercent; 654 mContentionTimeStats = contentionTimeStats; 655 mRateStats = rateStats; 656 mRadioStats = radiostats; 657 mChannelUtilizationRatio = channelUtilizationRatio; 658 mIsThroughputSufficient = isThroughputSufficient; 659 mIsWifiScoringEnabled = isWifiScoringEnabled; 660 mIsCellularDataAvailable = isCellularDataAvailable; 661 mCellularDataNetworkType = cellularDataNetworkType; 662 mCellularSignalStrengthDbm = cellularSignalStrengthDbm; 663 mCellularSignalStrengthDb = cellularSignalStrengthDb; 664 mIsSameRegisteredCell = isSameRegisteredCell; 665 } 666 667 /** Implement the Parcelable interface */ describeContents()668 public int describeContents() { 669 return 0; 670 } 671 672 /** Implement the Parcelable interface */ writeToParcel(Parcel dest, int flags)673 public void writeToParcel(Parcel dest, int flags) { 674 dest.writeLong(mTimeStampMillis); 675 dest.writeInt(mRssi); 676 dest.writeInt(mLinkSpeedMbps); 677 dest.writeLong(mTotalTxSuccess); 678 dest.writeLong(mTotalTxRetries); 679 dest.writeLong(mTotalTxBad); 680 dest.writeLong(mTotalRxSuccess); 681 dest.writeLong(mTotalRadioOnTimeMillis); 682 dest.writeLong(mTotalRadioTxTimeMillis); 683 dest.writeLong(mTotalRadioRxTimeMillis); 684 dest.writeLong(mTotalScanTimeMillis); 685 dest.writeLong(mTotalNanScanTimeMillis); 686 dest.writeLong(mTotalBackgroundScanTimeMillis); 687 dest.writeLong(mTotalRoamScanTimeMillis); 688 dest.writeLong(mTotalPnoScanTimeMillis); 689 dest.writeLong(mTotalHotspot2ScanTimeMillis); 690 dest.writeLong(mTotalCcaBusyFreqTimeMillis); 691 dest.writeLong(mTotalRadioOnFreqTimeMillis); 692 dest.writeLong(mTotalBeaconRx); 693 dest.writeInt(mProbeStatusSinceLastUpdate); 694 dest.writeInt(mProbeElapsedTimeSinceLastUpdateMillis); 695 dest.writeInt(mProbeMcsRateSinceLastUpdate); 696 dest.writeInt(mRxLinkSpeedMbps); 697 dest.writeInt(mTimeSliceDutyCycleInPercent); 698 dest.writeTypedArray(mContentionTimeStats, flags); 699 dest.writeTypedArray(mRateStats, flags); 700 dest.writeTypedArray(mRadioStats, flags); 701 dest.writeInt(mChannelUtilizationRatio); 702 dest.writeBoolean(mIsThroughputSufficient); 703 dest.writeBoolean(mIsWifiScoringEnabled); 704 dest.writeBoolean(mIsCellularDataAvailable); 705 dest.writeInt(mCellularDataNetworkType); 706 dest.writeInt(mCellularSignalStrengthDbm); 707 dest.writeInt(mCellularSignalStrengthDb); 708 dest.writeBoolean(mIsSameRegisteredCell); 709 } 710 711 /** Implement the Parcelable interface */ 712 public static final @android.annotation.NonNull Creator<WifiUsabilityStatsEntry> CREATOR = 713 new Creator<WifiUsabilityStatsEntry>() { 714 public WifiUsabilityStatsEntry createFromParcel(Parcel in) { 715 return new WifiUsabilityStatsEntry( 716 in.readLong(), in.readInt(), 717 in.readInt(), in.readLong(), in.readLong(), 718 in.readLong(), in.readLong(), in.readLong(), 719 in.readLong(), in.readLong(), in.readLong(), 720 in.readLong(), in.readLong(), in.readLong(), 721 in.readLong(), in.readLong(), in.readLong(), 722 in.readLong(), in.readLong(), in.readInt(), 723 in.readInt(), in.readInt(), in.readInt(), 724 in.readInt(), in.createTypedArray(ContentionTimeStats.CREATOR), 725 in.createTypedArray(RateStats.CREATOR), 726 in.createTypedArray(RadioStats.CREATOR), 727 in.readInt(), in.readBoolean(), in.readBoolean(), 728 in.readBoolean(), in.readInt(), in.readInt(), 729 in.readInt(), in.readBoolean() 730 ); 731 } 732 733 public WifiUsabilityStatsEntry[] newArray(int size) { 734 return new WifiUsabilityStatsEntry[size]; 735 } 736 }; 737 738 /** Absolute milliseconds from device boot when these stats were sampled */ getTimeStampMillis()739 public long getTimeStampMillis() { 740 return mTimeStampMillis; 741 } 742 743 /** The RSSI (in dBm) at the sample time */ getRssi()744 public int getRssi() { 745 return mRssi; 746 } 747 748 /** Link speed at the sample time in Mbps */ getLinkSpeedMbps()749 public int getLinkSpeedMbps() { 750 return mLinkSpeedMbps; 751 } 752 753 /** The total number of tx success counted from the last radio chip reset */ getTotalTxSuccess()754 public long getTotalTxSuccess() { 755 return mTotalTxSuccess; 756 } 757 758 /** The total number of MPDU data packet retries counted from the last radio chip reset */ getTotalTxRetries()759 public long getTotalTxRetries() { 760 return mTotalTxRetries; 761 } 762 763 /** The total number of tx bad counted from the last radio chip reset */ getTotalTxBad()764 public long getTotalTxBad() { 765 return mTotalTxBad; 766 } 767 768 /** The total number of rx success counted from the last radio chip reset */ getTotalRxSuccess()769 public long getTotalRxSuccess() { 770 return mTotalRxSuccess; 771 } 772 773 /** The total time the wifi radio is on in ms counted from the last radio chip reset */ getTotalRadioOnTimeMillis()774 public long getTotalRadioOnTimeMillis() { 775 return mTotalRadioOnTimeMillis; 776 } 777 778 /** The total time the wifi radio is doing tx in ms counted from the last radio chip reset */ getTotalRadioTxTimeMillis()779 public long getTotalRadioTxTimeMillis() { 780 return mTotalRadioTxTimeMillis; 781 } 782 783 /** The total time the wifi radio is doing rx in ms counted from the last radio chip reset */ getTotalRadioRxTimeMillis()784 public long getTotalRadioRxTimeMillis() { 785 return mTotalRadioRxTimeMillis; 786 } 787 788 /** The total time spent on all types of scans in ms counted from the last radio chip reset */ getTotalScanTimeMillis()789 public long getTotalScanTimeMillis() { 790 return mTotalScanTimeMillis; 791 } 792 793 /** The total time spent on nan scans in ms counted from the last radio chip reset */ getTotalNanScanTimeMillis()794 public long getTotalNanScanTimeMillis() { 795 return mTotalNanScanTimeMillis; 796 } 797 798 /** The total time spent on background scans in ms counted from the last radio chip reset */ getTotalBackgroundScanTimeMillis()799 public long getTotalBackgroundScanTimeMillis() { 800 return mTotalBackgroundScanTimeMillis; 801 } 802 803 /** The total time spent on roam scans in ms counted from the last radio chip reset */ getTotalRoamScanTimeMillis()804 public long getTotalRoamScanTimeMillis() { 805 return mTotalRoamScanTimeMillis; 806 } 807 808 /** The total time spent on pno scans in ms counted from the last radio chip reset */ getTotalPnoScanTimeMillis()809 public long getTotalPnoScanTimeMillis() { 810 return mTotalPnoScanTimeMillis; 811 } 812 813 /** The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the last radio 814 * chip reset */ getTotalHotspot2ScanTimeMillis()815 public long getTotalHotspot2ScanTimeMillis() { 816 return mTotalHotspot2ScanTimeMillis; 817 } 818 819 /** The total time CCA is on busy status on the current frequency in ms counted from the last 820 * radio chip reset */ getTotalCcaBusyFreqTimeMillis()821 public long getTotalCcaBusyFreqTimeMillis() { 822 return mTotalCcaBusyFreqTimeMillis; 823 } 824 825 /** The total radio on time on the current frequency from the last radio chip reset */ getTotalRadioOnFreqTimeMillis()826 public long getTotalRadioOnFreqTimeMillis() { 827 return mTotalRadioOnFreqTimeMillis; 828 } 829 830 /** The total number of beacons received from the last radio chip reset */ getTotalBeaconRx()831 public long getTotalBeaconRx() { 832 return mTotalBeaconRx; 833 } 834 835 /** The status of link probe since last stats update */ getProbeStatusSinceLastUpdate()836 @ProbeStatus public int getProbeStatusSinceLastUpdate() { 837 return mProbeStatusSinceLastUpdate; 838 } 839 840 /** The elapsed time of the most recent link probe since last stats update */ getProbeElapsedTimeSinceLastUpdateMillis()841 public int getProbeElapsedTimeSinceLastUpdateMillis() { 842 return mProbeElapsedTimeSinceLastUpdateMillis; 843 } 844 845 /** The MCS rate of the most recent link probe since last stats update */ getProbeMcsRateSinceLastUpdate()846 public int getProbeMcsRateSinceLastUpdate() { 847 return mProbeMcsRateSinceLastUpdate; 848 } 849 850 /** Rx link speed at the sample time in Mbps */ getRxLinkSpeedMbps()851 public int getRxLinkSpeedMbps() { 852 return mRxLinkSpeedMbps; 853 } 854 855 /** 856 * Duty cycle of the connection. 857 * if this connection is being served using time slicing on a radio with one or more interfaces 858 * (i.e MCC), then this method returns the duty cycle assigned to this interface in percent. 859 * If no concurrency or not using time slicing during concurrency (i.e SCC or DBS), set to 100. 860 * 861 * @return duty cycle in percent if known. 862 * @throws NoSuchElementException if the duty cylce is unknown (not provided by the HAL). 863 */ getTimeSliceDutyCycleInPercent()864 public @IntRange(from = 0, to = 100) int getTimeSliceDutyCycleInPercent() { 865 if (mTimeSliceDutyCycleInPercent == -1) { 866 throw new NoSuchElementException("Unknown value"); 867 } 868 return mTimeSliceDutyCycleInPercent; 869 } 870 871 /** 872 * Data packet contention time statistics for Access Category. 873 * @param ac The access category, see {@link WmeAccessCategory}. 874 * @return The contention time statistics, see {@link ContentionTimeStats} 875 */ 876 @NonNull getContentionTimeStats(@meAccessCategory int ac)877 public ContentionTimeStats getContentionTimeStats(@WmeAccessCategory int ac) { 878 if (mContentionTimeStats != null 879 && mContentionTimeStats.length == NUM_WME_ACCESS_CATEGORIES) { 880 return mContentionTimeStats[ac]; 881 } 882 Log.e(TAG, "The ContentionTimeStats is not filled out correctly: " + mContentionTimeStats); 883 return new ContentionTimeStats(); 884 } 885 886 /** 887 * Rate information and statistics, which are ordered by preamble, modulation and coding scheme 888 * (MCS), and number of spatial streams (NSS). 889 * @return A list of rate statistics in the form of a list of {@link RateStats} objects. 890 * Depending on the link type, the list is created following the order of: 891 * - HT (IEEE Std 802.11-2020, Section 19): LEGACY rates (1Mbps, ..., 54Mbps), 892 * HT MCS0, ..., MCS15; 893 * - VHT (IEEE Std 802.11-2020, Section 21): LEGACY rates (1Mbps, ..., 54Mbps), 894 * VHT MCS0/NSS1, ..., VHT MCS11/NSS1, VHT MCSO/NSS2, ..., VHT MCS11/NSS2; 895 * - HE (IEEE Std 802.11ax-2020, Section 27): LEGACY rates (1Mbps, ..., 54Mbps), 896 * HE MCS0/NSS1, ..., HE MCS11/NSS1, HE MCSO/NSS2, ..., HE MCS11/NSS2. 897 * - EHT (IEEE std 802.11be-2021, Section 36): Legacy rates (1Mbps, ..., 54Mbps), 898 * EHT MSC0/NSS1, ..., EHT MCS14/NSS1, EHT MCS0/NSS2, ..., EHT MCS14/NSS2. 899 */ 900 @NonNull getRateStats()901 public List<RateStats> getRateStats() { 902 if (mRateStats != null) { 903 return Arrays.asList(mRateStats); 904 } 905 return Collections.emptyList(); 906 } 907 908 /** 909 * Radio stats from all the radios, see {@link RadioStats#getRadioId()} 910 * @return A list of Wifi link layer radio stats, see {@link RadioStats} 911 */ 912 @NonNull getWifiLinkLayerRadioStats()913 public List<RadioStats> getWifiLinkLayerRadioStats() { 914 if (mRadioStats != null) { 915 return Arrays.asList(mRadioStats); 916 } 917 return Collections.emptyList(); 918 } 919 920 /** 921 * Channel utilization ratio on the current channel. 922 * 923 * @return The channel utilization ratio (value) in the range of [0, 255], where x corresponds 924 * to (x * 100 / 255)%, or -1 indicating that there is no valid value to return. 925 */ getChannelUtilizationRatio()926 public @IntRange(from = -1, to = 255) int getChannelUtilizationRatio() { 927 return mChannelUtilizationRatio; 928 } 929 930 /** 931 * Indicate whether current link layer (L2) throughput is sufficient. L2 throughput is 932 * sufficient when one of the following conditions is met: 1) L3 throughput is low and L2 933 * throughput is above its low threshold; 2) L3 throughput is not low and L2 throughput over L3 934 * throughput ratio is above a threshold; 3) L3 throughput is not low and L2 throughput is 935 * above its high threshold. 936 * 937 * @return true if it is sufficient or false if it is insufficient. 938 */ isThroughputSufficient()939 public boolean isThroughputSufficient() { 940 return mIsThroughputSufficient; 941 } 942 943 /** 944 * Indicate whether Wi-Fi scoring is enabled by the user, 945 * see {@link WifiManager#setWifiScoringEnabled(boolean)}. 946 * 947 * @return true if it is enabled. 948 */ isWifiScoringEnabled()949 public boolean isWifiScoringEnabled() { 950 return mIsWifiScoringEnabled; 951 } 952 953 /** 954 * Indicate whether Cellular data is available. 955 * 956 * @return true if it is available and false otherwise. 957 */ isCellularDataAvailable()958 public boolean isCellularDataAvailable() { 959 return mIsCellularDataAvailable; 960 } 961 962 /** Cellular data network type currently in use on the device for data transmission */ getCellularDataNetworkType()963 @NetworkType public int getCellularDataNetworkType() { 964 return mCellularDataNetworkType; 965 } 966 967 /** 968 * Cellular signal strength in dBm, NR: CsiRsrp, LTE: Rsrp, WCDMA/TDSCDMA: Rscp, 969 * CDMA: Rssi, EVDO: Rssi, GSM: Rssi 970 */ getCellularSignalStrengthDbm()971 public int getCellularSignalStrengthDbm() { 972 return mCellularSignalStrengthDbm; 973 } 974 975 /** 976 * Cellular signal strength in dB, NR: CsiSinr, LTE: Rsrq, WCDMA: EcNo, TDSCDMA: invalid, 977 * CDMA: Ecio, EVDO: SNR, GSM: invalid 978 */ getCellularSignalStrengthDb()979 public int getCellularSignalStrengthDb() { 980 return mCellularSignalStrengthDb; 981 } 982 983 /** Whether the primary registered cell of current entry is same as that of previous entry */ isSameRegisteredCell()984 public boolean isSameRegisteredCell() { 985 return mIsSameRegisteredCell; 986 } 987 } 988