File: ApfProgramEvent.java

package info (click to toggle)
android-platform-frameworks-base 1%3A10.0.0%2Br36-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 321,788 kB
  • sloc: java: 962,234; cpp: 274,314; xml: 242,770; python: 5,060; sh: 1,432; ansic: 494; makefile: 47; sed: 19
file content (247 lines) | stat: -rw-r--r-- 8,036 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net.metrics;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.SparseArray;

import com.android.internal.util.MessageUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

/**
 * An event logged when there is a change or event that requires updating the
 * the APF program in place with a new APF program.
 * {@hide}
 */
@TestApi
@SystemApi
public final class ApfProgramEvent implements IpConnectivityLog.Event {

    // Bitflag constants describing what an Apf program filters.
    // Bits are indexeds from LSB to MSB, starting at index 0.
    /** @hide */
    public static final int FLAG_MULTICAST_FILTER_ON = 0;
    /** @hide */
    public static final int FLAG_HAS_IPV4_ADDRESS    = 1;

    /** {@hide} */
    @IntDef(flag = true, value = {FLAG_MULTICAST_FILTER_ON, FLAG_HAS_IPV4_ADDRESS})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Flags {}

    /** @hide */
    @UnsupportedAppUsage
    public final long lifetime;       // Maximum computed lifetime of the program in seconds
    /** @hide */
    @UnsupportedAppUsage
    public final long actualLifetime; // Effective program lifetime in seconds
    /** @hide */
    @UnsupportedAppUsage
    public final int filteredRas;     // Number of RAs filtered by the APF program
    /** @hide */
    @UnsupportedAppUsage
    public final int currentRas;      // Total number of current RAs at generation time
    /** @hide */
    @UnsupportedAppUsage
    public final int programLength;   // Length of the APF program in bytes
    /** @hide */
    @UnsupportedAppUsage
    public final int flags;           // Bitfield compound of FLAG_* constants

    private ApfProgramEvent(long lifetime, long actualLifetime, int filteredRas, int currentRas,
            int programLength, int flags) {
        this.lifetime = lifetime;
        this.actualLifetime = actualLifetime;
        this.filteredRas = filteredRas;
        this.currentRas = currentRas;
        this.programLength = programLength;
        this.flags = flags;
    }

    private ApfProgramEvent(Parcel in) {
        this.lifetime = in.readLong();
        this.actualLifetime = in.readLong();
        this.filteredRas = in.readInt();
        this.currentRas = in.readInt();
        this.programLength = in.readInt();
        this.flags = in.readInt();
    }

    /**
     * Utility to create an instance of {@link ApfProgramEvent}.
     */
    public static final class Builder {
        private long mLifetime;
        private long mActualLifetime;
        private int mFilteredRas;
        private int mCurrentRas;
        private int mProgramLength;
        private int mFlags;

        /**
         * Set the maximum computed lifetime of the program in seconds.
         */
        @NonNull
        public Builder setLifetime(long lifetime) {
            mLifetime = lifetime;
            return this;
        }

        /**
         * Set the effective program lifetime in seconds.
         */
        @NonNull
        public Builder setActualLifetime(long lifetime) {
            mActualLifetime = lifetime;
            return this;
        }

        /**
         * Set the number of RAs filtered by the APF program.
         */
        @NonNull
        public Builder setFilteredRas(int filteredRas) {
            mFilteredRas = filteredRas;
            return this;
        }

        /**
         * Set the total number of current RAs at generation time.
         */
        @NonNull
        public Builder setCurrentRas(int currentRas) {
            mCurrentRas = currentRas;
            return this;
        }

        /**
         * Set the length of the APF program in bytes.
         */
        @NonNull
        public Builder setProgramLength(int programLength) {
            mProgramLength = programLength;
            return this;
        }

        /**
         * Set the flags describing what an Apf program filters.
         */
        @NonNull
        public Builder setFlags(boolean hasIPv4, boolean multicastFilterOn) {
            mFlags = flagsFor(hasIPv4, multicastFilterOn);
            return this;
        }

        /**
         * Build a new {@link ApfProgramEvent}.
         */
        @NonNull
        public ApfProgramEvent build() {
            return new ApfProgramEvent(mLifetime, mActualLifetime, mFilteredRas, mCurrentRas,
                    mProgramLength, mFlags);
        }
    }

    /** @hide */
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeLong(lifetime);
        out.writeLong(actualLifetime);
        out.writeInt(filteredRas);
        out.writeInt(currentRas);
        out.writeInt(programLength);
        out.writeInt(this.flags);
    }

    /** @hide */
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public String toString() {
        String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever";
        return String.format("ApfProgramEvent(%d/%d RAs %dB %ds/%s %s)", filteredRas, currentRas,
                programLength, actualLifetime, lifetimeString, namesOf(flags));
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null || !(obj.getClass().equals(ApfProgramEvent.class))) return false;
        final ApfProgramEvent other = (ApfProgramEvent) obj;
        return lifetime == other.lifetime
                && actualLifetime == other.actualLifetime
                && filteredRas == other.filteredRas
                && currentRas == other.currentRas
                && programLength == other.programLength
                && flags == other.flags;
    }

    /** @hide */
    public static final @android.annotation.NonNull Parcelable.Creator<ApfProgramEvent> CREATOR
            = new Parcelable.Creator<ApfProgramEvent>() {
        public ApfProgramEvent createFromParcel(Parcel in) {
            return new ApfProgramEvent(in);
        }

        public ApfProgramEvent[] newArray(int size) {
            return new ApfProgramEvent[size];
        }
    };

    /** @hide */
    @UnsupportedAppUsage
    public static @Flags int flagsFor(boolean hasIPv4, boolean multicastFilterOn) {
        int bitfield = 0;
        if (hasIPv4) {
            bitfield |= (1 << FLAG_HAS_IPV4_ADDRESS);
        }
        if (multicastFilterOn) {
            bitfield |= (1 << FLAG_MULTICAST_FILTER_ON);
        }
        return bitfield;
    }

    private static String namesOf(@Flags int bitfield) {
        List<String> names = new ArrayList<>(Integer.bitCount(bitfield));
        BitSet set = BitSet.valueOf(new long[]{bitfield & Integer.MAX_VALUE});
        // Only iterate over flag bits which are set.
        for (int bit = set.nextSetBit(0); bit >= 0; bit = set.nextSetBit(bit+1)) {
            names.add(Decoder.constants.get(bit));
        }
        return TextUtils.join("|", names);
    }

    final static class Decoder {
        static final SparseArray<String> constants =
                MessageUtils.findMessageNames(
                       new Class[]{ApfProgramEvent.class}, new String[]{"FLAG_"});
    }
}