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