1 /* 2 * Copyright (C) 2014 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; 18 19 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.SystemApi; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 27 import java.util.Objects; 28 29 /** 30 * Allows a network transport to provide the system with policy and configuration information about 31 * a particular network when registering a {@link NetworkAgent}. This information cannot change once the agent is registered. 32 * 33 * @hide 34 */ 35 @SystemApi 36 public final class NetworkAgentConfig implements Parcelable { 37 38 /** 39 * If the {@link Network} is a VPN, whether apps are allowed to bypass the 40 * VPN. This is set by a {@link VpnService} and used by 41 * {@link ConnectivityManager} when creating a VPN. 42 * 43 * @hide 44 */ 45 public boolean allowBypass; 46 47 /** 48 * Set if the network was manually/explicitly connected to by the user either from settings 49 * or a 3rd party app. For example, turning on cell data is not explicit but tapping on a wifi 50 * ap in the wifi settings to trigger a connection is explicit. A 3rd party app asking to 51 * connect to a particular access point is also explicit, though this may change in the future 52 * as we want apps to use the multinetwork apis. 53 * TODO : this is a bad name, because it sounds like the user just tapped on the network. 54 * It's not necessarily the case ; auto-reconnection to WiFi has this true for example. 55 * @hide 56 */ 57 public boolean explicitlySelected; 58 59 /** 60 * @return whether this network was explicitly selected by the user. 61 */ isExplicitlySelected()62 public boolean isExplicitlySelected() { 63 return explicitlySelected; 64 } 65 66 /** 67 * @return whether this VPN connection can be bypassed by the apps. 68 * 69 * @hide 70 */ 71 @SystemApi(client = MODULE_LIBRARIES) isBypassableVpn()72 public boolean isBypassableVpn() { 73 return allowBypass; 74 } 75 76 /** 77 * Set if the user desires to use this network even if it is unvalidated. This field has meaning 78 * only if {@link explicitlySelected} is true. If it is, this field must also be set to the 79 * appropriate value based on previous user choice. 80 * 81 * TODO : rename this field to match its accessor 82 * @hide 83 */ 84 public boolean acceptUnvalidated; 85 86 /** 87 * @return whether the system should accept this network even if it doesn't validate. 88 */ isUnvalidatedConnectivityAcceptable()89 public boolean isUnvalidatedConnectivityAcceptable() { 90 return acceptUnvalidated; 91 } 92 93 /** 94 * Whether the user explicitly set that this network should be validated even if presence of 95 * only partial internet connectivity. 96 * 97 * TODO : rename this field to match its accessor 98 * @hide 99 */ 100 public boolean acceptPartialConnectivity; 101 102 /** 103 * @return whether the system should validate this network even if it only offers partial 104 * Internet connectivity. 105 */ isPartialConnectivityAcceptable()106 public boolean isPartialConnectivityAcceptable() { 107 return acceptPartialConnectivity; 108 } 109 110 /** 111 * Set to avoid surfacing the "Sign in to network" notification. 112 * if carrier receivers/apps are registered to handle the carrier-specific provisioning 113 * procedure, a carrier specific provisioning notification will be placed. 114 * only one notification should be displayed. This field is set based on 115 * which notification should be used for provisioning. 116 * 117 * @hide 118 */ 119 public boolean provisioningNotificationDisabled; 120 121 /** 122 * 123 * @return whether the sign in to network notification is enabled by this configuration. 124 * @hide 125 */ isProvisioningNotificationEnabled()126 public boolean isProvisioningNotificationEnabled() { 127 return !provisioningNotificationDisabled; 128 } 129 130 /** 131 * For mobile networks, this is the subscriber ID (such as IMSI). 132 * 133 * @hide 134 */ 135 public String subscriberId; 136 137 /** 138 * @return the subscriber ID, or null if none. 139 * @hide 140 */ 141 @SystemApi(client = MODULE_LIBRARIES) 142 @Nullable getSubscriberId()143 public String getSubscriberId() { 144 return subscriberId; 145 } 146 147 /** 148 * Set to skip 464xlat. This means the device will treat the network as IPv6-only and 149 * will not attempt to detect a NAT64 via RFC 7050 DNS lookups. 150 * 151 * @hide 152 */ 153 public boolean skip464xlat; 154 155 /** 156 * @return whether NAT64 prefix detection is enabled. 157 * @hide 158 */ isNat64DetectionEnabled()159 public boolean isNat64DetectionEnabled() { 160 return !skip464xlat; 161 } 162 163 /** 164 * The legacy type of this network agent, or TYPE_NONE if unset. 165 * @hide 166 */ 167 public int legacyType = ConnectivityManager.TYPE_NONE; 168 169 /** 170 * @return the legacy type 171 */ 172 @ConnectivityManager.LegacyNetworkType getLegacyType()173 public int getLegacyType() { 174 return legacyType; 175 } 176 177 /** 178 * The legacy Sub type of this network agent, or TYPE_NONE if unset. 179 * @hide 180 */ 181 public int legacySubType = ConnectivityManager.TYPE_NONE; 182 183 /** 184 * Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network. 185 * Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode. 186 * 187 * This is not parceled, because it would not make sense. 188 * 189 * @hide 190 */ 191 public transient boolean hasShownBroken; 192 193 /** 194 * The name of the legacy network type. It's a free-form string used in logging. 195 * @hide 196 */ 197 @NonNull 198 public String legacyTypeName = ""; 199 200 /** 201 * @return the name of the legacy network type. It's a free-form string used in logging. 202 */ 203 @NonNull getLegacyTypeName()204 public String getLegacyTypeName() { 205 return legacyTypeName; 206 } 207 208 /** 209 * The name of the legacy Sub network type. It's a free-form string. 210 * @hide 211 */ 212 @NonNull 213 public String legacySubTypeName = ""; 214 215 /** 216 * The legacy extra info of the agent. The extra info should only be : 217 * <ul> 218 * <li>For cellular agents, the APN name.</li> 219 * <li>For ethernet agents, the interface name.</li> 220 * </ul> 221 * @hide 222 */ 223 @NonNull 224 private String mLegacyExtraInfo = ""; 225 226 /** 227 * The legacy extra info of the agent. 228 * @hide 229 */ 230 @NonNull getLegacyExtraInfo()231 public String getLegacyExtraInfo() { 232 return mLegacyExtraInfo; 233 } 234 235 /** @hide */ NetworkAgentConfig()236 public NetworkAgentConfig() { 237 } 238 239 /** @hide */ NetworkAgentConfig(@ullable NetworkAgentConfig nac)240 public NetworkAgentConfig(@Nullable NetworkAgentConfig nac) { 241 if (nac != null) { 242 allowBypass = nac.allowBypass; 243 explicitlySelected = nac.explicitlySelected; 244 acceptUnvalidated = nac.acceptUnvalidated; 245 acceptPartialConnectivity = nac.acceptPartialConnectivity; 246 subscriberId = nac.subscriberId; 247 provisioningNotificationDisabled = nac.provisioningNotificationDisabled; 248 skip464xlat = nac.skip464xlat; 249 legacyType = nac.legacyType; 250 legacyTypeName = nac.legacyTypeName; 251 legacySubType = nac.legacySubType; 252 legacySubTypeName = nac.legacySubTypeName; 253 mLegacyExtraInfo = nac.mLegacyExtraInfo; 254 } 255 } 256 257 /** 258 * Builder class to facilitate constructing {@link NetworkAgentConfig} objects. 259 */ 260 public static final class Builder { 261 private final NetworkAgentConfig mConfig = new NetworkAgentConfig(); 262 263 /** 264 * Sets whether the network was explicitly selected by the user. 265 * 266 * @return this builder, to facilitate chaining. 267 */ 268 @NonNull setExplicitlySelected(final boolean explicitlySelected)269 public Builder setExplicitlySelected(final boolean explicitlySelected) { 270 mConfig.explicitlySelected = explicitlySelected; 271 return this; 272 } 273 274 /** 275 * Sets whether the system should validate this network even if it is found not to offer 276 * Internet connectivity. 277 * 278 * @return this builder, to facilitate chaining. 279 */ 280 @NonNull setUnvalidatedConnectivityAcceptable( final boolean unvalidatedConnectivityAcceptable)281 public Builder setUnvalidatedConnectivityAcceptable( 282 final boolean unvalidatedConnectivityAcceptable) { 283 mConfig.acceptUnvalidated = unvalidatedConnectivityAcceptable; 284 return this; 285 } 286 287 /** 288 * Sets whether the system should validate this network even if it is found to only offer 289 * partial Internet connectivity. 290 * 291 * @return this builder, to facilitate chaining. 292 */ 293 @NonNull setPartialConnectivityAcceptable( final boolean partialConnectivityAcceptable)294 public Builder setPartialConnectivityAcceptable( 295 final boolean partialConnectivityAcceptable) { 296 mConfig.acceptPartialConnectivity = partialConnectivityAcceptable; 297 return this; 298 } 299 300 /** 301 * Sets the subscriber ID for this network. 302 * 303 * @return this builder, to facilitate chaining. 304 * @hide 305 */ 306 @NonNull 307 @SystemApi(client = MODULE_LIBRARIES) setSubscriberId(@ullable String subscriberId)308 public Builder setSubscriberId(@Nullable String subscriberId) { 309 mConfig.subscriberId = subscriberId; 310 return this; 311 } 312 313 /** 314 * Enables or disables active detection of NAT64 (e.g., via RFC 7050 DNS lookups). Used to 315 * save power and reduce idle traffic on networks that are known to be IPv6-only without a 316 * NAT64. By default, NAT64 detection is enabled. 317 * 318 * @return this builder, to facilitate chaining. 319 */ 320 @NonNull setNat64DetectionEnabled(boolean enabled)321 public Builder setNat64DetectionEnabled(boolean enabled) { 322 mConfig.skip464xlat = !enabled; 323 return this; 324 } 325 326 /** 327 * Enables or disables the "Sign in to network" notification. Used if the network transport 328 * will perform its own carrier-specific provisioning procedure. By default, the 329 * notification is enabled. 330 * 331 * @return this builder, to facilitate chaining. 332 */ 333 @NonNull setProvisioningNotificationEnabled(boolean enabled)334 public Builder setProvisioningNotificationEnabled(boolean enabled) { 335 mConfig.provisioningNotificationDisabled = !enabled; 336 return this; 337 } 338 339 /** 340 * Sets the legacy type for this network. 341 * 342 * @param legacyType the type 343 * @return this builder, to facilitate chaining. 344 */ 345 @NonNull setLegacyType(int legacyType)346 public Builder setLegacyType(int legacyType) { 347 mConfig.legacyType = legacyType; 348 return this; 349 } 350 351 /** 352 * Sets the legacy sub-type for this network. 353 * 354 * @param legacySubType the type 355 * @return this builder, to facilitate chaining. 356 */ 357 @NonNull setLegacySubType(final int legacySubType)358 public Builder setLegacySubType(final int legacySubType) { 359 mConfig.legacySubType = legacySubType; 360 return this; 361 } 362 363 /** 364 * Sets the name of the legacy type of the agent. It's a free-form string used in logging. 365 * @param legacyTypeName the name 366 * @return this builder, to facilitate chaining. 367 */ 368 @NonNull setLegacyTypeName(@onNull String legacyTypeName)369 public Builder setLegacyTypeName(@NonNull String legacyTypeName) { 370 mConfig.legacyTypeName = legacyTypeName; 371 return this; 372 } 373 374 /** 375 * Sets the name of the legacy Sub-type of the agent. It's a free-form string. 376 * @param legacySubTypeName the name 377 * @return this builder, to facilitate chaining. 378 */ 379 @NonNull setLegacySubTypeName(@onNull String legacySubTypeName)380 public Builder setLegacySubTypeName(@NonNull String legacySubTypeName) { 381 mConfig.legacySubTypeName = legacySubTypeName; 382 return this; 383 } 384 385 /** 386 * Sets the legacy extra info of the agent. 387 * @param legacyExtraInfo the legacy extra info. 388 * @return this builder, to facilitate chaining. 389 */ 390 @NonNull setLegacyExtraInfo(@onNull String legacyExtraInfo)391 public Builder setLegacyExtraInfo(@NonNull String legacyExtraInfo) { 392 mConfig.mLegacyExtraInfo = legacyExtraInfo; 393 return this; 394 } 395 396 /** 397 * Sets whether the apps can bypass the VPN connection. 398 * 399 * @return this builder, to facilitate chaining. 400 * @hide 401 */ 402 @NonNull 403 @SystemApi(client = MODULE_LIBRARIES) setBypassableVpn(boolean allowBypass)404 public Builder setBypassableVpn(boolean allowBypass) { 405 mConfig.allowBypass = allowBypass; 406 return this; 407 } 408 409 /** 410 * Returns the constructed {@link NetworkAgentConfig} object. 411 */ 412 @NonNull build()413 public NetworkAgentConfig build() { 414 return mConfig; 415 } 416 } 417 418 @Override equals(final Object o)419 public boolean equals(final Object o) { 420 if (this == o) return true; 421 if (o == null || getClass() != o.getClass()) return false; 422 final NetworkAgentConfig that = (NetworkAgentConfig) o; 423 return allowBypass == that.allowBypass 424 && explicitlySelected == that.explicitlySelected 425 && acceptUnvalidated == that.acceptUnvalidated 426 && acceptPartialConnectivity == that.acceptPartialConnectivity 427 && provisioningNotificationDisabled == that.provisioningNotificationDisabled 428 && skip464xlat == that.skip464xlat 429 && legacyType == that.legacyType 430 && Objects.equals(subscriberId, that.subscriberId) 431 && Objects.equals(legacyTypeName, that.legacyTypeName) 432 && Objects.equals(mLegacyExtraInfo, that.mLegacyExtraInfo); 433 } 434 435 @Override hashCode()436 public int hashCode() { 437 return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated, 438 acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId, 439 skip464xlat, legacyType, legacyTypeName, mLegacyExtraInfo); 440 } 441 442 @Override toString()443 public String toString() { 444 return "NetworkAgentConfig {" 445 + " allowBypass = " + allowBypass 446 + ", explicitlySelected = " + explicitlySelected 447 + ", acceptUnvalidated = " + acceptUnvalidated 448 + ", acceptPartialConnectivity = " + acceptPartialConnectivity 449 + ", provisioningNotificationDisabled = " + provisioningNotificationDisabled 450 + ", subscriberId = '" + subscriberId + '\'' 451 + ", skip464xlat = " + skip464xlat 452 + ", legacyType = " + legacyType 453 + ", hasShownBroken = " + hasShownBroken 454 + ", legacyTypeName = '" + legacyTypeName + '\'' 455 + ", legacyExtraInfo = '" + mLegacyExtraInfo + '\'' 456 + "}"; 457 } 458 459 @Override describeContents()460 public int describeContents() { 461 return 0; 462 } 463 464 @Override writeToParcel(@onNull Parcel out, int flags)465 public void writeToParcel(@NonNull Parcel out, int flags) { 466 out.writeInt(allowBypass ? 1 : 0); 467 out.writeInt(explicitlySelected ? 1 : 0); 468 out.writeInt(acceptUnvalidated ? 1 : 0); 469 out.writeInt(acceptPartialConnectivity ? 1 : 0); 470 out.writeString(subscriberId); 471 out.writeInt(provisioningNotificationDisabled ? 1 : 0); 472 out.writeInt(skip464xlat ? 1 : 0); 473 out.writeInt(legacyType); 474 out.writeString(legacyTypeName); 475 out.writeInt(legacySubType); 476 out.writeString(legacySubTypeName); 477 out.writeString(mLegacyExtraInfo); 478 } 479 480 public static final @NonNull Creator<NetworkAgentConfig> CREATOR = 481 new Creator<NetworkAgentConfig>() { 482 @Override 483 public NetworkAgentConfig createFromParcel(Parcel in) { 484 NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig(); 485 networkAgentConfig.allowBypass = in.readInt() != 0; 486 networkAgentConfig.explicitlySelected = in.readInt() != 0; 487 networkAgentConfig.acceptUnvalidated = in.readInt() != 0; 488 networkAgentConfig.acceptPartialConnectivity = in.readInt() != 0; 489 networkAgentConfig.subscriberId = in.readString(); 490 networkAgentConfig.provisioningNotificationDisabled = in.readInt() != 0; 491 networkAgentConfig.skip464xlat = in.readInt() != 0; 492 networkAgentConfig.legacyType = in.readInt(); 493 networkAgentConfig.legacyTypeName = in.readString(); 494 networkAgentConfig.legacySubType = in.readInt(); 495 networkAgentConfig.legacySubTypeName = in.readString(); 496 networkAgentConfig.mLegacyExtraInfo = in.readString(); 497 return networkAgentConfig; 498 } 499 500 @Override 501 public NetworkAgentConfig[] newArray(int size) { 502 return new NetworkAgentConfig[size]; 503 } 504 }; 505 } 506