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