Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 29fe0c99 authored by Etan Cohen's avatar Etan Cohen Committed by Lorenzo Colitti
Browse files

Make the NetworkSpecifier a class instead of a string.

Bug: 27533960
Bug: 36053921
Bug: 36275276
Test: connectivity, wifi, telephony unit tests
Change-Id: Idd9b10a8418c53c8cf386d9ff8252226b076bbf9
Merged-In: I7535495681da8f168c46d6d95e13925cffecc99b
Merged-In: I6500639ae839ee9ad5af34d1292d1539c943e2ad
parent 677999af
Loading
Loading
Loading
Loading
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.os.Parcel;
import android.os.Parcelable;

/**
 * MatchAllNetworkSpecifier is a marker class used by NetworkFactory classes to indicate
 * that they accept (match) any network specifier in requests.
 *
 * The class must never be used as part of a network request (those semantics aren't specified).
 *
 * @hide
 */
public final class MatchAllNetworkSpecifier extends NetworkSpecifier implements Parcelable {
    /**
     * Utility method which verifies that the ns argument is not a MatchAllNetworkSpecifier and
     * throws an IllegalArgumentException if it is.
     */
    public static void checkNotMatchAllNetworkSpecifier(NetworkSpecifier ns) {
        if (ns instanceof MatchAllNetworkSpecifier) {
            throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted");
        }
    }

    public boolean satisfiedBy(NetworkSpecifier other) {
        /*
         * The method is called by a NetworkRequest to see if it is satisfied by a proposed
         * network (e.g. as offered by a network factory). Since MatchAllNetweorkSpecifier must
         * not be used in network requests this method should never be called.
         */
        throw new IllegalStateException(
                "MatchAllNetworkSpecifier must not be used in NetworkRequests");
    }

    @Override
    public boolean equals(Object o) {
        return o instanceof MatchAllNetworkSpecifier;
    }

    @Override
    public int hashCode() {
        return 0;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // Nothing to write.
    }

    public static final Parcelable.Creator<MatchAllNetworkSpecifier> CREATOR =
            new Parcelable.Creator<MatchAllNetworkSpecifier>() {
        public MatchAllNetworkSpecifier createFromParcel(Parcel in) {
            return new MatchAllNetworkSpecifier();
        }
        public MatchAllNetworkSpecifier[] newArray(int size) {
            return new MatchAllNetworkSpecifier[size];
        }
    };
}
+26 −42
Original line number Diff line number Diff line
@@ -18,9 +18,11 @@ package android.net;

import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import com.android.internal.util.BitUtils;

import java.util.Objects;

/**
 * This class represents the capabilities of a network.  This is used both to specify
 * needs to {@link ConnectivityManager} and when inspecting a network.
@@ -33,6 +35,8 @@ import com.android.internal.util.BitUtils;
 * all cellular based connections are metered and all Wi-Fi based connections are not.
 */
public final class NetworkCapabilities implements Parcelable {
    private static final String TAG = "NetworkCapabilities";

    /**
     * @hide
     */
@@ -204,19 +208,6 @@ public final class NetworkCapabilities implements Parcelable {
            (1 << NET_CAPABILITY_CAPTIVE_PORTAL) |
            (1 << NET_CAPABILITY_FOREGROUND);

    /**
     * Network specifier for factories which want to match any network specifier
     * (NS) in a request. Behavior:
     * <li>Empty NS in request matches any network factory NS</li>
     * <li>Empty NS in the network factory NS only matches a request with an
     * empty NS</li>
     * <li>"*" (this constant) NS in the network factory matches requests with
     * any NS</li>
     *
     * @hide
     */
    public static final String MATCH_ALL_REQUESTS_NETWORK_SPECIFIER = "*";

    /**
     * Network capabilities that are not allowed in NetworkRequests. This exists because the
     * NetworkFactory / NetworkAgent model does not deal well with the situation where a
@@ -579,63 +570,56 @@ public final class NetworkCapabilities implements Parcelable {
                this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
    }

    private String mNetworkSpecifier;
    private NetworkSpecifier mNetworkSpecifier = null;

    /**
     * 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.
     * </p>
     * 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 (name)
     * or Subscription ID.
     *
     * @param networkSpecifier An {@code String} of opaque format used to specify the bearer
     *                         specific network specifier where the bearer has a choice of
     *                         networks.
     *
     * @param networkSpecifier A concrete, parcelable framework class that extends
     *                         NetworkSpecifier.
     * @return This NetworkCapabilities instance, to facilitate chaining.
     * @hide
     */
    public NetworkCapabilities setNetworkSpecifier(String networkSpecifier) {
        if (TextUtils.isEmpty(networkSpecifier) == false && Long.bitCount(mTransportTypes) != 1) {
    public NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
        if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) {
            throw new IllegalStateException("Must have a single transport specified to use " +
                    "setNetworkSpecifier");
        }

        mNetworkSpecifier = networkSpecifier;

        return this;
    }

    /**
     * Gets the optional bearer specific network specifier.
     *
     * @return The optional {@code String} specifying the bearer specific network specifier.
     *         See {@link #setNetworkSpecifier}.
     * @return The optional {@link NetworkSpecifier} specifying the bearer specific network
     *         specifier. See {@link #setNetworkSpecifier}.
     * @hide
     */
    public String getNetworkSpecifier() {
    public NetworkSpecifier getNetworkSpecifier() {
        return mNetworkSpecifier;
    }

    private void combineSpecifiers(NetworkCapabilities nc) {
        String otherSpecifier = nc.getNetworkSpecifier();
        if (TextUtils.isEmpty(otherSpecifier)) return;
        if (TextUtils.isEmpty(mNetworkSpecifier) == false) {
        if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) {
            throw new IllegalStateException("Can't combine two networkSpecifiers");
        }
        setNetworkSpecifier(otherSpecifier);
        setNetworkSpecifier(nc.mNetworkSpecifier);
    }

    private boolean satisfiedBySpecifier(NetworkCapabilities nc) {
        return (TextUtils.isEmpty(mNetworkSpecifier) ||
                mNetworkSpecifier.equals(nc.mNetworkSpecifier) ||
                MATCH_ALL_REQUESTS_NETWORK_SPECIFIER.equals(nc.mNetworkSpecifier));
        return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier)
                || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier;
    }

    private boolean equalsSpecifier(NetworkCapabilities nc) {
        if (TextUtils.isEmpty(mNetworkSpecifier)) {
            return TextUtils.isEmpty(nc.mNetworkSpecifier);
        } else {
            return mNetworkSpecifier.equals(nc.mNetworkSpecifier);
        }
        return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier);
    }

    /**
@@ -797,7 +781,7 @@ public final class NetworkCapabilities implements Parcelable {
                ((int)(mTransportTypes >> 32) * 7) +
                (mLinkUpBandwidthKbps * 11) +
                (mLinkDownBandwidthKbps * 13) +
                (TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17) +
                Objects.hashCode(mNetworkSpecifier) * 17 +
                (mSignalStrength * 19));
    }

@@ -811,7 +795,7 @@ public final class NetworkCapabilities implements Parcelable {
        dest.writeLong(mTransportTypes);
        dest.writeInt(mLinkUpBandwidthKbps);
        dest.writeInt(mLinkDownBandwidthKbps);
        dest.writeString(mNetworkSpecifier);
        dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
        dest.writeInt(mSignalStrength);
    }

@@ -825,7 +809,7 @@ public final class NetworkCapabilities implements Parcelable {
                netCap.mTransportTypes = in.readLong();
                netCap.mLinkUpBandwidthKbps = in.readInt();
                netCap.mLinkDownBandwidthKbps = in.readInt();
                netCap.mNetworkSpecifier = in.readString();
                netCap.mNetworkSpecifier = in.readParcelable(null);
                netCap.mSignalStrength = in.readInt();
                return netCap;
            }
+23 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.net;

import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import java.util.Objects;

@@ -259,10 +260,28 @@ public class NetworkRequest implements Parcelable {
         *                         networks.
         */
        public Builder setNetworkSpecifier(String networkSpecifier) {
            if (NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER.equals(networkSpecifier)) {
                throw new IllegalArgumentException("Invalid network specifier - must not be '"
                        + NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER + "'");
            /*
             * 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.
         * </p>
         *
         * @param networkSpecifier A concrete, parcelable framework class that extends
         *                         NetworkSpecifier.
         * @hide
         */
        public Builder setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
            MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(networkSpecifier);
            mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
            return this;
        }
+35 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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;

/**
 * Describes specific properties of a network for use in a {@link NetworkRequest}.
 *
 * Applications cannot instantiate this class by themselves, but can obtain instances of
 * subclasses of this class via other APIs.
 *
 * @hide
 */
public abstract class NetworkSpecifier {
    /**
     * Returns true if a request with this {@link NetworkSpecifier} is satisfied by a network
     * with the given NetworkSpecifier.
     *
     * @hide
     */
    public abstract boolean satisfiedBy(NetworkSpecifier other);
}
+79 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import com.android.internal.util.Preconditions;

import java.util.Objects;

/** @hide */
public final class StringNetworkSpecifier extends NetworkSpecifier implements Parcelable {
    /**
     * Arbitrary string used to pass (additional) information to the network factory.
     */
    public final String specifier;

    public StringNetworkSpecifier(String specifier) {
        Preconditions.checkStringNotEmpty(specifier);
        this.specifier = specifier;
    }

    @Override
    public boolean satisfiedBy(NetworkSpecifier other) {
        return equals(other);
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof StringNetworkSpecifier)) return false;
        return TextUtils.equals(specifier, ((StringNetworkSpecifier) o).specifier);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(specifier);
    }

    @Override
    public String toString() {
        return specifier;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(specifier);
    }

    public static final Parcelable.Creator<StringNetworkSpecifier> CREATOR =
            new Parcelable.Creator<StringNetworkSpecifier>() {
        public StringNetworkSpecifier createFromParcel(Parcel in) {
            return new StringNetworkSpecifier(in.readString());
        }
        public StringNetworkSpecifier[] newArray(int size) {
            return new StringNetworkSpecifier[size];
        }
    };
}
Loading