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.net.ConnectivityManager.TYPE_WIFI; 20 21 import android.annotation.Nullable; 22 import android.content.Context; 23 import android.net.wifi.WifiInfo; 24 import android.net.wifi.WifiManager; 25 import android.service.NetworkIdentityProto; 26 import android.telephony.Annotation.NetworkType; 27 import android.util.proto.ProtoOutputStream; 28 29 import com.android.net.module.util.NetworkIdentityUtils; 30 31 import java.util.Objects; 32 33 /** 34 * Network definition that includes strong identity. Analogous to combining 35 * {@link NetworkCapabilities} and an IMSI. 36 * 37 * @hide 38 */ 39 public class NetworkIdentity implements Comparable<NetworkIdentity> { 40 private static final String TAG = "NetworkIdentity"; 41 42 public static final int SUBTYPE_COMBINED = -1; 43 44 /** 45 * Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}. 46 * @hide 47 */ 48 public static final int OEM_NONE = 0x0; 49 /** 50 * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}. 51 * @hide 52 */ 53 public static final int OEM_PAID = 0x1; 54 /** 55 * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}. 56 * @hide 57 */ 58 public static final int OEM_PRIVATE = 0x2; 59 60 final int mType; 61 final int mSubType; 62 final String mSubscriberId; 63 final String mNetworkId; 64 final boolean mRoaming; 65 final boolean mMetered; 66 final boolean mDefaultNetwork; 67 final int mOemManaged; 68 NetworkIdentity( int type, int subType, String subscriberId, String networkId, boolean roaming, boolean metered, boolean defaultNetwork, int oemManaged)69 public NetworkIdentity( 70 int type, int subType, String subscriberId, String networkId, boolean roaming, 71 boolean metered, boolean defaultNetwork, int oemManaged) { 72 mType = type; 73 mSubType = subType; 74 mSubscriberId = subscriberId; 75 mNetworkId = networkId; 76 mRoaming = roaming; 77 mMetered = metered; 78 mDefaultNetwork = defaultNetwork; 79 mOemManaged = oemManaged; 80 } 81 82 @Override hashCode()83 public int hashCode() { 84 return Objects.hash(mType, mSubType, mSubscriberId, mNetworkId, mRoaming, mMetered, 85 mDefaultNetwork, mOemManaged); 86 } 87 88 @Override equals(@ullable Object obj)89 public boolean equals(@Nullable Object obj) { 90 if (obj instanceof NetworkIdentity) { 91 final NetworkIdentity ident = (NetworkIdentity) obj; 92 return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming 93 && Objects.equals(mSubscriberId, ident.mSubscriberId) 94 && Objects.equals(mNetworkId, ident.mNetworkId) 95 && mMetered == ident.mMetered 96 && mDefaultNetwork == ident.mDefaultNetwork 97 && mOemManaged == ident.mOemManaged; 98 } 99 return false; 100 } 101 102 @Override toString()103 public String toString() { 104 final StringBuilder builder = new StringBuilder("{"); 105 builder.append("type=").append(mType); 106 builder.append(", subType="); 107 if (mSubType == SUBTYPE_COMBINED) { 108 builder.append("COMBINED"); 109 } else { 110 builder.append(mSubType); 111 } 112 if (mSubscriberId != null) { 113 builder.append(", subscriberId=") 114 .append(NetworkIdentityUtils.scrubSubscriberId(mSubscriberId)); 115 } 116 if (mNetworkId != null) { 117 builder.append(", networkId=").append(mNetworkId); 118 } 119 if (mRoaming) { 120 builder.append(", ROAMING"); 121 } 122 builder.append(", metered=").append(mMetered); 123 builder.append(", defaultNetwork=").append(mDefaultNetwork); 124 // TODO(180557699): Print a human readable string for OEM managed state. 125 builder.append(", oemManaged=").append(mOemManaged); 126 return builder.append("}").toString(); 127 } 128 dumpDebug(ProtoOutputStream proto, long tag)129 public void dumpDebug(ProtoOutputStream proto, long tag) { 130 final long start = proto.start(tag); 131 132 proto.write(NetworkIdentityProto.TYPE, mType); 133 134 // Not dumping mSubType, subtypes are no longer supported. 135 136 if (mSubscriberId != null) { 137 proto.write(NetworkIdentityProto.SUBSCRIBER_ID, 138 NetworkIdentityUtils.scrubSubscriberId(mSubscriberId)); 139 } 140 proto.write(NetworkIdentityProto.NETWORK_ID, mNetworkId); 141 proto.write(NetworkIdentityProto.ROAMING, mRoaming); 142 proto.write(NetworkIdentityProto.METERED, mMetered); 143 proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork); 144 proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged); 145 146 proto.end(start); 147 } 148 getType()149 public int getType() { 150 return mType; 151 } 152 getSubType()153 public int getSubType() { 154 return mSubType; 155 } 156 getSubscriberId()157 public String getSubscriberId() { 158 return mSubscriberId; 159 } 160 getNetworkId()161 public String getNetworkId() { 162 return mNetworkId; 163 } 164 getRoaming()165 public boolean getRoaming() { 166 return mRoaming; 167 } 168 getMetered()169 public boolean getMetered() { 170 return mMetered; 171 } 172 getDefaultNetwork()173 public boolean getDefaultNetwork() { 174 return mDefaultNetwork; 175 } 176 getOemManaged()177 public int getOemManaged() { 178 return mOemManaged; 179 } 180 181 /** 182 * Build a {@link NetworkIdentity} from the given {@link NetworkStateSnapshot} and 183 * {@code subType}, assuming that any mobile networks are using the current IMSI. 184 * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_* 185 * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not. 186 */ buildNetworkIdentity(Context context, NetworkStateSnapshot snapshot, boolean defaultNetwork, @NetworkType int subType)187 public static NetworkIdentity buildNetworkIdentity(Context context, 188 NetworkStateSnapshot snapshot, boolean defaultNetwork, @NetworkType int subType) { 189 final int legacyType = snapshot.getLegacyType(); 190 191 final String subscriberId = snapshot.getSubscriberId(); 192 String networkId = null; 193 boolean roaming = !snapshot.getNetworkCapabilities().hasCapability( 194 NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 195 boolean metered = !snapshot.getNetworkCapabilities().hasCapability( 196 NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 197 198 final int oemManaged = getOemBitfield(snapshot.getNetworkCapabilities()); 199 200 if (legacyType == TYPE_WIFI) { 201 networkId = snapshot.getNetworkCapabilities().getSsid(); 202 if (networkId == null) { 203 final WifiManager wifi = context.getSystemService(WifiManager.class); 204 final WifiInfo info = wifi.getConnectionInfo(); 205 networkId = info != null ? info.getSSID() : null; 206 } 207 } 208 209 return new NetworkIdentity(legacyType, subType, subscriberId, networkId, roaming, metered, 210 defaultNetwork, oemManaged); 211 } 212 213 /** 214 * Builds a bitfield of {@code NetworkIdentity.OEM_*} based on {@link NetworkCapabilities}. 215 * @hide 216 */ getOemBitfield(NetworkCapabilities nc)217 public static int getOemBitfield(NetworkCapabilities nc) { 218 int oemManaged = OEM_NONE; 219 220 if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)) { 221 oemManaged |= OEM_PAID; 222 } 223 if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)) { 224 oemManaged |= OEM_PRIVATE; 225 } 226 227 return oemManaged; 228 } 229 230 @Override compareTo(NetworkIdentity another)231 public int compareTo(NetworkIdentity another) { 232 int res = Integer.compare(mType, another.mType); 233 if (res == 0) { 234 res = Integer.compare(mSubType, another.mSubType); 235 } 236 if (res == 0 && mSubscriberId != null && another.mSubscriberId != null) { 237 res = mSubscriberId.compareTo(another.mSubscriberId); 238 } 239 if (res == 0 && mNetworkId != null && another.mNetworkId != null) { 240 res = mNetworkId.compareTo(another.mNetworkId); 241 } 242 if (res == 0) { 243 res = Boolean.compare(mRoaming, another.mRoaming); 244 } 245 if (res == 0) { 246 res = Boolean.compare(mMetered, another.mMetered); 247 } 248 if (res == 0) { 249 res = Boolean.compare(mDefaultNetwork, another.mDefaultNetwork); 250 } 251 if (res == 0) { 252 res = Integer.compare(mOemManaged, another.mOemManaged); 253 } 254 return res; 255 } 256 } 257