blob: 0bb26323a52553a6eef484ef179c9d300f6e7c38 [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 }
Robert Greenwalt5c55e332014-05-08 00:02:04 -070087 public boolean hasCapability(int networkCapability) {
88 if (networkCapability < MIN_NET_CAPABILITY ||
89 networkCapability > MAX_NET_CAPABILITY) {
90 return false;
91 }
92 return ((mNetworkCapabilities & (1 << networkCapability)) != 0);
93 }
Robert Greenwalt1448f052014-04-08 13:41:39 -070094
95 private Collection<Integer> enumerateBits(long val) {
96 ArrayList<Integer> result = new ArrayList<Integer>();
97 int resource = 0;
98 while (val > 0) {
99 if ((val & 1) == 1) result.add(resource);
100 val = val >> 1;
101 resource++;
102 }
103 return result;
104 }
105
106 private void combineNetCapabilities(NetworkCapabilities nc) {
107 this.mNetworkCapabilities |= nc.mNetworkCapabilities;
108 }
109
110 private boolean satisfiedByNetCapabilities(NetworkCapabilities nc) {
111 return ((nc.mNetworkCapabilities & this.mNetworkCapabilities) == this.mNetworkCapabilities);
112 }
113
114 private boolean equalsNetCapabilities(NetworkCapabilities nc) {
115 return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
116 }
117
118 /**
119 * Representing the transport type. Apps should generally not care about transport. A
120 * request for a fast internet connection could be satisfied by a number of different
121 * transports. If any are specified here it will be satisfied a Network that matches
122 * any of them. If a caller doesn't care about the transport it should not specify any.
123 */
124 private long mTransportTypes;
125
126 /**
127 * Values for TransportType
128 */
129 public static final int TRANSPORT_CELLULAR = 0;
130 public static final int TRANSPORT_WIFI = 1;
131 public static final int TRANSPORT_BLUETOOTH = 2;
132 public static final int TRANSPORT_ETHERNET = 3;
133
134 private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
135 private static final int MAX_TRANSPORT = TRANSPORT_ETHERNET;
136
137 public void addTransportType(int transportType) {
138 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
139 throw new IllegalArgumentException("TransportType out of range");
140 }
141 mTransportTypes |= 1 << transportType;
142 }
143 public void removeTransportType(int transportType) {
144 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
145 throw new IllegalArgumentException("TransportType out of range");
146 }
147 mTransportTypes &= ~(1 << transportType);
148 }
149 public Collection<Integer> getTransportTypes() {
150 return enumerateBits(mTransportTypes);
151 }
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700152 public boolean hasTransport(int transportType) {
153 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
154 return false;
155 }
156 return ((mTransportTypes & (1 << transportType)) != 0);
157 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700158
159 private void combineTransportTypes(NetworkCapabilities nc) {
160 this.mTransportTypes |= nc.mTransportTypes;
161 }
162 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
163 return ((this.mTransportTypes == 0) ||
164 ((this.mTransportTypes & nc.mTransportTypes) != 0));
165 }
166 private boolean equalsTransportTypes(NetworkCapabilities nc) {
167 return (nc.mTransportTypes == this.mTransportTypes);
168 }
169
170 /**
171 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth
172 * for the first hop on the given transport. It is not measured, but may take into account
173 * link parameters (Radio technology, allocated channels, etc).
174 */
175 private int mLinkUpBandwidthKbps;
176 private int mLinkDownBandwidthKbps;
177
178 public void setLinkUpstreamBandwidthKbps(int upKbps) {
179 mLinkUpBandwidthKbps = upKbps;
180 }
181 public int getLinkUpstreamBandwidthKbps() {
182 return mLinkUpBandwidthKbps;
183 }
184 public void setLinkDownstreamBandwidthKbps(int downKbps) {
185 mLinkDownBandwidthKbps = downKbps;
186 }
187 public int getLinkDownstreamBandwidthKbps() {
188 return mLinkDownBandwidthKbps;
189 }
190
191 private void combineLinkBandwidths(NetworkCapabilities nc) {
192 this.mLinkUpBandwidthKbps =
193 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
194 this.mLinkDownBandwidthKbps =
195 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
196 }
197 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
198 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
199 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
200 }
201 private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
202 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
203 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
204 }
205
206 /**
207 * Combine a set of Capabilities to this one. Useful for coming up with the complete set
208 * {@hide}
209 */
210 public void combineCapabilities(NetworkCapabilities nc) {
211 combineNetCapabilities(nc);
212 combineTransportTypes(nc);
213 combineLinkBandwidths(nc);
214 }
215
216 /**
217 * Check if our requirements are satisfied by the given Capabilities.
218 * {@hide}
219 */
220 public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700221 return (nc != null &&
222 satisfiedByNetCapabilities(nc) &&
Robert Greenwalt1448f052014-04-08 13:41:39 -0700223 satisfiedByTransportTypes(nc) &&
224 satisfiedByLinkBandwidths(nc));
225 }
226
227 @Override
228 public boolean equals(Object obj) {
229 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
230 NetworkCapabilities that = (NetworkCapabilities)obj;
231 return (equalsNetCapabilities(that) &&
232 equalsTransportTypes(that) &&
233 equalsLinkBandwidths(that));
234 }
235
236 @Override
237 public int hashCode() {
238 return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
239 ((int)(mNetworkCapabilities >> 32) * 3) +
240 ((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
241 ((int)(mTransportTypes >> 32) * 7) +
242 (mLinkUpBandwidthKbps * 11) +
243 (mLinkDownBandwidthKbps * 13));
244 }
245
246 public NetworkCapabilities() {
247 }
248
249 public NetworkCapabilities(NetworkCapabilities nc) {
250 mNetworkCapabilities = nc.mNetworkCapabilities;
251 mTransportTypes = nc.mTransportTypes;
252 mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
253 mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
254 }
255
256 // Parcelable
257 public int describeContents() {
258 return 0;
259 }
260 public void writeToParcel(Parcel dest, int flags) {
261 dest.writeLong(mNetworkCapabilities);
262 dest.writeLong(mTransportTypes);
263 dest.writeInt(mLinkUpBandwidthKbps);
264 dest.writeInt(mLinkDownBandwidthKbps);
265 }
266 public static final Creator<NetworkCapabilities> CREATOR =
267 new Creator<NetworkCapabilities>() {
268 public NetworkCapabilities createFromParcel(Parcel in) {
269 NetworkCapabilities netCap = new NetworkCapabilities();
270
271 netCap.mNetworkCapabilities = in.readLong();
272 netCap.mTransportTypes = in.readLong();
273 netCap.mLinkUpBandwidthKbps = in.readInt();
274 netCap.mLinkDownBandwidthKbps = in.readInt();
275 return netCap;
276 }
277 public NetworkCapabilities[] newArray(int size) {
278 return new NetworkCapabilities[size];
279 }
280 };
281
282 public String toString() {
283 Collection<Integer> types = getTransportTypes();
284 String transports = (types.size() > 0 ? " Transports: " : "");
285 Iterator<Integer> i = types.iterator();
286 while (i.hasNext()) {
287 switch (i.next()) {
288 case TRANSPORT_CELLULAR: transports += "CELLULAR"; break;
289 case TRANSPORT_WIFI: transports += "WIFI"; break;
290 case TRANSPORT_BLUETOOTH: transports += "BLUETOOTH"; break;
291 case TRANSPORT_ETHERNET: transports += "ETHERNET"; break;
292 }
293 if (i.hasNext()) transports += "|";
294 }
295
296 types = getNetworkCapabilities();
297 String capabilities = (types.size() > 0 ? " Capabilities: " : "");
298 i = types.iterator();
299 while (i.hasNext()) {
300 switch (i.next().intValue()) {
301 case NET_CAPABILITY_MMS: capabilities += "MMS"; break;
302 case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break;
303 case NET_CAPABILITY_DUN: capabilities += "DUN"; break;
304 case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break;
305 case NET_CAPABILITY_IMS: capabilities += "IMS"; break;
306 case NET_CAPABILITY_CBS: capabilities += "CBS"; break;
307 case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break;
308 case NET_CAPABILITY_IA: capabilities += "IA"; break;
309 case NET_CAPABILITY_RCS: capabilities += "RCS"; break;
310 case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break;
311 case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break;
312 case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break;
313 case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break;
314 case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
315 }
316 if (i.hasNext()) capabilities += "&";
317 }
318
319 String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
320 mLinkUpBandwidthKbps + "Kbps" : "");
321 String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
322 mLinkDownBandwidthKbps + "Kbps" : "");
323
324 return "NetworkCapabilities: [" + transports + capabilities + upBand + dnBand + "]";
325 }
326}