1 /* 2 * Copyright (C) 2021 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 package android.net.vcn; 17 18 import static com.android.internal.annotations.VisibleForTesting.Visibility; 19 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.os.PersistableBundle; 24 import android.util.SparseArray; 25 26 import com.android.internal.annotations.VisibleForTesting; 27 import com.android.internal.util.IndentingPrintWriter; 28 import com.android.internal.util.Preconditions; 29 30 import java.lang.annotation.Retention; 31 import java.lang.annotation.RetentionPolicy; 32 import java.util.Objects; 33 34 /** 35 * This class represents a template containing set of underlying network requirements for doing 36 * route selection. 37 * 38 * <p>Apps provisioning a VCN can configure the underlying network priority for each Gateway 39 * Connection by setting a list (in priority order, most to least preferred) of the appropriate 40 * subclasses in the VcnGatewayConnectionConfig. See {@link 41 * VcnGatewayConnectionConfig.Builder#setVcnUnderlyingNetworkPriorities} 42 */ 43 public abstract class VcnUnderlyingNetworkTemplate { 44 /** @hide */ 45 static final int NETWORK_PRIORITY_TYPE_WIFI = 1; 46 /** @hide */ 47 static final int NETWORK_PRIORITY_TYPE_CELL = 2; 48 49 /** 50 * Used to configure the matching criteria of a network characteristic. This may include network 51 * capabilities, or cellular subscription information. Denotes that networks with or without the 52 * characteristic are both acceptable to match this template. 53 */ 54 public static final int MATCH_ANY = 0; 55 56 /** 57 * Used to configure the matching criteria of a network characteristic. This may include network 58 * capabilities, or cellular subscription information. Denotes that a network MUST have the 59 * capability in order to match this template. 60 */ 61 public static final int MATCH_REQUIRED = 1; 62 63 /** 64 * Used to configure the matching criteria of a network characteristic. This may include network 65 * capabilities, or cellular subscription information. Denotes that a network MUST NOT have the 66 * capability in order to match this template. 67 */ 68 public static final int MATCH_FORBIDDEN = 2; 69 70 /** @hide */ 71 @Retention(RetentionPolicy.SOURCE) 72 @IntDef({MATCH_ANY, MATCH_REQUIRED, MATCH_FORBIDDEN}) 73 public @interface MatchCriteria {} 74 75 private static final SparseArray<String> MATCH_CRITERIA_TO_STRING_MAP = new SparseArray<>(); 76 77 static { MATCH_CRITERIA_TO_STRING_MAP.put(MATCH_ANY, "MATCH_ANY")78 MATCH_CRITERIA_TO_STRING_MAP.put(MATCH_ANY, "MATCH_ANY"); MATCH_CRITERIA_TO_STRING_MAP.put(MATCH_REQUIRED, "MATCH_REQUIRED")79 MATCH_CRITERIA_TO_STRING_MAP.put(MATCH_REQUIRED, "MATCH_REQUIRED"); MATCH_CRITERIA_TO_STRING_MAP.put(MATCH_FORBIDDEN, "MATCH_FORBIDDEN")80 MATCH_CRITERIA_TO_STRING_MAP.put(MATCH_FORBIDDEN, "MATCH_FORBIDDEN"); 81 } 82 83 private static final String NETWORK_PRIORITY_TYPE_KEY = "mNetworkPriorityType"; 84 private final int mNetworkPriorityType; 85 86 /** @hide */ 87 static final String METERED_MATCH_KEY = "mMeteredMatchCriteria"; 88 89 /** @hide */ 90 static final int DEFAULT_METERED_MATCH_CRITERIA = MATCH_ANY; 91 92 private final int mMeteredMatchCriteria; 93 94 /** @hide */ 95 public static final int DEFAULT_MIN_BANDWIDTH_KBPS = 0; 96 97 /** @hide */ 98 static final String MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY = "mMinEntryUpstreamBandwidthKbps"; 99 100 private final int mMinEntryUpstreamBandwidthKbps; 101 102 /** @hide */ 103 static final String MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY = "mMinExitUpstreamBandwidthKbps"; 104 105 private final int mMinExitUpstreamBandwidthKbps; 106 107 /** @hide */ 108 static final String MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY = 109 "mMinEntryDownstreamBandwidthKbps"; 110 111 private final int mMinEntryDownstreamBandwidthKbps; 112 113 /** @hide */ 114 static final String MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY = "mMinExitDownstreamBandwidthKbps"; 115 116 private final int mMinExitDownstreamBandwidthKbps; 117 118 /** @hide */ VcnUnderlyingNetworkTemplate( int networkPriorityType, int meteredMatchCriteria, int minEntryUpstreamBandwidthKbps, int minExitUpstreamBandwidthKbps, int minEntryDownstreamBandwidthKbps, int minExitDownstreamBandwidthKbps)119 VcnUnderlyingNetworkTemplate( 120 int networkPriorityType, 121 int meteredMatchCriteria, 122 int minEntryUpstreamBandwidthKbps, 123 int minExitUpstreamBandwidthKbps, 124 int minEntryDownstreamBandwidthKbps, 125 int minExitDownstreamBandwidthKbps) { 126 mNetworkPriorityType = networkPriorityType; 127 mMeteredMatchCriteria = meteredMatchCriteria; 128 mMinEntryUpstreamBandwidthKbps = minEntryUpstreamBandwidthKbps; 129 mMinExitUpstreamBandwidthKbps = minExitUpstreamBandwidthKbps; 130 mMinEntryDownstreamBandwidthKbps = minEntryDownstreamBandwidthKbps; 131 mMinExitDownstreamBandwidthKbps = minExitDownstreamBandwidthKbps; 132 } 133 134 /** @hide */ validateMatchCriteria(int matchCriteria, String matchingCapability)135 static void validateMatchCriteria(int matchCriteria, String matchingCapability) { 136 Preconditions.checkArgument( 137 MATCH_CRITERIA_TO_STRING_MAP.contains(matchCriteria), 138 "Invalid matching criteria: " + matchCriteria + " for " + matchingCapability); 139 } 140 141 /** @hide */ validateMinBandwidthKbps(int minEntryBandwidth, int minExitBandwidth)142 static void validateMinBandwidthKbps(int minEntryBandwidth, int minExitBandwidth) { 143 Preconditions.checkArgument( 144 minEntryBandwidth >= 0, "Invalid minEntryBandwidth, must be >= 0"); 145 Preconditions.checkArgument( 146 minExitBandwidth >= 0, "Invalid minExitBandwidth, must be >= 0"); 147 Preconditions.checkArgument( 148 minEntryBandwidth >= minExitBandwidth, 149 "Minimum entry bandwidth must be >= exit bandwidth"); 150 } 151 152 /** @hide */ validate()153 protected void validate() { 154 validateMatchCriteria(mMeteredMatchCriteria, "mMeteredMatchCriteria"); 155 validateMinBandwidthKbps(mMinEntryUpstreamBandwidthKbps, mMinExitUpstreamBandwidthKbps); 156 validateMinBandwidthKbps(mMinEntryDownstreamBandwidthKbps, mMinExitDownstreamBandwidthKbps); 157 } 158 159 /** @hide */ 160 @NonNull 161 @VisibleForTesting(visibility = Visibility.PROTECTED) fromPersistableBundle( @onNull PersistableBundle in)162 public static VcnUnderlyingNetworkTemplate fromPersistableBundle( 163 @NonNull PersistableBundle in) { 164 Objects.requireNonNull(in, "PersistableBundle is null"); 165 166 final int networkPriorityType = in.getInt(NETWORK_PRIORITY_TYPE_KEY); 167 switch (networkPriorityType) { 168 case NETWORK_PRIORITY_TYPE_WIFI: 169 return VcnWifiUnderlyingNetworkTemplate.fromPersistableBundle(in); 170 case NETWORK_PRIORITY_TYPE_CELL: 171 return VcnCellUnderlyingNetworkTemplate.fromPersistableBundle(in); 172 default: 173 throw new IllegalArgumentException( 174 "Invalid networkPriorityType:" + networkPriorityType); 175 } 176 } 177 178 /** @hide */ 179 @NonNull toPersistableBundle()180 PersistableBundle toPersistableBundle() { 181 final PersistableBundle result = new PersistableBundle(); 182 183 result.putInt(NETWORK_PRIORITY_TYPE_KEY, mNetworkPriorityType); 184 result.putInt(METERED_MATCH_KEY, mMeteredMatchCriteria); 185 result.putInt(MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY, mMinEntryUpstreamBandwidthKbps); 186 result.putInt(MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY, mMinExitUpstreamBandwidthKbps); 187 result.putInt(MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY, mMinEntryDownstreamBandwidthKbps); 188 result.putInt(MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY, mMinExitDownstreamBandwidthKbps); 189 190 return result; 191 } 192 193 @Override hashCode()194 public int hashCode() { 195 return Objects.hash( 196 mNetworkPriorityType, 197 mMeteredMatchCriteria, 198 mMinEntryUpstreamBandwidthKbps, 199 mMinExitUpstreamBandwidthKbps, 200 mMinEntryDownstreamBandwidthKbps, 201 mMinExitDownstreamBandwidthKbps); 202 } 203 204 @Override equals(@ullable Object other)205 public boolean equals(@Nullable Object other) { 206 if (!(other instanceof VcnUnderlyingNetworkTemplate)) { 207 return false; 208 } 209 210 final VcnUnderlyingNetworkTemplate rhs = (VcnUnderlyingNetworkTemplate) other; 211 return mNetworkPriorityType == rhs.mNetworkPriorityType 212 && mMeteredMatchCriteria == rhs.mMeteredMatchCriteria 213 && mMinEntryUpstreamBandwidthKbps == rhs.mMinEntryUpstreamBandwidthKbps 214 && mMinExitUpstreamBandwidthKbps == rhs.mMinExitUpstreamBandwidthKbps 215 && mMinEntryDownstreamBandwidthKbps == rhs.mMinEntryDownstreamBandwidthKbps 216 && mMinExitDownstreamBandwidthKbps == rhs.mMinExitDownstreamBandwidthKbps; 217 } 218 219 /** @hide */ getNameString(SparseArray<String> toStringMap, int key)220 static String getNameString(SparseArray<String> toStringMap, int key) { 221 return toStringMap.get(key, "Invalid value " + key); 222 } 223 224 /** @hide */ getMatchCriteriaString(int matchCriteria)225 static String getMatchCriteriaString(int matchCriteria) { 226 return getNameString(MATCH_CRITERIA_TO_STRING_MAP, matchCriteria); 227 } 228 229 /** @hide */ dumpTransportSpecificFields(IndentingPrintWriter pw)230 abstract void dumpTransportSpecificFields(IndentingPrintWriter pw); 231 232 /** 233 * Dumps the state of this record for logging and debugging purposes. 234 * 235 * @hide 236 */ dump(IndentingPrintWriter pw)237 public void dump(IndentingPrintWriter pw) { 238 pw.println(this.getClass().getSimpleName() + ":"); 239 pw.increaseIndent(); 240 241 if (mMeteredMatchCriteria != DEFAULT_METERED_MATCH_CRITERIA) { 242 pw.println("mMeteredMatchCriteria: " + getMatchCriteriaString(mMeteredMatchCriteria)); 243 } 244 if (mMinEntryUpstreamBandwidthKbps != DEFAULT_MIN_BANDWIDTH_KBPS) { 245 pw.println("mMinEntryUpstreamBandwidthKbps: " + mMinEntryUpstreamBandwidthKbps); 246 } 247 if (mMinExitUpstreamBandwidthKbps != DEFAULT_MIN_BANDWIDTH_KBPS) { 248 pw.println("mMinExitUpstreamBandwidthKbps: " + mMinExitUpstreamBandwidthKbps); 249 } 250 if (mMinEntryDownstreamBandwidthKbps != DEFAULT_MIN_BANDWIDTH_KBPS) { 251 pw.println("mMinEntryDownstreamBandwidthKbps: " + mMinEntryDownstreamBandwidthKbps); 252 } 253 if (mMinExitDownstreamBandwidthKbps != DEFAULT_MIN_BANDWIDTH_KBPS) { 254 pw.println("mMinExitDownstreamBandwidthKbps: " + mMinExitDownstreamBandwidthKbps); 255 } 256 dumpTransportSpecificFields(pw); 257 258 pw.decreaseIndent(); 259 } 260 261 /** 262 * Return the matching criteria for metered networks. 263 * 264 * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMetered(int) 265 * @see VcnCellUnderlyingNetworkTemplate.Builder#setMetered(int) 266 */ getMetered()267 public int getMetered() { 268 return mMeteredMatchCriteria; 269 } 270 271 /** 272 * Returns the minimum entry upstream bandwidth allowed by this template. 273 * 274 * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int) 275 * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int) 276 */ getMinEntryUpstreamBandwidthKbps()277 public int getMinEntryUpstreamBandwidthKbps() { 278 return mMinEntryUpstreamBandwidthKbps; 279 } 280 281 /** 282 * Returns the minimum exit upstream bandwidth allowed by this template. 283 * 284 * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int) 285 * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int) 286 */ getMinExitUpstreamBandwidthKbps()287 public int getMinExitUpstreamBandwidthKbps() { 288 return mMinExitUpstreamBandwidthKbps; 289 } 290 291 /** 292 * Returns the minimum entry downstream bandwidth allowed by this template. 293 * 294 * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int) 295 * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int) 296 */ getMinEntryDownstreamBandwidthKbps()297 public int getMinEntryDownstreamBandwidthKbps() { 298 return mMinEntryDownstreamBandwidthKbps; 299 } 300 301 /** 302 * Returns the minimum exit downstream bandwidth allowed by this template. 303 * 304 * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int) 305 * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int) 306 */ getMinExitDownstreamBandwidthKbps()307 public int getMinExitDownstreamBandwidthKbps() { 308 return mMinExitDownstreamBandwidthKbps; 309 } 310 } 311