blob: cd8ce8d8777820226ae3df3a50a58ceb71b1d3f1 [file] [log] [blame]
Hugo Benichi4fc3ee52016-06-02 11:20:27 +09001/*
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
17package android.net.metrics;
18
Hugo Benichicf6b12f2016-07-04 11:28:05 +090019import android.annotation.IntDef;
paulhu79b380c2019-03-15 17:17:02 +080020import android.annotation.NonNull;
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090021import android.annotation.SystemApi;
22import android.annotation.TestApi;
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010023import android.annotation.UnsupportedAppUsage;
Hugo Benichi4fc3ee52016-06-02 11:20:27 +090024import android.os.Parcel;
25import android.os.Parcelable;
Hugo Benichicf6b12f2016-07-04 11:28:05 +090026import android.text.TextUtils;
Hugo Benichi4fc3ee52016-06-02 11:20:27 +090027import android.util.SparseArray;
28
Hugo Benichi4fc3ee52016-06-02 11:20:27 +090029import com.android.internal.util.MessageUtils;
30
Hugo Benichicf6b12f2016-07-04 11:28:05 +090031import java.lang.annotation.Retention;
32import java.lang.annotation.RetentionPolicy;
33import java.util.ArrayList;
34import java.util.BitSet;
35import java.util.List;
36
Hugo Benichi4fc3ee52016-06-02 11:20:27 +090037/**
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 */
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090042@TestApi
43@SystemApi
44public final class ApfProgramEvent implements IpConnectivityLog.Event {
Hugo Benichi4fc3ee52016-06-02 11:20:27 +090045
46 // Bitflag constants describing what an Apf program filters.
47 // Bits are indexeds from LSB to MSB, starting at index 0.
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090048 /** @hide */
Hugo Benichi4fc3ee52016-06-02 11:20:27 +090049 public static final int FLAG_MULTICAST_FILTER_ON = 0;
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090050 /** @hide */
Hugo Benichi4fc3ee52016-06-02 11:20:27 +090051 public static final int FLAG_HAS_IPV4_ADDRESS = 1;
52
Hugo Benichicf6b12f2016-07-04 11:28:05 +090053 /** {@hide} */
54 @IntDef(flag = true, value = {FLAG_MULTICAST_FILTER_ON, FLAG_HAS_IPV4_ADDRESS})
55 @Retention(RetentionPolicy.SOURCE)
56 public @interface Flags {}
57
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090058 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010059 @UnsupportedAppUsage
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090060 public final long lifetime; // Maximum computed lifetime of the program in seconds
61 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010062 @UnsupportedAppUsage
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090063 public final long actualLifetime; // Effective program lifetime in seconds
64 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010065 @UnsupportedAppUsage
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090066 public final int filteredRas; // Number of RAs filtered by the APF program
67 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010068 @UnsupportedAppUsage
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090069 public final int currentRas; // Total number of current RAs at generation time
70 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010071 @UnsupportedAppUsage
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090072 public final int programLength; // Length of the APF program in bytes
73 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010074 @UnsupportedAppUsage
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090075 public final int flags; // Bitfield compound of FLAG_* constants
Hugo Benichi4fc3ee52016-06-02 11:20:27 +090076
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090077 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;
Hugo Benichi4fc3ee52016-06-02 11:20:27 +090085 }
86
87 private ApfProgramEvent(Parcel in) {
88 this.lifetime = in.readLong();
Hugo Benichi22d9b2d2017-02-22 13:02:27 +090089 this.actualLifetime = in.readLong();
Hugo Benichi4fc3ee52016-06-02 11:20:27 +090090 this.filteredRas = in.readInt();
91 this.currentRas = in.readInt();
92 this.programLength = in.readInt();
93 this.flags = in.readInt();
94 }
95
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +090096 /**
97 * Utility to create an instance of {@link ApfProgramEvent}.
98 */
paulhu79b380c2019-03-15 17:17:02 +080099 public static final class Builder {
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900100 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 */
paulhu79b380c2019-03-15 17:17:02 +0800110 @NonNull
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900111 public Builder setLifetime(long lifetime) {
112 mLifetime = lifetime;
113 return this;
114 }
115
116 /**
117 * Set the effective program lifetime in seconds.
118 */
paulhu79b380c2019-03-15 17:17:02 +0800119 @NonNull
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900120 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 */
paulhu79b380c2019-03-15 17:17:02 +0800128 @NonNull
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900129 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 */
paulhu79b380c2019-03-15 17:17:02 +0800137 @NonNull
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900138 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 */
paulhu79b380c2019-03-15 17:17:02 +0800146 @NonNull
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900147 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 */
paulhu79b380c2019-03-15 17:17:02 +0800155 @NonNull
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900156 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 */
paulhu79b380c2019-03-15 17:17:02 +0800164 @NonNull
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900165 public ApfProgramEvent build() {
166 return new ApfProgramEvent(mLifetime, mActualLifetime, mFilteredRas, mCurrentRas,
167 mProgramLength, mFlags);
168 }
169 }
170
171 /** @hide */
Hugo Benichi4fc3ee52016-06-02 11:20:27 +0900172 @Override
173 public void writeToParcel(Parcel out, int flags) {
174 out.writeLong(lifetime);
Hugo Benichi22d9b2d2017-02-22 13:02:27 +0900175 out.writeLong(actualLifetime);
Hugo Benichi4fc3ee52016-06-02 11:20:27 +0900176 out.writeInt(filteredRas);
177 out.writeInt(currentRas);
178 out.writeInt(programLength);
paulhuf32da692019-04-18 15:24:48 +0800179 out.writeInt(this.flags);
Hugo Benichi4fc3ee52016-06-02 11:20:27 +0900180 }
181
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900182 /** @hide */
Hugo Benichi4fc3ee52016-06-02 11:20:27 +0900183 @Override
184 public int describeContents() {
185 return 0;
186 }
187
188 @Override
189 public String toString() {
190 String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever";
Hugo Benichi22d9b2d2017-02-22 13:02:27 +0900191 return String.format("ApfProgramEvent(%d/%d RAs %dB %ds/%s %s)", filteredRas, currentRas,
192 programLength, actualLifetime, lifetimeString, namesOf(flags));
Hugo Benichi4fc3ee52016-06-02 11:20:27 +0900193 }
194
paulhuf32da692019-04-18 15:24:48 +0800195 @Override
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
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900207 /** @hide */
Hugo Benichi4fc3ee52016-06-02 11:20:27 +0900208 public static final 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
Remi NGUYEN VAN7b84fb32019-01-19 21:13:24 +0900219 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100220 @UnsupportedAppUsage
Hugo Benichicf6b12f2016-07-04 11:28:05 +0900221 public static @Flags int flagsFor(boolean hasIPv4, boolean multicastFilterOn) {
Hugo Benichi4fc3ee52016-06-02 11:20:27 +0900222 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
Hugo Benichicf6b12f2016-07-04 11:28:05 +0900232 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));
Hugo Benichi4fc3ee52016-06-02 11:20:27 +0900238 }
Hugo Benichi0d1c65b2016-06-22 17:01:43 +0900239 return TextUtils.join("|", names);
Hugo Benichi4fc3ee52016-06-02 11:20:27 +0900240 }
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}