blob: 435bf4fcfea4a0a1f1cfb17af73f1a83d8312205 [file] [log] [blame]
Aurimas Liutikasdc3f8852024-07-11 10:07:48 -07001/*
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
17package android.net.wifi;
18
19import android.annotation.FlaggedApi;
20import android.annotation.IntDef;
21import android.annotation.IntRange;
22import android.annotation.NonNull;
23import android.annotation.SystemApi;
24import android.os.Parcel;
25import android.os.Parcelable;
26import android.telephony.Annotation.NetworkType;
27import android.util.Log;
28import android.util.SparseArray;
29
30import androidx.annotation.Nullable;
31
32import com.android.wifi.flags.Flags;
33
34import java.lang.annotation.Retention;
35import java.lang.annotation.RetentionPolicy;
36import java.util.Arrays;
37import java.util.Collections;
38import java.util.List;
39import java.util.NoSuchElementException;
40
41/**
42 * This class makes a subset of
43 * com.android.server.wifi.nano.WifiMetricsProto.WifiUsabilityStatsEntry parcelable.
44 *
45 * @hide
46 */
47@SystemApi
48public final class WifiUsabilityStatsEntry implements Parcelable {
49 private static final String TAG = "WifiUsabilityStatsEntry";
50
51 /** @hide */
52 @Retention(RetentionPolicy.SOURCE)
53 @IntDef(prefix = {"LINK_STATE_"}, value = {
54 LINK_STATE_UNKNOWN,
55 LINK_STATE_NOT_IN_USE,
56 LINK_STATE_IN_USE})
57 public @interface LinkState {}
58
59 /** @hide */
60 public static String getLinkStateString(@LinkState int state) {
61 switch (state) {
62 case LINK_STATE_NOT_IN_USE:
63 return "LINK_STATE_NOT_IN_USE";
64 case LINK_STATE_IN_USE:
65 return "LINK_STATE_IN_USE";
66 default:
67 return "LINK_STATE_UNKNOWN";
68 }
69 }
70
71 /** Chip does not support reporting the state of the link. */
72 public static final int LINK_STATE_UNKNOWN = 0;
73 /**
74 * Link has not been in use since last report. It is placed in power save. All management,
75 * control and data frames for the MLO connection are carried over other links. In this state
76 * the link will not listen to beacons even in DTIM period and does not perform any
77 * GTK/IGTK/BIGTK updates but remains associated.
78 */
79 public static final int LINK_STATE_NOT_IN_USE = 1;
80 /**
81 * Link is in use. In presence of traffic, it is set to be power active. When the traffic
82 * stops, the link will go into power save mode and will listen for beacons every DTIM period.
83 */
84 public static final int LINK_STATE_IN_USE = 2;
85
86 /** @hide */
87 @Retention(RetentionPolicy.SOURCE)
88 @IntDef(prefix = {"PROBE_STATUS_"}, value = {
89 PROBE_STATUS_UNKNOWN,
90 PROBE_STATUS_NO_PROBE,
91 PROBE_STATUS_SUCCESS,
92 PROBE_STATUS_FAILURE})
93 public @interface ProbeStatus {}
94
95 /** Link probe status is unknown */
96 public static final int PROBE_STATUS_UNKNOWN = 0;
97 /** Link probe is not triggered */
98 public static final int PROBE_STATUS_NO_PROBE = 1;
99 /** Link probe is triggered and the result is success */
100 public static final int PROBE_STATUS_SUCCESS = 2;
101 /** Link probe is triggered and the result is failure */
102 public static final int PROBE_STATUS_FAILURE = 3;
103
104 /** Absolute milliseconds from device boot when these stats were sampled */
105 private final long mTimeStampMillis;
106 /** The RSSI (in dBm) at the sample time */
107 private final int mRssi;
108 /** Link speed at the sample time in Mbps */
109 private final int mLinkSpeedMbps;
110 /** The total number of tx success counted from the last radio chip reset */
111 private final long mTotalTxSuccess;
112 /** The total number of MPDU data packet retries counted from the last radio chip reset */
113 private final long mTotalTxRetries;
114 /** The total number of tx bad counted from the last radio chip reset */
115 private final long mTotalTxBad;
116 /** The total number of rx success counted from the last radio chip reset */
117 private final long mTotalRxSuccess;
118 /** The total time the wifi radio is on in ms counted from the last radio chip reset */
119 private final long mTotalRadioOnTimeMillis;
120 /** The total time the wifi radio is doing tx in ms counted from the last radio chip reset */
121 private final long mTotalRadioTxTimeMillis;
122 /** The total time the wifi radio is doing rx in ms counted from the last radio chip reset */
123 private final long mTotalRadioRxTimeMillis;
124 /** The total time spent on all types of scans in ms counted from the last radio chip reset */
125 private final long mTotalScanTimeMillis;
126 /** The total time spent on nan scans in ms counted from the last radio chip reset */
127 private final long mTotalNanScanTimeMillis;
128 /** The total time spent on background scans in ms counted from the last radio chip reset */
129 private final long mTotalBackgroundScanTimeMillis;
130 /** The total time spent on roam scans in ms counted from the last radio chip reset */
131 private final long mTotalRoamScanTimeMillis;
132 /** The total time spent on pno scans in ms counted from the last radio chip reset */
133 private final long mTotalPnoScanTimeMillis;
134 /** The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the last radio
135 * chip reset */
136 private final long mTotalHotspot2ScanTimeMillis;
137 /** The total time CCA is on busy status on the current frequency in ms counted from the last
138 * radio chip reset */
139 private final long mTotalCcaBusyFreqTimeMillis;
140 /** The total radio on time on the current frequency from the last radio chip reset */
141 private final long mTotalRadioOnFreqTimeMillis;
142 /** The total number of beacons received from the last radio chip reset */
143 private final long mTotalBeaconRx;
144 /** The status of link probe since last stats update */
145 @ProbeStatus private final int mProbeStatusSinceLastUpdate;
146 /** The elapsed time of the most recent link probe since last stats update */
147 private final int mProbeElapsedTimeSinceLastUpdateMillis;
148 /** The MCS rate of the most recent link probe since last stats update */
149 private final int mProbeMcsRateSinceLastUpdate;
150 /** Rx link speed at the sample time in Mbps */
151 private final int mRxLinkSpeedMbps;
152 /** @see #getTimeSliceDutyCycleInPercent() */
153 private final int mTimeSliceDutyCycleInPercent;
154
155 /** {@hide} */
156 @Retention(RetentionPolicy.SOURCE)
157 @IntDef(prefix = {"WME_ACCESS_CATEGORY_"}, value = {
158 WME_ACCESS_CATEGORY_BE,
159 WME_ACCESS_CATEGORY_BK,
160 WME_ACCESS_CATEGORY_VI,
161 WME_ACCESS_CATEGORY_VO})
162 public @interface WmeAccessCategory {}
163
164 /**
165 * Wireless Multimedia Extensions (WME) Best Effort Access Category, IEEE Std 802.11-2020,
166 * Section 9.4.2.28, Table 9-155
167 */
168 public static final int WME_ACCESS_CATEGORY_BE = 0;
169 /**
170 * Wireless Multimedia Extensions (WME) Background Access Category, IEEE Std 802.11-2020,
171 * Section 9.4.2.28, Table 9-155
172 */
173 public static final int WME_ACCESS_CATEGORY_BK = 1;
174 /**
175 * Wireless Multimedia Extensions (WME) Video Access Category, IEEE Std 802.11-2020,
176 * Section 9.4.2.28, Table 9-155
177 */
178 public static final int WME_ACCESS_CATEGORY_VI = 2;
179 /**
180 * Wireless Multimedia Extensions (WME) Voice Access Category, IEEE Std 802.11-2020,
181 * Section 9.4.2.28, Table 9-155
182 */
183 public static final int WME_ACCESS_CATEGORY_VO = 3;
184 /** Number of WME Access Categories */
185 public static final int NUM_WME_ACCESS_CATEGORIES = 4;
186
187 /**
188 * Data packet contention time statistics.
189 */
190 public static final class ContentionTimeStats implements Parcelable {
191 private long mContentionTimeMinMicros;
192 private long mContentionTimeMaxMicros;
193 private long mContentionTimeAvgMicros;
194 private long mContentionNumSamples;
195
196 /** @hide */
197 public ContentionTimeStats() {
198 }
199
200 /**
201 * Constructor function
202 * @param timeMin The minimum data packet contention time
203 * @param timeMax The maximum data packet contention time
204 * @param timeAvg The average data packet contention time
205 * @param numSamples The number of samples used to get the reported contention time
206 */
207 public ContentionTimeStats(long timeMin, long timeMax, long timeAvg, long numSamples) {
208 this.mContentionTimeMinMicros = timeMin;
209 this.mContentionTimeMaxMicros = timeMax;
210 this.mContentionTimeAvgMicros = timeAvg;
211 this.mContentionNumSamples = numSamples;
212 }
213
214 @Override
215 public int describeContents() {
216 return 0;
217 }
218
219 @Override
220 public void writeToParcel(@NonNull Parcel dest, int flags) {
221 dest.writeLong(mContentionTimeMinMicros);
222 dest.writeLong(mContentionTimeMaxMicros);
223 dest.writeLong(mContentionTimeAvgMicros);
224 dest.writeLong(mContentionNumSamples);
225 }
226
227 /** Implement the Parcelable interface */
228 public static final @NonNull Creator<ContentionTimeStats> CREATOR =
229 new Creator<ContentionTimeStats>() {
230 public ContentionTimeStats createFromParcel(Parcel in) {
231 ContentionTimeStats stats = new ContentionTimeStats();
232 stats.mContentionTimeMinMicros = in.readLong();
233 stats.mContentionTimeMaxMicros = in.readLong();
234 stats.mContentionTimeAvgMicros = in.readLong();
235 stats.mContentionNumSamples = in.readLong();
236 return stats;
237 }
238 public ContentionTimeStats[] newArray(int size) {
239 return new ContentionTimeStats[size];
240 }
241 };
242
243 /** Data packet min contention time in microseconds */
244 public long getContentionTimeMinMicros() {
245 return mContentionTimeMinMicros;
246 }
247
248 /** Data packet max contention time in microseconds */
249 public long getContentionTimeMaxMicros() {
250 return mContentionTimeMaxMicros;
251 }
252
253 /** Data packet average contention time in microseconds */
254 public long getContentionTimeAvgMicros() {
255 return mContentionTimeAvgMicros;
256 }
257
258 /**
259 * Number of data packets used for deriving the min, the max, and the average
260 * contention time
261 */
262 public long getContentionNumSamples() {
263 return mContentionNumSamples;
264 }
265 }
266 private final ContentionTimeStats[] mContentionTimeStats;
267
268 /** {@hide} */
269 @Retention(RetentionPolicy.SOURCE)
270 @IntDef(prefix = {"WIFI_PREAMBLE_"}, value = {
271 WIFI_PREAMBLE_OFDM,
272 WIFI_PREAMBLE_CCK,
273 WIFI_PREAMBLE_HT,
274 WIFI_PREAMBLE_VHT,
275 WIFI_PREAMBLE_HE,
276 WIFI_PREAMBLE_EHT,
277 WIFI_PREAMBLE_INVALID})
278 public @interface WifiPreambleType {}
279
280 /** Preamble type for 802.11a/g, IEEE Std 802.11-2020, Section 17 */
281 public static final int WIFI_PREAMBLE_OFDM = 0;
282 /** Preamble type for 802.11b, IEEE Std 802.11-2020, Section 16 */
283 public static final int WIFI_PREAMBLE_CCK = 1;
284 /** Preamble type for 802.11n, IEEE Std 802.11-2020, Section 19 */
285 public static final int WIFI_PREAMBLE_HT = 2;
286 /** Preamble type for 802.11ac, IEEE Std 802.11-2020, Section 21 */
287 public static final int WIFI_PREAMBLE_VHT = 3;
288 /** Preamble type for 802.11ax, IEEE Std 802.11ax-2021, Section 27 */
289 public static final int WIFI_PREAMBLE_HE = 5;
290 /** Preamble type for 802.11be, IEEE Std 802.11be-2021, Section 36 */
291 public static final int WIFI_PREAMBLE_EHT = 6;
292 /** Invalid */
293 public static final int WIFI_PREAMBLE_INVALID = -1;
294
295 /** {@hide} */
296 @Retention(RetentionPolicy.SOURCE)
297 @IntDef(prefix = {"WIFI_SPATIAL_STREAMS_"}, value = {
298 WIFI_SPATIAL_STREAMS_ONE,
299 WIFI_SPATIAL_STREAMS_TWO,
300 WIFI_SPATIAL_STREAMS_THREE,
301 WIFI_SPATIAL_STREAMS_FOUR,
302 WIFI_SPATIAL_STREAMS_INVALID})
303 public @interface WifiSpatialStreams {}
304
305 /** Single stream, 1x1 */
306 public static final int WIFI_SPATIAL_STREAMS_ONE = 1;
307 /** Dual streams, 2x2 */
308 public static final int WIFI_SPATIAL_STREAMS_TWO = 2;
309 /** Three streams, 3x3 */
310 public static final int WIFI_SPATIAL_STREAMS_THREE = 3;
311 /** Four streams, 4x4 */
312 public static final int WIFI_SPATIAL_STREAMS_FOUR = 4;
313 /** Invalid */
314 public static final int WIFI_SPATIAL_STREAMS_INVALID = -1;
315
316 /** {@hide} */
317 @Retention(RetentionPolicy.SOURCE)
318 @IntDef(prefix = {"WIFI_BANDWIDTH_"}, value = {
319 WIFI_BANDWIDTH_20_MHZ,
320 WIFI_BANDWIDTH_40_MHZ,
321 WIFI_BANDWIDTH_80_MHZ,
322 WIFI_BANDWIDTH_160_MHZ,
323 WIFI_BANDWIDTH_320_MHZ,
324 WIFI_BANDWIDTH_80P80_MHZ,
325 WIFI_BANDWIDTH_5_MHZ,
326 WIFI_BANDWIDTH_10_MHZ,
327 WIFI_BANDWIDTH_INVALID})
328 public @interface WifiChannelBandwidth {}
329
330 /** Channel bandwidth: 20MHz */
331 public static final int WIFI_BANDWIDTH_20_MHZ = 0;
332 /** Channel bandwidth: 40MHz */
333 public static final int WIFI_BANDWIDTH_40_MHZ = 1;
334 /** Channel bandwidth: 80MHz */
335 public static final int WIFI_BANDWIDTH_80_MHZ = 2;
336 /** Channel bandwidth: 160MHz */
337 public static final int WIFI_BANDWIDTH_160_MHZ = 3;
338 /** Channel bandwidth: 80MHz + 80MHz */
339 public static final int WIFI_BANDWIDTH_80P80_MHZ = 4;
340 /** Channel bandwidth: 5MHz */
341 public static final int WIFI_BANDWIDTH_5_MHZ = 5;
342 /** Channel bandwidth: 10MHz */
343 public static final int WIFI_BANDWIDTH_10_MHZ = 6;
344 /** Channel bandwidth: 320MHz */
345 public static final int WIFI_BANDWIDTH_320_MHZ = 7;
346 /** Invalid */
347 public static final int WIFI_BANDWIDTH_INVALID = -1;
348
349 /**
350 * Rate information and statistics: packet counters (tx/rx successful packets, retries, lost)
351 * indexed by preamble, bandwidth, number of spatial streams, MCS, and bit rate.
352 */
353 public static final class RateStats implements Parcelable {
354 @WifiPreambleType private int mPreamble;
355 @WifiSpatialStreams private int mNss;
356 @WifiChannelBandwidth private int mBw;
357 private int mRateMcsIdx;
358 private int mBitRateInKbps;
359 private int mTxMpdu;
360 private int mRxMpdu;
361 private int mMpduLost;
362 private int mRetries;
363
364 /** @hide */
365 public RateStats() {
366 }
367
368 /**
369 * Constructor function.
370 * @param preamble Preamble information.
371 * @param nss Number of spatial streams.
372 * @param bw Bandwidth information.
373 * @param rateMcsIdx MCS index. OFDM/CCK rate code would be as per IEEE std in the units of
374 * 0.5Mbps. HT/VHT/HE/EHT: it would be MCS index.
375 * @param bitRateInKbps Bitrate in units of 100 Kbps.
376 * @param txMpdu Number of successfully transmitted data packets (ACK received).
377 * @param rxMpdu Number of received data packets.
378 * @param mpduLost Number of data packet losses (no ACK).
379 * @param retries Number of data packet retries.
380 */
381 public RateStats(@WifiPreambleType int preamble, @WifiSpatialStreams int nss,
382 @WifiChannelBandwidth int bw, int rateMcsIdx, int bitRateInKbps, int txMpdu,
383 int rxMpdu, int mpduLost, int retries) {
384 this.mPreamble = preamble;
385 this.mNss = nss;
386 this.mBw = bw;
387 this.mRateMcsIdx = rateMcsIdx;
388 this.mBitRateInKbps = bitRateInKbps;
389 this.mTxMpdu = txMpdu;
390 this.mRxMpdu = rxMpdu;
391 this.mMpduLost = mpduLost;
392 this.mRetries = retries;
393 }
394
395 @Override
396 public int describeContents() {
397 return 0;
398 }
399
400 @Override
401 public void writeToParcel(@NonNull Parcel dest, int flags) {
402 dest.writeInt(mPreamble);
403 dest.writeInt(mNss);
404 dest.writeInt(mBw);
405 dest.writeInt(mRateMcsIdx);
406 dest.writeInt(mBitRateInKbps);
407 dest.writeInt(mTxMpdu);
408 dest.writeInt(mRxMpdu);
409 dest.writeInt(mMpduLost);
410 dest.writeInt(mRetries);
411 }
412
413 /** Implement the Parcelable interface */
414 public static final @NonNull Creator<RateStats> CREATOR = new Creator<RateStats>() {
415 public RateStats createFromParcel(Parcel in) {
416 RateStats stats = new RateStats();
417 stats.mPreamble = in.readInt();
418 stats.mNss = in.readInt();
419 stats.mBw = in.readInt();
420 stats.mRateMcsIdx = in.readInt();
421 stats.mBitRateInKbps = in.readInt();
422 stats.mTxMpdu = in.readInt();
423 stats.mRxMpdu = in.readInt();
424 stats.mMpduLost = in.readInt();
425 stats.mRetries = in.readInt();
426 return stats;
427 }
428 public RateStats[] newArray(int size) {
429 return new RateStats[size];
430 }
431 };
432
433 /** Preamble information, see {@link WifiPreambleType} */
434 @WifiPreambleType public int getPreamble() {
435 return mPreamble;
436 }
437
438 /** Number of spatial streams, see {@link WifiSpatialStreams} */
439 @WifiSpatialStreams public int getNumberOfSpatialStreams() {
440 return mNss;
441 }
442
443 /** Bandwidth information, see {@link WifiChannelBandwidth} */
444 @WifiChannelBandwidth public int getBandwidthInMhz() {
445 return mBw;
446 }
447
448 /**
449 * MCS index. OFDM/CCK rate code would be as per IEEE std in the units of 0.5Mbps.
450 * HT/VHT/HE/EHT: it would be MCS index
451 */
452 public int getRateMcsIdx() {
453 return mRateMcsIdx;
454 }
455
456 /** Bitrate in units of a hundred Kbps */
457 public int getBitRateInKbps() {
458 return mBitRateInKbps;
459 }
460
461 /** Number of successfully transmitted data packets (ACK received) */
462 public int getTxMpdu() {
463 return mTxMpdu;
464 }
465
466 /** Number of received data packets */
467 public int getRxMpdu() {
468 return mRxMpdu;
469 }
470
471 /** Number of data packet losses (no ACK) */
472 public int getMpduLost() {
473 return mMpduLost;
474 }
475
476 /** Number of data packet retries */
477 public int getRetries() {
478 return mRetries;
479 }
480 }
481 private final RateStats[] mRateStats;
482
483 /**
484 * Wifi link layer radio stats.
485 */
486 public static final class RadioStats implements Parcelable {
487 /**
488 * Invalid radio id.
489 * @hide
490 */
491 public static final int INVALID_RADIO_ID = -1;
492 private int mRadioId;
493 private long mTotalRadioOnTimeMillis;
494 private long mTotalRadioTxTimeMillis;
495 private long mTotalRadioRxTimeMillis;
496 private long mTotalScanTimeMillis;
497 private long mTotalNanScanTimeMillis;
498 private long mTotalBackgroundScanTimeMillis;
499 private long mTotalRoamScanTimeMillis;
500 private long mTotalPnoScanTimeMillis;
501 private long mTotalHotspot2ScanTimeMillis;
502
503 /** @hide */
504 public RadioStats() {
505 }
506
507 /**
508 * Constructor function
509 * @param radioId Firmware/Hardware implementation specific persistent value for this
510 * device, identifying the radio interface for which the stats are produced.
511 * @param onTime The total time the wifi radio is on in ms counted from the last radio
512 * chip reset
513 * @param txTime The total time the wifi radio is transmitting in ms counted from the last
514 * radio chip reset
515 * @param rxTime The total time the wifi radio is receiving in ms counted from the last
516 * radio chip reset
517 * @param onTimeScan The total time spent on all types of scans in ms counted from the
518 * last radio chip reset
519 * @param onTimeNanScan The total time spent on nan scans in ms counted from the last radio
520 * chip reset
521 * @param onTimeBackgroundScan The total time spent on background scans in ms counted from
522 * the last radio chip reset
523 * @param onTimeRoamScan The total time spent on roam scans in ms counted from the last
524 * radio chip reset
525 * @param onTimePnoScan The total time spent on pno scans in ms counted from the last radio
526 * chip reset
527 * @param onTimeHs20Scan The total time spent on hotspot2.0 scans and GAS exchange in ms
528 * counted from the last radio chip reset
529 */
530 public RadioStats(int radioId, long onTime, long txTime, long rxTime, long onTimeScan,
531 long onTimeNanScan, long onTimeBackgroundScan, long onTimeRoamScan,
532 long onTimePnoScan, long onTimeHs20Scan) {
533 this.mRadioId = radioId;
534 this.mTotalRadioOnTimeMillis = onTime;
535 this.mTotalRadioTxTimeMillis = txTime;
536 this.mTotalRadioRxTimeMillis = rxTime;
537 this.mTotalScanTimeMillis = onTimeScan;
538 this.mTotalNanScanTimeMillis = onTimeNanScan;
539 this.mTotalBackgroundScanTimeMillis = onTimeBackgroundScan;
540 this.mTotalRoamScanTimeMillis = onTimeRoamScan;
541 this.mTotalPnoScanTimeMillis = onTimePnoScan;
542 this.mTotalHotspot2ScanTimeMillis = onTimeHs20Scan;
543 }
544
545 @Override
546 public int describeContents() {
547 return 0;
548 }
549
550 @Override
551 public void writeToParcel(@NonNull Parcel dest, int flags) {
552 dest.writeInt(mRadioId);
553 dest.writeLong(mTotalRadioOnTimeMillis);
554 dest.writeLong(mTotalRadioTxTimeMillis);
555 dest.writeLong(mTotalRadioRxTimeMillis);
556 dest.writeLong(mTotalScanTimeMillis);
557 dest.writeLong(mTotalNanScanTimeMillis);
558 dest.writeLong(mTotalBackgroundScanTimeMillis);
559 dest.writeLong(mTotalRoamScanTimeMillis);
560 dest.writeLong(mTotalPnoScanTimeMillis);
561 dest.writeLong(mTotalHotspot2ScanTimeMillis);
562 }
563
564 /** Implement the Parcelable interface */
565 public static final @NonNull Creator<RadioStats> CREATOR =
566 new Creator<RadioStats>() {
567 public RadioStats createFromParcel(Parcel in) {
568 RadioStats stats = new RadioStats();
569 stats.mRadioId = in.readInt();
570 stats.mTotalRadioOnTimeMillis = in.readLong();
571 stats.mTotalRadioTxTimeMillis = in.readLong();
572 stats.mTotalRadioRxTimeMillis = in.readLong();
573 stats.mTotalScanTimeMillis = in.readLong();
574 stats.mTotalNanScanTimeMillis = in.readLong();
575 stats.mTotalBackgroundScanTimeMillis = in.readLong();
576 stats.mTotalRoamScanTimeMillis = in.readLong();
577 stats.mTotalPnoScanTimeMillis = in.readLong();
578 stats.mTotalHotspot2ScanTimeMillis = in.readLong();
579 return stats;
580 }
581 public RadioStats[] newArray(int size) {
582 return new RadioStats[size];
583 }
584 };
585
586 /**
587 * Firmware/Hardware implementation specific persistent value for this
588 * device, identifying the radio interface for which the stats are produced.
589 */
590 public long getRadioId() {
591 return mRadioId;
592 }
593
594 /** The total time the wifi radio is on in ms counted from the last radio chip reset */
595 public long getTotalRadioOnTimeMillis() {
596 return mTotalRadioOnTimeMillis;
597 }
598
599 /**
600 * The total time the wifi radio is transmitting in ms counted from the last radio chip
601 * reset
602 */
603 public long getTotalRadioTxTimeMillis() {
604 return mTotalRadioTxTimeMillis;
605 }
606
607 /**
608 * The total time the wifi radio is receiving in ms counted from the last radio chip reset
609 */
610 public long getTotalRadioRxTimeMillis() {
611 return mTotalRadioRxTimeMillis;
612 }
613
614 /**
615 * The total time spent on all types of scans in ms counted from the last radio chip reset
616 */
617 public long getTotalScanTimeMillis() {
618 return mTotalScanTimeMillis;
619 }
620
621 /** The total time spent on nan scans in ms counted from the last radio chip reset */
622 public long getTotalNanScanTimeMillis() {
623 return mTotalNanScanTimeMillis;
624 }
625
626 /** The total time spent on background scans in ms counted from the last radio chip reset */
627 public long getTotalBackgroundScanTimeMillis() {
628 return mTotalBackgroundScanTimeMillis;
629 }
630
631 /** The total time spent on roam scans in ms counted from the last radio chip reset */
632 public long getTotalRoamScanTimeMillis() {
633 return mTotalRoamScanTimeMillis;
634 }
635
636 /** The total time spent on pno scans in ms counted from the last radio chip reset */
637 public long getTotalPnoScanTimeMillis() {
638 return mTotalPnoScanTimeMillis;
639 }
640
641 /**
642 * The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the
643 * last radio chip reset
644 */
645 public long getTotalHotspot2ScanTimeMillis() {
646 return mTotalHotspot2ScanTimeMillis;
647 }
648 }
649 private final RadioStats[] mRadioStats;
650 private final int mChannelUtilizationRatio;
651 private final boolean mIsThroughputSufficient;
652 private final boolean mIsWifiScoringEnabled;
653 private final boolean mIsCellularDataAvailable;
654 private final @NetworkType int mCellularDataNetworkType;
655 private final int mCellularSignalStrengthDbm;
656 private final int mCellularSignalStrengthDb;
657 private final boolean mIsSameRegisteredCell;
658
659 /**
660 * Link specific statistics.
661 *
662 * @hide
663 */
664 public static final class LinkStats implements Parcelable {
665 /** Link identifier (0 to 14) */
666 private final int mLinkId;
667 /** Link state as listed {@link LinkState} */
668 private final @LinkState int mState;
669 /** Radio identifier */
670 private final int mRadioId;
671 /** The RSSI (in dBm) at the sample time */
672 private final int mRssi;
673 /** Tx Link speed at the sample time in Mbps */
674 private final int mTxLinkSpeedMbps;
675 /** Rx link speed at the sample time in Mbps */
676 private final int mRxLinkSpeedMbps;
677 /** The total number of tx success counted from the last radio chip reset */
678 private final long mTotalTxSuccess;
679 /** The total number of MPDU data packet retries counted from the last radio chip reset */
680 private final long mTotalTxRetries;
681 /** The total number of tx bad counted from the last radio chip reset */
682 private final long mTotalTxBad;
683 /** The total number of rx success counted from the last radio chip reset */
684 private final long mTotalRxSuccess;
685 /** The total number of beacons received from the last radio chip reset */
686 private final long mTotalBeaconRx;
687 /** @see #WifiUsabilityStatsEntry#getTimeSliceDutyCycleInPercent() */
688 private final int mTimeSliceDutyCycleInPercent;
689 /**
690 * The total time CCA is on busy status on the link frequency in ms counted from the last
691 * radio chip reset
692 */
693 private final long mTotalCcaBusyFreqTimeMillis;
694 /** The total radio on time on the link frequency in ms from the last radio chip reset */
695 private final long mTotalRadioOnFreqTimeMillis;
696 /** Data packet contention time statistics */
697 private final ContentionTimeStats[] mContentionTimeStats;
698 /** Rate information and statistics */
699 private final RateStats[] mRateStats;
700
701 /** @hide */
702 public LinkStats() {
703 mLinkId = MloLink.INVALID_MLO_LINK_ID;
704 mState = LINK_STATE_UNKNOWN;
705 mRssi = WifiInfo.INVALID_RSSI;
706 mRadioId = RadioStats.INVALID_RADIO_ID;
707 mTxLinkSpeedMbps = WifiInfo.LINK_SPEED_UNKNOWN;
708 mRxLinkSpeedMbps = WifiInfo.LINK_SPEED_UNKNOWN;
709 mTotalTxSuccess = 0;
710 mTotalTxRetries = 0;
711 mTotalTxBad = 0;
712 mTotalRxSuccess = 0;
713 mTotalBeaconRx = 0;
714 mTimeSliceDutyCycleInPercent = 0;
715 mTotalCcaBusyFreqTimeMillis = 0;
716 mTotalRadioOnFreqTimeMillis = 0;
717 mContentionTimeStats = null;
718 mRateStats = null;
719 }
720
721 /** @hide
722 * Constructor function
723 *
724 * @param linkId Identifier of the link.
725 * @param radioId Identifier of the radio on which the link is operating
726 * currently.
727 * @param rssi Link Rssi (in dBm) at sample time.
728 * @param txLinkSpeedMpbs Transmit link speed in Mpbs at sample time.
729 * @param rxLinkSpeedMpbs Receive link speed in Mbps at sample time.
730 * @param totalTxSuccess Total number of Tx success.
731 * @param totalTxRetries Total packet retries.
732 * @param totalTxBad Total number of bad packets.
733 * @param totalRxSuccess Total number of good receive packets.
734 * @param totalBeaconRx Total number of beacon received.
735 * @param timeSliceDutyCycleInPercent Duty cycle of the connection.
736 * @param totalCcaBusyFreqTimeMillis Total CCA is on busy status on the link frequency from
737 * the last radio chip reset.
738 * @param totalRadioOnFreqTimeMillis Total Radio on time on the link frequency from the
739 * last radio chip reset.
740 * @param contentionTimeStats Data packet contention time statistics.
741 * @param rateStats Rate information.
742 */
743 public LinkStats(int linkId, int state, int radioId, int rssi, int txLinkSpeedMpbs,
744 int rxLinkSpeedMpbs, long totalTxSuccess, long totalTxRetries, long totalTxBad,
745 long totalRxSuccess, long totalBeaconRx, int timeSliceDutyCycleInPercent,
746 long totalCcaBusyFreqTimeMillis, long totalRadioOnFreqTimeMillis,
747 ContentionTimeStats[] contentionTimeStats, RateStats[] rateStats) {
748 this.mLinkId = linkId;
749 this.mState = state;
750 this.mRadioId = radioId;
751 this.mRssi = rssi;
752 this.mTxLinkSpeedMbps = txLinkSpeedMpbs;
753 this.mRxLinkSpeedMbps = rxLinkSpeedMpbs;
754 this.mTotalTxSuccess = totalTxSuccess;
755 this.mTotalTxRetries = totalTxRetries;
756 this.mTotalTxBad = totalTxBad;
757 this.mTotalRxSuccess = totalRxSuccess;
758 this.mTotalBeaconRx = totalBeaconRx;
759 this.mTimeSliceDutyCycleInPercent = timeSliceDutyCycleInPercent;
760 this.mTotalCcaBusyFreqTimeMillis = totalCcaBusyFreqTimeMillis;
761 this.mTotalRadioOnFreqTimeMillis = totalRadioOnFreqTimeMillis;
762 this.mContentionTimeStats = contentionTimeStats;
763 this.mRateStats = rateStats;
764 }
765
766 @Override
767 public int describeContents() {
768 return 0;
769 }
770
771 @Override
772 public void writeToParcel(@NonNull Parcel dest, int flags) {
773 dest.writeInt(mLinkId);
774 dest.writeInt(mState);
775 dest.writeInt(mRadioId);
776 dest.writeInt(mRssi);
777 dest.writeInt(mTxLinkSpeedMbps);
778 dest.writeInt(mRxLinkSpeedMbps);
779 dest.writeLong(mTotalTxSuccess);
780 dest.writeLong(mTotalTxRetries);
781 dest.writeLong(mTotalTxBad);
782 dest.writeLong(mTotalRxSuccess);
783 dest.writeLong(mTotalBeaconRx);
784 dest.writeInt(mTimeSliceDutyCycleInPercent);
785 dest.writeLong(mTotalCcaBusyFreqTimeMillis);
786 dest.writeLong(mTotalRadioOnFreqTimeMillis);
787 dest.writeTypedArray(mContentionTimeStats, flags);
788 dest.writeTypedArray(mRateStats, flags);
789 }
790
791 /** Implement the Parcelable interface */
792 @NonNull
793 public static final Creator<LinkStats> CREATOR =
794 new Creator<>() {
795 public LinkStats createFromParcel(Parcel in) {
796 return new LinkStats(in.readInt(), in.readInt(), in.readInt(), in.readInt(),
797 in.readInt(), in.readInt(), in.readLong(), in.readLong(),
798 in.readLong(), in.readLong(), in.readLong(), in.readInt(),
799 in.readLong(), in.readLong(),
800 in.createTypedArray(ContentionTimeStats.CREATOR),
801 in.createTypedArray(RateStats.CREATOR));
802 }
803
804 public LinkStats[] newArray(int size) {
805 return new LinkStats[size];
806 }
807 };
808 }
809
810 /** Link stats per link */
811 private final SparseArray<LinkStats> mLinkStats;
812
813 /** Constructor function {@hide} */
814 public WifiUsabilityStatsEntry(long timeStampMillis, int rssi, int linkSpeedMbps,
815 long totalTxSuccess, long totalTxRetries, long totalTxBad, long totalRxSuccess,
816 long totalRadioOnTimeMillis, long totalRadioTxTimeMillis, long totalRadioRxTimeMillis,
817 long totalScanTimeMillis, long totalNanScanTimeMillis,
818 long totalBackgroundScanTimeMillis,
819 long totalRoamScanTimeMillis, long totalPnoScanTimeMillis,
820 long totalHotspot2ScanTimeMillis,
821 long totalCcaBusyFreqTimeMillis, long totalRadioOnFreqTimeMillis, long totalBeaconRx,
822 @ProbeStatus int probeStatusSinceLastUpdate, int probeElapsedTimeSinceLastUpdateMillis,
823 int probeMcsRateSinceLastUpdate, int rxLinkSpeedMbps,
824 int timeSliceDutyCycleInPercent, ContentionTimeStats[] contentionTimeStats,
825 RateStats[] rateStats, RadioStats[] radiostats, int channelUtilizationRatio,
826 boolean isThroughputSufficient, boolean isWifiScoringEnabled,
827 boolean isCellularDataAvailable, @NetworkType int cellularDataNetworkType,
828 int cellularSignalStrengthDbm, int cellularSignalStrengthDb,
829 boolean isSameRegisteredCell, SparseArray<LinkStats> linkStats) {
830 mTimeStampMillis = timeStampMillis;
831 mRssi = rssi;
832 mLinkSpeedMbps = linkSpeedMbps;
833 mTotalTxSuccess = totalTxSuccess;
834 mTotalTxRetries = totalTxRetries;
835 mTotalTxBad = totalTxBad;
836 mTotalRxSuccess = totalRxSuccess;
837 mTotalRadioOnTimeMillis = totalRadioOnTimeMillis;
838 mTotalRadioTxTimeMillis = totalRadioTxTimeMillis;
839 mTotalRadioRxTimeMillis = totalRadioRxTimeMillis;
840 mTotalScanTimeMillis = totalScanTimeMillis;
841 mTotalNanScanTimeMillis = totalNanScanTimeMillis;
842 mTotalBackgroundScanTimeMillis = totalBackgroundScanTimeMillis;
843 mTotalRoamScanTimeMillis = totalRoamScanTimeMillis;
844 mTotalPnoScanTimeMillis = totalPnoScanTimeMillis;
845 mTotalHotspot2ScanTimeMillis = totalHotspot2ScanTimeMillis;
846 mTotalCcaBusyFreqTimeMillis = totalCcaBusyFreqTimeMillis;
847 mTotalRadioOnFreqTimeMillis = totalRadioOnFreqTimeMillis;
848 mTotalBeaconRx = totalBeaconRx;
849 mProbeStatusSinceLastUpdate = probeStatusSinceLastUpdate;
850 mProbeElapsedTimeSinceLastUpdateMillis = probeElapsedTimeSinceLastUpdateMillis;
851 mProbeMcsRateSinceLastUpdate = probeMcsRateSinceLastUpdate;
852 mRxLinkSpeedMbps = rxLinkSpeedMbps;
853 mTimeSliceDutyCycleInPercent = timeSliceDutyCycleInPercent;
854 mContentionTimeStats = contentionTimeStats;
855 mRateStats = rateStats;
856 mRadioStats = radiostats;
857 mChannelUtilizationRatio = channelUtilizationRatio;
858 mIsThroughputSufficient = isThroughputSufficient;
859 mIsWifiScoringEnabled = isWifiScoringEnabled;
860 mIsCellularDataAvailable = isCellularDataAvailable;
861 mCellularDataNetworkType = cellularDataNetworkType;
862 mCellularSignalStrengthDbm = cellularSignalStrengthDbm;
863 mCellularSignalStrengthDb = cellularSignalStrengthDb;
864 mIsSameRegisteredCell = isSameRegisteredCell;
865 mLinkStats = linkStats;
866 }
867
868 /** Implement the Parcelable interface */
869 public int describeContents() {
870 return 0;
871 }
872
873 /** Implement the Parcelable interface */
874 public void writeToParcel(Parcel dest, int flags) {
875 dest.writeLong(mTimeStampMillis);
876 dest.writeInt(mRssi);
877 dest.writeInt(mLinkSpeedMbps);
878 dest.writeLong(mTotalTxSuccess);
879 dest.writeLong(mTotalTxRetries);
880 dest.writeLong(mTotalTxBad);
881 dest.writeLong(mTotalRxSuccess);
882 dest.writeLong(mTotalRadioOnTimeMillis);
883 dest.writeLong(mTotalRadioTxTimeMillis);
884 dest.writeLong(mTotalRadioRxTimeMillis);
885 dest.writeLong(mTotalScanTimeMillis);
886 dest.writeLong(mTotalNanScanTimeMillis);
887 dest.writeLong(mTotalBackgroundScanTimeMillis);
888 dest.writeLong(mTotalRoamScanTimeMillis);
889 dest.writeLong(mTotalPnoScanTimeMillis);
890 dest.writeLong(mTotalHotspot2ScanTimeMillis);
891 dest.writeLong(mTotalCcaBusyFreqTimeMillis);
892 dest.writeLong(mTotalRadioOnFreqTimeMillis);
893 dest.writeLong(mTotalBeaconRx);
894 dest.writeInt(mProbeStatusSinceLastUpdate);
895 dest.writeInt(mProbeElapsedTimeSinceLastUpdateMillis);
896 dest.writeInt(mProbeMcsRateSinceLastUpdate);
897 dest.writeInt(mRxLinkSpeedMbps);
898 dest.writeInt(mTimeSliceDutyCycleInPercent);
899 dest.writeTypedArray(mContentionTimeStats, flags);
900 dest.writeTypedArray(mRateStats, flags);
901 dest.writeTypedArray(mRadioStats, flags);
902 dest.writeInt(mChannelUtilizationRatio);
903 dest.writeBoolean(mIsThroughputSufficient);
904 dest.writeBoolean(mIsWifiScoringEnabled);
905 dest.writeBoolean(mIsCellularDataAvailable);
906 dest.writeInt(mCellularDataNetworkType);
907 dest.writeInt(mCellularSignalStrengthDbm);
908 dest.writeInt(mCellularSignalStrengthDb);
909 dest.writeBoolean(mIsSameRegisteredCell);
910 dest.writeSparseArray(mLinkStats);
911 }
912
913 /** Implement the Parcelable interface */
914 public static final @android.annotation.NonNull Creator<WifiUsabilityStatsEntry> CREATOR =
915 new Creator<WifiUsabilityStatsEntry>() {
916 public WifiUsabilityStatsEntry createFromParcel(Parcel in) {
917 return new WifiUsabilityStatsEntry(
918 in.readLong(), in.readInt(),
919 in.readInt(), in.readLong(), in.readLong(),
920 in.readLong(), in.readLong(), in.readLong(),
921 in.readLong(), in.readLong(), in.readLong(),
922 in.readLong(), in.readLong(), in.readLong(),
923 in.readLong(), in.readLong(), in.readLong(),
924 in.readLong(), in.readLong(), in.readInt(),
925 in.readInt(), in.readInt(), in.readInt(),
926 in.readInt(), in.createTypedArray(ContentionTimeStats.CREATOR),
927 in.createTypedArray(RateStats.CREATOR),
928 in.createTypedArray(RadioStats.CREATOR),
929 in.readInt(), in.readBoolean(), in.readBoolean(),
930 in.readBoolean(), in.readInt(), in.readInt(),
931 in.readInt(), in.readBoolean(),
932 in.readSparseArray(LinkStats.class.getClassLoader())
933 );
934 }
935
936 public WifiUsabilityStatsEntry[] newArray(int size) {
937 return new WifiUsabilityStatsEntry[size];
938 }
939 };
940
941 /** Get identifiers of the links if multi link configuration exists.
942 *
943 * @return An array of link identifiers if exists, otherwise null.
944 */
945 @Nullable
946 public int[] getLinkIds() {
947 if (mLinkStats == null) return null;
948 int[] result = new int[mLinkStats.size()];
949 for (int i = 0; i < mLinkStats.size(); i++) {
950 result[i] = mLinkStats.keyAt(i);
951 }
952 return result;
953 }
954
955 /**
956 * Get link state. Refer {@link LinkState}.
957 *
958 * @param linkId Identifier of the link.
959 * @return Link state.
960 * @throws NoSuchElementException if linkId is invalid.
961 */
962 public @LinkState int getLinkState(int linkId) {
963 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mState;
964 throw new NoSuchElementException("linkId is invalid - " + linkId);
965 }
966
967 /** Absolute milliseconds from device boot when these stats were sampled */
968 public long getTimeStampMillis() {
969 return mTimeStampMillis;
970 }
971
972 /**
973 * The RSSI (in dBm) at the sample time. In case of Multi Link Operation (MLO), returned RSSI is
974 * the highest of all associated links.
975 *
976 * @return the RSSI.
977 */
978 public int getRssi() {
979 return mRssi;
980 }
981
982 /** The RSSI (in dBm) of the link at the sample time.
983 *
984 * @param linkId Identifier of the link.
985 * @return RSSI in dBm.
986 * @throws NoSuchElementException if linkId is invalid.
987 */
988 public int getRssi(int linkId) {
989 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mRssi;
990 throw new NoSuchElementException("linkId is invalid - " + linkId);
991 }
992
993 /**
994 * Get firmware/hardware implementation specific persistent value for this
995 * device, identifying the radio interface for which the stats are produced.
996 *
997 * @param linkId Identifier of the link.
998 * @return Radio identifier.
999 * @throws NoSuchElementException if linkId is invalid.
1000 */
1001 public long getRadioId(int linkId) {
1002 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mRadioId;
1003 throw new NoSuchElementException("linkId is invalid - " + linkId);
1004 }
1005
1006 /** Link speed at the sample time in Mbps. In case of Multi Link Operation (MLO), returned value
1007 * is the current link speed of the associated link with the highest RSSI.
1008 *
1009 * @return Link speed in Mpbs or {@link WifiInfo#LINK_SPEED_UNKNOWN} if link speed is unknown.
1010 */
1011 public int getLinkSpeedMbps() {
1012 return mLinkSpeedMbps;
1013 }
1014
1015 /**
1016 * Tx Link speed of the link at the sample time in Mbps.
1017 *
1018 * @param linkId Identifier of the link.
1019 * @return Transmit link speed in Mpbs or {@link WifiInfo#LINK_SPEED_UNKNOWN} if link speed
1020 * is unknown.
1021 * @throws NoSuchElementException if linkId is invalid.
1022 */
1023 public int getTxLinkSpeedMbps(int linkId) {
1024 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mTxLinkSpeedMbps;
1025 throw new NoSuchElementException("linkId is invalid - " + linkId);
1026 }
1027
1028 /**
1029 * The total number of tx success counted from the last radio chip reset. In case of Multi
1030 * Link Operation (MLO), the returned value is the sum of total number of tx success on all
1031 * associated links.
1032 *
1033 * @return total tx success count.
1034 */
1035 public long getTotalTxSuccess() {
1036 return mTotalTxSuccess;
1037 }
1038
1039 /**
1040 * The total number of tx success on a link counted from the last radio chip reset.
1041 *
1042 * @param linkId Identifier of the link.
1043 * @return total tx success count.
1044 * @throws NoSuchElementException if linkId is invalid.
1045 */
1046 public long getTotalTxSuccess(int linkId) {
1047 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mTotalTxSuccess;
1048 throw new NoSuchElementException("linkId is invalid - " + linkId);
1049 }
1050
1051 /**
1052 * The total number of MPDU data packet retries counted from the last radio chip reset. In
1053 * case of Multi Link Operation (MLO), the returned value is the sum of total number of MPDU
1054 * data packet retries on all associated links.
1055 *
1056 * @return total tx retries count.
1057 */
1058 public long getTotalTxRetries() {
1059 return mTotalTxRetries;
1060 }
1061
1062 /**
1063 * The total number of MPDU data packet retries on a link counted from the last radio chip
1064 * reset.
1065 *
1066 * @param linkId Identifier of the link.
1067 * @return total tx retries count.
1068 * @throws NoSuchElementException if linkId is invalid.
1069 */
1070 public long getTotalTxRetries(int linkId) {
1071 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mTotalTxRetries;
1072 throw new NoSuchElementException("linkId is invalid - " + linkId);
1073 }
1074
1075 /**
1076 * The total number of tx bad counted from the last radio chip reset. In case of Multi Link
1077 * Operation (MLO), the returned value is the sum of total number of tx bad on all associated
1078 * links.
1079 *
1080 * @return total tx bad count.
1081 */
1082 public long getTotalTxBad() {
1083 return mTotalTxBad;
1084 }
1085
1086 /**
1087 * The total number of tx bad on a link counted from the last radio chip reset.
1088 *
1089 * @param linkId Identifier of the link.
1090 * @return total tx bad count.
1091 * @throws NoSuchElementException if linkId is invalid.
1092 */
1093 public long getTotalTxBad(int linkId) {
1094 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mTotalTxBad;
1095 throw new NoSuchElementException("linkId is invalid - " + linkId);
1096 }
1097
1098 /**
1099 * The total number of rx success counted from the last radio chip reset. In case of Multi
1100 * Link Operation (MLO), the returned value is the sum of total number of rx success on all
1101 * associated links.
1102 *
1103 * @return total rx success count.
1104 */
1105 public long getTotalRxSuccess() {
1106 return mTotalRxSuccess;
1107 }
1108
1109 /**
1110 * The total number of rx success on a link counted from the last radio chip reset.
1111 *
1112 * @param linkId Identifier of the link.
1113 * @return total rx success count.
1114 * @throws NoSuchElementException if linkId is invalid.
1115 */
1116 public long getTotalRxSuccess(int linkId) {
1117 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mTotalRxSuccess;
1118 throw new NoSuchElementException("linkId is invalid - " + linkId);
1119 }
1120
1121 /** The total time the wifi radio is on in ms counted from the last radio chip reset */
1122 public long getTotalRadioOnTimeMillis() {
1123 return mTotalRadioOnTimeMillis;
1124 }
1125
1126 /** The total time the wifi radio is doing tx in ms counted from the last radio chip reset */
1127 public long getTotalRadioTxTimeMillis() {
1128 return mTotalRadioTxTimeMillis;
1129 }
1130
1131 /** The total time the wifi radio is doing rx in ms counted from the last radio chip reset */
1132 public long getTotalRadioRxTimeMillis() {
1133 return mTotalRadioRxTimeMillis;
1134 }
1135
1136 /** The total time spent on all types of scans in ms counted from the last radio chip reset */
1137 public long getTotalScanTimeMillis() {
1138 return mTotalScanTimeMillis;
1139 }
1140
1141 /** The total time spent on nan scans in ms counted from the last radio chip reset */
1142 public long getTotalNanScanTimeMillis() {
1143 return mTotalNanScanTimeMillis;
1144 }
1145
1146 /** The total time spent on background scans in ms counted from the last radio chip reset */
1147 public long getTotalBackgroundScanTimeMillis() {
1148 return mTotalBackgroundScanTimeMillis;
1149 }
1150
1151 /** The total time spent on roam scans in ms counted from the last radio chip reset */
1152 public long getTotalRoamScanTimeMillis() {
1153 return mTotalRoamScanTimeMillis;
1154 }
1155
1156 /** The total time spent on pno scans in ms counted from the last radio chip reset */
1157 public long getTotalPnoScanTimeMillis() {
1158 return mTotalPnoScanTimeMillis;
1159 }
1160
1161 /** The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the last radio
1162 * chip reset */
1163 public long getTotalHotspot2ScanTimeMillis() {
1164 return mTotalHotspot2ScanTimeMillis;
1165 }
1166
1167 /**
1168 * The total time CCA is on busy status on the current frequency in ms counted from the last
1169 * radio chip reset.In case of Multi Link Operation (MLO), returned value is the total time
1170 * CCA is on busy status on the current frequency of the associated link with the highest
1171 * RSSI.
1172 */
1173 public long getTotalCcaBusyFreqTimeMillis() {
1174 return mTotalCcaBusyFreqTimeMillis;
1175 }
1176
1177 /**
1178 * The total time CCA is on busy status on the link frequency in ms counted from the last radio
1179 * chip reset.
1180 *
1181 * @param linkId Identifier of the link.
1182 * @return total time CCA is on busy status for the link in ms.
1183 * @throws NoSuchElementException if linkId is invalid.
1184 */
1185 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
1186 public long getTotalCcaBusyFreqTimeMillis(int linkId) {
1187 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mTotalCcaBusyFreqTimeMillis;
1188 throw new NoSuchElementException("linkId is invalid - " + linkId);
1189 }
1190
1191 /**
1192 * The total radio on time on the current frequency from the last radio chip reset. In case of
1193 * Multi Link Operation (MLO), returned value is the total time radio on time on the current
1194 * frequency of the associated link with the highest RSSI.
1195 */
1196 public long getTotalRadioOnFreqTimeMillis() {
1197 return mTotalRadioOnFreqTimeMillis;
1198 }
1199
1200 /**
1201 * The total radio on time on the link frequency from the last radio chip reset
1202 *
1203 * @param linkId Identifier of the link.
1204 * @return The total radio on time for the link in ms.
1205 * @throws NoSuchElementException if linkId is invalid.
1206 */
1207 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
1208 public long getTotalRadioOnFreqTimeMillis(int linkId) {
1209 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mTotalRadioOnFreqTimeMillis;
1210 throw new NoSuchElementException("linkId is invalid - " + linkId);
1211 }
1212
1213 /**
1214 * The total number of beacons received from the last radio chip reset. In case of Multi Link
1215 * Operation (MLO), the returned value is the beacons received on the associated link with
1216 * the highest RSSI.
1217 *
1218 * @return total beacons received.
1219 */
1220 public long getTotalBeaconRx() {
1221 return mTotalBeaconRx;
1222 }
1223
1224 /**
1225 * The total number of beacons received from the last radio chip reset.
1226 *
1227 * @param linkId Identifier of the link.
1228 * @return total beacons received.
1229 * @throws NoSuchElementException if linkId is invalid.
1230 */
1231 public long getTotalBeaconRx(int linkId) {
1232 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mTotalBeaconRx;
1233 throw new NoSuchElementException("linkId is invalid - " + linkId);
1234 }
1235
1236 /** The status of link probe since last stats update */
1237 @ProbeStatus public int getProbeStatusSinceLastUpdate() {
1238 return mProbeStatusSinceLastUpdate;
1239 }
1240
1241 /** The elapsed time of the most recent link probe since last stats update */
1242 public int getProbeElapsedTimeSinceLastUpdateMillis() {
1243 return mProbeElapsedTimeSinceLastUpdateMillis;
1244 }
1245
1246 /** The MCS rate of the most recent link probe since last stats update */
1247 public int getProbeMcsRateSinceLastUpdate() {
1248 return mProbeMcsRateSinceLastUpdate;
1249 }
1250
1251 /**
1252 * Rx link speed at the sample time in Mbps. In case of Multi Link Operation (MLO), returned
1253 * value is the receive link speed of the associated link with the highest RSSI.
1254 *
1255 * @return Receive link speed in Mbps or {@link WifiInfo#LINK_SPEED_UNKNOWN} if link speed
1256 * is unknown.
1257 */
1258 public int getRxLinkSpeedMbps() {
1259 return mRxLinkSpeedMbps;
1260 }
1261
1262 /**
1263 * Rx Link speed of the link at the sample time in Mbps.
1264 *
1265 * @param linkId Identifier of the link.
1266 * @return Receive link speed in Mbps or {@link WifiInfo#LINK_SPEED_UNKNOWN} if link speed
1267 * is unknown.
1268 * @throws NoSuchElementException if linkId is invalid.
1269 */
1270 public int getRxLinkSpeedMbps(int linkId) {
1271 if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mRxLinkSpeedMbps;
1272 throw new NoSuchElementException("linkId is invalid - " + linkId);
1273 }
1274
1275 /**
1276 * Duty cycle of the connection.
1277 * If this connection is being served using time slicing on a radio with one or more interfaces
1278 * (i.e MCC), then this method returns the duty cycle assigned to this interface in percent.
1279 * If no concurrency or not using time slicing during concurrency (i.e SCC or DBS), set to 100.
1280 * In case of Multi Link Operation (MLO), returned value is the duty cycle of the associated
1281 * link with the highest RSSI.
1282 *
1283 * @return duty cycle in percent if known.
1284 * @throws NoSuchElementException if the duty cycle is unknown (not provided by the HAL).
1285 */
1286 public @IntRange(from = 0, to = 100) int getTimeSliceDutyCycleInPercent() {
1287 if (mTimeSliceDutyCycleInPercent == -1) {
1288 throw new NoSuchElementException("Unknown value");
1289 }
1290 return mTimeSliceDutyCycleInPercent;
1291 }
1292
1293 /**
1294 * Duty cycle of the connection for a link.
1295 * If this connection is being served using time slicing on a radio with one or more interfaces
1296 * (i.e MCC) and links, then this method returns the duty cycle assigned to this interface in
1297 * percent for the link. If no concurrency or not using time slicing during concurrency (i.e SCC
1298 * or DBS), set to 100.
1299 *
1300 * @param linkId Identifier of the link.
1301 * @return duty cycle in percent if known.
1302 * @throws NoSuchElementException if the duty cycle is unknown (not provided by the HAL) or
1303 * linkId is invalid.
1304 */
1305 public @IntRange(from = 0, to = 100) int getTimeSliceDutyCycleInPercent(int linkId) {
1306 if (!mLinkStats.contains(linkId)) {
1307 throw new NoSuchElementException("linkId is invalid - " + linkId);
1308 }
1309 if (mLinkStats.get(linkId).mTimeSliceDutyCycleInPercent == -1) {
1310 throw new NoSuchElementException("Unknown value");
1311 }
1312 return mLinkStats.get(linkId).mTimeSliceDutyCycleInPercent;
1313 }
1314
1315 /**
1316 * Data packet contention time statistics for Access Category. In case of Multi Link
1317 * Operation (MLO), the returned value is the contention stats of the associated link with the
1318 * highest RSSI.
1319 *
1320 * @param ac The access category, see {@link WmeAccessCategory}.
1321 * @return The contention time statistics, see {@link ContentionTimeStats}
1322 */
1323 @NonNull
1324 public ContentionTimeStats getContentionTimeStats(@WmeAccessCategory int ac) {
1325 if (mContentionTimeStats != null
1326 && mContentionTimeStats.length == NUM_WME_ACCESS_CATEGORIES) {
1327 return mContentionTimeStats[ac];
1328 }
1329 Log.e(TAG, "The ContentionTimeStats is not filled out correctly: "
1330 + Arrays.toString(mContentionTimeStats));
1331 return new ContentionTimeStats();
1332 }
1333
1334 /**
1335 * Data packet contention time statistics of a link for Access Category.
1336 *
1337 * @param linkId Identifier of the link.
1338 * @param ac The access category, see {@link WmeAccessCategory}.
1339 * @return The contention time statistics, see {@link ContentionTimeStats}.
1340 * @throws NoSuchElementException if linkId is invalid.
1341 */
1342 @NonNull
1343 public ContentionTimeStats getContentionTimeStats(int linkId, @WmeAccessCategory int ac) {
1344 if (!mLinkStats.contains(linkId)) {
1345 throw new NoSuchElementException("linkId is invalid - " + linkId);
1346 }
1347 ContentionTimeStats[] linkContentionTimeStats = mLinkStats.get(
1348 linkId).mContentionTimeStats;
1349 if (linkContentionTimeStats != null
1350 && linkContentionTimeStats.length == NUM_WME_ACCESS_CATEGORIES) {
1351 return linkContentionTimeStats[ac];
1352 }
1353 Log.e(TAG, "The ContentionTimeStats is not filled out correctly: "
1354 + Arrays.toString(mContentionTimeStats));
1355 return new ContentionTimeStats();
1356 }
1357
1358 /**
1359 * Rate information and statistics, which are ordered by preamble, modulation and coding scheme
1360 * (MCS), and number of spatial streams (NSS). In case of Multi Link Operation (MLO), the
1361 * returned rate information is that of the associated link with the highest RSSI.
1362 *
1363 * @return A list of rate statistics in the form of a list of {@link RateStats} objects.
1364 * Depending on the link type, the list is created following the order of:
1365 * - HT (IEEE Std 802.11-2020, Section 19): LEGACY rates (1Mbps, ..., 54Mbps),
1366 * HT MCS0, ..., MCS15;
1367 * - VHT (IEEE Std 802.11-2020, Section 21): LEGACY rates (1Mbps, ..., 54Mbps),
1368 * VHT MCS0/NSS1, ..., VHT MCS11/NSS1, VHT MCSO/NSS2, ..., VHT MCS11/NSS2;
1369 * - HE (IEEE Std 802.11ax-2020, Section 27): LEGACY rates (1Mbps, ..., 54Mbps),
1370 * HE MCS0/NSS1, ..., HE MCS11/NSS1, HE MCSO/NSS2, ..., HE MCS11/NSS2.
1371 * - EHT (IEEE std 802.11be-2021, Section 36): Legacy rates (1Mbps, ..., 54Mbps),
1372 * EHT MSC0/NSS1, ..., EHT MCS14/NSS1, EHT MCS0/NSS2, ..., EHT MCS14/NSS2.
1373 */
1374 @NonNull
1375 public List<RateStats> getRateStats() {
1376 if (mRateStats != null) {
1377 return Arrays.asList(mRateStats);
1378 }
1379 return Collections.emptyList();
1380 }
1381
1382 /**
1383 * Rate information and statistics, which are ordered by preamble, modulation and coding scheme
1384 * (MCS), and number of spatial streams (NSS) for link.
1385 *
1386 * @param linkId Identifier of the link.
1387 * @return A list of rate statistics in the form of a list of {@link RateStats} objects.
1388 * Depending on the link type, the list is created following the order of:
1389 * - HT (IEEE Std 802.11-2020, Section 19): LEGACY rates (1Mbps, ..., 54Mbps),
1390 * HT MCS0, ..., MCS15;
1391 * - VHT (IEEE Std 802.11-2020, Section 21): LEGACY rates (1Mbps, ..., 54Mbps),
1392 * VHT MCS0/NSS1, ..., VHT MCS11/NSS1, VHT MCSO/NSS2, ..., VHT MCS11/NSS2;
1393 * - HE (IEEE Std 802.11ax-2020, Section 27): LEGACY rates (1Mbps, ..., 54Mbps),
1394 * HE MCS0/NSS1, ..., HE MCS11/NSS1, HE MCSO/NSS2, ..., HE MCS11/NSS2.
1395 * - EHT (IEEE std 802.11be-2021, Section 36): Legacy rates (1Mbps, ..., 54Mbps),
1396 * EHT MSC0/NSS1, ..., EHT MCS14/NSS1, EHT MCS0/NSS2, ..., EHT MCS14/NSS2.
1397 * @throws NoSuchElementException if linkId is invalid.
1398 */
1399 @NonNull
1400 public List<RateStats> getRateStats(int linkId) {
1401 if (mLinkStats.contains(linkId)) {
1402 RateStats[] rateStats = mLinkStats.get(linkId).mRateStats;
1403 if (rateStats != null) return Arrays.asList(rateStats);
1404 return Collections.emptyList();
1405 }
1406 throw new NoSuchElementException("linkId is invalid - " + linkId);
1407 }
1408
1409 /**
1410 * Radio stats from all the radios, see {@link RadioStats#getRadioId()}
1411 * @return A list of Wifi link layer radio stats, see {@link RadioStats}
1412 */
1413 @NonNull
1414 public List<RadioStats> getWifiLinkLayerRadioStats() {
1415 if (mRadioStats != null) {
1416 return Arrays.asList(mRadioStats);
1417 }
1418 return Collections.emptyList();
1419 }
1420
1421 /**
1422 * Channel utilization ratio on the current channel.
1423 *
1424 * @return The channel utilization ratio (value) in the range of [0, 255], where x corresponds
1425 * to (x * 100 / 255)%, or -1 indicating that there is no valid value to return.
1426 */
1427 public @IntRange(from = -1, to = 255) int getChannelUtilizationRatio() {
1428 return mChannelUtilizationRatio;
1429 }
1430
1431 /**
1432 * Indicate whether current link layer (L2) throughput is sufficient. L2 throughput is
1433 * sufficient when one of the following conditions is met: 1) L3 throughput is low and L2
1434 * throughput is above its low threshold; 2) L3 throughput is not low and L2 throughput over L3
1435 * throughput ratio is above a threshold; 3) L3 throughput is not low and L2 throughput is
1436 * above its high threshold.
1437 *
1438 * @return true if it is sufficient or false if it is insufficient.
1439 */
1440 public boolean isThroughputSufficient() {
1441 return mIsThroughputSufficient;
1442 }
1443
1444 /**
1445 * Indicate whether Wi-Fi scoring is enabled by the user,
1446 * see {@link WifiManager#setWifiScoringEnabled(boolean)}.
1447 *
1448 * @return true if it is enabled.
1449 */
1450 public boolean isWifiScoringEnabled() {
1451 return mIsWifiScoringEnabled;
1452 }
1453
1454 /**
1455 * Indicate whether Cellular data is available.
1456 *
1457 * @return true if it is available and false otherwise.
1458 */
1459 public boolean isCellularDataAvailable() {
1460 return mIsCellularDataAvailable;
1461 }
1462
1463 /** Cellular data network type currently in use on the device for data transmission */
1464 @NetworkType public int getCellularDataNetworkType() {
1465 return mCellularDataNetworkType;
1466 }
1467
1468 /**
1469 * Cellular signal strength in dBm, NR: CsiRsrp, LTE: Rsrp, WCDMA/TDSCDMA: Rscp,
1470 * CDMA: Rssi, EVDO: Rssi, GSM: Rssi
1471 */
1472 public int getCellularSignalStrengthDbm() {
1473 return mCellularSignalStrengthDbm;
1474 }
1475
1476 /**
1477 * Cellular signal strength in dB, NR: CsiSinr, LTE: Rsrq, WCDMA: EcNo, TDSCDMA: invalid,
1478 * CDMA: Ecio, EVDO: SNR, GSM: invalid
1479 */
1480 public int getCellularSignalStrengthDb() {
1481 return mCellularSignalStrengthDb;
1482 }
1483
1484 /** Whether the primary registered cell of current entry is same as that of previous entry */
1485 public boolean isSameRegisteredCell() {
1486 return mIsSameRegisteredCell;
1487 }
1488}