596 lines
20 KiB
Java
596 lines
20 KiB
Java
/*
|
|
* Copyright (C) 2014 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.net;
|
|
|
|
import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
|
|
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.annotation.SystemApi;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
|
|
import com.android.modules.utils.build.SdkLevel;
|
|
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* Allows a network transport to provide the system with policy and configuration information about
|
|
* a particular network when registering a {@link NetworkAgent}. This information cannot change once the agent is registered.
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
public final class NetworkAgentConfig implements Parcelable {
|
|
// TODO : make this object immutable. The fields that should stay mutable should likely
|
|
// migrate to NetworkAgentInfo.
|
|
|
|
/**
|
|
* If the {@link Network} is a VPN, whether apps are allowed to bypass the
|
|
* VPN. This is set by a {@link VpnService} and used by
|
|
* {@link ConnectivityManager} when creating a VPN.
|
|
*
|
|
* @hide
|
|
*/
|
|
public boolean allowBypass;
|
|
|
|
/**
|
|
* Set if the network was manually/explicitly connected to by the user either from settings
|
|
* or a 3rd party app. For example, turning on cell data is not explicit but tapping on a wifi
|
|
* ap in the wifi settings to trigger a connection is explicit. A 3rd party app asking to
|
|
* connect to a particular access point is also explicit, though this may change in the future
|
|
* as we want apps to use the multinetwork apis.
|
|
* TODO : this is a bad name, because it sounds like the user just tapped on the network.
|
|
* It's not necessarily the case ; auto-reconnection to WiFi has this true for example.
|
|
* @hide
|
|
*/
|
|
public boolean explicitlySelected;
|
|
|
|
/**
|
|
* @return whether this network was explicitly selected by the user.
|
|
*/
|
|
public boolean isExplicitlySelected() {
|
|
return explicitlySelected;
|
|
}
|
|
|
|
/**
|
|
* @return whether this VPN connection can be bypassed by the apps.
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi(client = MODULE_LIBRARIES)
|
|
public boolean isBypassableVpn() {
|
|
return allowBypass;
|
|
}
|
|
|
|
/**
|
|
* Set if the user desires to use this network even if it is unvalidated. This field has meaning
|
|
* only if {@link explicitlySelected} is true. If it is, this field must also be set to the
|
|
* appropriate value based on previous user choice.
|
|
*
|
|
* TODO : rename this field to match its accessor
|
|
* @hide
|
|
*/
|
|
public boolean acceptUnvalidated;
|
|
|
|
/**
|
|
* @return whether the system should accept this network even if it doesn't validate.
|
|
*/
|
|
public boolean isUnvalidatedConnectivityAcceptable() {
|
|
return acceptUnvalidated;
|
|
}
|
|
|
|
/**
|
|
* Whether the user explicitly set that this network should be validated even if presence of
|
|
* only partial internet connectivity.
|
|
*
|
|
* TODO : rename this field to match its accessor
|
|
* @hide
|
|
*/
|
|
public boolean acceptPartialConnectivity;
|
|
|
|
/**
|
|
* @return whether the system should validate this network even if it only offers partial
|
|
* Internet connectivity.
|
|
*/
|
|
public boolean isPartialConnectivityAcceptable() {
|
|
return acceptPartialConnectivity;
|
|
}
|
|
|
|
/**
|
|
* Set to avoid surfacing the "Sign in to network" notification.
|
|
* if carrier receivers/apps are registered to handle the carrier-specific provisioning
|
|
* procedure, a carrier specific provisioning notification will be placed.
|
|
* only one notification should be displayed. This field is set based on
|
|
* which notification should be used for provisioning.
|
|
*
|
|
* @hide
|
|
*/
|
|
public boolean provisioningNotificationDisabled;
|
|
|
|
/**
|
|
*
|
|
* @return whether the sign in to network notification is enabled by this configuration.
|
|
* @hide
|
|
*/
|
|
public boolean isProvisioningNotificationEnabled() {
|
|
return !provisioningNotificationDisabled;
|
|
}
|
|
|
|
/**
|
|
* For mobile networks, this is the subscriber ID (such as IMSI).
|
|
*
|
|
* @hide
|
|
*/
|
|
public String subscriberId;
|
|
|
|
/**
|
|
* @return the subscriber ID, or null if none.
|
|
* @hide
|
|
*/
|
|
@SystemApi(client = MODULE_LIBRARIES)
|
|
@Nullable
|
|
public String getSubscriberId() {
|
|
return subscriberId;
|
|
}
|
|
|
|
/**
|
|
* Set to skip 464xlat. This means the device will treat the network as IPv6-only and
|
|
* will not attempt to detect a NAT64 via RFC 7050 DNS lookups.
|
|
*
|
|
* @hide
|
|
*/
|
|
public boolean skip464xlat;
|
|
|
|
/**
|
|
* @return whether NAT64 prefix detection is enabled.
|
|
* @hide
|
|
*/
|
|
public boolean isNat64DetectionEnabled() {
|
|
return !skip464xlat;
|
|
}
|
|
|
|
/**
|
|
* The legacy type of this network agent, or TYPE_NONE if unset.
|
|
* @hide
|
|
*/
|
|
public int legacyType = ConnectivityManager.TYPE_NONE;
|
|
|
|
/**
|
|
* @return the legacy type
|
|
*/
|
|
@ConnectivityManager.LegacyNetworkType
|
|
public int getLegacyType() {
|
|
return legacyType;
|
|
}
|
|
|
|
/**
|
|
* The legacy Sub type of this network agent, or TYPE_NONE if unset.
|
|
* @hide
|
|
*/
|
|
public int legacySubType = ConnectivityManager.TYPE_NONE;
|
|
|
|
/**
|
|
* Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network.
|
|
* Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode.
|
|
*
|
|
* This is not parceled, because it would not make sense. It's also ignored by the
|
|
* equals() and hashcode() methods.
|
|
*
|
|
* @hide
|
|
*/
|
|
public transient boolean hasShownBroken;
|
|
|
|
/**
|
|
* The name of the legacy network type. It's a free-form string used in logging.
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
public String legacyTypeName = "";
|
|
|
|
/**
|
|
* @return the name of the legacy network type. It's a free-form string used in logging.
|
|
*/
|
|
@NonNull
|
|
public String getLegacyTypeName() {
|
|
return legacyTypeName;
|
|
}
|
|
|
|
/**
|
|
* The name of the legacy Sub network type. It's a free-form string.
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
public String legacySubTypeName = "";
|
|
|
|
/**
|
|
* The legacy extra info of the agent. The extra info should only be :
|
|
* <ul>
|
|
* <li>For cellular agents, the APN name.</li>
|
|
* <li>For ethernet agents, the interface name.</li>
|
|
* </ul>
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
private String mLegacyExtraInfo = "";
|
|
|
|
/**
|
|
* The legacy extra info of the agent.
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
public String getLegacyExtraInfo() {
|
|
return mLegacyExtraInfo;
|
|
}
|
|
|
|
/**
|
|
* If the {@link Network} is a VPN, whether the local traffic is exempted from the VPN.
|
|
* @hide
|
|
*/
|
|
public boolean excludeLocalRouteVpn = false;
|
|
|
|
/**
|
|
* @return whether local traffic is excluded from the VPN network.
|
|
* @hide
|
|
*/
|
|
public boolean areLocalRoutesExcludedForVpn() {
|
|
return excludeLocalRouteVpn;
|
|
}
|
|
|
|
/**
|
|
* Whether network validation should be performed for this VPN network.
|
|
* @see #isVpnValidationRequired
|
|
* @hide
|
|
*/
|
|
private boolean mVpnRequiresValidation = false;
|
|
|
|
/**
|
|
* Whether network validation should be performed for this VPN network.
|
|
*
|
|
* If this network isn't a VPN this should always be {@code false}, and will be ignored
|
|
* if set.
|
|
* If this network is a VPN, false means this network should always be considered validated;
|
|
* true means it follows the same validation semantics as general internet networks.
|
|
* @hide
|
|
*/
|
|
@SystemApi(client = MODULE_LIBRARIES)
|
|
public boolean isVpnValidationRequired() {
|
|
return mVpnRequiresValidation;
|
|
}
|
|
|
|
/** @hide */
|
|
public NetworkAgentConfig() {
|
|
}
|
|
|
|
/** @hide */
|
|
public NetworkAgentConfig(@Nullable NetworkAgentConfig nac) {
|
|
if (nac != null) {
|
|
allowBypass = nac.allowBypass;
|
|
explicitlySelected = nac.explicitlySelected;
|
|
acceptUnvalidated = nac.acceptUnvalidated;
|
|
acceptPartialConnectivity = nac.acceptPartialConnectivity;
|
|
subscriberId = nac.subscriberId;
|
|
provisioningNotificationDisabled = nac.provisioningNotificationDisabled;
|
|
skip464xlat = nac.skip464xlat;
|
|
legacyType = nac.legacyType;
|
|
legacyTypeName = nac.legacyTypeName;
|
|
legacySubType = nac.legacySubType;
|
|
legacySubTypeName = nac.legacySubTypeName;
|
|
mLegacyExtraInfo = nac.mLegacyExtraInfo;
|
|
excludeLocalRouteVpn = nac.excludeLocalRouteVpn;
|
|
mVpnRequiresValidation = nac.mVpnRequiresValidation;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Builder class to facilitate constructing {@link NetworkAgentConfig} objects.
|
|
*/
|
|
public static final class Builder {
|
|
private final NetworkAgentConfig mConfig = new NetworkAgentConfig();
|
|
|
|
/**
|
|
* Sets whether the network was explicitly selected by the user.
|
|
*
|
|
* @return this builder, to facilitate chaining.
|
|
*/
|
|
@NonNull
|
|
public Builder setExplicitlySelected(final boolean explicitlySelected) {
|
|
mConfig.explicitlySelected = explicitlySelected;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether the system should validate this network even if it is found not to offer
|
|
* Internet connectivity.
|
|
*
|
|
* @return this builder, to facilitate chaining.
|
|
*/
|
|
@NonNull
|
|
public Builder setUnvalidatedConnectivityAcceptable(
|
|
final boolean unvalidatedConnectivityAcceptable) {
|
|
mConfig.acceptUnvalidated = unvalidatedConnectivityAcceptable;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether the system should validate this network even if it is found to only offer
|
|
* partial Internet connectivity.
|
|
*
|
|
* @return this builder, to facilitate chaining.
|
|
*/
|
|
@NonNull
|
|
public Builder setPartialConnectivityAcceptable(
|
|
final boolean partialConnectivityAcceptable) {
|
|
mConfig.acceptPartialConnectivity = partialConnectivityAcceptable;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the subscriber ID for this network.
|
|
*
|
|
* @return this builder, to facilitate chaining.
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
@SystemApi(client = MODULE_LIBRARIES)
|
|
public Builder setSubscriberId(@Nullable String subscriberId) {
|
|
mConfig.subscriberId = subscriberId;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Enables or disables active detection of NAT64 (e.g., via RFC 7050 DNS lookups). Used to
|
|
* save power and reduce idle traffic on networks that are known to be IPv6-only without a
|
|
* NAT64. By default, NAT64 detection is enabled.
|
|
*
|
|
* @return this builder, to facilitate chaining.
|
|
*/
|
|
@NonNull
|
|
public Builder setNat64DetectionEnabled(boolean enabled) {
|
|
mConfig.skip464xlat = !enabled;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Enables or disables the "Sign in to network" notification. Used if the network transport
|
|
* will perform its own carrier-specific provisioning procedure. By default, the
|
|
* notification is enabled.
|
|
*
|
|
* @return this builder, to facilitate chaining.
|
|
*/
|
|
@NonNull
|
|
public Builder setProvisioningNotificationEnabled(boolean enabled) {
|
|
mConfig.provisioningNotificationDisabled = !enabled;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the legacy type for this network.
|
|
*
|
|
* @param legacyType the type
|
|
* @return this builder, to facilitate chaining.
|
|
*/
|
|
@NonNull
|
|
public Builder setLegacyType(int legacyType) {
|
|
mConfig.legacyType = legacyType;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the legacy sub-type for this network.
|
|
*
|
|
* @param legacySubType the type
|
|
* @return this builder, to facilitate chaining.
|
|
*/
|
|
@NonNull
|
|
public Builder setLegacySubType(final int legacySubType) {
|
|
mConfig.legacySubType = legacySubType;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the name of the legacy type of the agent. It's a free-form string used in logging.
|
|
* @param legacyTypeName the name
|
|
* @return this builder, to facilitate chaining.
|
|
*/
|
|
@NonNull
|
|
public Builder setLegacyTypeName(@NonNull String legacyTypeName) {
|
|
mConfig.legacyTypeName = legacyTypeName;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the name of the legacy Sub-type of the agent. It's a free-form string.
|
|
* @param legacySubTypeName the name
|
|
* @return this builder, to facilitate chaining.
|
|
*/
|
|
@NonNull
|
|
public Builder setLegacySubTypeName(@NonNull String legacySubTypeName) {
|
|
mConfig.legacySubTypeName = legacySubTypeName;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the legacy extra info of the agent.
|
|
* @param legacyExtraInfo the legacy extra info.
|
|
* @return this builder, to facilitate chaining.
|
|
*/
|
|
@NonNull
|
|
public Builder setLegacyExtraInfo(@NonNull String legacyExtraInfo) {
|
|
mConfig.mLegacyExtraInfo = legacyExtraInfo;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether network validation should be performed for this VPN network.
|
|
*
|
|
* Only agents registering a VPN network should use this setter. On other network
|
|
* types it will be ignored.
|
|
* False means this network should always be considered validated;
|
|
* true means it follows the same validation semantics as general internet.
|
|
*
|
|
* @param vpnRequiresValidation whether this VPN requires validation.
|
|
* Default is {@code false}.
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
@SystemApi(client = MODULE_LIBRARIES)
|
|
public Builder setVpnRequiresValidation(boolean vpnRequiresValidation) {
|
|
mConfig.mVpnRequiresValidation = vpnRequiresValidation;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether the apps can bypass the VPN connection.
|
|
*
|
|
* @return this builder, to facilitate chaining.
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
@SystemApi(client = MODULE_LIBRARIES)
|
|
public Builder setBypassableVpn(boolean allowBypass) {
|
|
mConfig.allowBypass = allowBypass;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether the local traffic is exempted from VPN.
|
|
*
|
|
* @return this builder, to facilitate chaining.
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
@SystemApi(client = MODULE_LIBRARIES)
|
|
public Builder setLocalRoutesExcludedForVpn(boolean excludeLocalRoutes) {
|
|
if (!SdkLevel.isAtLeastT()) {
|
|
throw new UnsupportedOperationException("Method is not supported");
|
|
}
|
|
mConfig.excludeLocalRouteVpn = excludeLocalRoutes;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Returns the constructed {@link NetworkAgentConfig} object.
|
|
*/
|
|
@NonNull
|
|
public NetworkAgentConfig build() {
|
|
return mConfig;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(final Object o) {
|
|
if (this == o) return true;
|
|
if (o == null || getClass() != o.getClass()) return false;
|
|
final NetworkAgentConfig that = (NetworkAgentConfig) o;
|
|
return allowBypass == that.allowBypass
|
|
&& explicitlySelected == that.explicitlySelected
|
|
&& acceptUnvalidated == that.acceptUnvalidated
|
|
&& acceptPartialConnectivity == that.acceptPartialConnectivity
|
|
&& provisioningNotificationDisabled == that.provisioningNotificationDisabled
|
|
&& skip464xlat == that.skip464xlat
|
|
&& legacyType == that.legacyType
|
|
&& legacySubType == that.legacySubType
|
|
&& Objects.equals(subscriberId, that.subscriberId)
|
|
&& Objects.equals(legacyTypeName, that.legacyTypeName)
|
|
&& Objects.equals(legacySubTypeName, that.legacySubTypeName)
|
|
&& Objects.equals(mLegacyExtraInfo, that.mLegacyExtraInfo)
|
|
&& excludeLocalRouteVpn == that.excludeLocalRouteVpn
|
|
&& mVpnRequiresValidation == that.mVpnRequiresValidation;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated,
|
|
acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId,
|
|
skip464xlat, legacyType, legacySubType, legacyTypeName, legacySubTypeName,
|
|
mLegacyExtraInfo, excludeLocalRouteVpn, mVpnRequiresValidation);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "NetworkAgentConfig {"
|
|
+ " allowBypass = " + allowBypass
|
|
+ ", explicitlySelected = " + explicitlySelected
|
|
+ ", acceptUnvalidated = " + acceptUnvalidated
|
|
+ ", acceptPartialConnectivity = " + acceptPartialConnectivity
|
|
+ ", provisioningNotificationDisabled = " + provisioningNotificationDisabled
|
|
+ ", subscriberId = '" + subscriberId + '\''
|
|
+ ", skip464xlat = " + skip464xlat
|
|
+ ", legacyType = " + legacyType
|
|
+ ", legacySubType = " + legacySubType
|
|
+ ", hasShownBroken = " + hasShownBroken
|
|
+ ", legacyTypeName = '" + legacyTypeName + '\''
|
|
+ ", legacySubTypeName = '" + legacySubTypeName + '\''
|
|
+ ", legacyExtraInfo = '" + mLegacyExtraInfo + '\''
|
|
+ ", excludeLocalRouteVpn = '" + excludeLocalRouteVpn + '\''
|
|
+ ", vpnRequiresValidation = '" + mVpnRequiresValidation + '\''
|
|
+ "}";
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(@NonNull Parcel out, int flags) {
|
|
out.writeInt(allowBypass ? 1 : 0);
|
|
out.writeInt(explicitlySelected ? 1 : 0);
|
|
out.writeInt(acceptUnvalidated ? 1 : 0);
|
|
out.writeInt(acceptPartialConnectivity ? 1 : 0);
|
|
out.writeString(subscriberId);
|
|
out.writeInt(provisioningNotificationDisabled ? 1 : 0);
|
|
out.writeInt(skip464xlat ? 1 : 0);
|
|
out.writeInt(legacyType);
|
|
out.writeString(legacyTypeName);
|
|
out.writeInt(legacySubType);
|
|
out.writeString(legacySubTypeName);
|
|
out.writeString(mLegacyExtraInfo);
|
|
out.writeInt(excludeLocalRouteVpn ? 1 : 0);
|
|
out.writeInt(mVpnRequiresValidation ? 1 : 0);
|
|
}
|
|
|
|
public static final @NonNull Creator<NetworkAgentConfig> CREATOR =
|
|
new Creator<NetworkAgentConfig>() {
|
|
@Override
|
|
public NetworkAgentConfig createFromParcel(Parcel in) {
|
|
NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
|
|
networkAgentConfig.allowBypass = in.readInt() != 0;
|
|
networkAgentConfig.explicitlySelected = in.readInt() != 0;
|
|
networkAgentConfig.acceptUnvalidated = in.readInt() != 0;
|
|
networkAgentConfig.acceptPartialConnectivity = in.readInt() != 0;
|
|
networkAgentConfig.subscriberId = in.readString();
|
|
networkAgentConfig.provisioningNotificationDisabled = in.readInt() != 0;
|
|
networkAgentConfig.skip464xlat = in.readInt() != 0;
|
|
networkAgentConfig.legacyType = in.readInt();
|
|
networkAgentConfig.legacyTypeName = in.readString();
|
|
networkAgentConfig.legacySubType = in.readInt();
|
|
networkAgentConfig.legacySubTypeName = in.readString();
|
|
networkAgentConfig.mLegacyExtraInfo = in.readString();
|
|
networkAgentConfig.excludeLocalRouteVpn = in.readInt() != 0;
|
|
networkAgentConfig.mVpnRequiresValidation = in.readInt() != 0;
|
|
return networkAgentConfig;
|
|
}
|
|
|
|
@Override
|
|
public NetworkAgentConfig[] newArray(int size) {
|
|
return new NetworkAgentConfig[size];
|
|
}
|
|
};
|
|
}
|