Add NetworkCapabilities part of API.
Merging to master, adding @hide until we're ready to reveal the API change. bug:13885501 Change-Id: Ib40e28092e092630bfec557bde77f58eec8ae1c8
This commit is contained in:
312
core/java/android/net/NetworkCapabilities.java
Normal file
312
core/java/android/net/NetworkCapabilities.java
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
/*
|
||||||
|
* 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.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.IllegalArgumentException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class representing the capabilities of a network
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final class NetworkCapabilities implements Parcelable {
|
||||||
|
private static final String TAG = "NetworkCapabilities";
|
||||||
|
private static final boolean DBG = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the network's capabilities. If any are specified they will be satisfied
|
||||||
|
* by any Network that matches all of them.
|
||||||
|
*/
|
||||||
|
private long mNetworkCapabilities = (1 << NET_CAPABILITY_NOT_RESTRICTED);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Values for NetworkCapabilities. Roughly matches/extends deprecated
|
||||||
|
* ConnectivityManager TYPE_*
|
||||||
|
*/
|
||||||
|
public static final int NET_CAPABILITY_MMS = 0;
|
||||||
|
public static final int NET_CAPABILITY_SUPL = 1;
|
||||||
|
public static final int NET_CAPABILITY_DUN = 2;
|
||||||
|
public static final int NET_CAPABILITY_FOTA = 3;
|
||||||
|
public static final int NET_CAPABILITY_IMS = 4;
|
||||||
|
public static final int NET_CAPABILITY_CBS = 5;
|
||||||
|
public static final int NET_CAPABILITY_WIFI_P2P = 6;
|
||||||
|
public static final int NET_CAPABILITY_IA = 7;
|
||||||
|
public static final int NET_CAPABILITY_RCS = 8;
|
||||||
|
public static final int NET_CAPABILITY_XCAP = 9;
|
||||||
|
public static final int NET_CAPABILITY_EIMS = 10;
|
||||||
|
public static final int NET_CAPABILITY_NOT_METERED = 11;
|
||||||
|
public static final int NET_CAPABILITY_INTERNET = 12;
|
||||||
|
/** Set by default */
|
||||||
|
public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
|
||||||
|
|
||||||
|
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
|
||||||
|
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_RESTRICTED;
|
||||||
|
|
||||||
|
public void addNetworkCapability(int networkCapability) {
|
||||||
|
if (networkCapability < MIN_NET_CAPABILITY ||
|
||||||
|
networkCapability > MAX_NET_CAPABILITY) {
|
||||||
|
throw new IllegalArgumentException("NetworkCapability out of range");
|
||||||
|
}
|
||||||
|
mNetworkCapabilities |= 1 << networkCapability;
|
||||||
|
}
|
||||||
|
public void removeNetworkCapability(int networkCapability) {
|
||||||
|
if (networkCapability < MIN_NET_CAPABILITY ||
|
||||||
|
networkCapability > MAX_NET_CAPABILITY) {
|
||||||
|
throw new IllegalArgumentException("NetworkCapability out of range");
|
||||||
|
}
|
||||||
|
mNetworkCapabilities &= ~(1 << networkCapability);
|
||||||
|
}
|
||||||
|
public Collection<Integer> getNetworkCapabilities() {
|
||||||
|
return enumerateBits(mNetworkCapabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<Integer> enumerateBits(long val) {
|
||||||
|
ArrayList<Integer> result = new ArrayList<Integer>();
|
||||||
|
int resource = 0;
|
||||||
|
while (val > 0) {
|
||||||
|
if ((val & 1) == 1) result.add(resource);
|
||||||
|
val = val >> 1;
|
||||||
|
resource++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void combineNetCapabilities(NetworkCapabilities nc) {
|
||||||
|
this.mNetworkCapabilities |= nc.mNetworkCapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean satisfiedByNetCapabilities(NetworkCapabilities nc) {
|
||||||
|
return ((nc.mNetworkCapabilities & this.mNetworkCapabilities) == this.mNetworkCapabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean equalsNetCapabilities(NetworkCapabilities nc) {
|
||||||
|
return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representing the transport type. Apps should generally not care about transport. A
|
||||||
|
* request for a fast internet connection could be satisfied by a number of different
|
||||||
|
* transports. If any are specified here it will be satisfied a Network that matches
|
||||||
|
* any of them. If a caller doesn't care about the transport it should not specify any.
|
||||||
|
*/
|
||||||
|
private long mTransportTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Values for TransportType
|
||||||
|
*/
|
||||||
|
public static final int TRANSPORT_CELLULAR = 0;
|
||||||
|
public static final int TRANSPORT_WIFI = 1;
|
||||||
|
public static final int TRANSPORT_BLUETOOTH = 2;
|
||||||
|
public static final int TRANSPORT_ETHERNET = 3;
|
||||||
|
|
||||||
|
private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
|
||||||
|
private static final int MAX_TRANSPORT = TRANSPORT_ETHERNET;
|
||||||
|
|
||||||
|
public void addTransportType(int transportType) {
|
||||||
|
if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
|
||||||
|
throw new IllegalArgumentException("TransportType out of range");
|
||||||
|
}
|
||||||
|
mTransportTypes |= 1 << transportType;
|
||||||
|
}
|
||||||
|
public void removeTransportType(int transportType) {
|
||||||
|
if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
|
||||||
|
throw new IllegalArgumentException("TransportType out of range");
|
||||||
|
}
|
||||||
|
mTransportTypes &= ~(1 << transportType);
|
||||||
|
}
|
||||||
|
public Collection<Integer> getTransportTypes() {
|
||||||
|
return enumerateBits(mTransportTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void combineTransportTypes(NetworkCapabilities nc) {
|
||||||
|
this.mTransportTypes |= nc.mTransportTypes;
|
||||||
|
}
|
||||||
|
private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
|
||||||
|
return ((this.mTransportTypes == 0) ||
|
||||||
|
((this.mTransportTypes & nc.mTransportTypes) != 0));
|
||||||
|
}
|
||||||
|
private boolean equalsTransportTypes(NetworkCapabilities nc) {
|
||||||
|
return (nc.mTransportTypes == this.mTransportTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passive link bandwidth. This is a rough guide of the expected peak bandwidth
|
||||||
|
* for the first hop on the given transport. It is not measured, but may take into account
|
||||||
|
* link parameters (Radio technology, allocated channels, etc).
|
||||||
|
*/
|
||||||
|
private int mLinkUpBandwidthKbps;
|
||||||
|
private int mLinkDownBandwidthKbps;
|
||||||
|
|
||||||
|
public void setLinkUpstreamBandwidthKbps(int upKbps) {
|
||||||
|
mLinkUpBandwidthKbps = upKbps;
|
||||||
|
}
|
||||||
|
public int getLinkUpstreamBandwidthKbps() {
|
||||||
|
return mLinkUpBandwidthKbps;
|
||||||
|
}
|
||||||
|
public void setLinkDownstreamBandwidthKbps(int downKbps) {
|
||||||
|
mLinkDownBandwidthKbps = downKbps;
|
||||||
|
}
|
||||||
|
public int getLinkDownstreamBandwidthKbps() {
|
||||||
|
return mLinkDownBandwidthKbps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void combineLinkBandwidths(NetworkCapabilities nc) {
|
||||||
|
this.mLinkUpBandwidthKbps =
|
||||||
|
Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
|
||||||
|
this.mLinkDownBandwidthKbps =
|
||||||
|
Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
|
||||||
|
}
|
||||||
|
private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
|
||||||
|
return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
|
||||||
|
this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
|
||||||
|
}
|
||||||
|
private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
|
||||||
|
return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
|
||||||
|
this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combine a set of Capabilities to this one. Useful for coming up with the complete set
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
public void combineCapabilities(NetworkCapabilities nc) {
|
||||||
|
combineNetCapabilities(nc);
|
||||||
|
combineTransportTypes(nc);
|
||||||
|
combineLinkBandwidths(nc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if our requirements are satisfied by the given Capabilities.
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
|
||||||
|
return (satisfiedByNetCapabilities(nc) &&
|
||||||
|
satisfiedByTransportTypes(nc) &&
|
||||||
|
satisfiedByLinkBandwidths(nc));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
|
||||||
|
NetworkCapabilities that = (NetworkCapabilities)obj;
|
||||||
|
return (equalsNetCapabilities(that) &&
|
||||||
|
equalsTransportTypes(that) &&
|
||||||
|
equalsLinkBandwidths(that));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
|
||||||
|
((int)(mNetworkCapabilities >> 32) * 3) +
|
||||||
|
((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
|
||||||
|
((int)(mTransportTypes >> 32) * 7) +
|
||||||
|
(mLinkUpBandwidthKbps * 11) +
|
||||||
|
(mLinkDownBandwidthKbps * 13));
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetworkCapabilities() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetworkCapabilities(NetworkCapabilities nc) {
|
||||||
|
mNetworkCapabilities = nc.mNetworkCapabilities;
|
||||||
|
mTransportTypes = nc.mTransportTypes;
|
||||||
|
mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
|
||||||
|
mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parcelable
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeLong(mNetworkCapabilities);
|
||||||
|
dest.writeLong(mTransportTypes);
|
||||||
|
dest.writeInt(mLinkUpBandwidthKbps);
|
||||||
|
dest.writeInt(mLinkDownBandwidthKbps);
|
||||||
|
}
|
||||||
|
public static final Creator<NetworkCapabilities> CREATOR =
|
||||||
|
new Creator<NetworkCapabilities>() {
|
||||||
|
public NetworkCapabilities createFromParcel(Parcel in) {
|
||||||
|
NetworkCapabilities netCap = new NetworkCapabilities();
|
||||||
|
|
||||||
|
netCap.mNetworkCapabilities = in.readLong();
|
||||||
|
netCap.mTransportTypes = in.readLong();
|
||||||
|
netCap.mLinkUpBandwidthKbps = in.readInt();
|
||||||
|
netCap.mLinkDownBandwidthKbps = in.readInt();
|
||||||
|
return netCap;
|
||||||
|
}
|
||||||
|
public NetworkCapabilities[] newArray(int size) {
|
||||||
|
return new NetworkCapabilities[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
Collection<Integer> types = getTransportTypes();
|
||||||
|
String transports = (types.size() > 0 ? " Transports: " : "");
|
||||||
|
Iterator<Integer> i = types.iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
switch (i.next()) {
|
||||||
|
case TRANSPORT_CELLULAR: transports += "CELLULAR"; break;
|
||||||
|
case TRANSPORT_WIFI: transports += "WIFI"; break;
|
||||||
|
case TRANSPORT_BLUETOOTH: transports += "BLUETOOTH"; break;
|
||||||
|
case TRANSPORT_ETHERNET: transports += "ETHERNET"; break;
|
||||||
|
}
|
||||||
|
if (i.hasNext()) transports += "|";
|
||||||
|
}
|
||||||
|
|
||||||
|
types = getNetworkCapabilities();
|
||||||
|
String capabilities = (types.size() > 0 ? " Capabilities: " : "");
|
||||||
|
i = types.iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
switch (i.next().intValue()) {
|
||||||
|
case NET_CAPABILITY_MMS: capabilities += "MMS"; break;
|
||||||
|
case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break;
|
||||||
|
case NET_CAPABILITY_DUN: capabilities += "DUN"; break;
|
||||||
|
case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break;
|
||||||
|
case NET_CAPABILITY_IMS: capabilities += "IMS"; break;
|
||||||
|
case NET_CAPABILITY_CBS: capabilities += "CBS"; break;
|
||||||
|
case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break;
|
||||||
|
case NET_CAPABILITY_IA: capabilities += "IA"; break;
|
||||||
|
case NET_CAPABILITY_RCS: capabilities += "RCS"; break;
|
||||||
|
case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break;
|
||||||
|
case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break;
|
||||||
|
case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break;
|
||||||
|
case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break;
|
||||||
|
case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
|
||||||
|
}
|
||||||
|
if (i.hasNext()) capabilities += "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
|
||||||
|
mLinkUpBandwidthKbps + "Kbps" : "");
|
||||||
|
String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
|
||||||
|
mLinkDownBandwidthKbps + "Kbps" : "");
|
||||||
|
|
||||||
|
return "NetworkCapabilities: [" + transports + capabilities + upBand + dnBand + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user