/*
* 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.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.NetworkCapabilities.NetCapability;
import android.net.NetworkCapabilities.Transport;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
import android.text.TextUtils;
import android.util.Range;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* Defines a request for a network, made through {@link NetworkRequest.Builder} and used
* to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
* via {@link ConnectivityManager#registerNetworkCallback}.
*/
public class NetworkRequest implements Parcelable {
/**
* The first requestId value that will be allocated.
* @hide only used by ConnectivityService.
*/
public static final int FIRST_REQUEST_ID = 1;
/**
* The requestId value that represents the absence of a request.
* @hide only used by ConnectivityService.
*/
public static final int REQUEST_ID_NONE = -1;
/**
* The {@link NetworkCapabilities} that define this request.
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public final @NonNull NetworkCapabilities networkCapabilities;
/**
* Identifies the request. NetworkRequests should only be constructed by
* the Framework and given out to applications as tokens to be used to identify
* the request.
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public final int requestId;
/**
* Set for legacy requests and the default. Set to TYPE_NONE for none.
* Causes CONNECTIVITY_ACTION broadcasts to be sent.
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public final int legacyType;
/**
* A NetworkRequest as used by the system can be one of the following types:
*
* - LISTEN, for which the framework will issue callbacks about any
* and all networks that match the specified NetworkCapabilities,
*
* - REQUEST, capable of causing a specific network to be created
* first (e.g. a telephony DUN request), the framework will issue
* callbacks about the single, highest scoring current network
* (if any) that matches the specified NetworkCapabilities, or
*
* - TRACK_DEFAULT, which causes the framework to issue callbacks for
* the single, highest scoring current network (if any) that will
* be chosen for an app, but which cannot cause the framework to
* either create or retain the existence of any specific network.
*
* - TRACK_SYSTEM_DEFAULT, which causes the framework to send callbacks
* for the network (if any) that satisfies the default Internet
* request.
*
* - TRACK_BEST, which causes the framework to send callbacks about
* the single, highest scoring current network (if any) that matches
* the specified NetworkCapabilities.
*
* - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
* to retain the NET_CAPABILITY_FOREGROUND capability. A network with
* no foreground requests is in the background. A network that has
* one or more background requests and loses its last foreground
* request to a higher-scoring network will not go into the
* background immediately, but will linger and go into the background
* after the linger timeout.
*
* - The value NONE is used only by applications. When an application
* creates a NetworkRequest, it does not have a type; the type is set
* by the system depending on the method used to file the request
* (requestNetwork, registerNetworkCallback, etc.).
*
* @hide
*/
public static enum Type {
NONE,
LISTEN,
TRACK_DEFAULT,
REQUEST,
BACKGROUND_REQUEST,
TRACK_SYSTEM_DEFAULT,
LISTEN_FOR_BEST,
};
/**
* The type of the request. This is only used by the system and is always NONE elsewhere.
*
* @hide
*/
public final Type type;
/**
* @hide
*/
public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type) {
if (nc == null) {
throw new NullPointerException();
}
requestId = rId;
networkCapabilities = nc;
this.legacyType = legacyType;
this.type = type;
}
/**
* @hide
*/
public NetworkRequest(NetworkRequest that) {
networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
requestId = that.requestId;
this.legacyType = that.legacyType;
this.type = that.type;
}
/**
* Builder used to create {@link NetworkRequest} objects. Specify the Network features
* needed in terms of {@link NetworkCapabilities} features
*/
public static class Builder {
/**
* Capabilities that are currently compatible with VCN networks.
*/
private static final List
* If the capability was previously added to the list of required capabilities (for
* example, it was there by default or added using {@link #addCapability(int)} method), then
* it will be removed from the list of required capabilities as well.
*
* @see #addCapability(int)
*
* @param capability The capability to add to forbidden capability list.
* @return The builder to facilitate chaining.
*
* @hide
*/
@NonNull
@SuppressLint("MissingGetterMatchingBuilder")
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public Builder addForbiddenCapability(@NetworkCapabilities.NetCapability int capability) {
mNetworkCapabilities.addForbiddenCapability(capability);
return this;
}
/**
* Removes (if found) the given forbidden capability from this builder instance.
*
* @param capability The forbidden capability to remove.
* @return The builder to facilitate chaining.
*
* @hide
*/
@NonNull
@SuppressLint("BuilderSetStyle")
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public Builder removeForbiddenCapability(
@NetworkCapabilities.NetCapability int capability) {
mNetworkCapabilities.removeForbiddenCapability(capability);
return this;
}
/**
* Completely clears all the {@code NetworkCapabilities} from this builder instance,
* removing even the capabilities that are set by default when the object is constructed.
*
* @return The builder to facilitate chaining.
*/
@NonNull
public Builder clearCapabilities() {
mNetworkCapabilities.clearAll();
// If the caller explicitly clear all capabilities, the NOT_VCN_MANAGED capabilities
// should not be add back later.
mShouldDeduceNotVcnManaged = false;
return this;
}
/**
* Adds the given transport requirement to this builder. These represent
* the set of allowed transports for the request. Only networks using one
* of these transports will satisfy the request. If no particular transports
* are required, none should be specified here.
*
* @param transportType The transport type to add.
* @return The builder to facilitate chaining.
*/
public Builder addTransportType(@NetworkCapabilities.Transport int transportType) {
mNetworkCapabilities.addTransportType(transportType);
return this;
}
/**
* Removes (if found) the given transport from this builder instance.
*
* @param transportType The transport type to remove.
* @return The builder to facilitate chaining.
*/
public Builder removeTransportType(@NetworkCapabilities.Transport int transportType) {
mNetworkCapabilities.removeTransportType(transportType);
return this;
}
/**
* @hide
*/
public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
return this;
}
/**
* @hide
*/
public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
return this;
}
/**
* Sets the optional bearer specific network specifier.
* This has no meaning if a single transport is also not specified, so calling
* this without a single transport set will generate an exception, as will
* subsequently adding or removing transports after this is set.
*
*
*
* @param networkSpecifier A {@code String} of either a SubscriptionId in cellular
* network request or an ethernet interface name in ethernet
* network request.
*
* @deprecated Use {@link #setNetworkSpecifier(NetworkSpecifier)} instead.
*/
@Deprecated
public Builder setNetworkSpecifier(String networkSpecifier) {
try {
int subId = Integer.parseInt(networkSpecifier);
return setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
.setSubscriptionId(subId).build());
} catch (NumberFormatException nfe) {
// An EthernetNetworkSpecifier or TestNetworkSpecifier does not accept null or empty
// ("") strings. When network specifiers were strings a null string and an empty
// string were considered equivalent. Hence no meaning is attached to a null or
// empty ("") string.
if (TextUtils.isEmpty(networkSpecifier)) {
return setNetworkSpecifier((NetworkSpecifier) null);
} else if (mNetworkCapabilities.hasTransport(TRANSPORT_TEST)) {
return setNetworkSpecifier(new TestNetworkSpecifier(networkSpecifier));
} else {
return setNetworkSpecifier(new EthernetNetworkSpecifier(networkSpecifier));
}
}
}
/**
* Sets the optional bearer specific network specifier.
* This has no meaning if a single transport is also not specified, so calling
* this without a single transport set will generate an exception, as will
* subsequently adding or removing transports after this is set.
*
* Note that when used to register a network callback, this specifies the minimum acceptable * signal strength. When received as the state of an existing network it specifies the * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when * received and has no effect when requesting a callback. * *
This method requires the caller to hold the * {@link android.Manifest.permission#NETWORK_SIGNAL_STRENGTH_WAKEUP} permission * * @param signalStrength the bearer-specific signal strength. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public @NonNull Builder setSignalStrength(int signalStrength) { mNetworkCapabilities.setSignalStrength(signalStrength); return this; } /** * Deduce the NET_CAPABILITY_NOT_VCN_MANAGED capability from other capabilities * and user intention, which includes: * 1. For the requests that don't have anything besides * {@link #VCN_SUPPORTED_CAPABILITIES}, add the NET_CAPABILITY_NOT_VCN_MANAGED to * allow the callers automatically utilize VCN networks if available. * 2. For the requests that explicitly add or remove NET_CAPABILITY_NOT_VCN_MANAGED, * or has clear intention of tracking specific network, * do not alter them to allow user fire request that suits their need. * * @hide */ private void deduceNotVcnManagedCapability(final NetworkCapabilities nc) { if (!mShouldDeduceNotVcnManaged) return; for (final int cap : nc.getCapabilities()) { if (!VCN_SUPPORTED_CAPABILITIES.contains(cap)) return; } nc.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); } /** * Sets the optional subscription ID set. *
* This specify the subscription IDs requirement. * A network will satisfy this request only if it matches one of the subIds in this set. * An empty set matches all networks, including those without a subId. * *
Registering a NetworkRequest with a non-empty set of subIds requires the
* NETWORK_FACTORY permission.
*
* @param subIds A {@code Set} that represents subscription IDs.
* @hide
*/
@NonNull
@SystemApi
public Builder setSubscriptionIds(@NonNull Set