• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.SystemApi;
22 import android.annotation.TestApi;
23 import android.annotation.UnsupportedAppUsage;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 import android.text.TextUtils;
27 import android.util.SparseArray;
28 
29 import com.android.internal.util.MessageUtils;
30 
31 import java.lang.annotation.Retention;
32 import java.lang.annotation.RetentionPolicy;
33 import java.util.ArrayList;
34 import java.util.BitSet;
35 import java.util.List;
36 
37 /**
38  * An event logged when there is a change or event that requires updating the
39  * the APF program in place with a new APF program.
40  * {@hide}
41  */
42 @TestApi
43 @SystemApi
44 public final class ApfProgramEvent implements IpConnectivityLog.Event {
45 
46     // Bitflag constants describing what an Apf program filters.
47     // Bits are indexeds from LSB to MSB, starting at index 0.
48     /** @hide */
49     public static final int FLAG_MULTICAST_FILTER_ON = 0;
50     /** @hide */
51     public static final int FLAG_HAS_IPV4_ADDRESS    = 1;
52 
53     /** {@hide} */
54     @IntDef(flag = true, value = {FLAG_MULTICAST_FILTER_ON, FLAG_HAS_IPV4_ADDRESS})
55     @Retention(RetentionPolicy.SOURCE)
56     public @interface Flags {}
57 
58     /** @hide */
59     @UnsupportedAppUsage
60     public final long lifetime;       // Maximum computed lifetime of the program in seconds
61     /** @hide */
62     @UnsupportedAppUsage
63     public final long actualLifetime; // Effective program lifetime in seconds
64     /** @hide */
65     @UnsupportedAppUsage
66     public final int filteredRas;     // Number of RAs filtered by the APF program
67     /** @hide */
68     @UnsupportedAppUsage
69     public final int currentRas;      // Total number of current RAs at generation time
70     /** @hide */
71     @UnsupportedAppUsage
72     public final int programLength;   // Length of the APF program in bytes
73     /** @hide */
74     @UnsupportedAppUsage
75     public final int flags;           // Bitfield compound of FLAG_* constants
76 
ApfProgramEvent(long lifetime, long actualLifetime, int filteredRas, int currentRas, int programLength, int flags)77     private ApfProgramEvent(long lifetime, long actualLifetime, int filteredRas, int currentRas,
78             int programLength, int flags) {
79         this.lifetime = lifetime;
80         this.actualLifetime = actualLifetime;
81         this.filteredRas = filteredRas;
82         this.currentRas = currentRas;
83         this.programLength = programLength;
84         this.flags = flags;
85     }
86 
ApfProgramEvent(Parcel in)87     private ApfProgramEvent(Parcel in) {
88         this.lifetime = in.readLong();
89         this.actualLifetime = in.readLong();
90         this.filteredRas = in.readInt();
91         this.currentRas = in.readInt();
92         this.programLength = in.readInt();
93         this.flags = in.readInt();
94     }
95 
96     /**
97      * Utility to create an instance of {@link ApfProgramEvent}.
98      */
99     public static final class Builder {
100         private long mLifetime;
101         private long mActualLifetime;
102         private int mFilteredRas;
103         private int mCurrentRas;
104         private int mProgramLength;
105         private int mFlags;
106 
107         /**
108          * Set the maximum computed lifetime of the program in seconds.
109          */
110         @NonNull
setLifetime(long lifetime)111         public Builder setLifetime(long lifetime) {
112             mLifetime = lifetime;
113             return this;
114         }
115 
116         /**
117          * Set the effective program lifetime in seconds.
118          */
119         @NonNull
setActualLifetime(long lifetime)120         public Builder setActualLifetime(long lifetime) {
121             mActualLifetime = lifetime;
122             return this;
123         }
124 
125         /**
126          * Set the number of RAs filtered by the APF program.
127          */
128         @NonNull
setFilteredRas(int filteredRas)129         public Builder setFilteredRas(int filteredRas) {
130             mFilteredRas = filteredRas;
131             return this;
132         }
133 
134         /**
135          * Set the total number of current RAs at generation time.
136          */
137         @NonNull
setCurrentRas(int currentRas)138         public Builder setCurrentRas(int currentRas) {
139             mCurrentRas = currentRas;
140             return this;
141         }
142 
143         /**
144          * Set the length of the APF program in bytes.
145          */
146         @NonNull
setProgramLength(int programLength)147         public Builder setProgramLength(int programLength) {
148             mProgramLength = programLength;
149             return this;
150         }
151 
152         /**
153          * Set the flags describing what an Apf program filters.
154          */
155         @NonNull
setFlags(boolean hasIPv4, boolean multicastFilterOn)156         public Builder setFlags(boolean hasIPv4, boolean multicastFilterOn) {
157             mFlags = flagsFor(hasIPv4, multicastFilterOn);
158             return this;
159         }
160 
161         /**
162          * Build a new {@link ApfProgramEvent}.
163          */
164         @NonNull
build()165         public ApfProgramEvent build() {
166             return new ApfProgramEvent(mLifetime, mActualLifetime, mFilteredRas, mCurrentRas,
167                     mProgramLength, mFlags);
168         }
169     }
170 
171     /** @hide */
172     @Override
writeToParcel(Parcel out, int flags)173     public void writeToParcel(Parcel out, int flags) {
174         out.writeLong(lifetime);
175         out.writeLong(actualLifetime);
176         out.writeInt(filteredRas);
177         out.writeInt(currentRas);
178         out.writeInt(programLength);
179         out.writeInt(this.flags);
180     }
181 
182     /** @hide */
183     @Override
describeContents()184     public int describeContents() {
185         return 0;
186     }
187 
188     @Override
toString()189     public String toString() {
190         String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever";
191         return String.format("ApfProgramEvent(%d/%d RAs %dB %ds/%s %s)", filteredRas, currentRas,
192                 programLength, actualLifetime, lifetimeString, namesOf(flags));
193     }
194 
195     @Override
equals(Object obj)196     public boolean equals(Object obj) {
197         if (obj == null || !(obj.getClass().equals(ApfProgramEvent.class))) return false;
198         final ApfProgramEvent other = (ApfProgramEvent) obj;
199         return lifetime == other.lifetime
200                 && actualLifetime == other.actualLifetime
201                 && filteredRas == other.filteredRas
202                 && currentRas == other.currentRas
203                 && programLength == other.programLength
204                 && flags == other.flags;
205     }
206 
207     /** @hide */
208     public static final @android.annotation.NonNull Parcelable.Creator<ApfProgramEvent> CREATOR
209             = new Parcelable.Creator<ApfProgramEvent>() {
210         public ApfProgramEvent createFromParcel(Parcel in) {
211             return new ApfProgramEvent(in);
212         }
213 
214         public ApfProgramEvent[] newArray(int size) {
215             return new ApfProgramEvent[size];
216         }
217     };
218 
219     /** @hide */
220     @UnsupportedAppUsage
flagsFor(boolean hasIPv4, boolean multicastFilterOn)221     public static @Flags int flagsFor(boolean hasIPv4, boolean multicastFilterOn) {
222         int bitfield = 0;
223         if (hasIPv4) {
224             bitfield |= (1 << FLAG_HAS_IPV4_ADDRESS);
225         }
226         if (multicastFilterOn) {
227             bitfield |= (1 << FLAG_MULTICAST_FILTER_ON);
228         }
229         return bitfield;
230     }
231 
namesOf(@lags int bitfield)232     private static String namesOf(@Flags int bitfield) {
233         List<String> names = new ArrayList<>(Integer.bitCount(bitfield));
234         BitSet set = BitSet.valueOf(new long[]{bitfield & Integer.MAX_VALUE});
235         // Only iterate over flag bits which are set.
236         for (int bit = set.nextSetBit(0); bit >= 0; bit = set.nextSetBit(bit+1)) {
237             names.add(Decoder.constants.get(bit));
238         }
239         return TextUtils.join("|", names);
240     }
241 
242     final static class Decoder {
243         static final SparseArray<String> constants =
244                 MessageUtils.findMessageNames(
245                        new Class[]{ApfProgramEvent.class}, new String[]{"FLAG_"});
246     }
247 }
248