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