• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 
17 package android.net;
18 
19 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
20 import static android.net.ConnectivityManager.TYPE_MOBILE;
21 import static android.net.ConnectivityManager.TYPE_WIFI;
22 import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
23 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
24 
25 import android.annotation.IntDef;
26 import android.annotation.NonNull;
27 import android.annotation.Nullable;
28 import android.annotation.SuppressLint;
29 import android.annotation.SystemApi;
30 import android.app.usage.NetworkStatsManager;
31 import android.content.Context;
32 import android.net.wifi.WifiInfo;
33 import android.service.NetworkIdentityProto;
34 import android.telephony.TelephonyManager;
35 import android.util.proto.ProtoOutputStream;
36 
37 import com.android.net.module.util.CollectionUtils;
38 import com.android.net.module.util.NetworkCapabilitiesUtils;
39 import com.android.net.module.util.NetworkIdentityUtils;
40 
41 import java.lang.annotation.Retention;
42 import java.lang.annotation.RetentionPolicy;
43 import java.util.ArrayList;
44 import java.util.Objects;
45 
46 /**
47  * Network definition that includes strong identity. Analogous to combining
48  * {@link NetworkCapabilities} and an IMSI.
49  *
50  * @hide
51  */
52 @SystemApi(client = MODULE_LIBRARIES)
53 public class NetworkIdentity {
54     private static final String TAG = "NetworkIdentity";
55 
56     /** @hide */
57     // TODO: Remove this after migrating all callers to use
58     //  {@link NetworkTemplate#NETWORK_TYPE_ALL} instead.
59     public static final int SUBTYPE_COMBINED = -1;
60 
61     /** @hide */
62     @Retention(RetentionPolicy.SOURCE)
63     @IntDef(prefix = { "OEM_MANAGED_" }, flag = true, value = {
64             NetworkTemplate.OEM_MANAGED_NO,
65             NetworkTemplate.OEM_MANAGED_PAID,
66             NetworkTemplate.OEM_MANAGED_PRIVATE
67     })
68     public @interface OemManaged{}
69 
70     /**
71      * Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}.
72      * @hide
73      */
74     public static final int OEM_NONE = 0x0;
75     /**
76      * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}.
77      * @hide
78      */
79     public static final int OEM_PAID = 1 << 0;
80     /**
81      * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}.
82      * @hide
83      */
84     public static final int OEM_PRIVATE = 1 << 1;
85 
86     private static final long SUPPORTED_OEM_MANAGED_TYPES = OEM_PAID | OEM_PRIVATE;
87 
88     final int mType;
89     final int mRatType;
90     final int mSubId;
91     final String mSubscriberId;
92     final String mWifiNetworkKey;
93     final boolean mRoaming;
94     final boolean mMetered;
95     final boolean mDefaultNetwork;
96     final int mOemManaged;
97 
98     /** @hide */
NetworkIdentity( int type, int ratType, @Nullable String subscriberId, @Nullable String wifiNetworkKey, boolean roaming, boolean metered, boolean defaultNetwork, int oemManaged, int subId)99     public NetworkIdentity(
100             int type, int ratType, @Nullable String subscriberId, @Nullable String wifiNetworkKey,
101             boolean roaming, boolean metered, boolean defaultNetwork, int oemManaged, int subId) {
102         mType = type;
103         mRatType = ratType;
104         mSubscriberId = subscriberId;
105         mWifiNetworkKey = wifiNetworkKey;
106         mRoaming = roaming;
107         mMetered = metered;
108         mDefaultNetwork = defaultNetwork;
109         mOemManaged = oemManaged;
110         mSubId = subId;
111     }
112 
113     @Override
hashCode()114     public int hashCode() {
115         return Objects.hash(mType, mRatType, mSubscriberId, mWifiNetworkKey, mRoaming, mMetered,
116                 mDefaultNetwork, mOemManaged, mSubId);
117     }
118 
119     @Override
equals(@ullable Object obj)120     public boolean equals(@Nullable Object obj) {
121         if (obj instanceof NetworkIdentity) {
122             final NetworkIdentity ident = (NetworkIdentity) obj;
123             return mType == ident.mType && mRatType == ident.mRatType && mRoaming == ident.mRoaming
124                     && Objects.equals(mSubscriberId, ident.mSubscriberId)
125                     && Objects.equals(mWifiNetworkKey, ident.mWifiNetworkKey)
126                     && mMetered == ident.mMetered
127                     && mDefaultNetwork == ident.mDefaultNetwork
128                     && mOemManaged == ident.mOemManaged
129                     && mSubId == ident.mSubId;
130         }
131         return false;
132     }
133 
134     @Override
toString()135     public String toString() {
136         final StringBuilder builder = new StringBuilder("{");
137         builder.append("type=").append(mType);
138         builder.append(", ratType=");
139         if (mRatType == NETWORK_TYPE_ALL) {
140             builder.append("COMBINED");
141         } else {
142             builder.append(mRatType);
143         }
144         if (mSubscriberId != null) {
145             builder.append(", subscriberId=")
146                     .append(NetworkIdentityUtils.scrubSubscriberId(mSubscriberId));
147         }
148         if (mWifiNetworkKey != null) {
149             builder.append(", wifiNetworkKey=").append(mWifiNetworkKey);
150         }
151         if (mRoaming) {
152             builder.append(", ROAMING");
153         }
154         builder.append(", metered=").append(mMetered);
155         builder.append(", defaultNetwork=").append(mDefaultNetwork);
156         builder.append(", oemManaged=").append(getOemManagedNames(mOemManaged));
157         builder.append(", subId=").append(mSubId);
158         return builder.append("}").toString();
159     }
160 
161     /**
162      * Get the human readable representation of a bitfield representing the OEM managed state of a
163      * network.
164      */
getOemManagedNames(int oemManaged)165     static String getOemManagedNames(int oemManaged) {
166         if (oemManaged == OEM_NONE) {
167             return "OEM_NONE";
168         }
169         final int[] bitPositions = NetworkCapabilitiesUtils.unpackBits(oemManaged);
170         final ArrayList<String> oemManagedNames = new ArrayList<String>();
171         for (int position : bitPositions) {
172             oemManagedNames.add(nameOfOemManaged(1 << position));
173         }
174         return String.join(",", oemManagedNames);
175     }
176 
nameOfOemManaged(int oemManagedBit)177     private static String nameOfOemManaged(int oemManagedBit) {
178         switch (oemManagedBit) {
179             case OEM_PAID:
180                 return "OEM_PAID";
181             case OEM_PRIVATE:
182                 return "OEM_PRIVATE";
183             default:
184                 return "Invalid(" + oemManagedBit + ")";
185         }
186     }
187 
188     /** @hide */
dumpDebug(ProtoOutputStream proto, long tag)189     public void dumpDebug(ProtoOutputStream proto, long tag) {
190         final long start = proto.start(tag);
191 
192         proto.write(NetworkIdentityProto.TYPE, mType);
193 
194         // TODO: dump mRatType as well.
195 
196         proto.write(NetworkIdentityProto.ROAMING, mRoaming);
197         proto.write(NetworkIdentityProto.METERED, mMetered);
198         proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork);
199         proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged);
200 
201         proto.end(start);
202     }
203 
204     /** Get the network type of this instance. */
getType()205     public int getType() {
206         return mType;
207     }
208 
209     /** Get the Radio Access Technology(RAT) type of this instance. */
getRatType()210     public int getRatType() {
211         return mRatType;
212     }
213 
214     /** Get the Subscriber Id of this instance. */
215     @Nullable
getSubscriberId()216     public String getSubscriberId() {
217         return mSubscriberId;
218     }
219 
220     /** Get the Wifi Network Key of this instance. See {@link WifiInfo#getNetworkKey()}. */
221     @Nullable
getWifiNetworkKey()222     public String getWifiNetworkKey() {
223         return mWifiNetworkKey;
224     }
225 
226     /** @hide */
227     // TODO: Remove this function after all callers are removed.
getRoaming()228     public boolean getRoaming() {
229         return mRoaming;
230     }
231 
232     /** Return whether this network is roaming. */
isRoaming()233     public boolean isRoaming() {
234         return mRoaming;
235     }
236 
237     /** @hide */
238     // TODO: Remove this function after all callers are removed.
getMetered()239     public boolean getMetered() {
240         return mMetered;
241     }
242 
243     /** Return whether this network is metered. */
isMetered()244     public boolean isMetered() {
245         return mMetered;
246     }
247 
248     /** @hide */
249     // TODO: Remove this function after all callers are removed.
getDefaultNetwork()250     public boolean getDefaultNetwork() {
251         return mDefaultNetwork;
252     }
253 
254     /** Return whether this network is the default network. */
isDefaultNetwork()255     public boolean isDefaultNetwork() {
256         return mDefaultNetwork;
257     }
258 
259     /** Get the OEM managed type of this instance. */
getOemManaged()260     public int getOemManaged() {
261         return mOemManaged;
262     }
263 
264     /** Get the SubId of this instance. */
getSubId()265     public int getSubId() {
266         return mSubId;
267     }
268 
269     /**
270      * Assemble a {@link NetworkIdentity} from the passed arguments.
271      *
272      * This methods builds an identity based on the capabilities of the network in the
273      * snapshot and other passed arguments. The identity is used as a key to record data usage.
274      *
275      * @param snapshot the snapshot of network state. See {@link NetworkStateSnapshot}.
276      * @param defaultNetwork whether the network is a default network.
277      * @param ratType the Radio Access Technology(RAT) type of the network. Or
278      *                {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if not applicable.
279      *                See {@code TelephonyManager.NETWORK_TYPE_*}.
280      * @hide
281      * @deprecated See {@link NetworkIdentity.Builder}.
282      */
283     // TODO: Remove this after all callers are migrated to use new Api.
284     @Deprecated
285     @NonNull
buildNetworkIdentity(Context context, @NonNull NetworkStateSnapshot snapshot, boolean defaultNetwork, int ratType)286     public static NetworkIdentity buildNetworkIdentity(Context context,
287             @NonNull NetworkStateSnapshot snapshot, boolean defaultNetwork, int ratType) {
288         final NetworkIdentity.Builder builder = new NetworkIdentity.Builder()
289                 .setNetworkStateSnapshot(snapshot).setDefaultNetwork(defaultNetwork)
290                 .setSubId(snapshot.getSubId());
291         if (snapshot.getLegacyType() == TYPE_MOBILE && ratType != NETWORK_TYPE_ALL) {
292             builder.setRatType(ratType);
293         }
294         return builder.build();
295     }
296 
297     /**
298      * Builds a bitfield of {@code NetworkIdentity.OEM_*} based on {@link NetworkCapabilities}.
299      * @hide
300      */
getOemBitfield(@onNull NetworkCapabilities nc)301     public static int getOemBitfield(@NonNull NetworkCapabilities nc) {
302         int oemManaged = OEM_NONE;
303 
304         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)) {
305             oemManaged |= OEM_PAID;
306         }
307         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)) {
308             oemManaged |= OEM_PRIVATE;
309         }
310 
311         return oemManaged;
312     }
313 
314     /** @hide */
compare(@onNull NetworkIdentity left, @NonNull NetworkIdentity right)315     public static int compare(@NonNull NetworkIdentity left, @NonNull NetworkIdentity right) {
316         Objects.requireNonNull(right);
317         int res = Integer.compare(left.mType, right.mType);
318         if (res == 0) {
319             res = Integer.compare(left.mRatType, right.mRatType);
320         }
321         if (res == 0 && left.mSubscriberId != null && right.mSubscriberId != null) {
322             res = left.mSubscriberId.compareTo(right.mSubscriberId);
323         }
324         if (res == 0 && left.mWifiNetworkKey != null && right.mWifiNetworkKey != null) {
325             res = left.mWifiNetworkKey.compareTo(right.mWifiNetworkKey);
326         }
327         if (res == 0) {
328             res = Boolean.compare(left.mRoaming, right.mRoaming);
329         }
330         if (res == 0) {
331             res = Boolean.compare(left.mMetered, right.mMetered);
332         }
333         if (res == 0) {
334             res = Boolean.compare(left.mDefaultNetwork, right.mDefaultNetwork);
335         }
336         if (res == 0) {
337             res = Integer.compare(left.mOemManaged, right.mOemManaged);
338         }
339         if (res == 0) {
340             res = Integer.compare(left.mSubId, right.mSubId);
341         }
342         return res;
343     }
344 
345     /**
346      * Builder class for {@link NetworkIdentity}.
347      */
348     public static final class Builder {
349         // Need to be synchronized with ConnectivityManager.
350         // TODO: Use {@link ConnectivityManager#MAX_NETWORK_TYPE} when this file is in the module.
351         private static final int MAX_NETWORK_TYPE = 18; // TYPE_TEST
352         private static final int MIN_NETWORK_TYPE = TYPE_MOBILE;
353 
354         private int mType;
355         private int mRatType;
356         private String mSubscriberId;
357         private String mWifiNetworkKey;
358         private boolean mRoaming;
359         private boolean mMetered;
360         private boolean mDefaultNetwork;
361         private int mOemManaged;
362         private int mSubId;
363 
364         /**
365          * Creates a new Builder.
366          */
Builder()367         public Builder() {
368             // Initialize with default values. Will be overwritten by setters.
369             mType = ConnectivityManager.TYPE_NONE;
370             mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
371             mSubscriberId = null;
372             mWifiNetworkKey = null;
373             mRoaming = false;
374             mMetered = false;
375             mDefaultNetwork = false;
376             mOemManaged = NetworkTemplate.OEM_MANAGED_NO;
377             mSubId = INVALID_SUBSCRIPTION_ID;
378         }
379 
380         /**
381          * Add an {@link NetworkStateSnapshot} into the {@link NetworkIdentity} instance.
382          * This is a useful shorthand that will read from the snapshot and set the
383          * following fields, if they are set in the snapshot :
384          *  - type
385          *  - subscriberId
386          *  - roaming
387          *  - metered
388          *  - oemManaged
389          *  - wifiNetworkKey
390          *
391          * @param snapshot The target {@link NetworkStateSnapshot} object.
392          * @return The builder object.
393          */
394         @SuppressLint("MissingGetterMatchingBuilder")
395         @NonNull
setNetworkStateSnapshot(@onNull NetworkStateSnapshot snapshot)396         public Builder setNetworkStateSnapshot(@NonNull NetworkStateSnapshot snapshot) {
397             setType(snapshot.getLegacyType());
398 
399             setSubscriberId(snapshot.getSubscriberId());
400             setRoaming(!snapshot.getNetworkCapabilities().hasCapability(
401                     NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING));
402             setMetered(!(snapshot.getNetworkCapabilities().hasCapability(
403                     NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
404                     || snapshot.getNetworkCapabilities().hasCapability(
405                     NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)));
406 
407             setOemManaged(getOemBitfield(snapshot.getNetworkCapabilities()));
408 
409             if (mType == TYPE_WIFI) {
410                 final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
411                         .getTransportInfo();
412                 if (transportInfo instanceof WifiInfo) {
413                     final WifiInfo info = (WifiInfo) transportInfo;
414                     setWifiNetworkKey(info.getNetworkKey());
415                 }
416             }
417             return this;
418         }
419 
420         /**
421          * Set the network type of the network.
422          *
423          * @param type the network type. See {@link ConnectivityManager#TYPE_*}.
424          *
425          * @return this builder.
426          */
427         @NonNull
setType(int type)428         public Builder setType(int type) {
429             // Include TYPE_NONE for compatibility, type field might not be filled by some
430             // networks such as test networks.
431             if ((type < MIN_NETWORK_TYPE || MAX_NETWORK_TYPE < type)
432                     && type != ConnectivityManager.TYPE_NONE) {
433                 throw new IllegalArgumentException("Invalid network type: " + type);
434             }
435             mType = type;
436             return this;
437         }
438 
439         /**
440          * Set the Radio Access Technology(RAT) type of the network.
441          *
442          * No RAT type is specified by default. Call clearRatType to reset.
443          *
444          * @param ratType the Radio Access Technology(RAT) type if applicable. See
445          *                {@code TelephonyManager.NETWORK_TYPE_*}.
446          *
447          * @return this builder.
448          */
449         @NonNull
setRatType(int ratType)450         public Builder setRatType(int ratType) {
451             if (!CollectionUtils.contains(TelephonyManager.getAllNetworkTypes(), ratType)
452                     && ratType != TelephonyManager.NETWORK_TYPE_UNKNOWN
453                     && ratType != NetworkStatsManager.NETWORK_TYPE_5G_NSA) {
454                 throw new IllegalArgumentException("Invalid ratType " + ratType);
455             }
456             mRatType = ratType;
457             return this;
458         }
459 
460         /**
461          * Clear the Radio Access Technology(RAT) type of the network.
462          *
463          * @return this builder.
464          */
465         @NonNull
clearRatType()466         public Builder clearRatType() {
467             mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
468             return this;
469         }
470 
471         /**
472          * Set the Subscriber Id.
473          *
474          * @param subscriberId the Subscriber Id of the network. Or null if not applicable.
475          * @return this builder.
476          */
477         @NonNull
setSubscriberId(@ullable String subscriberId)478         public Builder setSubscriberId(@Nullable String subscriberId) {
479             mSubscriberId = subscriberId;
480             return this;
481         }
482 
483         /**
484          * Set the Wifi Network Key.
485          *
486          * @param wifiNetworkKey Wifi Network Key of the network,
487          *                        see {@link WifiInfo#getNetworkKey()}.
488          *                        Or null if not applicable.
489          * @return this builder.
490          */
491         @NonNull
setWifiNetworkKey(@ullable String wifiNetworkKey)492         public Builder setWifiNetworkKey(@Nullable String wifiNetworkKey) {
493             mWifiNetworkKey = wifiNetworkKey;
494             return this;
495         }
496 
497         /**
498          * Set whether this network is roaming.
499          *
500          * This field is false by default. Call with false to reset.
501          *
502          * @param roaming the roaming status of the network.
503          * @return this builder.
504          */
505         @NonNull
setRoaming(boolean roaming)506         public Builder setRoaming(boolean roaming) {
507             mRoaming = roaming;
508             return this;
509         }
510 
511         /**
512          * Set whether this network is metered.
513          *
514          * This field is false by default. Call with false to reset.
515          *
516          * @param metered the meteredness of the network.
517          * @return this builder.
518          */
519         @NonNull
setMetered(boolean metered)520         public Builder setMetered(boolean metered) {
521             mMetered = metered;
522             return this;
523         }
524 
525         /**
526          * Set whether this network is the default network.
527          *
528          * This field is false by default. Call with false to reset.
529          *
530          * @param defaultNetwork the default network status of the network.
531          * @return this builder.
532          */
533         @NonNull
setDefaultNetwork(boolean defaultNetwork)534         public Builder setDefaultNetwork(boolean defaultNetwork) {
535             mDefaultNetwork = defaultNetwork;
536             return this;
537         }
538 
539         /**
540          * Set the OEM managed type.
541          *
542          * @param oemManaged Type of OEM managed network or unmanaged networks.
543          *                   See {@code NetworkTemplate#OEM_MANAGED_*}.
544          * @return this builder.
545          */
546         @NonNull
setOemManaged(@emManaged int oemManaged)547         public Builder setOemManaged(@OemManaged int oemManaged) {
548             // Assert input does not contain illegal oemManage bits.
549             if ((~SUPPORTED_OEM_MANAGED_TYPES & oemManaged) != 0) {
550                 throw new IllegalArgumentException("Invalid value for OemManaged : " + oemManaged);
551             }
552             mOemManaged = oemManaged;
553             return this;
554         }
555 
556         /**
557          * Set the Subscription Id.
558          *
559          * @param subId the Subscription Id of the network. Or INVALID_SUBSCRIPTION_ID if not
560          *              applicable.
561          * @return this builder.
562          */
563         @NonNull
setSubId(int subId)564         public Builder setSubId(int subId) {
565             mSubId = subId;
566             return this;
567         }
568 
ensureValidParameters()569         private void ensureValidParameters() {
570             // Assert non-mobile network cannot have a ratType.
571             if (mType != TYPE_MOBILE && mRatType != NetworkTemplate.NETWORK_TYPE_ALL) {
572                 throw new IllegalArgumentException(
573                         "Invalid ratType " + mRatType + " for type " + mType);
574             }
575 
576             // Assert non-wifi network cannot have a wifi network key.
577             if (mType != TYPE_WIFI && mWifiNetworkKey != null) {
578                 throw new IllegalArgumentException("Invalid wifi network key for type " + mType);
579             }
580         }
581 
582         /**
583          * Builds the instance of the {@link NetworkIdentity}.
584          *
585          * @return the built instance of {@link NetworkIdentity}.
586          */
587         @NonNull
build()588         public NetworkIdentity build() {
589             ensureValidParameters();
590             return new NetworkIdentity(mType, mRatType, mSubscriberId, mWifiNetworkKey,
591                     mRoaming, mMetered, mDefaultNetwork, mOemManaged, mSubId);
592         }
593     }
594 }
595