blob: 3cd058cb6dc59fe7857da9594e0b186cd1a0ecc9 [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
19import android.annotation.SystemApi;
20import android.os.Parcel;
21import android.os.Parcelable;
22import android.util.SparseArray;
23
24import java.util.Arrays;
25import java.util.stream.Collectors;
26
27import com.android.internal.util.MessageUtils;
28
29/**
30 * An event logged when there is a change or event that requires updating the
31 * the APF program in place with a new APF program.
32 * {@hide}
33 */
34@SystemApi
35public final class ApfProgramEvent implements Parcelable {
36
37 // Bitflag constants describing what an Apf program filters.
38 // Bits are indexeds from LSB to MSB, starting at index 0.
39 // TODO: use @IntDef
40 public static final int FLAG_MULTICAST_FILTER_ON = 0;
41 public static final int FLAG_HAS_IPV4_ADDRESS = 1;
42
43 public final long lifetime; // Lifetime of the program in seconds
44 public final int filteredRas; // Number of RAs filtered by the APF program
45 public final int currentRas; // Total number of current RAs at generation time
46 public final int programLength; // Length of the APF program in bytes
47 public final int flags; // Bitfield compound of FLAG_* constants
48
49 /** {@hide} */
50 public ApfProgramEvent(
51 long lifetime, int filteredRas, int currentRas, int programLength, int flags) {
52 this.lifetime = lifetime;
53 this.filteredRas = filteredRas;
54 this.currentRas = currentRas;
55 this.programLength = programLength;
56 this.flags = flags;
57 }
58
59 private ApfProgramEvent(Parcel in) {
60 this.lifetime = in.readLong();
61 this.filteredRas = in.readInt();
62 this.currentRas = in.readInt();
63 this.programLength = in.readInt();
64 this.flags = in.readInt();
65 }
66
67 @Override
68 public void writeToParcel(Parcel out, int flags) {
69 out.writeLong(lifetime);
70 out.writeInt(filteredRas);
71 out.writeInt(currentRas);
72 out.writeInt(programLength);
73 out.writeInt(flags);
74 }
75
76 @Override
77 public int describeContents() {
78 return 0;
79 }
80
81 @Override
82 public String toString() {
83 String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever";
84 return String.format("ApfProgramEvent(%d/%d RAs %dB %s %s)",
85 filteredRas, currentRas, programLength, lifetimeString, namesOf(flags));
86 }
87
88 public static final Parcelable.Creator<ApfProgramEvent> CREATOR
89 = new Parcelable.Creator<ApfProgramEvent>() {
90 public ApfProgramEvent createFromParcel(Parcel in) {
91 return new ApfProgramEvent(in);
92 }
93
94 public ApfProgramEvent[] newArray(int size) {
95 return new ApfProgramEvent[size];
96 }
97 };
98
99 /** {@hide} */
100 public static int flagsFor(boolean hasIPv4, boolean multicastFilterOn) {
101 int bitfield = 0;
102 if (hasIPv4) {
103 bitfield |= (1 << FLAG_HAS_IPV4_ADDRESS);
104 }
105 if (multicastFilterOn) {
106 bitfield |= (1 << FLAG_MULTICAST_FILTER_ON);
107 }
108 return bitfield;
109 }
110
111 // TODO: consider using java.util.BitSet
112 private static int[] bitflagsOf(int bitfield) {
113 int[] flags = new int[Integer.bitCount(bitfield)];
114 int i = 0;
115 int bitflag = 0;
116 while (bitfield != 0) {
117 if ((bitfield & 1) != 0) {
118 flags[i++] = bitflag;
119 }
120 bitflag++;
121 bitfield = bitfield >>> 1;
122 }
123 return flags;
124 }
125
126 private static String namesOf(int bitfields) {
127 return Arrays.stream(bitflagsOf(bitfields))
128 .mapToObj(i -> Decoder.constants.get(i))
129 .collect(Collectors.joining(", "));
130 }
131
132 final static class Decoder {
133 static final SparseArray<String> constants =
134 MessageUtils.findMessageNames(
135 new Class[]{ApfProgramEvent.class}, new String[]{"FLAG_"});
136 }
137}