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