1 /* 2 * Copyright (C) 2020 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 android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; 19 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED; 20 21 import static com.android.internal.annotations.VisibleForTesting.Visibility; 22 23 import android.annotation.IntDef; 24 import android.annotation.IntRange; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.SuppressLint; 28 import android.net.Network; 29 import android.net.NetworkCapabilities; 30 import android.net.ipsec.ike.IkeTunnelConnectionParams; 31 import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtils; 32 import android.os.PersistableBundle; 33 import android.util.ArraySet; 34 35 import com.android.internal.annotations.VisibleForTesting; 36 import com.android.internal.util.ArrayUtils; 37 import com.android.internal.util.Preconditions; 38 import com.android.server.vcn.util.PersistableBundleUtils; 39 40 import java.lang.annotation.Retention; 41 import java.lang.annotation.RetentionPolicy; 42 import java.util.ArrayList; 43 import java.util.Arrays; 44 import java.util.Collections; 45 import java.util.List; 46 import java.util.Objects; 47 import java.util.Set; 48 import java.util.SortedSet; 49 import java.util.TreeSet; 50 import java.util.concurrent.TimeUnit; 51 52 /** 53 * This class represents a configuration for a connection to a Virtual Carrier Network gateway. 54 * 55 * <p>Each VcnGatewayConnectionConfig represents a single logical connection to a carrier gateway, 56 * and may provide one or more telephony services (as represented by network capabilities). Each 57 * gateway is expected to provide mobility for a given session as the device roams across {@link 58 * Network}s. 59 * 60 * <p>A VCN connection based on this configuration will be brought up dynamically based on device 61 * settings, and filed NetworkRequests. Underlying Networks must provide INTERNET connectivity, and 62 * must be part of the subscription group under which this configuration is registered (see {@link 63 * VcnManager#setVcnConfig}). 64 * 65 * <p>As an abstraction of a cellular network, services that can be provided by a VCN network are 66 * limited to services provided by cellular networks: 67 * 68 * <ul> 69 * <li>{@link NetworkCapabilities#NET_CAPABILITY_MMS} 70 * <li>{@link NetworkCapabilities#NET_CAPABILITY_SUPL} 71 * <li>{@link NetworkCapabilities#NET_CAPABILITY_DUN} 72 * <li>{@link NetworkCapabilities#NET_CAPABILITY_FOTA} 73 * <li>{@link NetworkCapabilities#NET_CAPABILITY_IMS} 74 * <li>{@link NetworkCapabilities#NET_CAPABILITY_CBS} 75 * <li>{@link NetworkCapabilities#NET_CAPABILITY_IA} 76 * <li>{@link NetworkCapabilities#NET_CAPABILITY_RCS} 77 * <li>{@link NetworkCapabilities#NET_CAPABILITY_XCAP} 78 * <li>{@link NetworkCapabilities#NET_CAPABILITY_EIMS} 79 * <li>{@link NetworkCapabilities#NET_CAPABILITY_INTERNET} 80 * <li>{@link NetworkCapabilities#NET_CAPABILITY_MCX} 81 * </ul> 82 */ 83 public final class VcnGatewayConnectionConfig { 84 // TODO: Use MIN_MTU_V6 once it is public, @hide 85 @VisibleForTesting(visibility = Visibility.PRIVATE) 86 static final int MIN_MTU_V6 = 1280; 87 88 /** 89 * The set of allowed capabilities for exposed capabilities. 90 * 91 * @hide 92 */ 93 public static final Set<Integer> ALLOWED_CAPABILITIES; 94 95 static { 96 Set<Integer> allowedCaps = new ArraySet<>(); 97 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_MMS); 98 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_SUPL); 99 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_DUN); 100 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_FOTA); 101 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_IMS); 102 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_CBS); 103 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_IA); 104 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_RCS); 105 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_XCAP); 106 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_EIMS); 107 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_INTERNET); 108 allowedCaps.add(NetworkCapabilities.NET_CAPABILITY_MCX); 109 110 ALLOWED_CAPABILITIES = Collections.unmodifiableSet(allowedCaps); 111 } 112 113 /** @hide */ 114 @Retention(RetentionPolicy.SOURCE) 115 @IntDef( 116 prefix = {"NET_CAPABILITY_"}, 117 value = { 118 NetworkCapabilities.NET_CAPABILITY_MMS, 119 NetworkCapabilities.NET_CAPABILITY_SUPL, 120 NetworkCapabilities.NET_CAPABILITY_DUN, 121 NetworkCapabilities.NET_CAPABILITY_FOTA, 122 NetworkCapabilities.NET_CAPABILITY_IMS, 123 NetworkCapabilities.NET_CAPABILITY_CBS, 124 NetworkCapabilities.NET_CAPABILITY_IA, 125 NetworkCapabilities.NET_CAPABILITY_RCS, 126 NetworkCapabilities.NET_CAPABILITY_XCAP, 127 NetworkCapabilities.NET_CAPABILITY_EIMS, 128 NetworkCapabilities.NET_CAPABILITY_INTERNET, 129 NetworkCapabilities.NET_CAPABILITY_MCX, 130 }) 131 public @interface VcnSupportedCapability {} 132 133 private static final int DEFAULT_MAX_MTU = 1500; 134 135 /** 136 * The maximum number of retry intervals that may be specified. 137 * 138 * <p>Limited to ensure an upper bound on config sizes. 139 */ 140 private static final int MAX_RETRY_INTERVAL_COUNT = 10; 141 142 /** 143 * The minimum allowable repeating retry interval 144 * 145 * <p>To ensure the device is not constantly being woken up, this retry interval MUST be greater 146 * than this value. 147 * 148 * @see {@link Builder#setRetryIntervalsMillis()} 149 */ 150 private static final long MINIMUM_REPEATING_RETRY_INTERVAL_MS = TimeUnit.MINUTES.toMillis(15); 151 152 private static final long[] DEFAULT_RETRY_INTERVALS_MS = 153 new long[] { 154 TimeUnit.SECONDS.toMillis(1), 155 TimeUnit.SECONDS.toMillis(2), 156 TimeUnit.SECONDS.toMillis(5), 157 TimeUnit.SECONDS.toMillis(30), 158 TimeUnit.MINUTES.toMillis(1), 159 TimeUnit.MINUTES.toMillis(5), 160 TimeUnit.MINUTES.toMillis(15) 161 }; 162 163 /** @hide */ 164 @VisibleForTesting(visibility = Visibility.PRIVATE) 165 public static final List<VcnUnderlyingNetworkTemplate> DEFAULT_UNDERLYING_NETWORK_TEMPLATES = 166 new ArrayList<>(); 167 168 static { DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add( new VcnCellUnderlyingNetworkTemplate.Builder() .setOpportunistic(MATCH_REQUIRED) .build())169 DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add( 170 new VcnCellUnderlyingNetworkTemplate.Builder() 171 .setOpportunistic(MATCH_REQUIRED) 172 .build()); 173 DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add( new VcnWifiUnderlyingNetworkTemplate.Builder() .build())174 DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add( 175 new VcnWifiUnderlyingNetworkTemplate.Builder() 176 .build()); 177 DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add( new VcnCellUnderlyingNetworkTemplate.Builder() .build())178 DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add( 179 new VcnCellUnderlyingNetworkTemplate.Builder() 180 .build()); 181 } 182 183 private static final String GATEWAY_CONNECTION_NAME_KEY = "mGatewayConnectionName"; 184 @NonNull private final String mGatewayConnectionName; 185 186 private static final String TUNNEL_CONNECTION_PARAMS_KEY = "mTunnelConnectionParams"; 187 @NonNull private IkeTunnelConnectionParams mTunnelConnectionParams; 188 189 private static final String EXPOSED_CAPABILITIES_KEY = "mExposedCapabilities"; 190 @NonNull private final SortedSet<Integer> mExposedCapabilities; 191 192 /** @hide */ 193 @VisibleForTesting(visibility = Visibility.PRIVATE) 194 public static final String UNDERLYING_NETWORK_TEMPLATES_KEY = "mUnderlyingNetworkTemplates"; 195 196 @NonNull private final List<VcnUnderlyingNetworkTemplate> mUnderlyingNetworkTemplates; 197 198 private static final String MAX_MTU_KEY = "mMaxMtu"; 199 private final int mMaxMtu; 200 201 private static final String RETRY_INTERVAL_MS_KEY = "mRetryIntervalsMs"; 202 @NonNull private final long[] mRetryIntervalsMs; 203 204 /** Builds a VcnGatewayConnectionConfig with the specified parameters. */ VcnGatewayConnectionConfig( @onNull String gatewayConnectionName, @NonNull IkeTunnelConnectionParams tunnelConnectionParams, @NonNull Set<Integer> exposedCapabilities, @NonNull List<VcnUnderlyingNetworkTemplate> underlyingNetworkTemplates, @NonNull long[] retryIntervalsMs, @IntRange(from = MIN_MTU_V6) int maxMtu)205 private VcnGatewayConnectionConfig( 206 @NonNull String gatewayConnectionName, 207 @NonNull IkeTunnelConnectionParams tunnelConnectionParams, 208 @NonNull Set<Integer> exposedCapabilities, 209 @NonNull List<VcnUnderlyingNetworkTemplate> underlyingNetworkTemplates, 210 @NonNull long[] retryIntervalsMs, 211 @IntRange(from = MIN_MTU_V6) int maxMtu) { 212 mGatewayConnectionName = gatewayConnectionName; 213 mTunnelConnectionParams = tunnelConnectionParams; 214 mExposedCapabilities = new TreeSet(exposedCapabilities); 215 mRetryIntervalsMs = retryIntervalsMs; 216 mMaxMtu = maxMtu; 217 218 mUnderlyingNetworkTemplates = new ArrayList<>(underlyingNetworkTemplates); 219 if (mUnderlyingNetworkTemplates.isEmpty()) { 220 mUnderlyingNetworkTemplates.addAll(DEFAULT_UNDERLYING_NETWORK_TEMPLATES); 221 } 222 223 validate(); 224 } 225 226 // Null check MUST be done for all new fields added to VcnGatewayConnectionConfig, to avoid 227 // crashes when parsing PersistableBundle built on old platforms. 228 /** @hide */ 229 @VisibleForTesting(visibility = Visibility.PRIVATE) VcnGatewayConnectionConfig(@onNull PersistableBundle in)230 public VcnGatewayConnectionConfig(@NonNull PersistableBundle in) { 231 final PersistableBundle tunnelConnectionParamsBundle = 232 in.getPersistableBundle(TUNNEL_CONNECTION_PARAMS_KEY); 233 Objects.requireNonNull( 234 tunnelConnectionParamsBundle, "tunnelConnectionParamsBundle was null"); 235 236 final PersistableBundle exposedCapsBundle = 237 in.getPersistableBundle(EXPOSED_CAPABILITIES_KEY); 238 mGatewayConnectionName = in.getString(GATEWAY_CONNECTION_NAME_KEY); 239 mTunnelConnectionParams = 240 TunnelConnectionParamsUtils.fromPersistableBundle(tunnelConnectionParamsBundle); 241 mExposedCapabilities = new TreeSet<>(PersistableBundleUtils.toList( 242 exposedCapsBundle, PersistableBundleUtils.INTEGER_DESERIALIZER)); 243 244 final PersistableBundle networkTemplatesBundle = 245 in.getPersistableBundle(UNDERLYING_NETWORK_TEMPLATES_KEY); 246 247 if (networkTemplatesBundle == null) { 248 // UNDERLYING_NETWORK_TEMPLATES_KEY was added in Android T. Thus 249 // VcnGatewayConnectionConfig created on old platforms will not have this data and will 250 // be assigned with the default value 251 mUnderlyingNetworkTemplates = new ArrayList<>(DEFAULT_UNDERLYING_NETWORK_TEMPLATES); 252 } else { 253 mUnderlyingNetworkTemplates = 254 PersistableBundleUtils.toList( 255 networkTemplatesBundle, 256 VcnUnderlyingNetworkTemplate::fromPersistableBundle); 257 } 258 259 mRetryIntervalsMs = in.getLongArray(RETRY_INTERVAL_MS_KEY); 260 mMaxMtu = in.getInt(MAX_MTU_KEY); 261 262 validate(); 263 } 264 validate()265 private void validate() { 266 Objects.requireNonNull(mGatewayConnectionName, "gatewayConnectionName was null"); 267 Objects.requireNonNull(mTunnelConnectionParams, "tunnel connection parameter was null"); 268 269 Preconditions.checkArgument( 270 mExposedCapabilities != null && !mExposedCapabilities.isEmpty(), 271 "exposedCapsBundle was null or empty"); 272 for (Integer cap : getAllExposedCapabilities()) { 273 checkValidCapability(cap); 274 } 275 276 validateNetworkTemplateList(mUnderlyingNetworkTemplates); 277 Objects.requireNonNull(mRetryIntervalsMs, "retryIntervalsMs was null"); 278 validateRetryInterval(mRetryIntervalsMs); 279 280 Preconditions.checkArgument( 281 mMaxMtu >= MIN_MTU_V6, "maxMtu must be at least IPv6 min MTU (1280)"); 282 } 283 checkValidCapability(int capability)284 private static void checkValidCapability(int capability) { 285 Preconditions.checkArgument( 286 ALLOWED_CAPABILITIES.contains(capability), 287 "NetworkCapability " + capability + "out of range"); 288 } 289 validateRetryInterval(@ullable long[] retryIntervalsMs)290 private static void validateRetryInterval(@Nullable long[] retryIntervalsMs) { 291 Preconditions.checkArgument( 292 retryIntervalsMs != null 293 && retryIntervalsMs.length > 0 294 && retryIntervalsMs.length <= MAX_RETRY_INTERVAL_COUNT, 295 "retryIntervalsMs was null, empty or exceed max interval count"); 296 297 final long repeatingInterval = retryIntervalsMs[retryIntervalsMs.length - 1]; 298 if (repeatingInterval < MINIMUM_REPEATING_RETRY_INTERVAL_MS) { 299 throw new IllegalArgumentException( 300 "Repeating retry interval was too short, must be a minimum of 15 minutes: " 301 + repeatingInterval); 302 } 303 } 304 validateNetworkTemplateList( List<VcnUnderlyingNetworkTemplate> networkPriorityRules)305 private static void validateNetworkTemplateList( 306 List<VcnUnderlyingNetworkTemplate> networkPriorityRules) { 307 Objects.requireNonNull(networkPriorityRules, "networkPriorityRules is null"); 308 309 Set<VcnUnderlyingNetworkTemplate> existingRules = new ArraySet<>(); 310 for (VcnUnderlyingNetworkTemplate rule : networkPriorityRules) { 311 Objects.requireNonNull(rule, "Found null value VcnUnderlyingNetworkTemplate"); 312 if (!existingRules.add(rule)) { 313 throw new IllegalArgumentException("Found duplicate VcnUnderlyingNetworkTemplate"); 314 } 315 } 316 } 317 318 /** 319 * Returns the configured Gateway Connection name. 320 * 321 * <p>This name is used by the configuring apps to distinguish between 322 * VcnGatewayConnectionConfigs configured on a single {@link VcnConfig}. This will be used as 323 * the identifier in VcnStatusCallback invocations. 324 * 325 * @see VcnManager.VcnStatusCallback#onGatewayConnectionError 326 */ 327 @NonNull getGatewayConnectionName()328 public String getGatewayConnectionName() { 329 return mGatewayConnectionName; 330 } 331 332 /** 333 * Returns tunnel connection parameters. 334 * 335 * @hide 336 */ 337 @NonNull getTunnelConnectionParams()338 public IkeTunnelConnectionParams getTunnelConnectionParams() { 339 return mTunnelConnectionParams; 340 } 341 342 /** 343 * Returns all exposed capabilities. 344 * 345 * <p>The returned integer-value capabilities will not contain duplicates, and will be sorted in 346 * ascending numerical order. 347 * 348 * @see Builder#addExposedCapability(int) 349 * @see Builder#removeExposedCapability(int) 350 */ 351 @NonNull getExposedCapabilities()352 public int[] getExposedCapabilities() { 353 // Sorted set guarantees ordering 354 return ArrayUtils.convertToIntArray(new ArrayList<>(mExposedCapabilities)); 355 } 356 357 /** 358 * Returns all exposed capabilities. 359 * 360 * <p>Left to prevent the need to make major changes while changes are actively in flight. 361 * 362 * @deprecated use getExposedCapabilities() instead 363 * @hide 364 */ 365 @Deprecated 366 @NonNull getAllExposedCapabilities()367 public Set<Integer> getAllExposedCapabilities() { 368 return Collections.unmodifiableSet(mExposedCapabilities); 369 } 370 371 /** 372 * Retrieve the VcnUnderlyingNetworkTemplate list, or a default list if it is not configured. 373 * 374 * @see Builder#setVcnUnderlyingNetworkPriorities(List) 375 */ 376 @NonNull getVcnUnderlyingNetworkPriorities()377 public List<VcnUnderlyingNetworkTemplate> getVcnUnderlyingNetworkPriorities() { 378 return new ArrayList<>(mUnderlyingNetworkTemplates); 379 } 380 381 /** 382 * Retrieves the configured retry intervals. 383 * 384 * @see Builder#setRetryIntervalsMillis(long[]) 385 */ 386 @NonNull getRetryIntervalsMillis()387 public long[] getRetryIntervalsMillis() { 388 return Arrays.copyOf(mRetryIntervalsMs, mRetryIntervalsMs.length); 389 } 390 391 /** 392 * Retrieves the maximum MTU allowed for this Gateway Connection. 393 * 394 * @see Builder#setMaxMtu(int) 395 */ 396 @IntRange(from = MIN_MTU_V6) getMaxMtu()397 public int getMaxMtu() { 398 return mMaxMtu; 399 } 400 401 /** 402 * Converts this config to a PersistableBundle. 403 * 404 * @hide 405 */ 406 @NonNull 407 @VisibleForTesting(visibility = Visibility.PROTECTED) toPersistableBundle()408 public PersistableBundle toPersistableBundle() { 409 final PersistableBundle result = new PersistableBundle(); 410 411 final PersistableBundle tunnelConnectionParamsBundle = 412 TunnelConnectionParamsUtils.toPersistableBundle(mTunnelConnectionParams); 413 final PersistableBundle exposedCapsBundle = 414 PersistableBundleUtils.fromList( 415 new ArrayList<>(mExposedCapabilities), 416 PersistableBundleUtils.INTEGER_SERIALIZER); 417 final PersistableBundle networkTemplatesBundle = 418 PersistableBundleUtils.fromList( 419 mUnderlyingNetworkTemplates, 420 VcnUnderlyingNetworkTemplate::toPersistableBundle); 421 422 result.putString(GATEWAY_CONNECTION_NAME_KEY, mGatewayConnectionName); 423 result.putPersistableBundle(TUNNEL_CONNECTION_PARAMS_KEY, tunnelConnectionParamsBundle); 424 result.putPersistableBundle(EXPOSED_CAPABILITIES_KEY, exposedCapsBundle); 425 result.putPersistableBundle(UNDERLYING_NETWORK_TEMPLATES_KEY, networkTemplatesBundle); 426 result.putLongArray(RETRY_INTERVAL_MS_KEY, mRetryIntervalsMs); 427 result.putInt(MAX_MTU_KEY, mMaxMtu); 428 429 return result; 430 } 431 432 @Override hashCode()433 public int hashCode() { 434 return Objects.hash( 435 mGatewayConnectionName, 436 mTunnelConnectionParams, 437 mExposedCapabilities, 438 mUnderlyingNetworkTemplates, 439 Arrays.hashCode(mRetryIntervalsMs), 440 mMaxMtu); 441 } 442 443 @Override equals(@ullable Object other)444 public boolean equals(@Nullable Object other) { 445 if (!(other instanceof VcnGatewayConnectionConfig)) { 446 return false; 447 } 448 449 final VcnGatewayConnectionConfig rhs = (VcnGatewayConnectionConfig) other; 450 return mGatewayConnectionName.equals(rhs.mGatewayConnectionName) 451 && mTunnelConnectionParams.equals(rhs.mTunnelConnectionParams) 452 && mExposedCapabilities.equals(rhs.mExposedCapabilities) 453 && mUnderlyingNetworkTemplates.equals(rhs.mUnderlyingNetworkTemplates) 454 && Arrays.equals(mRetryIntervalsMs, rhs.mRetryIntervalsMs) 455 && mMaxMtu == rhs.mMaxMtu; 456 } 457 458 /** 459 * This class is used to incrementally build {@link VcnGatewayConnectionConfig} objects. 460 */ 461 public static final class Builder { 462 @NonNull private final String mGatewayConnectionName; 463 @NonNull private final IkeTunnelConnectionParams mTunnelConnectionParams; 464 @NonNull private final Set<Integer> mExposedCapabilities = new ArraySet(); 465 466 @NonNull 467 private final List<VcnUnderlyingNetworkTemplate> mUnderlyingNetworkTemplates = 468 new ArrayList<>(DEFAULT_UNDERLYING_NETWORK_TEMPLATES); 469 470 @NonNull private long[] mRetryIntervalsMs = DEFAULT_RETRY_INTERVALS_MS; 471 private int mMaxMtu = DEFAULT_MAX_MTU; 472 473 // TODO: (b/175829816) Consider VCN-exposed capabilities that may be transport dependent. 474 // Consider the case where the VCN might only expose MMS on WiFi, but defer to MMS 475 // when on Cell. 476 477 /** 478 * Construct a Builder object. 479 * 480 * @param gatewayConnectionName the String GatewayConnection name for this 481 * VcnGatewayConnectionConfig. Each VcnGatewayConnectionConfig within a {@link 482 * VcnConfig} must be given a unique name. This name is used by the caller to 483 * distinguish between VcnGatewayConnectionConfigs configured on a single {@link 484 * VcnConfig}. This will be used as the identifier in VcnStatusCallback invocations. 485 * @param tunnelConnectionParams the IKE tunnel connection configuration 486 * @throws IllegalArgumentException if the provided IkeTunnelConnectionParams is not 487 * configured to support MOBIKE 488 * @see IkeTunnelConnectionParams 489 * @see VcnManager.VcnStatusCallback#onGatewayConnectionError 490 */ Builder( @onNull String gatewayConnectionName, @NonNull IkeTunnelConnectionParams tunnelConnectionParams)491 public Builder( 492 @NonNull String gatewayConnectionName, 493 @NonNull IkeTunnelConnectionParams tunnelConnectionParams) { 494 Objects.requireNonNull(gatewayConnectionName, "gatewayConnectionName was null"); 495 Objects.requireNonNull(tunnelConnectionParams, "tunnelConnectionParams was null"); 496 if (!tunnelConnectionParams.getIkeSessionParams().hasIkeOption(IKE_OPTION_MOBIKE)) { 497 throw new IllegalArgumentException( 498 "MOBIKE must be configured for the provided IkeSessionParams"); 499 } 500 501 mGatewayConnectionName = gatewayConnectionName; 502 mTunnelConnectionParams = tunnelConnectionParams; 503 } 504 505 /** 506 * Add a capability that this VCN Gateway Connection will support. 507 * 508 * @param exposedCapability the app-facing capability to be exposed by this VCN Gateway 509 * Connection (i.e., the capabilities that this VCN Gateway Connection will support). 510 * @return this {@link Builder} instance, for chaining 511 * @see VcnGatewayConnectionConfig for a list of capabilities may be exposed by a Gateway 512 * Connection 513 */ 514 @NonNull addExposedCapability(@cnSupportedCapability int exposedCapability)515 public Builder addExposedCapability(@VcnSupportedCapability int exposedCapability) { 516 checkValidCapability(exposedCapability); 517 518 mExposedCapabilities.add(exposedCapability); 519 return this; 520 } 521 522 /** 523 * Remove a capability that this VCN Gateway Connection will support. 524 * 525 * @param exposedCapability the app-facing capability to not be exposed by this VCN Gateway 526 * Connection (i.e., the capabilities that this VCN Gateway Connection will support) 527 * @return this {@link Builder} instance, for chaining 528 * @see VcnGatewayConnectionConfig for a list of capabilities may be exposed by a Gateway 529 * Connection 530 */ 531 @NonNull 532 @SuppressLint("BuilderSetStyle") // For consistency with NetCaps.Builder add/removeCap removeExposedCapability(@cnSupportedCapability int exposedCapability)533 public Builder removeExposedCapability(@VcnSupportedCapability int exposedCapability) { 534 checkValidCapability(exposedCapability); 535 536 mExposedCapabilities.remove(exposedCapability); 537 return this; 538 } 539 540 /** 541 * Set the list of templates to match underlying networks against, in high-to-low priority 542 * order. 543 * 544 * <p>To select the VCN underlying network, the VCN connection will go through all the 545 * network candidates and return a network matching the highest priority rule. 546 * 547 * <p>If multiple networks match the same rule, the VCN will prefer an already-selected 548 * network as opposed to a new/unselected network. However, if both are new/unselected 549 * networks, a network will be chosen arbitrarily amongst the networks matching the highest 550 * priority rule. 551 * 552 * <p>If all networks fail to match the rules provided, a carrier-owned underlying network 553 * will still be selected (if available, at random if necessary). 554 * 555 * @param underlyingNetworkTemplates a list of unique VcnUnderlyingNetworkTemplates that are 556 * ordered from most to least preferred, or an empty list to use the default 557 * prioritization. The default network prioritization order is Opportunistic cellular, 558 * Carrier WiFi and then Macro cellular. 559 * @return this {@link Builder} instance, for chaining 560 */ 561 @NonNull setVcnUnderlyingNetworkPriorities( @onNull List<VcnUnderlyingNetworkTemplate> underlyingNetworkTemplates)562 public Builder setVcnUnderlyingNetworkPriorities( 563 @NonNull List<VcnUnderlyingNetworkTemplate> underlyingNetworkTemplates) { 564 validateNetworkTemplateList(underlyingNetworkTemplates); 565 566 mUnderlyingNetworkTemplates.clear(); 567 568 if (underlyingNetworkTemplates.isEmpty()) { 569 mUnderlyingNetworkTemplates.addAll(DEFAULT_UNDERLYING_NETWORK_TEMPLATES); 570 } else { 571 mUnderlyingNetworkTemplates.addAll(underlyingNetworkTemplates); 572 } 573 574 return this; 575 } 576 577 /** 578 * Set the retry interval between VCN establishment attempts upon successive failures. 579 * 580 * <p>The last retry interval will be repeated until safe mode is entered, or a connection 581 * is successfully established, at which point the retry timers will be reset. For power 582 * reasons, the last (repeated) retry interval MUST be at least 15 minutes. 583 * 584 * <p>Retry intervals MAY be subject to system power saving modes. That is to say that if 585 * the system enters a power saving mode, the retry may not occur until the device leaves 586 * the specified power saving mode. Intervals are sequential, and intervals will NOT be 587 * skipped if system power saving results in delaying retries (even if it exceed multiple 588 * retry intervals). 589 * 590 * <p>Each Gateway Connection will retry according to the retry intervals configured, but if 591 * safe mode is enabled, all Gateway Connection(s) will be disabled. 592 * 593 * @param retryIntervalsMs an array of between 1 and 10 millisecond intervals after which 594 * the VCN will attempt to retry a session initiation. The last (repeating) retry 595 * interval must be at least 15 minutes. Defaults to: {@code [1s, 2s, 5s, 30s, 1m, 5m, 596 * 15m]} 597 * @return this {@link Builder} instance, for chaining 598 * @see VcnManager for additional discussion on fail-safe mode 599 */ 600 @NonNull setRetryIntervalsMillis(@onNull long[] retryIntervalsMs)601 public Builder setRetryIntervalsMillis(@NonNull long[] retryIntervalsMs) { 602 validateRetryInterval(retryIntervalsMs); 603 604 mRetryIntervalsMs = retryIntervalsMs; 605 return this; 606 } 607 608 /** 609 * Sets the maximum MTU allowed for this VCN Gateway Connection. 610 * 611 * <p>This MTU is applied to the VCN Gateway Connection exposed Networks, and represents the 612 * MTU of the virtualized network. 613 * 614 * <p>The system may reduce the MTU below the maximum specified based on signals such as the 615 * MTU of the underlying networks (and adjusted for Gateway Connection overhead). 616 * 617 * @param maxMtu the maximum MTU allowed for this Gateway Connection. Must be greater than 618 * the IPv6 minimum MTU of 1280. Defaults to 1500. 619 * @return this {@link Builder} instance, for chaining 620 */ 621 @NonNull setMaxMtu(@ntRangefrom = MIN_MTU_V6) int maxMtu)622 public Builder setMaxMtu(@IntRange(from = MIN_MTU_V6) int maxMtu) { 623 Preconditions.checkArgument( 624 maxMtu >= MIN_MTU_V6, "maxMtu must be at least IPv6 min MTU (1280)"); 625 626 mMaxMtu = maxMtu; 627 return this; 628 } 629 630 /** 631 * Builds and validates the VcnGatewayConnectionConfig. 632 * 633 * @return an immutable VcnGatewayConnectionConfig instance 634 */ 635 @NonNull build()636 public VcnGatewayConnectionConfig build() { 637 return new VcnGatewayConnectionConfig( 638 mGatewayConnectionName, 639 mTunnelConnectionParams, 640 mExposedCapabilities, 641 mUnderlyingNetworkTemplates, 642 mRetryIntervalsMs, 643 mMaxMtu); 644 } 645 } 646 } 647