1 /* 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 17 package android.net.metrics; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.compat.annotation.UnsupportedAppUsage; 24 import android.os.Build; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 import android.text.TextUtils; 28 import android.util.SparseArray; 29 30 import com.android.internal.util.MessageUtils; 31 32 import java.lang.annotation.Retention; 33 import java.lang.annotation.RetentionPolicy; 34 import java.util.ArrayList; 35 import java.util.BitSet; 36 import java.util.List; 37 38 /** 39 * An event logged when there is a change or event that requires updating the 40 * the APF program in place with a new APF program. 41 * {@hide} 42 * @deprecated The event may not be sent in Android S and above. The events 43 * are logged by a single caller in the system using signature permissions 44 * and that caller is migrating to statsd. 45 */ 46 @Deprecated 47 @SystemApi 48 public final class ApfProgramEvent implements IpConnectivityLog.Event { 49 50 // Bitflag constants describing what an Apf program filters. 51 // Bits are indexeds from LSB to MSB, starting at index 0. 52 /** @hide */ 53 public static final int FLAG_MULTICAST_FILTER_ON = 0; 54 /** @hide */ 55 public static final int FLAG_HAS_IPV4_ADDRESS = 1; 56 57 /** {@hide} */ 58 @IntDef(flag = true, value = {FLAG_MULTICAST_FILTER_ON, FLAG_HAS_IPV4_ADDRESS}) 59 @Retention(RetentionPolicy.SOURCE) 60 public @interface Flags {} 61 62 /** @hide */ 63 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 64 public final long lifetime; // Maximum computed lifetime of the program in seconds 65 /** @hide */ 66 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 67 public final long actualLifetime; // Effective program lifetime in seconds 68 /** @hide */ 69 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 70 public final int filteredRas; // Number of RAs filtered by the APF program 71 /** @hide */ 72 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 73 public final int currentRas; // Total number of current RAs at generation time 74 /** @hide */ 75 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 76 public final int programLength; // Length of the APF program in bytes 77 /** @hide */ 78 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 79 public final int flags; // Bitfield compound of FLAG_* constants 80 ApfProgramEvent(long lifetime, long actualLifetime, int filteredRas, int currentRas, int programLength, int flags)81 private ApfProgramEvent(long lifetime, long actualLifetime, int filteredRas, int currentRas, 82 int programLength, int flags) { 83 this.lifetime = lifetime; 84 this.actualLifetime = actualLifetime; 85 this.filteredRas = filteredRas; 86 this.currentRas = currentRas; 87 this.programLength = programLength; 88 this.flags = flags; 89 } 90 ApfProgramEvent(Parcel in)91 private ApfProgramEvent(Parcel in) { 92 this.lifetime = in.readLong(); 93 this.actualLifetime = in.readLong(); 94 this.filteredRas = in.readInt(); 95 this.currentRas = in.readInt(); 96 this.programLength = in.readInt(); 97 this.flags = in.readInt(); 98 } 99 100 /** 101 * Utility to create an instance of {@link ApfProgramEvent}. 102 */ 103 public static final class Builder { 104 private long mLifetime; 105 private long mActualLifetime; 106 private int mFilteredRas; 107 private int mCurrentRas; 108 private int mProgramLength; 109 private int mFlags; 110 111 /** 112 * Set the maximum computed lifetime of the program in seconds. 113 */ 114 @NonNull setLifetime(long lifetime)115 public Builder setLifetime(long lifetime) { 116 mLifetime = lifetime; 117 return this; 118 } 119 120 /** 121 * Set the effective program lifetime in seconds. 122 */ 123 @NonNull setActualLifetime(long lifetime)124 public Builder setActualLifetime(long lifetime) { 125 mActualLifetime = lifetime; 126 return this; 127 } 128 129 /** 130 * Set the number of RAs filtered by the APF program. 131 */ 132 @NonNull setFilteredRas(int filteredRas)133 public Builder setFilteredRas(int filteredRas) { 134 mFilteredRas = filteredRas; 135 return this; 136 } 137 138 /** 139 * Set the total number of current RAs at generation time. 140 */ 141 @NonNull setCurrentRas(int currentRas)142 public Builder setCurrentRas(int currentRas) { 143 mCurrentRas = currentRas; 144 return this; 145 } 146 147 /** 148 * Set the length of the APF program in bytes. 149 */ 150 @NonNull setProgramLength(int programLength)151 public Builder setProgramLength(int programLength) { 152 mProgramLength = programLength; 153 return this; 154 } 155 156 /** 157 * Set the flags describing what an Apf program filters. 158 */ 159 @NonNull setFlags(boolean hasIPv4, boolean multicastFilterOn)160 public Builder setFlags(boolean hasIPv4, boolean multicastFilterOn) { 161 mFlags = flagsFor(hasIPv4, multicastFilterOn); 162 return this; 163 } 164 165 /** 166 * Build a new {@link ApfProgramEvent}. 167 */ 168 @NonNull build()169 public ApfProgramEvent build() { 170 return new ApfProgramEvent(mLifetime, mActualLifetime, mFilteredRas, mCurrentRas, 171 mProgramLength, mFlags); 172 } 173 } 174 175 /** @hide */ 176 @Override writeToParcel(Parcel out, int flags)177 public void writeToParcel(Parcel out, int flags) { 178 out.writeLong(lifetime); 179 out.writeLong(actualLifetime); 180 out.writeInt(filteredRas); 181 out.writeInt(currentRas); 182 out.writeInt(programLength); 183 out.writeInt(this.flags); 184 } 185 186 /** @hide */ 187 @Override describeContents()188 public int describeContents() { 189 return 0; 190 } 191 192 @NonNull 193 @Override toString()194 public String toString() { 195 String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever"; 196 return String.format("ApfProgramEvent(%d/%d RAs %dB %ds/%s %s)", filteredRas, currentRas, 197 programLength, actualLifetime, lifetimeString, namesOf(flags)); 198 } 199 200 @Override equals(@ullable Object obj)201 public boolean equals(@Nullable Object obj) { 202 if (obj == null || !(obj.getClass().equals(ApfProgramEvent.class))) return false; 203 final ApfProgramEvent other = (ApfProgramEvent) obj; 204 return lifetime == other.lifetime 205 && actualLifetime == other.actualLifetime 206 && filteredRas == other.filteredRas 207 && currentRas == other.currentRas 208 && programLength == other.programLength 209 && flags == other.flags; 210 } 211 212 /** @hide */ 213 public static final @android.annotation.NonNull Parcelable.Creator<ApfProgramEvent> CREATOR 214 = new Parcelable.Creator<ApfProgramEvent>() { 215 public ApfProgramEvent createFromParcel(Parcel in) { 216 return new ApfProgramEvent(in); 217 } 218 219 public ApfProgramEvent[] newArray(int size) { 220 return new ApfProgramEvent[size]; 221 } 222 }; 223 224 /** @hide */ 225 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) flagsFor(boolean hasIPv4, boolean multicastFilterOn)226 public static @Flags int flagsFor(boolean hasIPv4, boolean multicastFilterOn) { 227 int bitfield = 0; 228 if (hasIPv4) { 229 bitfield |= (1 << FLAG_HAS_IPV4_ADDRESS); 230 } 231 if (multicastFilterOn) { 232 bitfield |= (1 << FLAG_MULTICAST_FILTER_ON); 233 } 234 return bitfield; 235 } 236 namesOf(@lags int bitfield)237 private static String namesOf(@Flags int bitfield) { 238 List<String> names = new ArrayList<>(Integer.bitCount(bitfield)); 239 BitSet set = BitSet.valueOf(new long[]{bitfield & Integer.MAX_VALUE}); 240 // Only iterate over flag bits which are set. 241 for (int bit = set.nextSetBit(0); bit >= 0; bit = set.nextSetBit(bit+1)) { 242 names.add(Decoder.constants.get(bit)); 243 } 244 return TextUtils.join("|", names); 245 } 246 247 final static class Decoder { 248 static final SparseArray<String> constants = 249 MessageUtils.findMessageNames( 250 new Class[]{ApfProgramEvent.class}, new String[]{"FLAG_"}); 251 } 252 } 253