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 import static android.net.ConnectivityManager.getNetworkTypeName; 21 import static android.net.ConnectivityManager.isNetworkTypeMobile; 22 23 import android.content.Context; 24 import android.net.wifi.WifiInfo; 25 import android.net.wifi.WifiManager; 26 import android.os.Build; 27 import android.telephony.TelephonyManager; 28 29 import com.android.internal.util.Objects; 30 31 /** 32 * Network definition that includes strong identity. Analogous to combining 33 * {@link NetworkInfo} and an IMSI. 34 * 35 * @hide 36 */ 37 public class NetworkIdentity { 38 /** 39 * When enabled, combine all {@link #mSubType} together under 40 * {@link #SUBTYPE_COMBINED}. 41 */ 42 public static final boolean COMBINE_SUBTYPE_ENABLED = true; 43 44 public static final int SUBTYPE_COMBINED = -1; 45 46 final int mType; 47 final int mSubType; 48 final String mSubscriberId; 49 final String mNetworkId; 50 final boolean mRoaming; 51 52 public NetworkIdentity( 53 int type, int subType, String subscriberId, String networkId, boolean roaming) { 54 mType = type; 55 mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType; 56 mSubscriberId = subscriberId; 57 mNetworkId = networkId; 58 mRoaming = roaming; 59 } 60 61 @Override 62 public int hashCode() { 63 return Objects.hashCode(mType, mSubType, mSubscriberId, mNetworkId, mRoaming); 64 } 65 66 @Override 67 public boolean equals(Object obj) { 68 if (obj instanceof NetworkIdentity) { 69 final NetworkIdentity ident = (NetworkIdentity) obj; 70 return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming 71 && Objects.equal(mSubscriberId, ident.mSubscriberId) 72 && Objects.equal(mNetworkId, ident.mNetworkId); 73 } 74 return false; 75 } 76 77 @Override 78 public String toString() { 79 final StringBuilder builder = new StringBuilder("["); 80 builder.append("type=").append(getNetworkTypeName(mType)); 81 builder.append(", subType="); 82 if (COMBINE_SUBTYPE_ENABLED) { 83 builder.append("COMBINED"); 84 } else if (ConnectivityManager.isNetworkTypeMobile(mType)) { 85 builder.append(TelephonyManager.getNetworkTypeName(mSubType)); 86 } else { 87 builder.append(mSubType); 88 } 89 if (mSubscriberId != null) { 90 builder.append(", subscriberId=").append(scrubSubscriberId(mSubscriberId)); 91 } 92 if (mNetworkId != null) { 93 builder.append(", networkId=").append(mNetworkId); 94 } 95 if (mRoaming) { 96 builder.append(", ROAMING"); 97 } 98 return builder.append("]").toString(); 99 } 100 101 public int getType() { 102 return mType; 103 } 104 105 public int getSubType() { 106 return mSubType; 107 } 108 109 public String getSubscriberId() { 110 return mSubscriberId; 111 } 112 113 public String getNetworkId() { 114 return mNetworkId; 115 } 116 117 public boolean getRoaming() { 118 return mRoaming; 119 } 120 121 /** 122 * Scrub given IMSI on production builds. 123 */ 124 public static String scrubSubscriberId(String subscriberId) { 125 if ("eng".equals(Build.TYPE)) { 126 return subscriberId; 127 } else if (subscriberId != null) { 128 // TODO: parse this as MCC+MNC instead of hard-coding 129 return subscriberId.substring(0, Math.min(6, subscriberId.length())) + "..."; 130 } else { 131 return "null"; 132 } 133 } 134 135 /** 136 * Build a {@link NetworkIdentity} from the given {@link NetworkState}, 137 * assuming that any mobile networks are using the current IMSI. 138 */ 139 public static NetworkIdentity buildNetworkIdentity(Context context, NetworkState state) { 140 final int type = state.networkInfo.getType(); 141 final int subType = state.networkInfo.getSubtype(); 142 143 // TODO: consider moving subscriberId over to LinkCapabilities, so it 144 // comes from an authoritative source. 145 146 String subscriberId = null; 147 String networkId = null; 148 boolean roaming = false; 149 150 if (isNetworkTypeMobile(type)) { 151 final TelephonyManager telephony = (TelephonyManager) context.getSystemService( 152 Context.TELEPHONY_SERVICE); 153 roaming = telephony.isNetworkRoaming(); 154 if (state.subscriberId != null) { 155 subscriberId = state.subscriberId; 156 } else { 157 subscriberId = telephony.getSubscriberId(); 158 } 159 160 } else if (type == TYPE_WIFI) { 161 if (state.networkId != null) { 162 networkId = state.networkId; 163 } else { 164 final WifiManager wifi = (WifiManager) context.getSystemService( 165 Context.WIFI_SERVICE); 166 final WifiInfo info = wifi.getConnectionInfo(); 167 networkId = info != null ? info.getSSID() : null; 168 } 169 } 170 171 return new NetworkIdentity(type, subType, subscriberId, networkId, roaming); 172 } 173 } 174