1 /*
2  * Copyright (C) 2016 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.metrics;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.SystemApi;
22 import android.annotation.TestApi;
23 import android.compat.annotation.UnsupportedAppUsage;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 
27 /**
28  * An event logged for an interface with APF capabilities when its IpClient state machine exits.
29  * {@hide}
30  */
31 @SystemApi
32 @TestApi
33 public final class ApfStats implements IpConnectivityLog.Event {
34 
35     /**
36      * time interval in milliseconds these stastistics covers.
37      * @hide
38      */
39     @UnsupportedAppUsage
40     public final long durationMs;
41     /**
42      * number of received RAs.
43      * @hide
44      */
45     @UnsupportedAppUsage
46     public final int receivedRas;
47     /**
48      * number of received RAs matching a known RA.
49      * @hide
50      */
51     @UnsupportedAppUsage
52     public final int matchingRas;
53     /**
54      * number of received RAs ignored due to the MAX_RAS limit.
55      * @hide
56      */
57     @UnsupportedAppUsage
58     public final int droppedRas;
59     /**
60      * number of received RAs with a minimum lifetime of 0.
61      * @hide
62      */
63     @UnsupportedAppUsage
64     public final int zeroLifetimeRas;
65     /**
66      * number of received RAs that could not be parsed.
67      * @hide
68      */
69     @UnsupportedAppUsage
70     public final int parseErrors;
71     /**
72      * number of APF program updates from receiving RAs.
73      * @hide
74      */
75     @UnsupportedAppUsage
76     public final int programUpdates;
77     /**
78      * total number of APF program updates.
79      * @hide
80      */
81     @UnsupportedAppUsage
82     public final int programUpdatesAll;
83     /**
84      * number of APF program updates from allowing multicast traffic.
85      * @hide
86      */
87     @UnsupportedAppUsage
88     public final int programUpdatesAllowingMulticast;
89     /**
90      * maximum APF program size advertised by hardware.
91      * @hide
92      */
93     @UnsupportedAppUsage
94     public final int maxProgramSize;
95 
ApfStats(Parcel in)96     private ApfStats(Parcel in) {
97         this.durationMs = in.readLong();
98         this.receivedRas = in.readInt();
99         this.matchingRas = in.readInt();
100         this.droppedRas = in.readInt();
101         this.zeroLifetimeRas = in.readInt();
102         this.parseErrors = in.readInt();
103         this.programUpdates = in.readInt();
104         this.programUpdatesAll = in.readInt();
105         this.programUpdatesAllowingMulticast = in.readInt();
106         this.maxProgramSize = in.readInt();
107     }
108 
ApfStats(long durationMs, int receivedRas, int matchingRas, int droppedRas, int zeroLifetimeRas, int parseErrors, int programUpdates, int programUpdatesAll, int programUpdatesAllowingMulticast, int maxProgramSize)109     private ApfStats(long durationMs, int receivedRas, int matchingRas, int droppedRas,
110             int zeroLifetimeRas, int parseErrors, int programUpdates, int programUpdatesAll,
111             int programUpdatesAllowingMulticast, int maxProgramSize) {
112         this.durationMs = durationMs;
113         this.receivedRas = receivedRas;
114         this.matchingRas = matchingRas;
115         this.droppedRas = droppedRas;
116         this.zeroLifetimeRas = zeroLifetimeRas;
117         this.parseErrors = parseErrors;
118         this.programUpdates = programUpdates;
119         this.programUpdatesAll = programUpdatesAll;
120         this.programUpdatesAllowingMulticast = programUpdatesAllowingMulticast;
121         this.maxProgramSize = maxProgramSize;
122     }
123 
124     /**
125      * Utility to create an instance of {@link ApfStats}.
126      * @hide
127      */
128     @SystemApi
129     @TestApi
130     public static final class Builder {
131         private long mDurationMs;
132         private int mReceivedRas;
133         private int mMatchingRas;
134         private int mDroppedRas;
135         private int mZeroLifetimeRas;
136         private int mParseErrors;
137         private int mProgramUpdates;
138         private int mProgramUpdatesAll;
139         private int mProgramUpdatesAllowingMulticast;
140         private int mMaxProgramSize;
141 
142         /**
143          * Set the time interval in milliseconds these statistics covers.
144          */
145         @NonNull
setDurationMs(long durationMs)146         public Builder setDurationMs(long durationMs) {
147             mDurationMs = durationMs;
148             return this;
149         }
150 
151         /**
152          * Set the number of received RAs.
153          */
154         @NonNull
setReceivedRas(int receivedRas)155         public Builder setReceivedRas(int receivedRas) {
156             mReceivedRas = receivedRas;
157             return this;
158         }
159 
160         /**
161          * Set the number of received RAs matching a known RA.
162          */
163         @NonNull
setMatchingRas(int matchingRas)164         public Builder setMatchingRas(int matchingRas) {
165             mMatchingRas = matchingRas;
166             return this;
167         }
168 
169         /**
170          * Set the number of received RAs ignored due to the MAX_RAS limit.
171          */
172         @NonNull
setDroppedRas(int droppedRas)173         public Builder setDroppedRas(int droppedRas) {
174             mDroppedRas = droppedRas;
175             return this;
176         }
177 
178         /**
179          * Set the number of received RAs with a minimum lifetime of 0.
180          */
181         @NonNull
setZeroLifetimeRas(int zeroLifetimeRas)182         public Builder setZeroLifetimeRas(int zeroLifetimeRas) {
183             mZeroLifetimeRas = zeroLifetimeRas;
184             return this;
185         }
186 
187         /**
188          * Set the number of received RAs that could not be parsed.
189          */
190         @NonNull
setParseErrors(int parseErrors)191         public Builder setParseErrors(int parseErrors) {
192             mParseErrors = parseErrors;
193             return this;
194         }
195 
196         /**
197          * Set the number of APF program updates from receiving RAs.
198          */
199         @NonNull
setProgramUpdates(int programUpdates)200         public Builder setProgramUpdates(int programUpdates) {
201             mProgramUpdates = programUpdates;
202             return this;
203         }
204 
205         /**
206          * Set the total number of APF program updates.
207          */
208         @NonNull
setProgramUpdatesAll(int programUpdatesAll)209         public Builder setProgramUpdatesAll(int programUpdatesAll) {
210             mProgramUpdatesAll = programUpdatesAll;
211             return this;
212         }
213 
214         /**
215          * Set the number of APF program updates from allowing multicast traffic.
216          */
217         @NonNull
setProgramUpdatesAllowingMulticast(int programUpdatesAllowingMulticast)218         public Builder setProgramUpdatesAllowingMulticast(int programUpdatesAllowingMulticast) {
219             mProgramUpdatesAllowingMulticast = programUpdatesAllowingMulticast;
220             return this;
221         }
222 
223         /**
224          * Set the maximum APF program size advertised by hardware.
225          */
226         @NonNull
setMaxProgramSize(int maxProgramSize)227         public Builder setMaxProgramSize(int maxProgramSize) {
228             mMaxProgramSize = maxProgramSize;
229             return this;
230         }
231 
232         /**
233          * Create a new {@link ApfStats}.
234          */
235         @NonNull
build()236         public ApfStats build() {
237             return new ApfStats(mDurationMs, mReceivedRas, mMatchingRas, mDroppedRas,
238                     mZeroLifetimeRas, mParseErrors, mProgramUpdates, mProgramUpdatesAll,
239                     mProgramUpdatesAllowingMulticast, mMaxProgramSize);
240         }
241     }
242 
243     /** @hide */
244     @Override
writeToParcel(Parcel out, int flags)245     public void writeToParcel(Parcel out, int flags) {
246         out.writeLong(durationMs);
247         out.writeInt(receivedRas);
248         out.writeInt(matchingRas);
249         out.writeInt(droppedRas);
250         out.writeInt(zeroLifetimeRas);
251         out.writeInt(parseErrors);
252         out.writeInt(programUpdates);
253         out.writeInt(programUpdatesAll);
254         out.writeInt(programUpdatesAllowingMulticast);
255         out.writeInt(maxProgramSize);
256     }
257 
258     /** @hide */
259     @Override
describeContents()260     public int describeContents() {
261         return 0;
262     }
263 
264     @NonNull
265     @Override
toString()266     public String toString() {
267         return new StringBuilder("ApfStats(")
268                 .append(String.format("%dms ", durationMs))
269                 .append(String.format("%dB RA: {", maxProgramSize))
270                 .append(String.format("%d received, ", receivedRas))
271                 .append(String.format("%d matching, ", matchingRas))
272                 .append(String.format("%d dropped, ", droppedRas))
273                 .append(String.format("%d zero lifetime, ", zeroLifetimeRas))
274                 .append(String.format("%d parse errors}, ", parseErrors))
275                 .append(String.format("updates: {all: %d, RAs: %d, allow multicast: %d})",
276                         programUpdatesAll, programUpdates, programUpdatesAllowingMulticast))
277                 .toString();
278     }
279 
280     @Override
equals(@ullable Object obj)281     public boolean equals(@Nullable Object obj) {
282         if (obj == null || !(obj.getClass().equals(ApfStats.class))) return false;
283         final ApfStats other = (ApfStats) obj;
284         return durationMs == other.durationMs
285                 && receivedRas == other.receivedRas
286                 && matchingRas == other.matchingRas
287                 && droppedRas == other.droppedRas
288                 && zeroLifetimeRas == other.zeroLifetimeRas
289                 && parseErrors == other.parseErrors
290                 && programUpdates == other.programUpdates
291                 && programUpdatesAll == other.programUpdatesAll
292                 && programUpdatesAllowingMulticast == other.programUpdatesAllowingMulticast
293                 && maxProgramSize == other.maxProgramSize;
294     }
295 
296     /** @hide */
297     public static final @android.annotation.NonNull Parcelable.Creator<ApfStats> CREATOR = new Parcelable.Creator<ApfStats>() {
298         public ApfStats createFromParcel(Parcel in) {
299             return new ApfStats(in);
300         }
301 
302         public ApfStats[] newArray(int size) {
303             return new ApfStats[size];
304         }
305     };
306 }
307