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