Add networkSpecifier string to NetworkCapabilties.
Allows transport specific network selectivity where multi-sim or sta+sta
is supported.
bug:1575597
Change-Id: I9c60fe7710e988c17d63236788b492a3ddd264a1
diff --git a/api/current.txt b/api/current.txt
index 092061c..1ab7884 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16579,6 +16579,7 @@
method public android.net.NetworkRequest build();
method public android.net.NetworkRequest.Builder removeCapability(int);
method public android.net.NetworkRequest.Builder removeTransportType(int);
+ method public android.net.NetworkRequest.Builder setNetworkSpecifier(java.lang.String);
}
public abstract interface PSKKeyManager {
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 239db86..835b269 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -18,6 +18,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
import android.util.Log;
import java.lang.IllegalArgumentException;
@@ -303,6 +304,7 @@
throw new IllegalArgumentException("TransportType out of range");
}
mTransportTypes |= 1 << transportType;
+ setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
return this;
}
@@ -318,6 +320,7 @@
throw new IllegalArgumentException("TransportType out of range");
}
mTransportTypes &= ~(1 << transportType);
+ setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
return this;
}
@@ -437,6 +440,61 @@
this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
}
+ private String mNetworkSpecifier;
+ /**
+ * 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.
+ *
+ * @param networkSpecifier An {@code String} of opaque format used to specify the bearer
+ * specific network specifier where the bearer has a choice of
+ * networks.
+ * @hide
+ */
+ public void setNetworkSpecifier(String networkSpecifier) {
+ if (TextUtils.isEmpty(networkSpecifier) == false && Long.bitCount(mTransportTypes) != 1) {
+ throw new IllegalStateException("Must have a single transport specified to use " +
+ "setNetworkSpecifier");
+ }
+ mNetworkSpecifier = networkSpecifier;
+ }
+
+ /**
+ * Gets the optional bearer specific network specifier.
+ *
+ * @return The optional {@code String} specifying the bearer specific network specifier.
+ * See {@link #setNetworkSpecifier}.
+ * @hide
+ */
+ public String getNetworkSpecifier() {
+ return mNetworkSpecifier;
+ }
+
+ private void combineSpecifiers(NetworkCapabilities nc) {
+ String otherSpecifier = nc.getNetworkSpecifier();
+ if (TextUtils.isEmpty(otherSpecifier)) return;
+ if (TextUtils.isEmpty(mNetworkSpecifier) == false) {
+ throw new IllegalStateException("Can't combine two networkSpecifiers");
+ }
+ setNetworkSpecifier(otherSpecifier);
+ }
+ private boolean satisfiedBySpecifier(NetworkCapabilities nc) {
+ return (TextUtils.isEmpty(mNetworkSpecifier) ||
+ mNetworkSpecifier.equals(nc.mNetworkSpecifier));
+ }
+ private boolean equalsSpecifier(NetworkCapabilities nc) {
+ if (TextUtils.isEmpty(mNetworkSpecifier)) {
+ return TextUtils.isEmpty(nc.mNetworkSpecifier);
+ } else {
+ return mNetworkSpecifier.equals(nc.mNetworkSpecifier);
+ }
+ }
+
/**
* Combine a set of Capabilities to this one. Useful for coming up with the complete set
* {@hide}
@@ -445,6 +503,7 @@
combineNetCapabilities(nc);
combineTransportTypes(nc);
combineLinkBandwidths(nc);
+ combineSpecifiers(nc);
}
/**
@@ -455,7 +514,8 @@
return (nc != null &&
satisfiedByNetCapabilities(nc) &&
satisfiedByTransportTypes(nc) &&
- satisfiedByLinkBandwidths(nc));
+ satisfiedByLinkBandwidths(nc) &&
+ satisfiedBySpecifier(nc));
}
@Override
@@ -464,7 +524,8 @@
NetworkCapabilities that = (NetworkCapabilities)obj;
return (equalsNetCapabilities(that) &&
equalsTransportTypes(that) &&
- equalsLinkBandwidths(that));
+ equalsLinkBandwidths(that) &&
+ equalsSpecifier(that));
}
@Override
@@ -474,7 +535,8 @@
((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
((int)(mTransportTypes >> 32) * 7) +
(mLinkUpBandwidthKbps * 11) +
- (mLinkDownBandwidthKbps * 13));
+ (mLinkDownBandwidthKbps * 13) +
+ (TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17));
}
public int describeContents() {
@@ -485,6 +547,7 @@
dest.writeLong(mTransportTypes);
dest.writeInt(mLinkUpBandwidthKbps);
dest.writeInt(mLinkDownBandwidthKbps);
+ dest.writeString(mNetworkSpecifier);
}
public static final Creator<NetworkCapabilities> CREATOR =
new Creator<NetworkCapabilities>() {
@@ -495,6 +558,7 @@
netCap.mTransportTypes = in.readLong();
netCap.mLinkUpBandwidthKbps = in.readInt();
netCap.mLinkDownBandwidthKbps = in.readInt();
+ netCap.mNetworkSpecifier = in.readString();
return netCap;
}
public NetworkCapabilities[] newArray(int size) {
@@ -545,6 +609,9 @@
String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
mLinkDownBandwidthKbps + "Kbps" : "");
- return "[" + transports + capabilities + upBand + dnBand + "]";
+ String specifier = (mNetworkSpecifier == null ?
+ "" : " Specifier: <" + mNetworkSpecifier + ">");
+
+ return "[" + transports + capabilities + upBand + dnBand + specifier + "]";
}
}
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 36dc573..83bdfaa 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -153,6 +153,25 @@
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.
+ * </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.
+ *
+ * @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) {
+ mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
+ return this;
+ }
}
// implement the Parcelable interface