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