blob: adbb185200521c05fa93cacc9140423e002c6c54 [file] [log] [blame]
Robert Greenwalt1448f052014-04-08 13:41:39 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21import android.util.Log;
22
23import java.lang.IllegalArgumentException;
24import java.util.ArrayList;
25import java.util.Collection;
26import java.util.HashMap;
27import java.util.Iterator;
28import java.util.Map;
29import java.util.Map.Entry;
30import java.util.Set;
31
32/**
33 * A class representing the capabilities of a network
34 * @hide
35 */
36public final class NetworkCapabilities implements Parcelable {
37 private static final String TAG = "NetworkCapabilities";
38 private static final boolean DBG = false;
39
40
41 /**
42 * Represents the network's capabilities. If any are specified they will be satisfied
43 * by any Network that matches all of them.
44 */
45 private long mNetworkCapabilities = (1 << NET_CAPABILITY_NOT_RESTRICTED);
46
47 /**
48 * Values for NetworkCapabilities. Roughly matches/extends deprecated
49 * ConnectivityManager TYPE_*
50 */
51 public static final int NET_CAPABILITY_MMS = 0;
52 public static final int NET_CAPABILITY_SUPL = 1;
53 public static final int NET_CAPABILITY_DUN = 2;
54 public static final int NET_CAPABILITY_FOTA = 3;
55 public static final int NET_CAPABILITY_IMS = 4;
56 public static final int NET_CAPABILITY_CBS = 5;
57 public static final int NET_CAPABILITY_WIFI_P2P = 6;
58 public static final int NET_CAPABILITY_IA = 7;
59 public static final int NET_CAPABILITY_RCS = 8;
60 public static final int NET_CAPABILITY_XCAP = 9;
61 public static final int NET_CAPABILITY_EIMS = 10;
62 public static final int NET_CAPABILITY_NOT_METERED = 11;
63 public static final int NET_CAPABILITY_INTERNET = 12;
64 /** Set by default */
65 public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
66
67 private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
68 private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_RESTRICTED;
69
70 public void addNetworkCapability(int networkCapability) {
71 if (networkCapability < MIN_NET_CAPABILITY ||
72 networkCapability > MAX_NET_CAPABILITY) {
73 throw new IllegalArgumentException("NetworkCapability out of range");
74 }
75 mNetworkCapabilities |= 1 << networkCapability;
76 }
77 public void removeNetworkCapability(int networkCapability) {
78 if (networkCapability < MIN_NET_CAPABILITY ||
79 networkCapability > MAX_NET_CAPABILITY) {
80 throw new IllegalArgumentException("NetworkCapability out of range");
81 }
82 mNetworkCapabilities &= ~(1 << networkCapability);
83 }
84 public Collection<Integer> getNetworkCapabilities() {
85 return enumerateBits(mNetworkCapabilities);
86 }
87
88 private Collection<Integer> enumerateBits(long val) {
89 ArrayList<Integer> result = new ArrayList<Integer>();
90 int resource = 0;
91 while (val > 0) {
92 if ((val & 1) == 1) result.add(resource);
93 val = val >> 1;
94 resource++;
95 }
96 return result;
97 }
98
99 private void combineNetCapabilities(NetworkCapabilities nc) {
100 this.mNetworkCapabilities |= nc.mNetworkCapabilities;
101 }
102
103 private boolean satisfiedByNetCapabilities(NetworkCapabilities nc) {
104 return ((nc.mNetworkCapabilities & this.mNetworkCapabilities) == this.mNetworkCapabilities);
105 }
106
107 private boolean equalsNetCapabilities(NetworkCapabilities nc) {
108 return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
109 }
110
111 /**
112 * Representing the transport type. Apps should generally not care about transport. A
113 * request for a fast internet connection could be satisfied by a number of different
114 * transports. If any are specified here it will be satisfied a Network that matches
115 * any of them. If a caller doesn't care about the transport it should not specify any.
116 */
117 private long mTransportTypes;
118
119 /**
120 * Values for TransportType
121 */
122 public static final int TRANSPORT_CELLULAR = 0;
123 public static final int TRANSPORT_WIFI = 1;
124 public static final int TRANSPORT_BLUETOOTH = 2;
125 public static final int TRANSPORT_ETHERNET = 3;
126
127 private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
128 private static final int MAX_TRANSPORT = TRANSPORT_ETHERNET;
129
130 public void addTransportType(int transportType) {
131 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
132 throw new IllegalArgumentException("TransportType out of range");
133 }
134 mTransportTypes |= 1 << transportType;
135 }
136 public void removeTransportType(int transportType) {
137 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
138 throw new IllegalArgumentException("TransportType out of range");
139 }
140 mTransportTypes &= ~(1 << transportType);
141 }
142 public Collection<Integer> getTransportTypes() {
143 return enumerateBits(mTransportTypes);
144 }
145
146 private void combineTransportTypes(NetworkCapabilities nc) {
147 this.mTransportTypes |= nc.mTransportTypes;
148 }
149 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
150 return ((this.mTransportTypes == 0) ||
151 ((this.mTransportTypes & nc.mTransportTypes) != 0));
152 }
153 private boolean equalsTransportTypes(NetworkCapabilities nc) {
154 return (nc.mTransportTypes == this.mTransportTypes);
155 }
156
157 /**
158 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth
159 * for the first hop on the given transport. It is not measured, but may take into account
160 * link parameters (Radio technology, allocated channels, etc).
161 */
162 private int mLinkUpBandwidthKbps;
163 private int mLinkDownBandwidthKbps;
164
165 public void setLinkUpstreamBandwidthKbps(int upKbps) {
166 mLinkUpBandwidthKbps = upKbps;
167 }
168 public int getLinkUpstreamBandwidthKbps() {
169 return mLinkUpBandwidthKbps;
170 }
171 public void setLinkDownstreamBandwidthKbps(int downKbps) {
172 mLinkDownBandwidthKbps = downKbps;
173 }
174 public int getLinkDownstreamBandwidthKbps() {
175 return mLinkDownBandwidthKbps;
176 }
177
178 private void combineLinkBandwidths(NetworkCapabilities nc) {
179 this.mLinkUpBandwidthKbps =
180 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
181 this.mLinkDownBandwidthKbps =
182 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
183 }
184 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
185 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
186 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
187 }
188 private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
189 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
190 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
191 }
192
193 /**
194 * Combine a set of Capabilities to this one. Useful for coming up with the complete set
195 * {@hide}
196 */
197 public void combineCapabilities(NetworkCapabilities nc) {
198 combineNetCapabilities(nc);
199 combineTransportTypes(nc);
200 combineLinkBandwidths(nc);
201 }
202
203 /**
204 * Check if our requirements are satisfied by the given Capabilities.
205 * {@hide}
206 */
207 public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
208 return (satisfiedByNetCapabilities(nc) &&
209 satisfiedByTransportTypes(nc) &&
210 satisfiedByLinkBandwidths(nc));
211 }
212
213 @Override
214 public boolean equals(Object obj) {
215 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
216 NetworkCapabilities that = (NetworkCapabilities)obj;
217 return (equalsNetCapabilities(that) &&
218 equalsTransportTypes(that) &&
219 equalsLinkBandwidths(that));
220 }
221
222 @Override
223 public int hashCode() {
224 return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
225 ((int)(mNetworkCapabilities >> 32) * 3) +
226 ((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
227 ((int)(mTransportTypes >> 32) * 7) +
228 (mLinkUpBandwidthKbps * 11) +
229 (mLinkDownBandwidthKbps * 13));
230 }
231
232 public NetworkCapabilities() {
233 }
234
235 public NetworkCapabilities(NetworkCapabilities nc) {
236 mNetworkCapabilities = nc.mNetworkCapabilities;
237 mTransportTypes = nc.mTransportTypes;
238 mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
239 mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
240 }
241
242 // Parcelable
243 public int describeContents() {
244 return 0;
245 }
246 public void writeToParcel(Parcel dest, int flags) {
247 dest.writeLong(mNetworkCapabilities);
248 dest.writeLong(mTransportTypes);
249 dest.writeInt(mLinkUpBandwidthKbps);
250 dest.writeInt(mLinkDownBandwidthKbps);
251 }
252 public static final Creator<NetworkCapabilities> CREATOR =
253 new Creator<NetworkCapabilities>() {
254 public NetworkCapabilities createFromParcel(Parcel in) {
255 NetworkCapabilities netCap = new NetworkCapabilities();
256
257 netCap.mNetworkCapabilities = in.readLong();
258 netCap.mTransportTypes = in.readLong();
259 netCap.mLinkUpBandwidthKbps = in.readInt();
260 netCap.mLinkDownBandwidthKbps = in.readInt();
261 return netCap;
262 }
263 public NetworkCapabilities[] newArray(int size) {
264 return new NetworkCapabilities[size];
265 }
266 };
267
268 public String toString() {
269 Collection<Integer> types = getTransportTypes();
270 String transports = (types.size() > 0 ? " Transports: " : "");
271 Iterator<Integer> i = types.iterator();
272 while (i.hasNext()) {
273 switch (i.next()) {
274 case TRANSPORT_CELLULAR: transports += "CELLULAR"; break;
275 case TRANSPORT_WIFI: transports += "WIFI"; break;
276 case TRANSPORT_BLUETOOTH: transports += "BLUETOOTH"; break;
277 case TRANSPORT_ETHERNET: transports += "ETHERNET"; break;
278 }
279 if (i.hasNext()) transports += "|";
280 }
281
282 types = getNetworkCapabilities();
283 String capabilities = (types.size() > 0 ? " Capabilities: " : "");
284 i = types.iterator();
285 while (i.hasNext()) {
286 switch (i.next().intValue()) {
287 case NET_CAPABILITY_MMS: capabilities += "MMS"; break;
288 case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break;
289 case NET_CAPABILITY_DUN: capabilities += "DUN"; break;
290 case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break;
291 case NET_CAPABILITY_IMS: capabilities += "IMS"; break;
292 case NET_CAPABILITY_CBS: capabilities += "CBS"; break;
293 case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break;
294 case NET_CAPABILITY_IA: capabilities += "IA"; break;
295 case NET_CAPABILITY_RCS: capabilities += "RCS"; break;
296 case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break;
297 case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break;
298 case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break;
299 case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break;
300 case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
301 }
302 if (i.hasNext()) capabilities += "&";
303 }
304
305 String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
306 mLinkUpBandwidthKbps + "Kbps" : "");
307 String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
308 mLinkDownBandwidthKbps + "Kbps" : "");
309
310 return "NetworkCapabilities: [" + transports + capabilities + upBand + dnBand + "]";
311 }
312}