14fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi/*
24fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * Copyright (C) 2016 The Android Open Source Project
34fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi *
44fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * Licensed under the Apache License, Version 2.0 (the "License");
54fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * you may not use this file except in compliance with the License.
64fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * You may obtain a copy of the License at
74fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi *
84fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi *      http://www.apache.org/licenses/LICENSE-2.0
94fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi *
104fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * Unless required by applicable law or agreed to in writing, software
114fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * distributed under the License is distributed on an "AS IS" BASIS,
124fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * See the License for the specific language governing permissions and
144fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * limitations under the License.
154fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi */
164fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
174fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichipackage android.net.metrics;
184fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
19cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichiimport android.annotation.IntDef;
204fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichiimport android.annotation.SystemApi;
214fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichiimport android.os.Parcel;
224fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichiimport android.os.Parcelable;
23cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichiimport android.text.TextUtils;
244fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichiimport android.util.SparseArray;
254fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
264fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichiimport com.android.internal.util.MessageUtils;
274fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
28cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichiimport java.lang.annotation.Retention;
29cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichiimport java.lang.annotation.RetentionPolicy;
30cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichiimport java.util.ArrayList;
31cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichiimport java.util.BitSet;
32cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichiimport java.util.List;
33cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi
344fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi/**
354fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * An event logged when there is a change or event that requires updating the
364fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * the APF program in place with a new APF program.
374fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi * {@hide}
384fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi */
394fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi@SystemApi
404fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichipublic final class ApfProgramEvent implements Parcelable {
414fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
424fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    // Bitflag constants describing what an Apf program filters.
434fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    // Bits are indexeds from LSB to MSB, starting at index 0.
444fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public static final int FLAG_MULTICAST_FILTER_ON = 0;
454fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public static final int FLAG_HAS_IPV4_ADDRESS    = 1;
464fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
47cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi    /** {@hide} */
48cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi    @IntDef(flag = true, value = {FLAG_MULTICAST_FILTER_ON, FLAG_HAS_IPV4_ADDRESS})
49cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi    @Retention(RetentionPolicy.SOURCE)
50cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi    public @interface Flags {}
51cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi
524fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public final long lifetime;     // Lifetime of the program in seconds
534fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public final int filteredRas;   // Number of RAs filtered by the APF program
544fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public final int currentRas;    // Total number of current RAs at generation time
554fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public final int programLength; // Length of the APF program in bytes
564fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public final int flags;         // Bitfield compound of FLAG_* constants
574fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
584fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    /** {@hide} */
594fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public ApfProgramEvent(
60cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi            long lifetime, int filteredRas, int currentRas, int programLength, @Flags int flags) {
614fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        this.lifetime = lifetime;
624fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        this.filteredRas = filteredRas;
634fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        this.currentRas = currentRas;
644fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        this.programLength = programLength;
654fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        this.flags = flags;
664fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    }
674fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
684fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    private ApfProgramEvent(Parcel in) {
694fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        this.lifetime = in.readLong();
704fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        this.filteredRas = in.readInt();
714fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        this.currentRas = in.readInt();
724fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        this.programLength = in.readInt();
734fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        this.flags = in.readInt();
744fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    }
754fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
764fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    @Override
774fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public void writeToParcel(Parcel out, int flags) {
784fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        out.writeLong(lifetime);
794fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        out.writeInt(filteredRas);
804fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        out.writeInt(currentRas);
814fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        out.writeInt(programLength);
824fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        out.writeInt(flags);
834fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    }
844fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
854fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    @Override
864fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public int describeContents() {
874fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        return 0;
884fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    }
894fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
904fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    @Override
914fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public String toString() {
924fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever";
934fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        return String.format("ApfProgramEvent(%d/%d RAs %dB %s %s)",
944fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi                filteredRas, currentRas, programLength, lifetimeString, namesOf(flags));
954fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    }
964fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
974fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    public static final Parcelable.Creator<ApfProgramEvent> CREATOR
984fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi            = new Parcelable.Creator<ApfProgramEvent>() {
994fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        public ApfProgramEvent createFromParcel(Parcel in) {
1004fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi            return new ApfProgramEvent(in);
1014fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        }
1024fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
1034fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        public ApfProgramEvent[] newArray(int size) {
1044fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi            return new ApfProgramEvent[size];
1054fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        }
1064fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    };
1074fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
1084fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    /** {@hide} */
109cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi    public static @Flags int flagsFor(boolean hasIPv4, boolean multicastFilterOn) {
1104fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        int bitfield = 0;
1114fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        if (hasIPv4) {
1124fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi            bitfield |= (1 << FLAG_HAS_IPV4_ADDRESS);
1134fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        }
1144fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        if (multicastFilterOn) {
1154fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi            bitfield |= (1 << FLAG_MULTICAST_FILTER_ON);
1164fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        }
1174fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        return bitfield;
1184fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    }
1194fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
120cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi    private static String namesOf(@Flags int bitfield) {
121cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi        List<String> names = new ArrayList<>(Integer.bitCount(bitfield));
122cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi        BitSet set = BitSet.valueOf(new long[]{bitfield & Integer.MAX_VALUE});
123cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi        // Only iterate over flag bits which are set.
124cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi        for (int bit = set.nextSetBit(0); bit >= 0; bit = set.nextSetBit(bit+1)) {
125cf6b12f50aa3251a3fc9929c565f8a19eaaac49eHugo Benichi            names.add(Decoder.constants.get(bit));
1264fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        }
1270d1c65b221dee1ef80a03c25877e7fd58fc106deHugo Benichi        return TextUtils.join("|", names);
1284fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    }
1294fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi
1304fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    final static class Decoder {
1314fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi        static final SparseArray<String> constants =
1324fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi                MessageUtils.findMessageNames(
1334fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi                       new Class[]{ApfProgramEvent.class}, new String[]{"FLAG_"});
1344fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi    }
1354fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi}
136