All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.android.net.NetworkRequest Maven / Gradle / Ivy

/*
 * 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 android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.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.proto.ProtoOutputStream;

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 {@link NetworkCapabilities} that define this request.
     * @hide
     */
    @UnsupportedAppUsage
    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
    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, a hybrid of the two designed such that the
     *       framework will issue callbacks for the single, highest scoring
     *       current network (if any) that matches the capabilities of the
     *       default Internet request (mDefaultRequest), but which cannot cause
     *       the framework to either create or retain the existence of any
     *       specific network. Note that from the point of view of the request
     *       matching code, TRACK_DEFAULT is identical to REQUEST: its special
     *       behaviour is not due to different semantics, but to the fact that
     *       the system will only ever create a TRACK_DEFAULT with capabilities
     *       that are identical to the default request's capabilities, thus
     *       causing it to share fate in every way with the default request.
     *
     *     - 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,
    };

    /**
     * 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 {
        private final NetworkCapabilities mNetworkCapabilities;

        /**
         * Default constructor for Builder.
         */
        public Builder() {
            // By default, restrict this request to networks available to this app.
            // Apps can rescind this restriction, but ConnectivityService will enforce
            // it for apps that do not have the NETWORK_SETTINGS permission.
            mNetworkCapabilities = new NetworkCapabilities();
            mNetworkCapabilities.setSingleUid(Process.myUid());
        }

        /**
         * Build {@link NetworkRequest} give the current set of capabilities.
         */
        public NetworkRequest build() {
            // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
            // when later an unrestricted capability could be added to mNetworkCapabilities, in
            // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
            // maybeMarkCapabilitiesRestricted() doesn't add back.
            final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
            nc.maybeMarkCapabilitiesRestricted();
            return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
                    ConnectivityManager.REQUEST_ID_UNSET, Type.NONE);
        }

        /**
         * Add the given capability requirement to this builder.  These represent
         * the requested network's required capabilities.  Note that when searching
         * for a network to satisfy a request, all capabilities requested must be
         * satisfied.
         *
         * @param capability The capability to add.
         * @return The builder to facilitate chaining
         *         {@code builder.addCapability(...).addCapability();}.
         */
        public Builder addCapability(@NetworkCapabilities.NetCapability int capability) {
            mNetworkCapabilities.addCapability(capability);
            return this;
        }

        /**
         * Removes (if found) the given capability from this builder instance.
         *
         * @param capability The capability to remove.
         * @return The builder to facilitate chaining.
         */
        public Builder removeCapability(@NetworkCapabilities.NetCapability int capability) {
            mNetworkCapabilities.removeCapability(capability);
            return this;
        }

        /**
         * Set the {@code NetworkCapabilities} for this builder instance,
         * overriding any capabilities that had been previously set.
         *
         * @param nc The superseding {@code NetworkCapabilities} instance.
         * @return The builder to facilitate chaining.
         * @hide
         */
        public Builder setCapabilities(NetworkCapabilities nc) {
            mNetworkCapabilities.set(nc);
            return this;
        }

        /**
         * Set the watched UIDs for this request. This will be reset and wiped out unless
         * the calling app holds the CHANGE_NETWORK_STATE permission.
         *
         * @param uids The watched UIDs as a set of UidRanges, or null for everything.
         * @return The builder to facilitate chaining.
         * @hide
         */
        public Builder setUids(Set uids) {
            mNetworkCapabilities.setUids(uids);
            return this;
        }

        /**
         * Add a capability that must not exist in the requested network.
         * 

* 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 unwanted capability list. * @return The builder to facilitate chaining. * * @hide */ public Builder addUnwantedCapability(@NetworkCapabilities.NetCapability int capability) { mNetworkCapabilities.addUnwantedCapability(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. * @hide */ @UnsupportedAppUsage public Builder clearCapabilities() { mNetworkCapabilities.clearAll(); 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. *

* The interpretation of this {@code String} is bearer specific and bearers that use * it should document their particulars. For example, Bluetooth may use some sort of * device id while WiFi could used ssid and/or bssid. Cellular may use carrier spn. * * @param networkSpecifier An {@code String} of opaque format used to specify the bearer * specific network specifier where the bearer has a choice of * networks. */ public Builder setNetworkSpecifier(String networkSpecifier) { /* * A StringNetworkSpecifier 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. */ return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null : new StringNetworkSpecifier(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. *

* * @param networkSpecifier A concrete, parcelable framework class that extends * NetworkSpecifier. */ public Builder setNetworkSpecifier(NetworkSpecifier networkSpecifier) { MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(networkSpecifier); mNetworkCapabilities.setNetworkSpecifier(networkSpecifier); return this; } /** * Sets the signal strength. This is a signed integer, with higher values indicating a * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same * RSSI units reported by WifiManager. *

* 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; } } // implement the Parcelable interface public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int flags) { networkCapabilities.writeToParcel(dest, flags); dest.writeInt(legacyType); dest.writeInt(requestId); dest.writeString(type.name()); } public static final @android.annotation.NonNull Creator CREATOR = new Creator() { public NetworkRequest createFromParcel(Parcel in) { NetworkCapabilities nc = NetworkCapabilities.CREATOR.createFromParcel(in); int legacyType = in.readInt(); int requestId = in.readInt(); Type type = Type.valueOf(in.readString()); // IllegalArgumentException if invalid. NetworkRequest result = new NetworkRequest(nc, legacyType, requestId, type); return result; } public NetworkRequest[] newArray(int size) { return new NetworkRequest[size]; } }; /** * Returns true iff. this NetworkRequest is of type LISTEN. * * @hide */ public boolean isListen() { return type == Type.LISTEN; } /** * Returns true iff. the contained NetworkRequest is one that: * * - should be associated with at most one satisfying network * at a time; * * - should cause a network to be kept up, but not necessarily in * the foreground, if it is the best network which can satisfy the * NetworkRequest. * * For full detail of how isRequest() is used for pairing Networks with * NetworkRequests read rematchNetworkAndRequests(). * * @hide */ public boolean isRequest() { return isForegroundRequest() || isBackgroundRequest(); } /** * Returns true iff. the contained NetworkRequest is one that: * * - should be associated with at most one satisfying network * at a time; * * - should cause a network to be kept up and in the foreground if * it is the best network which can satisfy the NetworkRequest. * * For full detail of how isRequest() is used for pairing Networks with * NetworkRequests read rematchNetworkAndRequests(). * * @hide */ public boolean isForegroundRequest() { return type == Type.TRACK_DEFAULT || type == Type.REQUEST; } /** * Returns true iff. this NetworkRequest is of type BACKGROUND_REQUEST. * * @hide */ public boolean isBackgroundRequest() { return type == Type.BACKGROUND_REQUEST; } /** * @see Builder#addCapability(int) */ public boolean hasCapability(@NetCapability int capability) { return networkCapabilities.hasCapability(capability); } /** * @see Builder#addUnwantedCapability(int) * * @hide */ public boolean hasUnwantedCapability(@NetCapability int capability) { return networkCapabilities.hasUnwantedCapability(capability); } /** * @see Builder#addTransportType(int) */ public boolean hasTransport(@Transport int transportType) { return networkCapabilities.hasTransport(transportType); } public String toString() { return "NetworkRequest [ " + type + " id=" + requestId + (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") + ", " + networkCapabilities.toString() + " ]"; } private int typeToProtoEnum(Type t) { switch (t) { case NONE: return NetworkRequestProto.TYPE_NONE; case LISTEN: return NetworkRequestProto.TYPE_LISTEN; case TRACK_DEFAULT: return NetworkRequestProto.TYPE_TRACK_DEFAULT; case REQUEST: return NetworkRequestProto.TYPE_REQUEST; case BACKGROUND_REQUEST: return NetworkRequestProto.TYPE_BACKGROUND_REQUEST; default: return NetworkRequestProto.TYPE_UNKNOWN; } } /** @hide */ public void writeToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type)); proto.write(NetworkRequestProto.REQUEST_ID, requestId); proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType); networkCapabilities.writeToProto(proto, NetworkRequestProto.NETWORK_CAPABILITIES); proto.end(token); } public boolean equals(Object obj) { if (obj instanceof NetworkRequest == false) return false; NetworkRequest that = (NetworkRequest)obj; return (that.legacyType == this.legacyType && that.requestId == this.requestId && that.type == this.type && Objects.equals(that.networkCapabilities, this.networkCapabilities)); } public int hashCode() { return Objects.hash(requestId, legacyType, networkCapabilities, type); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy